Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special keys in Insert Mode #615

Merged
merged 5 commits into from
Sep 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,20 +246,20 @@ Status | Command | Description
---|--------|------------------------------
| CTRL-V {char}.. | insert character literally, or enter decimal byte value
:warning: | NL or CR or CTRL-M or CTRL-J | begin new line
| CTRL-E | insert the character from below the cursor
| CTRL-Y | insert the character from above the cursor
:white_check_mark: | CTRL-E | insert the character from below the cursor
:white_check_mark: | CTRL-Y | insert the character from above the cursor
| CTRL-A | insert previously inserted text
| CTRL-@ | insert previously inserted text and stop Insert mode
| CTRL-R {0-9a-z%#:.-="} | insert the contents of a register
:white_check_mark: | CTRL-R {0-9a-z%#:.-="} | insert the contents of a register
| CTRL-N | insert next match of identifier before the cursor
| CTRL-P | insert previous match of identifier before the cursor
| CTRL-X ... | complete the word before the cursor in various ways
| BS or CTRL-H | delete the character before the cursor
:white_check_mark: | Del | delete the character under the cursor
:white_check_mark: | CTRL-W | delete word before the cursor
| CTRL-U | delete all entered characters in the current line
| CTRL-T | insert one shiftwidth of indent in front of the current line
| CTRL-D | delete one shiftwidth of indent in front of the current line
:white_check_mark: | BS or CTRL-H | delete the character before the cursor
:white_check_mark: | Del | delete the character under the cursor
:white_check_mark: | CTRL-W | delete word before the cursor
:white_check_mark: | CTRL-U | delete all entered characters in the current line
:white_check_mark: | CTRL-T | insert one shiftwidth of indent in front of the current line
:white_check_mark: | CTRL-D | delete one shiftwidth of indent in front of the current line
| 0 CTRL-D | delete all indent in the current line
| ^ CTRL-D | delete all indent in the current line, restore indent in next line

Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@
"command": "extension.vim_ctrl+b",
"when": "editorTextFocus && vim.mode != 'Insert Mode'"
},
{
"key": "ctrl+h",
"command": "extension.vim_ctrl+h",
"when": "editorTextFocus && vim.mode == 'Insert Mode'"
},
{
"key": "ctrl+e",
"command": "extension.vim_ctrl+e",
Expand All @@ -100,7 +105,7 @@
{
"key": "ctrl+d",
"command": "extension.vim_ctrl+d",
"when": "editorTextFocus"
"when": "editorTextFocus && vim.useCtrlKeys"
},
{
"key": "ctrl+[",
Expand All @@ -127,6 +132,11 @@
"command": "extension.vim_ctrl+x",
"when": "editorTextFocus && vim.useCtrlKeys"
},
{
"key": "ctrl+t",
"command": "extension.vim_ctrl+t",
"when": "editorTextFocus && vim.useCtrlKeys"
},
{
"key": "left",
"command": "extension.vim_left",
Expand Down
174 changes: 173 additions & 1 deletion src/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,49 @@ class CommandRegister extends BaseCommand {
}
}

@RegisterAction
class CommandInsertRegisterContent extends BaseCommand {
modes = [ModeName.Insert];
keys = ["ctrl+r", "<character>"];
isCompleteAction = false;

public async exec(position: Position, vimState: VimState): Promise<VimState> {
vimState.recordedState.registerName = this.keysPressed[1];
const register = await Register.get(vimState);
let text: string;

if (register.text instanceof Array) {
text = (register.text as string []).join("\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast is actually unnecessary here due to the magic of typescript 2.0 and discriminated union types! :)

} else {
text = register.text;
}

if (register.registerMode === RegisterMode.LineWise) {
text += "\n";
}

await TextEditor.insertAt(text, position);
vimState.currentMode = ModeName.Insert;
vimState.cursorStartPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);
vimState.cursorPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);

return vimState;
}

public doesActionApply(vimState: VimState, keysPressed: string[]): boolean {
const register = keysPressed[1];

return super.doesActionApply(vimState, keysPressed) && Register.isValidRegister(register);
}

public couldActionApply(vimState: VimState, keysPressed: string[]): boolean {
const register = keysPressed[1];

return super.couldActionApply(vimState, keysPressed) && Register.isValidRegister(register);
}

}

@RegisterAction
class CommandEsc extends BaseCommand {
modes = [
Expand Down Expand Up @@ -472,6 +515,81 @@ class CommandCtrlE extends BaseCommand {
}
}

@RegisterAction
class CommandInsertBelowChar extends BaseCommand {
modes = [ModeName.Insert];
keys = ["ctrl+e"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
if (TextEditor.isLastLine(position)) {
return vimState;
}

const charBelowCursorPosition = position.getDownByCount(1);

if (charBelowCursorPosition.isLineEnd()) {
return vimState;
}

const char = TextEditor.getText(new vscode.Range(charBelowCursorPosition, charBelowCursorPosition.getRight()));
await TextEditor.insert(char, position);

vimState.cursorStartPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);
vimState.cursorPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);

return vimState;
}
}

