From 3751cc96101b7bdd2c9cb707daf5ab2eea465e13 Mon Sep 17 00:00:00 2001 From: Jerome Lelong Date: Thu, 10 May 2018 16:02:17 +0200 Subject: [PATCH] Update environment name selection The former select-envname is renamed to multicursor-envname and sets a multicursor to the beginning of the environment name in the 'begin' and 'end' parts. The new function select-envname selects the environment name. This function does not work with the Vim extension. This closes #612. --- README.md | 3 ++- package.json | 7 +++++- src/commander.ts | 10 +++++++- src/components/envpair.ts | 50 ++++++++++++++++++++++++++------------- src/main.ts | 1 + 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c63d772c9..cc5e94dbe 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ LaTeX Workshop is an extension for [Visual Studio Code](https://code.visualstudi - LaTeX file formatting. - Auto close LaTeX environments: just call _LaTeX Workshop: Close current environment_ from the **Command Palette**. You can easily assign a shortcut to this action through the **Keyboard Shortcuts** menu, search for `latex-workshop.close-env`. - Navigate from `\begin/\end` to the corresponding `\end/\begin`: while on the `begin` or `end` keyword, call _LaTeX Workshop: Navigate to matching begin/end_ from the **Command Palette**. To define a shortcut, search for `latex-workshop.navigate-envpair` in the **Keyboard Shortcuts** menu. -- Add a multicursor to the current environment name: call _LaTeX Workshop: Multicursor selection of the current environment name_ from the **Command Palette**. For this command to work, the cursor must be strictly between `\begin{...}` and `\end{...}`. To define a shortcut, search for `latex-workshop.select-envname` in the **Keyboard Shortcuts** menu. Repeated calls result in selecting the outer environments. +- Select the current environment name: call _LaTeX Workshop: Select the current environment name_ from the **Command Palette**. For this command to work, the cursor must be strictly between `\begin{...}` and `\end{...}`. To define a shortcut, search for `latex-workshop.select-envname` in the **Keyboard Shortcuts** menu. Repeated calls result in selecting the outer environments. **Note**: this function _does not_ work with the [Vim](https://github.com/VSCodeVim/Vim) extension. +- Add a multicursor to the current environment name: call _LaTeX Workshop: Multicursor selection of the current environment name_ from the **Command Palette**. For this command to work, the cursor must be strictly between `\begin{...}` and `\end{...}`. To define a shortcut, search for `latex-workshop.multicursor-envname` in the **Keyboard Shortcuts** menu. Repeated calls result in selecting the outer environments. ## Requirements diff --git a/package.json b/package.json index a305768c9..5d318ddad 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,12 @@ }, { "command": "latex-workshop.select-envname", - "title": "Multicursor selection of the current environment name", + "title": "Select the current environment name", + "category": "LaTeX Workshop" + }, + { + "command": "latex-workshop.multicursor-envname", + "title": "Add a multicursor to the current environment name", "category": "LaTeX Workshop" }, { diff --git a/src/commander.ts b/src/commander.ts index 80169ce01..39a593f19 100644 --- a/src/commander.ts +++ b/src/commander.ts @@ -238,7 +238,15 @@ export class Commander { if (!vscode.window.activeTextEditor || !this.extension.manager.isTex(vscode.window.activeTextEditor.document.fileName)) { return } - this.extension.envPair.selectEnvName() + this.extension.envPair.selectEnvName('selection') + } + + multiCursorEnvName() { + this.extension.logger.addLogMessage(`MutliCursorEnvName command invoked.`) + if (!vscode.window.activeTextEditor || !this.extension.manager.isTex(vscode.window.activeTextEditor.document.fileName)) { + return + } + this.extension.envPair.selectEnvName('cursor') } closeEnv() { diff --git a/src/components/envpair.ts b/src/components/envpair.ts index 03c64a160..cde0add98 100644 --- a/src/components/envpair.ts +++ b/src/components/envpair.ts @@ -27,11 +27,6 @@ function regexpAllMatches(str: string, reg: RegExp) { return res } -interface MatchPair { - str: string - pos: vscode.Position -} - interface MatchEnv { name: string type: string // 'begin' or 'end' @@ -81,7 +76,7 @@ export class EnvPair { return null } - locateMatchingPair(pattern: string, dir: number, pos: vscode.Position, doc: vscode.TextDocument) : MatchPair | null { + locateMatchingPair(pattern: string, dir: number, pos: vscode.Position, doc: vscode.TextDocument) : MatchEnv | null { const patRegexp = new RegExp(pattern, 'g') let lineNumber = pos.line let nested = 0 @@ -105,8 +100,9 @@ export class EnvPair { if ((m[1] === 'end' && dir === 1) || (m[1] === 'begin' && dir === -1)) { if (nested === 0) { const matchPos = new vscode.Position(lineNumber, m.index + 1) - const matchStr = m[0] - return {str: matchStr, pos: matchPos} + const matchName = m[2] + const matchType = m[1] + return {name: matchName, type: matchType, pos: matchPos} } nested -= 1 } @@ -120,6 +116,9 @@ export class EnvPair { return null } + /** + * While on a 'begin' or 'end' keyword, moves the cursor to the corresponding 'end/begin' + */ gotoPair() { const editor = vscode.window.activeTextEditor if (!editor || editor.document.languageId !== 'latex') { @@ -143,7 +142,14 @@ export class EnvPair { } } - selectEnvName() { + /** + * Select or add a multicursor to an environment name + * + * @param selectionOrCursor can be + * - 'selection': the environment name is selected both in the begin and end part + * - 'cursor': a multicursor is added at the beginning of the environment name is selected both in the begin and end part + */ + selectEnvName(selectionOrCursor: string) { const editor = vscode.window.activeTextEditor if (!editor || editor.document.languageId !== 'latex') { return @@ -151,7 +157,7 @@ export class EnvPair { const curPos = editor.selection.active const document = editor.document - const pattern = '\\\\(begin|end)\\{[^\\{\\}]*\\}' + const pattern = '\\\\(begin|end)\\{([^\\{\\}]*)\\}' const dirUp = -1 const beginEnv = this.locateMatchingPair(pattern, dirUp, curPos, document) if (!beginEnv) { @@ -163,10 +169,22 @@ export class EnvPair { return } - const envStartPos = beginEnv.pos.translate(0, 'begin{'.length) - const envEndPos = endEnv.pos.translate(0, 'end{'.length) - editor.selections = [new vscode.Selection(envStartPos, envStartPos), new vscode.Selection(envEndPos, envEndPos)] - editor.revealRange(new vscode.Range(envStartPos, envEndPos)) + const beginEnvStartPos = beginEnv.pos.translate(0, 'begin{'.length) + const endEnvStartPos = endEnv.pos.translate(0, 'end{'.length) + switch (selectionOrCursor) { + case 'cursor': + editor.selections = [new vscode.Selection(beginEnvStartPos, beginEnvStartPos), new vscode.Selection(endEnvStartPos, endEnvStartPos)] + break + case 'selection': + const envNameLength = beginEnv.name.length + const beginEnvStopPos = beginEnvStartPos.translate(0, envNameLength) + const endEnvStopPos = endEnvStartPos.translate(0, envNameLength) + editor.selections = [new vscode.Selection(beginEnvStartPos, beginEnvStopPos), new vscode.Selection(endEnvStartPos, endEnvStopPos)] + break + default: + this.extension.logger.addLogMessage(`Error - while selecting environment name`) + } + // editor.revealRange(new vscode.Range(beginEnvStartPos, endEnvStartPos)) } closeEnv() { @@ -177,11 +195,11 @@ export class EnvPair { const document = editor.document const curPos = editor.selection.active - const pattern = '\\\\(begin|end)\\{[^\\{\\}]*\\}' + const pattern = '\\\\(begin|end)\\{([^\\{\\}]*)\\}' const dir = -1 const resMatchingPair = this.locateMatchingPair(pattern, dir, curPos, document) if (resMatchingPair) { - const endEnv = resMatchingPair.str.replace('begin', 'end') + const endEnv = '\\end{' + resMatchingPair.name + '}' const edits = [vscode.TextEdit.insert(curPos, endEnv)] const uri = document.uri const edit = new vscode.WorkspaceEdit() diff --git a/src/main.ts b/src/main.ts index 3c571f793..17b5c2e00 100644 --- a/src/main.ts +++ b/src/main.ts @@ -144,6 +144,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand('latex-workshop.goto-section', (filePath, lineNumber) => extension.commander.gotoSection(filePath, lineNumber)) vscode.commands.registerCommand('latex-workshop.navigate-envpair', () => extension.commander.navigateToEnvPair()) vscode.commands.registerCommand('latex-workshop.select-envname', () => extension.commander.selectEnvName()) + vscode.commands.registerCommand('latex-workshop.multicursor-envname', () => extension.commander.multiCursorEnvName()) vscode.commands.registerCommand('latex-workshop.close-env', () => extension.commander.closeEnv()) context.subscriptions.push(vscode.workspace.onDidSaveTextDocument((e: vscode.TextDocument) => {