From f9de0a56614354c230e9768b58b33217f0f21599 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 11 Nov 2014 13:02:30 +0400 Subject: [PATCH] use ctrl-c and mac repeat handling from old vim mode --- lib/ace/keyboard/vim2.js | 147 +++++++++++++++++++++++++++++---------- 1 file changed, 112 insertions(+), 35 deletions(-) diff --git a/lib/ace/keyboard/vim2.js b/lib/ace/keyboard/vim2.js index 4b709888..0e860db1 100644 --- a/lib/ace/keyboard/vim2.js +++ b/lib/ace/keyboard/vim2.js @@ -91,6 +91,7 @@ define(function(require, exports, module) { var KEYS = require("../lib/keys"); var event = require("../lib/event"); var Search = require("../search").Search; + var useragent = require("../lib/useragent"); var SearchHighlight = require("../search_highlight").SearchHighlight; var multiSelectCommands = require("../commands/multi_select_commands"); require("../multi_select"); @@ -5719,6 +5720,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ exports.CodeMirror = CodeMirror; var getVim = Vim.maybeInitVimState_; exports.handler = { + $id: "ace/keyboard/vim", drawCursor: function(style, pixelPos, config, sel, session) { var vim = this.state.vim || {}; var w = config.characterWidth; @@ -5742,25 +5744,42 @@ dom.importCssString(".normal-mode .ace_cursor{\ style.height = h + "px"; }, handleKeyboard: function(data, hashId, key, keyCode, e) { - var cm = data.editor.state.cm; - var vim = getVim(cm); - if (keyCode == -1) return; - if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) { - var insertMode = vim.insertMode; - var name = lookupKey(hashId, key, e || {}); - if (vim.status == null) - vim.status = ""; - var isHandled = multiSelectHandleKey(cm, name, 'user'); - vim = getVim(cm); // may be changed by multiSelectHandleKey - if (isHandled && vim.status != null) - vim.status += name; - else if (vim.status == null) - vim.status = ""; - cm._signal("changeStatus"); - if (!isHandled && (hashId != -1 || insertMode)) - return; - return {command: "null", passEvent: !isHandled}; + var editor = data.editor; + var cm = editor.state.cm; + var vim = getVim(cm); + if (keyCode == -1) return; + + if (key == "c" && hashId == 1) { // key == "ctrl-c" + if (!useragent.isMac && editor.getCopyText()) { + editor.once("copy", function() { + editor.selection.clearSelection(); + }); + return {command: "null", passEvent: true}; } + return {command: coreCommands.stop}; + } else if (!vim.insertMode) { + if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) { + hashId = -1; + key = data.inputChar; + } + } + + if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) { + var insertMode = vim.insertMode; + var name = lookupKey(hashId, key, e || {}); + if (vim.status == null) + vim.status = ""; + var isHandled = multiSelectHandleKey(cm, name, 'user'); + vim = getVim(cm); // may be changed by multiSelectHandleKey + if (isHandled && vim.status != null) + vim.status += name; + else if (vim.status == null) + vim.status = ""; + cm._signal("changeStatus"); + if (!isHandled && (hashId != -1 || insertMode)) + return; + return {command: "null", passEvent: !isHandled}; + } }, attach: function(editor) { if (!editor.state) editor.state = {}; @@ -5786,7 +5805,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ }); cm.ace.renderer.setStyle("normal-mode", !getVim(cm).insertMode); editor.renderer.$cursorLayer.drawCursor = this.drawCursor.bind(cm); - renderVirtualNumbers.attach(editor); + // renderVirtualNumbers.attach(editor); + this.updateMacCompositionHandlers(editor, true); }, detach: function(editor) { var cm = editor.state.cm; @@ -5796,24 +5816,79 @@ dom.importCssString(".normal-mode .ace_cursor{\ editor.$vimModeHandler = null; editor.renderer.$cursorLayer.drawCursor = null; editor.renderer.setStyle("normal-mode", false); - renderVirtualNumbers.detach(editor); + // renderVirtualNumbers.detach(editor); + this.updateMacCompositionHandlers(editor, false); }, getStatusText: function(editor) { - var cm = editor.state.cm; - var vim = getVim(cm); - if (vim.insertMode) - return "INSERT"; - var status = ""; - if (vim.visualMode) { - status += "VISUAL"; - if (vim.visualLine) - status += " LINE"; - if (vim.visualBlock) - status += " BLOCK"; + var cm = editor.state.cm; + var vim = getVim(cm); + if (vim.insertMode) + return "INSERT"; + var status = ""; + if (vim.visualMode) { + status += "VISUAL"; + if (vim.visualLine) + status += " LINE"; + if (vim.visualBlock) + status += " BLOCK"; + } + if (vim.status) + status += (status ? " " : "") + vim.status; + return status; + }, + // workaround for j not repeating with `defaults write -g ApplePressAndHoldEnabled -bool true` + handleMacRepeat: function(data, hashId, key) { + if (hashId == -1) { + // record key + data.inputChar = key; + data.lastEvent = "input"; + } else if (data.inputChar && data.$lastHash == hashId && data.$lastKey == key) { + // check for repeated keypress + if (data.lastEvent == "input") { + data.lastEvent = "input1"; + } else if (data.lastEvent == "input1") { + // simulate textinput + return true; } - if (vim.status) - status += (status ? " " : "") + vim.status; - return status; + } else { + // reset + data.$lastHash = hashId; + data.$lastKey = key; + data.lastEvent = "keypress"; + } + }, + // on mac, with some keyboard layouts (e.g swedish) ^ starts composition, we don't need it in normal mode + updateMacCompositionHandlers: function(editor, enable) { + var onCompositionUpdateOverride = function(text) { + if (util.currentMode !== "insert") { + var el = this.textInput.getElement(); + el.blur(); + el.focus(); + el.value = text; + } else { + this.onCompositionUpdateOrig(text); + } + }; + var onCompositionStartOverride = function(text) { + if (util.currentMode === "insert") { + this.onCompositionStartOrig(text); + } + }; + if (enable) { + if (!editor.onCompositionUpdateOrig) { + editor.onCompositionUpdateOrig = editor.onCompositionUpdate; + editor.onCompositionUpdate = onCompositionUpdateOverride; + editor.onCompositionStartOrig = editor.onCompositionStart; + editor.onCompositionStart = onCompositionStartOverride; + } + } else { + if (editor.onCompositionUpdateOrig) { + editor.onCompositionUpdate = editor.onCompositionUpdateOrig; + editor.onCompositionUpdateOrig = null; + editor.onCompositionStart = editor.onCompositionStartOrig; + editor.onCompositionStartOrig = null; + } + } } } var renderVirtualNumbers = { @@ -5879,5 +5954,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ actions.fold = function(cm, actionArgs, vim) { cm.ace.execCommand(['toggleFoldWidget', 'toggleFoldWidget', 'foldOther', 'unfoldall' ][(actionArgs.all ? 2 : 0) + (actionArgs.open ? 1 : 0)]); - } + }, + + Vim.map("Y", "yy"); });