From 543f6ce23093b3ca51880bec28d3cd7f02ac7801 Mon Sep 17 00:00:00 2001 From: Mark Rendle Date: Wed, 2 Dec 2015 20:12:33 +0200 Subject: [PATCH] Added block cursor when in Normal mode --- extension.ts | 8 +++++--- src/cursor/cursor.ts | 35 +++++++++++++++++++++++++++++++++++ src/mode/modeHandler.ts | 11 +++++++++++ test/caret.test.ts | 2 +- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/extension.ts b/extension.ts index f0087cf417c..4e5742e32dd 100644 --- a/extension.ts +++ b/extension.ts @@ -6,6 +6,7 @@ import {showCmdLine} from './src/cmd_line/main'; import * as cc from './src/cmd_line/lexer'; import ModeHandler from "./src/mode/modeHandler"; import {ModeName} from "./src/mode/mode"; +import Cursor from "./src/cursor/cursor"; var modeHandler : ModeHandler; @@ -13,6 +14,7 @@ var modeHandler : ModeHandler; // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { modeHandler = new ModeHandler(); + Cursor.blockCursor(modeHandler); console.log('Congratulations, your extension "vim" is now active!'); @@ -85,17 +87,17 @@ export function activate(context: vscode.ExtensionContext) { registerCommand(context, 'extension.vim_6', () => handleKeyEvent("6")); registerCommand(context, 'extension.vim_7', () => handleKeyEvent("7")); registerCommand(context, 'extension.vim_8', () => handleKeyEvent("8")); - registerCommand(context, 'extension.vim_9', () => handleKeyEvent("9")); + registerCommand(context, 'extension.vim_9', () => handleKeyEvent("9")); registerCommand(context, 'extension.vim_$', () => handleKeyEvent("$")); registerCommand(context, 'extension.vim_^', () => handleKeyEvent("^")); registerCommand(context, 'extension.vim_ctrl_r', () => handleKeyEvent("ctrl+r")); registerCommand(context, 'extension.vim_ctrl_[', () => handleKeyEvent("ctrl+[")); - + registerCommand(context, 'extension.vim_<', () => handleKeyEvent("<")); registerCommand(context, 'extension.vim_>', () => handleKeyEvent(">")); - + registerCommand(context, 'extension.vim_backslash', () => handleKeyEvent("\\")); } diff --git a/src/cursor/cursor.ts b/src/cursor/cursor.ts index 888a031a9d0..1732ef0ec4f 100644 --- a/src/cursor/cursor.ts +++ b/src/cursor/cursor.ts @@ -1,6 +1,21 @@ import * as _ from "lodash"; import * as vscode from "vscode"; import TextEditor from "./../textEditor"; +import {ModeName} from './../mode/mode'; +import ModeHandler from "./../mode/modeHandler"; + +const blockCursorDecoration = vscode.window.createTextEditorDecorationType({ + dark: { + backgroundColor: 'rgba(224, 224, 224, 0.5)', + borderColor: 'rgba(240, 240, 240, 0.8)' + }, + light: { + backgroundColor: 'rgba(32, 32, 32, 0.5)', + borderColor: 'rgba(16, 16, 16, 0.8)' + }, + borderStyle: 'solid', + borderWidth: '1px' +}); export default class Cursor { private static prevColumn: number = 0; @@ -154,6 +169,26 @@ export default class Cursor { return new vscode.Position(line, column); } + static blockCursor(modeHandler: ModeHandler) : void { + vscode.window.onDidChangeTextEditorSelection((e) => { + if (modeHandler.currentMode.Name !== ModeName.Normal) { + return; + } + if (e.selections.length === 1) { + let sel = e.selections[0]; + if (sel.start.isEqual(sel.end)) { + let range = new vscode.Range(sel.start, sel.end.translate(0, 1)); + e.textEditor.setDecorations(blockCursorDecoration, [range]); + } + } + }); + modeHandler.onModeChanged((mode) => { + if (mode.Name !== ModeName.Normal) { + vscode.window.activeTextEditor.setDecorations(blockCursorDecoration, []); + } + }); + } + private static isLineBeginning(position : vscode.Position) : boolean { return position.character === 0; } diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index 6886b88cd44..2c2d1149ff0 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -7,8 +7,11 @@ import InsertMode from './modeInsert'; import VisualMode from './modeVisual'; import Configuration from '../configuration'; +type ModeChangedHandler = (mode: Mode) => void; + export default class ModeHandler { private modes : Mode[]; + private modeChangedHandlers: ModeChangedHandler[] = []; private statusBarItem : vscode.StatusBarItem; configuration : Configuration; @@ -39,6 +42,10 @@ export default class ModeHandler { var statusBarText = (this.currentMode.Name === ModeName.Normal) ? '' : ModeName[modeName]; this.setupStatusBarItem(statusBarText.toUpperCase()); + + for (let handler of this.modeChangedHandlers) { + handler(this.currentMode); + } } handleKeyEvent(key : string) : void { @@ -68,6 +75,10 @@ export default class ModeHandler { this.currentMode.HandleKeyEvent(key); } + onModeChanged(handler: (newMode: Mode) => void) : void { + this.modeChangedHandlers.push(handler); + } + private setupStatusBarItem(text : string) : void { if (!this.statusBarItem) { this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); diff --git a/test/caret.test.ts b/test/caret.test.ts index 6f7b937a6a9..20d298dd8b9 100644 --- a/test/caret.test.ts +++ b/test/caret.test.ts @@ -18,7 +18,7 @@ suite("caret", () => { let range = new vscode.Range(Caret.documentBegin(), Caret.documentEnd()); TextEditor.delete(range).then(() => done()); }); - + test("right on right-most column should stay at the same location", () => { Caret.move(new vscode.Position(0, 7));