implement gj and gk

This commit is contained in:
Sandeep Somavarapu
2016-07-19 12:57:26 +02:00
parent 108986dde7
commit f53d0df26d
3 changed files with 115 additions and 18 deletions

View File

@ -44,8 +44,8 @@ Motions:
* `$` - end of line
* `0` - start of line
* `h` - left
* `j` - down
* `k` - up
* `j` - down by `n` lines
* `k` - up by `n` lines
* `l` - right
* `G` - go to line
* `gg` - go to first line
@ -53,6 +53,8 @@ Motions:
* `g^` - go to first non whitespace character of screen line
* `gm` - go to middle of screen line
* `g$` - go to end of screen line
* `gj` - down by `n` screen lines
* `gk` - up by `n` screen lines
Commands/Operators:
* `x` - delete char under cursor

View File

@ -5,7 +5,7 @@
'use strict';
import {TextEditor} from 'vscode';
import {Motion, Motions} from './motions';
import {Motion, Motions, MotionCommand} from './motions';
import {Operator, Operators} from './operators';
import {IController, Command} from './common';
@ -14,25 +14,33 @@ const CHAR_TO_MOTION: { [char: string]: Motion; } = {};
function defineMotion(char: string, motion: Motion): void {
CHAR_TO_MOTION[char] = motion;
};
defineMotion('w', Motions.NextWordStart);
defineMotion('e', Motions.NextWordEnd);
defineMotion('$', Motions.EndOfLine);
defineMotion('0', Motions.StartOfLine);
const CHAR_TO_MOTION_COMMAND: { [char: string]: MotionCommand; } = {};
function defineMotionCommand(char: string, motionCommand: MotionCommand): void {
CHAR_TO_MOTION_COMMAND[char] = motionCommand;
};
// Left-right motions
defineMotion('h', Motions.Left);
defineMotion('l', Motions.Right);
defineMotion('0', Motions.StartOfLine);
defineMotion('$', Motions.EndOfLine);
defineMotionCommand('g0', Motions.LineStart);
defineMotionCommand('g^', Motions.LineFirstNonWhiteSpaceCharacter);
defineMotionCommand('gm', Motions.LineColumnCenter);
defineMotionCommand('g$', Motions.LineEnd);
// Up-down motions
defineMotion('j', Motions.Down);
defineMotion('k', Motions.Up);
defineMotion('l', Motions.Right);
defineMotionCommand('gj', Motions.ViewLineDown);
defineMotionCommand('gk', Motions.ViewLineUp);
defineMotion('G', Motions.GoToLine);
defineMotion('gg', Motions.GoToFirstLine);
const CHAR_TO_MOTION_COMMAND: { [char: string]: Command; } = {};
function defineMotionCommand(char: string, commandId: string, args?: any): void {
CHAR_TO_MOTION_COMMAND[char] = {commandId : commandId, args: args};
};
defineMotionCommand('g0', 'cursorMove', {to: 'lineStart'});
defineMotionCommand('g^', 'cursorMove', {to: 'lineFirstNonWhitespaceCharacter'});
defineMotionCommand('gm', 'cursorMove', {to: 'lineColumnCenter'});
defineMotionCommand('g$', 'cursorMove', {to: 'lineEnd'});
// Word motions
defineMotion('w', Motions.NextWordStart);
defineMotion('e', Motions.NextWordEnd);
const CHAR_TO_OPERATOR: { [char: string]: Operator; } = {};
@ -82,7 +90,13 @@ export class Mappings {
if (!motionCommand) {
motionCommand = CHAR_TO_MOTION_COMMAND[parsed.input.substr(0, 2)];
}
return motionCommand;
if (!motionCommand) {
motionCommand = CHAR_TO_MOTION_COMMAND[parsed.input.substr(1, 2)];
}
if (!motionCommand) {
motionCommand = CHAR_TO_MOTION_COMMAND[parsed.input.substr(1, 3)];
}
return motionCommand ? motionCommand.command(parsed.repeatCount) : null;
}
public static findOperator(input: string): IFoundOperator {
@ -113,7 +127,7 @@ export class Mappings {
if (input === 'g') {
return true;
}
return /^[1-9]\d*$/.test(input);
return /^[1-9]\d*g?$/.test(input);
}
}

View File

@ -6,6 +6,7 @@
import {Position, TextDocument} from 'vscode';
import {Words, WordCharacters} from './words';
import {Command} from './common';
export class MotionState {
@ -21,6 +22,12 @@ export class MotionState {
}
export abstract class MotionCommand {
public abstract command(args?: any): Command;
}
export abstract class Motion {
public abstract run(doc: TextDocument, pos: Position, state: MotionState): Position;
@ -243,6 +250,73 @@ class GoToLineDefinedMotion extends GoToLineMotion {
}
}
abstract class CursorMoveCommand extends MotionCommand {
constructor(private to: string) {
super();
}
public command(count?: number): Command {
let cursorMoveArgs= { to: this.to }
return {
commandId: 'cursorMove',
args: this.addArgs(cursorMoveArgs, count)
};
}
protected addArgs(cursorMoveArgs: any, count?: number): any {
return cursorMoveArgs;
}
}
class LineStartMotionCommand extends CursorMoveCommand {
constructor() {
super('lineStart');
}
}
class LineFirstNonWhiteSpaceCharacterMotionCommand extends CursorMoveCommand {
constructor() {
super('lineFirstNonWhitespaceCharacter');
}
}
class LineColumnCenterMotionCommand extends CursorMoveCommand {
constructor() {
super('lineColumnCenter');
}
}
class LineEndMotionCommand extends CursorMoveCommand {
constructor() {
super('lineEnd');
}
}
class ViewLineUpMotionCommand extends CursorMoveCommand {
constructor() {
super('lineUp');
}
protected addArgs(cursorMoveArgs: any, count?: number): any {
cursorMoveArgs.noOfLines= count || 1;
return super.addArgs(cursorMoveArgs);
}
}
class ViewLineDownMotionCommand extends CursorMoveCommand {
constructor() {
super('lineDown');
}
protected addArgs(cursorMoveArgs: any, count?: number): any {
cursorMoveArgs.noOfLines= count || 1;
return super.addArgs(cursorMoveArgs);
}
}
export const Motions = {
NextCharacter: new NextCharacterMotion(),
Left: new LeftMotion(),
@ -256,4 +330,11 @@ export const Motions = {
GoToLine: new GoToLineUndefinedMotion(),
GoToFirstLine: new GoToFirstLineMotion(),
GoToLastLine: new GoToLastLineMotion(),
LineStart: new LineStartMotionCommand(),
LineFirstNonWhiteSpaceCharacter: new LineFirstNonWhiteSpaceCharacterMotionCommand(),
LineColumnCenter: new LineColumnCenterMotionCommand(),
LineEnd: new LineEndMotionCommand(),
ViewLineUp: new ViewLineUpMotionCommand(),
ViewLineDown: new ViewLineDownMotionCommand(),
};