diff --git a/lib/codemirror.js b/lib/codemirror.js index 8f96532..2a99e5d 100644 --- a/lib/codemirror.js +++ b/lib/codemirror.js @@ -1,4 +1,4 @@ -import { EditorState, Compartment, Transaction, Annotation } from '@codemirror/state' +import { EditorState, Compartment, Transaction, Annotation, EditorSelection } from '@codemirror/state' import { indentWithTab, undo, redo, history, defaultKeymap, historyKeymap, indentMore, indentLess } from '@codemirror/commands' import { EditorView, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine, keymap } from '@codemirror/view' import { foldGutter, indentOnInput, syntaxHighlighting, defaultHighlightStyle, bracketMatching, foldKeymap } from '@codemirror/language' @@ -45,5 +45,6 @@ export default { moveCompletionSelection, acceptCompletion, indentMore, - indentLess + indentLess, + EditorSelection, } diff --git a/lib/platforms/neutralino.js b/lib/platforms/neutralino.js index 43a28a8..121a390 100644 --- a/lib/platforms/neutralino.js +++ b/lib/platforms/neutralino.js @@ -78,8 +78,6 @@ window.Platform = { } } - console.log(out) - return '/' + out.join('/') }, diff --git a/src/config.js b/src/config.js index 1414022..0ac323b 100644 --- a/src/config.js +++ b/src/config.js @@ -35,6 +35,27 @@ languages: [ return markdown() } } -] +], + +plumb(selection) { + if(selection.length == 0) + return + + let isDirectory = selection.endsWith('/') + + editor.setDocPath( + Platform.absolute(selection) ? + selection : + Platform.join(Platform.dirname(editor.doc.getPath()), selection) + ) + + selection = editor.doc.getPath() + + if(isDirectory) { + return editor.openDirectory(selection) + } else { + return editor.openDocument(selection) + } +} } \ No newline at end of file diff --git a/src/index.html b/src/index.html index ec7df4f..63a5bbb 100644 --- a/src/index.html +++ b/src/index.html @@ -12,7 +12,7 @@ nav { background: #f5f5f5; color: #6c6c6c; margin: 2px 5px } nav input { all: unset; text-decoration: underline; font-family: sans-serif; } nav #workspace { float: right; text-align: right; } .cm-editor { flex-grow: 1; outline: 1px solid #ddd; overflow-y: auto; } -.cm-gutters { pointer-events: none; } +.cm-gutters { user-select: none; cursor: vertical-text; } .cm-editor::-webkit-scrollbar, .cm-scroller::-webkit-scrollbar { background: #f5f5f5; width: 14px; height: 14px; } .cm-editor::-webkit-scrollbar-thumb, .cm-scroller::-webkit-scrollbar-thumb { background: #ddd } .cm-editor::-webkit-scrollbar-corner, .cm-scroller::-webkit-scrollbar-corner { background: #f5f5f5; } diff --git a/src/qwe.js b/src/qwe.js index 59f7d3f..908c0c7 100644 --- a/src/qwe.js +++ b/src/qwe.js @@ -153,9 +153,85 @@ function Doc(content, initialPath) { // } this.createState = async () => { + let ranges = [] + let merge = true + let mouseDown = false + + const addBlock = (block) => { + if(block.length > 0) + ranges.push(cm.EditorSelection.range(block.from, block.from + block.length)) + } + let extensions = [ Doc.zen.of([ - cm.lineNumbers(), + cm.lineNumbers({ + domEventHandlers: { + contextmenu(v, b, e) { + event.preventDefault() + }, + + mousedown(view, block, event) { + // Prevent selection when dragging + event.preventDefault() + + switch(event.button) { + // Right click collects each line as a selection + // Left click creates a single selection, by merging them + case 0: + case 2: + mouseDown = true + merge = event.button == 0 + ranges = [] + addBlock(block) + break + + case 1: + config.plumb( + view.state.doc + .slice(block.from, block.from + block.length) + .toString() + .trim() + ) + .then(() => view.focus()) + } + }, + mousemove(view, block, event) { + if(mouseDown) + addBlock(block) + // editor.view.state.selection.addRange(cm.SelectionRange.create(block.from, block.from + block.length)) + }, + mouseup(view, block, event) { + if(mouseDown && ranges.length > 0) { + // Join with previous selection if shift is being held down + if(event.shiftKey) { + ranges = ranges.concat(view.state.selection.ranges) + } + + if(merge) { + let from = Infinity, to = 0 + + for(let range of ranges) { + if(range.from < from) + from = range.from + + if(range.to > to) + to = range.to + } + + ranges = [ cm.EditorSelection.range(from, to) ] + } + + view.dispatch(editor.view.state.update({ + selection: cm.EditorSelection.create(ranges) + })) + + view.focus() + } + + mouseDown = false + } + } + }), cm.highlightActiveLine(), cm.highlightActiveLineGutter(), cm.highlightSpecialChars(), @@ -224,8 +300,6 @@ function Doc(content, initialPath) { } const setViewLanguageExtension = (extension = []) => { - console.log('lang!', extension) - view.dispatch({ effects: Doc.language.reconfigure(extension) }) @@ -286,21 +360,7 @@ const Keymaps = { if(!mainSelection.empty) { let path = state.sliceDoc(mainSelection.from, mainSelection.to).trim() - let isDirectory = path.endsWith('/') - - editor.setDocPath( - Platform.absolute(path) ? - path : - Platform.join(Platform.dirname(editor.doc.getPath()), path) - ) - - path = editor.doc.getPath() - - if(isDirectory) { - editor.openDirectory(path) - } else { - editor.openDocument(path) - } + config.plumb(path) return } @@ -323,9 +383,6 @@ const Keymaps = { path = Platform.join(path, '../../') else path = Platform.dirname(path) - // path = path.endsWith('/') ? path.slice(0, -1) : path - - console.log(path) editor.openDirectory(path) }