From 08c845ff006ef60ee9f8c7855f845511a525fd92 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Mon, 6 Sep 2021 20:35:55 -0500 Subject: [PATCH 1/7] add underline hotkey and change italic hotkey to * Using `*` rather than `_` characters for italics is more inline with existing snippets. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 9707bde56..f32a7e130 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -51,6 +51,8 @@ const CodeEditor = createClass({ 'Cmd-B' : this.makeBold, 'Ctrl-I' : this.makeItalic, 'Cmd-I' : this.makeItalic, + 'Ctrl-U' : this.makeUnderline, + 'Cmd-U' : this.makeUnderline, 'Ctrl-M' : this.makeSpan, 'Cmd-M' : this.makeSpan, 'Ctrl-/' : this.makeComment, @@ -73,14 +75,23 @@ const CodeEditor = createClass({ }, makeItalic : function() { - const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '_' && selection.slice(-1) === '_'; - this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `_${selection}_`, 'around'); + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*'; + this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `*${selection}*`, 'around'); if(selection.length === 0){ const cursor = this.codeMirror.getCursor(); this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 1 }); } }, + makeUnderline : function() { + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '' && selection.slice(-4) === ''; + this.codeMirror.replaceSelection(t ? selection.slice(3, -4) : `${selection}`, 'around'); + if(selection.length === 0){ + const cursor = this.codeMirror.getCursor(); + this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 4 }); + } + }, + makeSpan : function() { const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around'); From 7dcd3356306632523c526cb4538ddfd06005dbf9 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Mon, 6 Sep 2021 21:12:48 -0500 Subject: [PATCH 2/7] add makeDiv hotkey - V3 Curly Divs Shift-Cmd/Ctrl-M makes a curly div. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 31 +++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index f32a7e130..6858d5840 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -47,16 +47,18 @@ const CodeEditor = createClass({ indentWithTabs : true, tabSize : 2, extraKeys : { - 'Ctrl-B' : this.makeBold, - 'Cmd-B' : this.makeBold, - 'Ctrl-I' : this.makeItalic, - 'Cmd-I' : this.makeItalic, - 'Ctrl-U' : this.makeUnderline, - 'Cmd-U' : this.makeUnderline, - 'Ctrl-M' : this.makeSpan, - 'Cmd-M' : this.makeSpan, - 'Ctrl-/' : this.makeComment, - 'Cmd-/' : this.makeComment + 'Ctrl-B' : this.makeBold, + 'Cmd-B' : this.makeBold, + 'Ctrl-I' : this.makeItalic, + 'Cmd-I' : this.makeItalic, + 'Ctrl-U' : this.makeUnderline, + 'Cmd-U' : this.makeUnderline, + 'Ctrl-M' : this.makeSpan, + 'Cmd-M' : this.makeSpan, + 'Shift-Ctrl-M' : this.makeDiv, + 'Shift-Cmd-M' : this.makeDiv, + 'Ctrl-/' : this.makeComment, + 'Cmd-/' : this.makeComment } }); @@ -101,6 +103,15 @@ const CodeEditor = createClass({ } }, + makeDiv : function() { + const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}'; + this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{\n${selection}\n}}`, 'around'); + if(selection.length === 0){ + const cursor = this.codeMirror.getCursor(); + this.codeMirror.setCursor({ line: cursor.line - 1, ch: cursor.ch }); // set to -2? if wanting to enter classes etc. if so, get rid of first \n when replacing selection + } + }, + makeComment : function() { const selection = this.codeMirror.getSelection(), t = selection.slice(0, 4) === ''; this.codeMirror.replaceSelection(t ? selection.slice(4, -3) : ``, 'around'); From 389ad1cf1778d88141935996a436dcbe8d7a6797 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Fri, 10 Sep 2021 23:18:23 -0500 Subject: [PATCH 3/7] add hotkeys for   and empty makeNbsp, makeSpace, removeSpace --- shared/naturalcrit/codeEditor/codeEditor.jsx | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 6858d5840..6d5685cd7 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -53,6 +53,12 @@ const CodeEditor = createClass({ 'Cmd-I' : this.makeItalic, 'Ctrl-U' : this.makeUnderline, 'Cmd-U' : this.makeUnderline, + 'Ctrl-.' : this.makeNbsp, + 'Cmd-.' : this.makeNbsp, + 'Shift-Ctrl-.' : this.makeSpace, + 'Shift-Cmd-.' : this.makeSpace, + 'Shift-Ctrl-,' : this.removeSpace, + 'Shift-Cmd-,' : this.removeSpace, 'Ctrl-M' : this.makeSpan, 'Cmd-M' : this.makeSpan, 'Shift-Ctrl-M' : this.makeDiv, @@ -85,6 +91,30 @@ const CodeEditor = createClass({ } }, + makeNbsp : function() { + this.codeMirror.replaceSelection(' ', 'end'); + }, + + makeSpace : function() { + const selection = this.codeMirror.getSelection(); + const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}'; + if(t){ + const percent = parseInt(selection.slice(8, -4)) + 10; + this.codeMirror.replaceSelection(percent < 90 ? `{{width:${percent}% }}` : '{{width:100% }}', 'around'); + } else { + this.codeMirror.replaceSelection(`{{width:10% }}`, 'around'); + } + }, + + removeSpace : function() { + const selection = this.codeMirror.getSelection(); + const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}'; + if(t){ + const percent = parseInt(selection.slice(8, -4)) - 10; + this.codeMirror.replaceSelection(percent > 10 ? `{{width:${percent}% }}` : '', 'around'); + } + }, + makeUnderline : function() { const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '' && selection.slice(-4) === ''; this.codeMirror.replaceSelection(t ? selection.slice(3, -4) : `${selection}`, 'around'); From bec2a7c77abca010522ea920aed1e56374c07839 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Sat, 11 Sep 2021 00:12:58 -0500 Subject: [PATCH 4/7] add hotkeys for new \page and \column --- shared/naturalcrit/codeEditor/codeEditor.jsx | 48 ++++++++++++-------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 6d5685cd7..a810bee3a 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -47,24 +47,28 @@ const CodeEditor = createClass({ indentWithTabs : true, tabSize : 2, extraKeys : { - 'Ctrl-B' : this.makeBold, - 'Cmd-B' : this.makeBold, - 'Ctrl-I' : this.makeItalic, - 'Cmd-I' : this.makeItalic, - 'Ctrl-U' : this.makeUnderline, - 'Cmd-U' : this.makeUnderline, - 'Ctrl-.' : this.makeNbsp, - 'Cmd-.' : this.makeNbsp, - 'Shift-Ctrl-.' : this.makeSpace, - 'Shift-Cmd-.' : this.makeSpace, - 'Shift-Ctrl-,' : this.removeSpace, - 'Shift-Cmd-,' : this.removeSpace, - 'Ctrl-M' : this.makeSpan, - 'Cmd-M' : this.makeSpan, - 'Shift-Ctrl-M' : this.makeDiv, - 'Shift-Cmd-M' : this.makeDiv, - 'Ctrl-/' : this.makeComment, - 'Cmd-/' : this.makeComment + 'Ctrl-B' : this.makeBold, + 'Cmd-B' : this.makeBold, + 'Ctrl-I' : this.makeItalic, + 'Cmd-I' : this.makeItalic, + 'Ctrl-U' : this.makeUnderline, + 'Cmd-U' : this.makeUnderline, + 'Ctrl-.' : this.makeNbsp, + 'Cmd-.' : this.makeNbsp, + 'Shift-Ctrl-.' : this.makeSpace, + 'Shift-Cmd-.' : this.makeSpace, + 'Shift-Ctrl-,' : this.removeSpace, + 'Shift-Cmd-,' : this.removeSpace, + 'Shift-Ctrl-Enter' : this.newColumn, + 'Shift-Cmd-Enter' : this.newColumn, + 'Ctrl-Enter' : this.newPage, + 'Cmd-Enter' : this.newPage, + 'Ctrl-M' : this.makeSpan, + 'Cmd-M' : this.makeSpan, + 'Shift-Ctrl-M' : this.makeDiv, + 'Shift-Cmd-M' : this.makeDiv, + 'Ctrl-/' : this.makeComment, + 'Cmd-/' : this.makeComment } }); @@ -115,6 +119,14 @@ const CodeEditor = createClass({ } }, + newColumn : function() { + this.codeMirror.replaceSelection('\n\\column\n\n', 'end'); + }, + + newPage : function() { + this.codeMirror.replaceSelection('\n\\page\n\n', 'end'); + }, + makeUnderline : function() { const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '' && selection.slice(-4) === ''; this.codeMirror.replaceSelection(t ? selection.slice(3, -4) : `${selection}`, 'around'); From 3bf5d7a2dbe44846a194ee99ae85bfcca1e29832 Mon Sep 17 00:00:00 2001 From: Gazook89 <58999374+Gazook89@users.noreply.github.com> Date: Thu, 30 Sep 2021 17:59:45 -0500 Subject: [PATCH 5/7] change makeComment function to adapt to gfm or css editor --- shared/naturalcrit/codeEditor/codeEditor.jsx | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index a810bee3a..ee318ee1d 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -155,12 +155,24 @@ const CodeEditor = createClass({ }, makeComment : function() { - const selection = this.codeMirror.getSelection(), t = selection.slice(0, 4) === ''; - this.codeMirror.replaceSelection(t ? selection.slice(4, -3) : ``, 'around'); + let regex; + let cursorPos; + let newComment; + const selection = this.codeMirror.getSelection(); + if(this.props.language === 'gfm'){ + regex = /^\s*()\s*$/gs; + cursorPos = 4; + newComment = ``; + } else { + regex = /^\s*(\/\*\s?)(.*?)(\s?\*\/)\s*$/gs; + cursorPos = 3; + newComment = `/* ${selection} */`; + } + this.codeMirror.replaceSelection(regex.test(selection) == true ? selection.replace(regex, '$2') : newComment, 'around'); if(selection.length === 0){ const cursor = this.codeMirror.getCursor(); - this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 4 }); - } + this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - cursorPos }); + }; }, //=-- Externally used -==// From 9da1bfc6063563264bc5602521d7598571680f8a Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 2 Dec 2021 12:18:22 -0500 Subject: [PATCH 6/7] Finish Merge with Master --- shared/naturalcrit/codeEditor/codeEditor.jsx | 126 ++++++++++++++++--- 1 file changed, 108 insertions(+), 18 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index ee318ee1d..423e46468 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({ @@ -25,28 +32,48 @@ const CodeEditor = createClass({ }; }, + getInitialState : function() { + return { + docs : {} + }; + }, + componentDidMount : function() { this.buildEditor(); + const newDoc = CodeMirror.Doc(this.props.value, this.props.language); + this.codeMirror.swapDoc(newDoc); }, componentDidUpdate : function(prevProps) { - if(prevProps.language !== this.props.language){ //rebuild editor when switching tabs - this.buildEditor(); - } - if(this.codeMirror && this.codeMirror.getValue() != this.props.value) { //update editor contents if brew.text is changed from outside + if(prevProps.view !== this.props.view){ //view changed; swap documents + let newDoc; + + if(!this.state.docs[this.props.view]) { + newDoc = CodeMirror.Doc(this.props.value, this.props.language); + } else { + newDoc = this.state.docs[this.props.view]; + } + + const oldDoc = { [prevProps.view]: this.codeMirror.swapDoc(newDoc) }; + + this.setState((prevState)=>({ + docs : _.merge({}, prevState.docs, oldDoc) + })); + + this.props.rerenderParent(); + } else if(this.codeMirror?.getValue() != this.props.value) { //update editor contents if brew.text is changed from outside this.codeMirror.setValue(this.props.value); } }, buildEditor : function() { this.codeMirror = CodeMirror(this.refs.editor, { - value : this.props.value, - lineNumbers : true, - lineWrapping : this.props.wrap, - mode : this.props.language, //TODO: CSS MODE DOESN'T SEEM TO LOAD PROPERLY - indentWithTabs : true, - tabSize : 2, - extraKeys : { + lineNumbers : true, + lineWrapping : this.props.wrap, + indentWithTabs : true, + tabSize : 2, + historyEventDelay : 250, + extraKeys : { 'Ctrl-B' : this.makeBold, 'Cmd-B' : this.makeBold, 'Ctrl-I' : this.makeItalic, @@ -59,17 +86,46 @@ const CodeEditor = createClass({ 'Shift-Cmd-.' : this.makeSpace, 'Shift-Ctrl-,' : this.removeSpace, 'Shift-Cmd-,' : this.removeSpace, - 'Shift-Ctrl-Enter' : this.newColumn, - 'Shift-Cmd-Enter' : this.newColumn, - 'Ctrl-Enter' : this.newPage, - 'Cmd-Enter' : this.newPage, 'Ctrl-M' : this.makeSpan, 'Cmd-M' : this.makeSpan, 'Shift-Ctrl-M' : this.makeDiv, 'Shift-Cmd-M' : this.makeDiv, 'Ctrl-/' : this.makeComment, - 'Cmd-/' : this.makeComment - } + 'Cmd-/' : this.makeComment, + 'Ctrl-K' : this.makeLink, + 'Cmd-K' : this.makeLink, + 'Shift-Ctrl-Enter' : this.newColumn, + 'Shift-Cmd-Enter' : this.newColumn, + 'Ctrl-Enter' : this.newPage, + 'Cmd-Enter' : this.newPage, + '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. @@ -175,6 +231,31 @@ const CodeEditor = createClass({ }; }, + makeLink : function() { + const isLink = /^\[(.*)\]\((.*)\)$/; + const selection = this.codeMirror.getSelection().trim(); + let match; + if(match = isLink.exec(selection)){ + const altText = match[1]; + const url = match[2]; + this.codeMirror.replaceSelection(`${altText} ${url}`); + const cursor = this.codeMirror.getCursor(); + this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - url.length }, { line: cursor.line, ch: cursor.ch }); + } else { + this.codeMirror.replaceSelection(`[${selection || 'alt text'}](url)`); + const cursor = this.codeMirror.getCursor(); + this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - 4 }, { line: cursor.line, ch: cursor.ch - 1 }); + } + }, + + foldAllCode : function() { + this.codeMirror.execCommand('foldAll'); + }, + + unfoldAllCode : function() { + this.codeMirror.execCommand('unfoldAll'); + }, + //=-- Externally used -==// setCursorPosition : function(line, char){ setTimeout(()=>{ @@ -188,10 +269,19 @@ const CodeEditor = createClass({ updateSize : function(){ this.codeMirror.refresh(); }, + redo : function(){ + return this.codeMirror.redo(); + }, + undo : function(){ + return this.codeMirror.undo(); + }, + historySize : function(){ + return this.codeMirror.doc.historySize(); + }, //----------------------// render : function(){ - return
; + return
; } }); From a30e150ade2df8d6564585f186c0a1295b4a9481 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 2 Dec 2021 15:47:18 -0500 Subject: [PATCH 7/7] Disable max lines to satisfy lint Eventually we should move the hotkey scripts into a separate file. They are becoming a beast of their own. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 423e46468..57e306bd3 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ require('./codeEditor.less'); const React = require('react'); const createClass = require('create-react-class');