From f53d0df26ddb54b007771fa979085b918c5ace4f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 19 Jul 2016 12:57:26 +0200 Subject: [PATCH] implement gj and gk --- vim-sample/README.md | 6 ++- vim-sample/src/mappings.ts | 46 ++++++++++++++-------- vim-sample/src/motions.ts | 81 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 18 deletions(-) diff --git a/vim-sample/README.md b/vim-sample/README.md index 9cb3ba67..1e257440 100644 --- a/vim-sample/README.md +++ b/vim-sample/README.md @@ -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 diff --git a/vim-sample/src/mappings.ts b/vim-sample/src/mappings.ts index 9789f1b1..593c1607 100644 --- a/vim-sample/src/mappings.ts +++ b/vim-sample/src/mappings.ts @@ -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); } } diff --git a/vim-sample/src/motions.ts b/vim-sample/src/motions.ts index d6debf7c..e7d15e90 100644 --- a/vim-sample/src/motions.ts +++ b/vim-sample/src/motions.ts @@ -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(), };