diff --git a/README.md b/README.md index def5ba3..04fd308 100644 --- a/README.md +++ b/README.md @@ -320,9 +320,9 @@ Current available commands are: - `Go to next fold` - - `Go to previous fold` - - `Go to parent fold` - +- Double key `Open Command-Palette` command via double Ctrl shortcut. #### Fixes - Made double key quick switcher shortcut to be triggered on second release rather than on second press - Double key registry registers command on release only if command released in desired timestamp -- Added double key `Open Command-Palette` command via double Ctrl shortcut. \ No newline at end of file diff --git a/src/classes/editor-position-manipulator.ts b/src/classes/editor-position-manipulator.ts index 42e9399..ac2f2cb 100644 --- a/src/classes/editor-position-manipulator.ts +++ b/src/classes/editor-position-manipulator.ts @@ -22,7 +22,7 @@ export default class EditorPositionManipulator implements EditorPosition, JavaLi } asEditorRange(): EditorRange { - return {from: this, to: this} + return {from: this.toEditorPosition(), to: this.toEditorPosition()} } getLine(): string { @@ -46,10 +46,24 @@ export default class EditorPositionManipulator implements EditorPosition, JavaLi return this } + moveToEndOfLine(): this { + this.ch = this.editor.getLine(this.line).length; + return this; + } + + moveToStartOfLine(): this { + this.ch = 0; + return this; + } + toOffset(): number { return this.editor.posToOffset(this) } + toEditorPosition(): EditorPosition { + return { line: this.line, ch: this.ch} + } + static documentStart(editor: Editor): EditorPositionManipulator { return new EditorPositionManipulator({ch: 0, line: 0}, editor); } diff --git a/src/commands.ts b/src/commands.ts index 9122a54..f1377b0 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -356,14 +356,14 @@ export const COMMANDS = (plugin: KeyshotsPlugin, map: KeyshotsMap): KeyshotsComm id: 'go-to-next-fold', name: "Go to next fold", hotkeys: map.go_to_next_fold, - editorCallback: (editor) => functions.goToNextFolding(editor) + editorCallback: (editor) => functions.goToFolding(editor, VerticalDirection.DOWN) }, { category: Category.TRANSFORM_SELECTIONS, id: 'go-to-previous-fold', name: "Go to previous fold", hotkeys: map.go_to_previous_fold, - editorCallback: (editor) => functions.goToPreviousFolding(editor) + editorCallback: (editor) => functions.goToFolding(editor, VerticalDirection.UP) }, { category: Category.TRANSFORM_SELECTIONS, diff --git a/src/functions.ts b/src/functions.ts index 6b8efdc..3fb9596 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -369,7 +369,7 @@ export function countRegexMatches(editor: Editor, regex: RegExp, onlySelection: export function toggleFocusMode() { const isFocus = window.document.body.classList.contains("keyshots-focus-mode"); electron.remote.BrowserWindow.getAllWindows().forEach(w => w.setFullScreen(!isFocus)) - Array.of("left","right").forEach(side => { + Array.of("left", "right").forEach(side => { const sideBar = document.querySelector(`div.mod-${side}-split`) if (sideBar && !sideBar.classList.contains(`is-sidedock-collapsed`) && !isFocus) app.commands.executeCommandById(`app:toggle-${side}-sidebar`) @@ -383,82 +383,68 @@ export function toggleFocusMode() { const FOLDING_REGEX = /#{1,6} .+/ -export function goToNextFolding(editor: Editor){ +export function goToFolding(editor: Editor, direction: VerticalDirection) { const cursor = EditorPositionManipulator.mainCursor(editor); - if (!editor.getValue().substring(cursor.toOffset()).includes("\n")) return; - const browseDoc = editor.getValue().substring(cursor.clone().setPos(cursor.line+1,0).toOffset()); - browseDoc.split("\n").every((v,i,arr)=>{ - let cursorIndent = 0; - const indentMatch = v.match(/^((?:\t| {4})*)(-|\d+\.) /); - if (indentMatch){ - const indentString = indentMatch[1]; - const indent = indentString.includes(" ") ? indentString.length/4 : indentString.length; - if (!arr[i+1].match(new RegExp(`(?:\t| {4}){${indent+1}}(?=- |\\d+\\. )`))) return true; - cursorIndent = (indentString.includes(" ") ? indent*4 : indent)+indentMatch[2].length+1; - } - else if (!v.match(FOLDING_REGEX)) return true; - cursor.setPos(cursor.line+1+i,cursorIndent); - editor.setCursor(cursor.line,cursor.ch); - return false; - }) -} + const isDown = () => direction == VerticalDirection.DOWN -export function goToPreviousFolding(editor: Editor){ - const cursor = EditorPositionManipulator.mainCursor(editor); - if (!editor.getValue().substring(0,cursor.toOffset()).includes("\n")) return; - const browseDoc = editor.getValue().substring(0,cursor.clone().setPos(cursor.line-1,editor.getLine(cursor.line-1).length).toOffset()); - browseDoc.split("\n").reverse().every((v,i,arr)=>{ + if (!editor.getValue().substring( + isDown() ? cursor.toOffset() : 0, + isDown() ? undefined : cursor.toOffset() + ).includes("\n")) return; + + const browseDoc = editor.getValue().substring( + isDown() ? cursor.clone().movePos(1, 0).moveToStartOfLine().toOffset() : 0, + isDown() ? undefined : cursor.clone().moveToEndOfLine().toOffset() + ); + const lines = browseDoc.split("\n"); + if (!isDown()) lines.reverse(); + lines.every((v, i, arr) => { let cursorIndent = 0; - const indentMatch = v.match(/^((?:\t| {4})*)(-|\d+\.) /); - if (indentMatch){ + if (v.match(FOLDING_REGEX) && i == 0) return true; + const indentMatch = v.match(/^((?:\t| {4})*)(-|\d+\.|- \[[x ]]) /); + if (indentMatch) { const indentString = indentMatch[1]; - const indent = indentString.includes(" ") ? indentString.length/4 : indentString.length; - if (!arr[i+1].match(new RegExp(`(?:\t| {4}){${indent-1}}(?=- |\\d+\\. )`))) return true; - cursorIndent = (indentString.includes(" ") ? indent*4 : indent)+indentMatch[2].length+1; - } - else if (!v.match(FOLDING_REGEX)) return true; - cursor.setPos(cursor.line-1-i,cursorIndent); - editor.setCursor(cursor.line,cursor.ch); + const indent = indentString.includes(" ") ? indentString.length / 4 : indentString.length; + if (!(arr[i + (isDown() ? 1 : -1)] ?? "").match(new RegExp(`^(?:\\t| {4}){${indent+1}}(?=- |\\d+\\. |- \\[[x ]] )`))) return true; /* diff */ + cursorIndent = (indentString.includes(" ") ? indent * 4 : indent) + indentMatch[2].length + 1; + } else if (!v.match(FOLDING_REGEX)) return true; + editor.setCursor(cursor.setPos(isDown() ? cursor.line + 1 + i : cursor.line - i, cursorIndent).toEditorPosition()); return false; }) } -export function goToParentFolding(editor: Editor){ +export function goToParentFolding(editor: Editor) { const cursor = EditorPositionManipulator.mainCursor(editor); - if (!editor.getValue().substring(0,cursor.toOffset()).includes("\n")) return; - const browseDoc = editor.getValue().substring(0,cursor.clone().setPos(cursor.line-1,editor.getLine(cursor.line-1).length).toOffset()); + if (!editor.getValue().substring(0, cursor.toOffset()).includes("\n")) return; + const browseDoc = editor.getValue().substring(0, cursor.clone().movePos(-1, 0).moveToEndOfLine().toOffset()); const line = editor.getLine(cursor.line); - - const listMatch = line.match(/^((?:\t| {4})*)(-|\d+\.) /) + const listMatch = line.match(/^((?:\t| {4})*)(-|\d+\.|- \[[x ]]) /) if (listMatch) { - const indentString = listMatch[1]; - const indent = indentString.includes(" ") ? indentString.length/4 : indentString.length; - - if (!browseDoc.split("\n").reverse().every((v,i)=> { + const indent = indentString.includes(" ") ? indentString.length / 4 : indentString.length; + if (!browseDoc.split("\n").reverse().every((v, i) => { const prevMatch = v.match(new RegExp(`^(?:\\t| {4}){${indent-1}}(-|\\d+\\.) `)); if (!prevMatch) return true; - cursor.setPos(cursor.line-1-i,(indentString.includes(" ") ? indent*4 :indent)+prevMatch[1].length); - editor.setCursor(cursor.line,cursor.ch); + cursor.setPos(cursor.line - 1 - i, (indentString.includes(" ") ? indent * 4 : indent) + prevMatch[1].length); + editor.setCursor(cursor.line, cursor.ch); return false; })) return; } const headingMatch = line.match(/^(#{1,6}) /); if (headingMatch) { const headingLevel = headingMatch[1].length; - if (!browseDoc.split("\n").reverse().every((v,i)=> { + if (!browseDoc.split("\n").reverse().every((v, i) => { const prevMatch = v.match(new RegExp(`^#{1,${headingLevel-1}} `)); if (!prevMatch) return true; - cursor.setPos(cursor.line-1-i,prevMatch[0].length); - editor.setCursor(cursor.line,cursor.ch); + cursor.setPos(cursor.line - 1 - i, prevMatch[0].length); + editor.setCursor(cursor.line, cursor.ch); return false; })) return; } - browseDoc.split("\n").reverse().every((v,i)=>{ + browseDoc.split("\n").reverse().every((v, i) => { if (!v.match(FOLDING_REGEX)) return true; - cursor.setPos(cursor.line-1-i,0); - editor.setCursor(cursor.line,cursor.ch); + editor.setCursor(cursor.movePos(-1-i,0).moveToStartOfLine().toEditorPosition()); return false; }) } \ No newline at end of file