From 5d36a519d6360379dd7f21d35be7326f0e0d19e4 Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Sat, 13 May 2023 00:51:14 +0200 Subject: [PATCH 1/2] Improve `surround` When no text selected, use `editor.wordAt` to get word at cursor position. If no word available, place cursor between prefix and suffix. --- main.ts | 52 +++++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 39 deletions(-) diff --git a/main.ts b/main.ts index b1e46b3..9856f1b 100644 --- a/main.ts +++ b/main.ts @@ -446,48 +446,22 @@ export default class VimrcPlugin extends Plugin { let beginning = newArgs[0].replace("\\\\", "\\").replace("\\ ", " "); // Get the beginning surround text let ending = newArgs[1].replace("\\\\", "\\").replace("\\ ", " "); // Get the ending surround text - let currentSelections = this.currentSelection; - var chosenSelection = currentSelections && currentSelections.length > 0 ? currentSelections[0] : null; - if (this.currentSelection && currentSelections?.length > 1) { - console.log("WARNING: Multiple selections in surround. Attempt to select matching cursor. (obsidian-vimrc-support)") - const cursorPos = editor.getCursor(); - for (const selection of currentSelections) { - if (selection.head.line == cursorPos.line && selection.head.ch == cursorPos.ch) { - console.log("RESOLVED: Selection matching cursor found. (obsidian-vimrc-support)") - chosenSelection = selection; - break; - } + // Get selection at main index + var chosenSelection = this.currentSelection?.[editor.cm.state.selection.mainIndex] || {anchor: editor.getCursor(), head: editor.getCursor()}; + if (editor.posToOffset(chosenSelection.anchor) === editor.posToOffset(chosenSelection.head)) { + // No range of selected text, so select word. + let wordAt = editor.wordAt(chosenSelection.head); + if (wordAt) { + chosenSelection = {anchor: wordAt.from, head: wordAt.to}; } } - if (JSON.stringify(chosenSelection.anchor) === JSON.stringify(chosenSelection.head)) { - // No range of selected text, so select word. - var line = editor.getLine(chosenSelection.anchor.line); - if (line.length === 0) - throw new Error("can't surround on an empty line"); - // Go to the beginning of the word - let wordStart = chosenSelection.anchor.ch; - for ( ; wordStart >= 0 ; wordStart--) - if (line[wordStart].match(/\s/)) - break; - wordStart++; - let wordEnd = chosenSelection.anchor.ch; - for ( ; wordEnd < line.length ; wordEnd++) - if (line[wordEnd].match(/\s/)) - break; - var word = line.substring(wordStart, wordEnd); - chosenSelection.anchor.ch = wordStart; - chosenSelection.head.ch = wordEnd; - chosenSelection = { - anchor: {line: chosenSelection.anchor.line, ch: wordStart}, - head: {line: chosenSelection.head.line, ch: wordEnd} - }; - } - // If the selection is reverse, switch the variables - if (chosenSelection.anchor.line > chosenSelection.head.line || - (chosenSelection.anchor.line == chosenSelection.head.line && chosenSelection.anchor.ch > chosenSelection.head.ch)) - [chosenSelection.anchor, chosenSelection.head] = [chosenSelection.head, chosenSelection.anchor]; - let currText = editor.getRange(chosenSelection.anchor, chosenSelection.head); + let currText = editor.getRange(...[chosenSelection.anchor, chosenSelection.head].sort((a, b) => editor.posToOffset(a) - editor.posToOffset(b))); editor.replaceRange(beginning + currText + ending, chosenSelection.anchor, chosenSelection.head); + // If no selection, place cursor between beginning and ending + if (editor.posToOffset(chosenSelection.anchor) === editor.posToOffset(chosenSelection.head)) { + chosenSelection.head.ch += beginning.length; + editor.setCursor(chosenSelection.head); + } } vimObject.defineEx("surround", "", (cm: any, params: any) => { surroundFunc(params.args); }); From 1c7ff072df30d26f5e545e535a80e5a82307ec6a Mon Sep 17 00:00:00 2001 From: twio142 <64556708+twio142@users.noreply.github.com> Date: Sat, 13 May 2023 02:01:03 +0200 Subject: [PATCH 2/2] Debug --- main.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/main.ts b/main.ts index 9856f1b..aa55406 100644 --- a/main.ts +++ b/main.ts @@ -446,8 +446,19 @@ export default class VimrcPlugin extends Plugin { let beginning = newArgs[0].replace("\\\\", "\\").replace("\\ ", " "); // Get the beginning surround text let ending = newArgs[1].replace("\\\\", "\\").replace("\\ ", " "); // Get the ending surround text - // Get selection at main index - var chosenSelection = this.currentSelection?.[editor.cm.state.selection.mainIndex] || {anchor: editor.getCursor(), head: editor.getCursor()}; + let currentSelections = this.currentSelection; + var chosenSelection = currentSelections?.[0] ? currentSelections[0] : {anchor: editor.getCursor(), head: editor.getCursor()}; + if (currentSelections?.length > 1) { + console.log("WARNING: Multiple selections in surround. Attempt to select matching cursor. (obsidian-vimrc-support)") + const cursorPos = editor.getCursor(); + for (const selection of currentSelections) { + if (selection.head.line == cursorPos.line && selection.head.ch == cursorPos.ch) { + console.log("RESOLVED: Selection matching cursor found. (obsidian-vimrc-support)") + chosenSelection = selection; + break; + } + } + } if (editor.posToOffset(chosenSelection.anchor) === editor.posToOffset(chosenSelection.head)) { // No range of selected text, so select word. let wordAt = editor.wordAt(chosenSelection.head); @@ -455,7 +466,12 @@ export default class VimrcPlugin extends Plugin { chosenSelection = {anchor: wordAt.from, head: wordAt.to}; } } - let currText = editor.getRange(...[chosenSelection.anchor, chosenSelection.head].sort((a, b) => editor.posToOffset(a) - editor.posToOffset(b))); + let currText; + if (editor.posToOffset(chosenSelection.anchor) > editor.posToOffset(chosenSelection.head)) { + currText = editor.getRange(chosenSelection.head, chosenSelection.anchor); + } else { + currText = editor.getRange(chosenSelection.anchor, chosenSelection.head); + } editor.replaceRange(beginning + currText + ending, chosenSelection.anchor, chosenSelection.head); // If no selection, place cursor between beginning and ending if (editor.posToOffset(chosenSelection.anchor) === editor.posToOffset(chosenSelection.head)) {