/* global CodeMirror prefs loadScript */ 'use strict'; (function () { // CodeMirror miserably fails on keyMap='' so let's ensure it's not if (!prefs.get('editor.keyMap')) { prefs.reset('editor.keyMap'); } const defaults = { mode: 'css', lineNumbers: true, lineWrapping: true, foldGutter: true, gutters: [ 'CodeMirror-linenumbers', 'CodeMirror-foldgutter', ...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []), ], matchBrackets: true, highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true}, hintOptions: {}, lintReportDelay: prefs.get('editor.lintReportDelay'), styleActiveLine: true, theme: 'default', keyMap: prefs.get('editor.keyMap'), extraKeys: { // independent of current keyMap 'Alt-Enter': 'toggleStyle', 'Alt-PageDown': 'nextEditor', 'Alt-PageUp': 'prevEditor' } }; Object.assign(CodeMirror.defaults, defaults, prefs.get('editor.options')); CodeMirror.commands.blockComment = cm => { cm.blockComment(cm.getCursor('from'), cm.getCursor('to'), {fullLines: false}); }; // 'basic' keymap only has basic keys by design, so we skip it const extraKeysCommands = {}; Object.keys(CodeMirror.defaults.extraKeys).forEach(key => { extraKeysCommands[CodeMirror.defaults.extraKeys[key]] = true; }); if (!extraKeysCommands.jumpToLine) { CodeMirror.keyMap.sublime['Ctrl-G'] = 'jumpToLine'; CodeMirror.keyMap.emacsy['Ctrl-G'] = 'jumpToLine'; CodeMirror.keyMap.pcDefault['Ctrl-J'] = 'jumpToLine'; CodeMirror.keyMap.macDefault['Cmd-J'] = 'jumpToLine'; } if (!extraKeysCommands.autocomplete) { // will be used by 'sublime' on PC via fallthrough CodeMirror.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete'; // OSX uses Ctrl-Space and Cmd-Space for something else CodeMirror.keyMap.macDefault['Alt-Space'] = 'autocomplete'; // copied from 'emacs' keymap CodeMirror.keyMap.emacsy['Alt-/'] = 'autocomplete'; // 'vim' and 'emacs' define their own autocomplete hotkeys } if (!extraKeysCommands.blockComment) { CodeMirror.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment'; } if (navigator.appVersion.includes('Windows')) { // 'pcDefault' keymap on Windows should have F3/Shift-F3 if (!extraKeysCommands.findNext) { CodeMirror.keyMap.pcDefault['F3'] = 'findNext'; } if (!extraKeysCommands.findPrev) { CodeMirror.keyMap.pcDefault['Shift-F3'] = 'findPrev'; } // try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys ['N', 'T', 'W'].forEach(char => { [ {from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']}, // Note: modifier order in CodeMirror is S-C-A {from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']} ].forEach(remap => { const oldKey = remap.from + char; Object.keys(CodeMirror.keyMap).forEach(keyMapName => { const keyMap = CodeMirror.keyMap[keyMapName]; const command = keyMap[oldKey]; if (!command) { return; } remap.to.some(newMod => { const newKey = newMod + char; if (!(newKey in keyMap)) { delete keyMap[oldKey]; keyMap[newKey] = command; return true; } }); }); }); }); } const MODE = { stylus: 'stylus', uso: 'css' }; CodeMirror.defineExtension('setPreprocessor', function (preprocessor) { const mode = MODE[preprocessor] || 'css'; return loadScript(mode !== 'css' && `/vendor/codemirror/mode/${mode}/${mode}.js`).then(() => { this.setOption('mode', mode); }); }); CodeMirror.defineExtension('isBlank', function () { // superfast checking as it runs only until the first non-blank line let isBlank = true; this.doc.eachLine(line => { if (line.text && line.text.trim()) { isBlank = false; return true; } }); return isBlank; }); })();