@RegisterAction
class CommandInsertIndentInCurrentLine extends BaseCommand {
modes = [ModeName.Insert];
keys = ["<C-t>"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
const originalText = TextEditor.getLineAt(position).text;
const indentationWidth = TextEditor.getIndentationLevel(originalText);
const tabSize = Configuration.getInstance().tabstop;
const newIndentationWidth = (indentationWidth / tabSize + 1) * tabSize;
await TextEditor.replace(new vscode.Range(position.getLineBegin(), position.getLineEnd()),
TextEditor.setIndentationLevel(originalText, newIndentationWidth));

const cursorPosition = Position.FromVSCodePosition(position.with(position.line,
position.character + (newIndentationWidth - indentationWidth) / tabSize));
vimState.cursorPosition = cursorPosition;
vimState.cursorStartPosition = cursorPosition;
vimState.currentMode = ModeName.Insert;
return vimState;
}
}

@RegisterAction
class CommandDeleteIndentInCurrentLine extends BaseCommand {
modes = [ModeName.Insert];
keys = ["<C-d>"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
const originalText = TextEditor.getLineAt(position).text;
const indentationWidth = TextEditor.getIndentationLevel(originalText);

if (indentationWidth === 0) {
return vimState;
}

const tabSize = Configuration.getInstance().tabstop;
const newIndentationWidth = (indentationWidth / tabSize - 1) * tabSize;
await TextEditor.replace(new vscode.Range(position.getLineBegin(), position.getLineEnd()),
TextEditor.setIndentationLevel(originalText, newIndentationWidth < 0 ? 0 : newIndentationWidth));

const cursorPosition = Position.FromVSCodePosition(position.with(position.line,
position.character + (newIndentationWidth - indentationWidth) / tabSize ));
vimState.cursorPosition = cursorPosition;
vimState.cursorStartPosition = cursorPosition;
vimState.currentMode = ModeName.Insert;
return vimState;
}
}

@RegisterAction
class CommandCtrlY extends BaseCommand {
modes = [ModeName.Normal];
Expand All @@ -484,6 +602,32 @@ class CommandCtrlY extends BaseCommand {
}
}

@RegisterAction
class CommandInsertAboveChar extends BaseCommand {
modes = [ModeName.Insert];
keys = ["ctrl+y"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
if (TextEditor.isFirstLine(position)) {
return vimState;
}

const charAboveCursorPosition = position.getUpByCount(1);

if (charAboveCursorPosition.isLineEnd()) {
return vimState;
}

const char = TextEditor.getText(new vscode.Range(charAboveCursorPosition, charAboveCursorPosition.getRight()));
await TextEditor.insert(char, position);

vimState.cursorStartPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);
vimState.cursorPosition = Position.FromVSCodePosition(vscode.window.activeTextEditor.selection.start);

return vimState;
}
}

@RegisterAction
class CommandCtrlC extends CommandEsc {
keys = ["<C-c>"];
Expand Down Expand Up @@ -743,7 +887,7 @@ class CommandInsertInInsertMode extends BaseCommand {
// The hard case is . where we have to track cursor pos since we don't
// update the view
public async exec(position: Position, vimState: VimState): Promise<VimState> {
const char = this.keysPressed[this.keysPressed.length - 1];
const char = this.keysPressed[this.keysPressed.length - 1];

if (char === "<BS>") {
const newPosition = await TextEditor.backspace(position);
Expand All @@ -766,6 +910,34 @@ class CommandInsertInInsertMode extends BaseCommand {
}
}

@RegisterAction
class CommandCtrlHInInsertMode extends BaseCommand {
modes = [ModeName.Insert];
keys = ["ctrl+h"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
const newPosition = await TextEditor.backspace(position);
vimState.cursorPosition = newPosition;
vimState.cursorStartPosition = newPosition;
return vimState;
}
}

@RegisterAction
class CommandCtrlUInInsertMode extends BaseCommand {
modes = [ModeName.Insert];
keys = ["ctrl+u"];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
const start = position.getLineBegin();
const stop = position.getLineEnd();
await TextEditor.delete(new vscode.Range(start, stop));
vimState.cursorPosition = start;
vimState.cursorStartPosition = start;
return vimState;
}
}

@RegisterAction
export class CommandSearchForwards extends BaseCommand {
modes = [ModeName.Normal];
Expand Down