diff --git a/Makefile b/Makefile
index 91bca468..06ad0d14 100644
--- a/Makefile
+++ b/Makefile
@@ -151,6 +151,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 $< $@
@@ -209,6 +215,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 \
@@ -236,6 +244,8 @@ MISC_JS = build/web/js/q.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 8db351c9..7248ea98 100644
--- a/src/web/editor.html
+++ b/src/web/editor.html
@@ -29,6 +29,7 @@
@@ -205,6 +207,13 @@
+
+
+
+
diff --git a/src/web/js/beforePyret.js b/src/web/js/beforePyret.js
index f4d03493..1c41e0f6 100644
--- a/src/web/js/beforePyret.js
+++ b/src/web/js/beforePyret.js
@@ -188,20 +188,24 @@ $(function() {
const mac = CodeMirror.keyMap.default === CodeMirror.keyMap.macDefault;
const modifier = mac ? "Cmd" : "Ctrl";
- var cmOptions = {
- extraKeys: CodeMirror.normalizeKeyMap({
+ defaultKeyMap = CodeMirror.normalizeKeyMap({
"Shift-Enter": function(cm) { runFun(cm.getValue()); },
"Shift-Ctrl-Enter": function(cm) { runFun(cm.getValue()); },
"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,
@@ -221,6 +225,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 860172e8..53a042e8 100644
--- a/src/web/js/cpo-main.js
+++ b/src/web/js/cpo-main.js
@@ -498,6 +498,36 @@
localSettings.change("theme", function(_, newTheme) {
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);});