diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 77001435d..14038f740 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -108,7 +108,7 @@ const Editor = createClass({ const codeMirror = this.refs.codeEditor.codeMirror; //reset custom text styles - const customHighlights = codeMirror.getAllMarks(); + const customHighlights = codeMirror.getAllMarks().filter((mark)=>!mark.__isFold); //Don't undo code folding for (let i=0;i{ diff --git a/scripts/project.json b/scripts/project.json index 9bb6ef1ed..a83b7a0a1 100644 --- a/scripts/project.json +++ b/scripts/project.json @@ -12,6 +12,8 @@ "codemirror/mode/gfm/gfm.js", "codemirror/mode/css/css.js", "codemirror/mode/javascript/javascript.js", + "codemirror/addon/fold/foldcode.js", + "codemirror/addon/fold/foldgutter.js", "moment", "superagent", "marked" diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 621e24f77..01eca0114 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -13,6 +13,13 @@ if(typeof navigator !== 'undefined'){ require('codemirror/mode/gfm/gfm.js'); //Github flavoured markdown require('codemirror/mode/css/css.js'); require('codemirror/mode/javascript/javascript.js'); + + //Addons + require('codemirror/addon/fold/foldcode.js'); + require('codemirror/addon/fold/foldgutter.js'); + + const foldCode = require('./fold-code'); + foldCode.registerHomebreweryHelper(CodeMirror); } const CodeEditor = createClass({ @@ -74,8 +81,35 @@ const CodeEditor = createClass({ 'Ctrl-M' : this.makeSpan, 'Cmd-M' : this.makeSpan, 'Ctrl-/' : this.makeComment, - 'Cmd-/' : this.makeComment - } + 'Cmd-/' : this.makeComment, + 'Ctrl-[' : this.foldAllCode, + 'Cmd-[' : this.foldAllCode, + 'Ctrl-]' : this.unfoldAllCode, + 'Cmd-]' : this.unfoldAllCode + }, + foldGutter : true, + foldOptions : { + scanUp : true, + rangeFinder : CodeMirror.fold.homebrewery, + widget : (from, to)=>{ + let text = ''; + let currentLine = from.line; + const maxLength = 50; + while (currentLine <= to.line && text.length <= maxLength) { + text += this.codeMirror.getLine(currentLine); + if(currentLine < to.line) + text += ' '; + currentLine += 1; + } + + text = text.trim(); + if(text.length > maxLength) + text = `${text.substr(0, maxLength)}...`; + + return `\u21A4 ${text} \u21A6`; + } + }, + gutters : ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'] }); // Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works. @@ -119,6 +153,14 @@ const CodeEditor = createClass({ } }, + foldAllCode : function() { + this.codeMirror.execCommand('foldAll'); + }, + + unfoldAllCode : function() { + this.codeMirror.execCommand('unfoldAll'); + }, + //=-- Externally used -==// setCursorPosition : function(line, char){ setTimeout(()=>{ diff --git a/shared/naturalcrit/codeEditor/codeEditor.less b/shared/naturalcrit/codeEditor/codeEditor.less index 7daa0c4da..0ad7a27f8 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.less +++ b/shared/naturalcrit/codeEditor/codeEditor.less @@ -1,5 +1,10 @@ @import (less) 'codemirror/lib/codemirror.css'; +@import (less) 'codemirror/addon/fold/foldgutter.css'; .codeEditor{ - + .CodeMirror-foldmarker { + font-family: inherit; + text-shadow: none; + font-weight: 600; + } } \ No newline at end of file diff --git a/shared/naturalcrit/codeEditor/fold-code.js b/shared/naturalcrit/codeEditor/fold-code.js new file mode 100644 index 000000000..cff1c64e0 --- /dev/null +++ b/shared/naturalcrit/codeEditor/fold-code.js @@ -0,0 +1,26 @@ +module.exports = { + registerHomebreweryHelper : function(CodeMirror) { + CodeMirror.registerHelper('fold', 'homebrewery', function(cm, start) { + const matcher = /^\\page.*/; + const prevLine = cm.getLine(start.line - 1); + + if(start.line === cm.firstLine() || prevLine.match(matcher)) { + const lastLineNo = cm.lastLine(); + let end = start.line; + + while (end < lastLineNo) { + if(cm.getLine(end + 1).match(matcher)) + break; + ++end; + } + + return { + from : CodeMirror.Pos(start.line, 0), + to : CodeMirror.Pos(end, cm.getLine(end).length) + }; + } + + return null; + }); + } +};