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);});