From 7f0f32d1c9d1c0c003e3317f3a982acc1c03c1d1 Mon Sep 17 00:00:00 2001 From: Jacob G-W Date: Sun, 20 Oct 2024 15:58:55 -0400 Subject: [PATCH] add vim mode to the editor --- Makefile | 12 +++++++++++- src/web/editor.html | 9 +++++++++ src/web/js/beforePyret.js | 15 ++++++++++----- src/web/js/cpo-main.js | 30 ++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index e16ffb23..4828e303 100644 --- a/Makefile +++ b/Makefile @@ -160,6 +160,12 @@ build/web/js/require.js: node_modules/requirejs/require.js build/web/js/codemirror.js: $(CM)/lib/codemirror.js cp $< $@ +build/web/js/codemirror-vim.js: $(CM)/keymap/vim.js + cp $< $@ + +build/web/js/codemirror-matchbrackets.js: $(CM)/addon/edit/matchbrackets.js + cp $< $@ + build/web/js/rulers.js: $(CM)/addon/display/rulers.js cp $< $@ @@ -218,6 +224,8 @@ MISC_JS = build/web/js/q.js \ build/web/js/url.js \ build/web/js/require.js \ build/web/js/codemirror.js \ + build/web/js/codemirror-vim.js \ + build/web/js/codemirror-matchbrackets.js \ build/web/js/rulers.js \ build/web/js/mark-selection.js \ build/web/js/pyret-mode.js \ @@ -244,11 +252,13 @@ MISC_JS = build/web/js/q.js \ build/web/js/lifecycle.js \ build/web/js/jszip.js \ build/web/js/FileSaver.js - + EDITOR_MISC_JS = build/web/js/q.js \ build/web/js/loader.js \ build/web/js/codemirror.js \ + build/web/js/codemirror-vim.js \ + build/web/js/codemirror-matchbrackets.js \ build/web/js/rulers.js \ build/web/js/scrollpastend.js \ build/web/js/foldcode.js \ diff --git a/src/web/editor.html b/src/web/editor.html index 8d6c788f..59df7852 100644 --- a/src/web/editor.html +++ b/src/web/editor.html @@ -31,6 +31,7 @@
@@ -207,6 +209,13 @@ + diff --git a/src/web/js/beforePyret.js b/src/web/js/beforePyret.js index 16f06d61..7962cc24 100644 --- a/src/web/js/beforePyret.js +++ b/src/web/js/beforePyret.js @@ -278,20 +278,23 @@ $(function() { const mac = CodeMirror.keyMap.default === CodeMirror.keyMap.macDefault; const modifier = mac ? "Cmd" : "Ctrl"; - var cmOptions = { - extraKeys: CodeMirror.normalizeKeyMap({ + var defaultKeyMap = CodeMirror.normalizeKeyMap({ "Shift-Enter": function(cm) { runFun(sourceAPI.get_loaded("definitions://").contents); }, "Shift-Ctrl-Enter": function(cm) { runFun(sourceAPI.get_loaded("definitions://")); }, "Tab": "indentAuto", "Ctrl-I": reindentAllLines, - "Esc Left": "goBackwardSexp", "Alt-Left": "goBackwardSexp", - "Esc Right": "goForwardSexp", "Alt-Right": "goForwardSexp", "Ctrl-Left": "goBackwardToken", "Ctrl-Right": "goForwardToken", [`${modifier}-/`]: "toggleComment", - }), + }); + CPO.noVimKeyMap = CodeMirror.normalizeKeyMap({ + "Esc Left": "goBackwardSexp", + "Esc Right": "goForwardSexp", + }); + var cmOptions = { + extraKeys: defaultKeyMap, indentUnit: 2, tabSize: 2, viewportMargin: Infinity, @@ -311,6 +314,8 @@ $(function() { cmOptions = merge(cmOptions, options.cmOptions || {}); var CM = CodeMirror.fromTextArea(textarea[0], cmOptions); + // we do this separately so we can more easily add and remove it for vim mode + CM.addKeyMap(CPO.noVimKeyMap); function firstLineIsNamespace() { const firstline = CM.getLine(0); diff --git a/src/web/js/cpo-main.js b/src/web/js/cpo-main.js index 3529e59b..1c9575c0 100644 --- a/src/web/js/cpo-main.js +++ b/src/web/js/cpo-main.js @@ -517,6 +517,36 @@ applyTheme(newTheme); }); + var curKeybind = document.getElementById("keybind-select").value; + var keybindSelect = $("#keybind-select"); + + function applyKeybind(keybinding) { + var cm = CPO.editor.cm; + cm.state.keyMaps = []; + if (keybinding !== 'vim') { + cm.addKeyMap(CPO.noVimKeyMap, true); + } + curKeybind = keybinding; + cm.setOption('keyMap', curKeybind); + } + + if (localSettings.getItem('keybind') !== null) { + applyKeybind(localSettings.getItem('keybind')); + } else { + localSettings.setItem('keybind', curKeybind); + } + + $("#keybinds").change(function(e) { + var value = e.target.value; + applyKeybind(value); + + localSettings.setItem("keybind", curKeybind); + }); + + localSettings.change("keybind", function(_, newKeybinds) { + applyKeybind(newKeybinds); + }); + $('.notificationArea').click(function() {$('.notificationArea span').fadeOut(1000);}); editor.cm.on('beforeChange', function(instance, changeObj){textHandlers.autoCorrect(instance, changeObj, editor.cm);});