An open API service indexing awesome lists of open source software.

https://github.com/lukstafi/navi-parens

VS Code extension: navigate structured code with keybindings. Markmacs: WYSIWYG for LaTeX via the preview pane.
https://github.com/lukstafi/navi-parens

editor-plugin emacs latex vscode vscode-extension wysiwyg

Last synced: about 1 year ago
JSON representation

VS Code extension: navigate structured code with keybindings. Markmacs: WYSIWYG for LaTeX via the preview pane.

Awesome Lists containing this project

README

          

# navi-parens README

[Navi Parens in the Open VSX Registry](https://open-vsx.org/extension/lukstafi/navi-parens)

_Navi Parens_ is a Visual Studio Code extension that provides structured code navigation similar to what's available in Emacs.
It also provides additional key bindings for moving the cursor without "fingers leaving the home row".

The future plan for _Navi Parens_ is to build out _Markmacs Mode_ to emulate TeXmacs-like WYSIWYG editing capabilities within preview panes.

## Keywords

VSCode, Structured Code Navigation, Emacs S-Expressions, Atom Block Travel, Jump, Selection, Keymaps, Key Shortcuts, Home Row Cursor Movement, LaTeX, WYSIWYG, TeXmacs

## Navi Parens

### Overview

_Navi Parens_ provides commands for moving the cursor around smoothly from the innermost parentheses to the outermost code blocks and in between. It also offers keybindings centered around the `J, K, L, I` keys and the `Alt` modifier. E.g. moves of the cursor: `Alt+J` one character left, `Ctrl+Alt+J` one scope left, `Alt+K` one line up, `Ctrl+Alt+K` to outside the beginning of the scope around the cursor.

![Overview](animations/overview.gif)
* Activates the extension.
* Navigates in `SEM` mode across functions.
* Navigates in `SEM/JTB` mode within function.
* Switches to `IND`, navigates within function.
* Navigates across functions.
* Switches to `RAW` to demonstrate navigating within docu-comments.

### Features

Commands:
* `goPastNextScope`: `ctrl+alt+l` Go past the next same-level closing bracket/scope
* `goPastPreviousScope`: `ctrl+alt+j` Go to the previous same-level opening bracket/scope
* `goToUpScope`: `ctrl+alt+i` Go outside the opening of the current level
* `goToDownScope`: `ctrl+alt+k` Go outside the closing of the current level
* `goToBeginScope`: `ctrl+alt+a` Go near the opening of the current level but stay inside scope
* `goToEndScope`: `ctrl+alt+e` Go near the closing of the current level but stay inside scope
* `goToPreviousEmptyLine`: `ctrl+alt+h` Go to the previous line with only whitespace (or empty)
* `goToNextEmptyLine`: `ctrl+alt+;` Go to the next line with only whitespace (or empty)
* `selectToNextScope`: `shift+ctrl+alt+l` Select past the next same-level closing bracket/scope
* `selectToPreviousScope`: `shift+ctrl+alt+j` Select to the previous same-level opening bracket/scope
* `selectToUpScope`: `shift+ctrl+alt+i` Select till outside the opening of the current level
* `selectToDownScope`: `shift+ctrl+alt+k` Select till outside the closing of the current level
* `selectToBeginScope`: `shift+ctrl+alt+a` Select to near the opening of the current level but stay inside scope
* `selectToEndScope`: `shift+ctrl+alt+e` Select to near the closing of the current level but stay inside scope
* `selectToPreviousEmptyLine`: `shift+ctrl+alt+h` Select to the previous line with only whitespace (or empty)
* `selectToNextEmptyLine`: `shift+ctrl+alt+;` Select to the next line with only whitespace (or empty)
* `cycleBracketScopeMode`: `ctrl+alt+p` Cycle through the bracket scope logic (`ctrl+shift+\`, delimiter counting, none)
* `cycleBlockScopeMode`: `shift+ctrl+alt+p` Cycle through block scope logic (symbols, indentation, none)
* `goPastNextWord`: `alt+;` Go past the curent/next word, ignoring language-specific rules
* `goPastPreviousWord`: `alt+h` Go past the previous word / beginning of current, ignoring language-specific rules
* `selectPastNextWord`: `shift+alt+;` Select past the current/next word, ignoring language-specific rules
* `selectPastPreviousWord`: `shift+alt+h` Select past the previous word / beginning of current, ignoring language-specific rules
* `toggleMarkmacsMode`: `ctrl+alt+n` Turn on / off cursor and scope visualization for LaTeX and Mermaid
* `goRightOverDelims`: `alt+l` Go right one character/separator/delimiter, i.e. skip over recognized delimiters
* `goLeftOverDelims`: `alt+j` Go left one character/separator/delimiter, i.e. skip over recognized delimiters
* `goUpOneLiner`: MM/`alt+i` Go left / up at least `oneLinerMin` characters, stopping on a scope boundary; binding to `alt+i` activated by `ctrl+alt+n`
* `goDownOneLiner`: MM/`alt+k` Go right / down at least `oneLinerMin` characters, stopping on a scope boundary; binding to `alt+k` activated by `ctrl+alt+n`
* `goBeginScopeOrArg`: `alt+a` Go near the opening of the current scope or argument
* `goEndScopeOrArg`: `alt+e` Go near the closing of the current scope or argument
* `selectRightOverDelims`: `shift+alt+l` Like `goRightOverDelims`, but extend the selection
* `selectLeftOverDelims`: `shift+alt+j` Like `goLeftOverDelims`, but extend the selection
* `selectUpOneLiner`: MM/`shift+alt+i` Like `goUpOneLiner`, but extend the selection
* `selectDownOneLiner`: MM/`shift+alt+k` Like `goDownOneLiner`, but extend the selection
* `selectBeginScopeOrArg`: `shift+alt+a` Like `goBeginScopeOrArg`, but extend the selection
* `selectEndScopeOrArg`: `shift+alt+e` Like `goEndScopeOrArg`, but extend the selection
* `toggleMarkmacsMode`: `ctrl+alt+n` Enable/disable Markmacs Mode, which is tailored for LaTeX and changes the behavior of the `alt+i`, `alt+k`, `alt+j`, `alt+l` bindings/commands.

The meaning of "near the beginning/end of a scope" is mode-specific.

Extra key bindings:
* `insertCursorAtEndOfEachLineSelected`: rebound from `shift+alt+i` to `shift+alt+p`
* `cursorRight`: `alt+l`
* `cursorLeft`: `alt+j`
* `cursorUp`, NoMM/`alt-i`, `list.focusUp`, `selectPrevCodeAction`, `selectPrevSuggestion`, `selectPrevParameterHint`: `alt+i`
* `cursorDown`, NoMM/`alt-k`, `list.focusDown`, `selectNextCodeAction`, `selectNextSuggestion`, `selectNextParameterHint`: `alt+k`
* `cursorHome`: `alt+a`
* `cursorEnd`: `alt+e`
* `cursorRightSelect`: `shift+alt+l`
* `cursorLeftSelect`: `shift+alt+j`
* `cursorUpSelect`: NoMM/`shift+alt+i`
* `cursorDownSelect`: NoMM/`shift+alt+k`
* `cursorHomeSelect`: `shift+alt+a`
* `cursorEndSelect`: `shift+alt+e`
* `deleteRight`: `alt+d`
* `deleteWordRight`: `ctrl+alt+d`

I suggest mapping `Caps Lock` to `alt` (rather than `ctrl`) to facilitate using the above bindings.

_Navi Parens_ combines two sources of structure information:
* Brackets, braces, parentheses.
* Code blocks.

Each of the sources comes in two variants.
* The bracket scopes come from either a judicious use of the built-in `Go to Bracket` command, or just looking for the delimiters.
* The block scopes come from either semantic symbol providers, as in the outline view, where the corresponding scope is the full range of a definition; or from indentation.

An indentation scope comprises a less-indented line followed by at least one more-indented line. The first, less-indented line is a big opening delimiter for the indentation scope: none of it is inside the scope, and only the first non-whitespace position and earlier are outside the scope. The closing delimiter is the whitespace from the end of the last indented line to before the first non-whitespace position of the less-indented following line. Currently, if there is an empty line at the end of an indentation scope, the `Go Past Next Scope` and `Go To Down Scope` commands put the cursor there.

The `Raw` mode for bracket scopes is useful as it enables navigating within comments or string literals, and does not cause "jitter" like the `JumpToBracket` mode does. However, it is less reliable since it will count brackets even if they were not intended as delimiters.

### Some use cases

First _Navi Parens_-specific command activates the scope navigation modes indicator.

![activation](animations/activation.gif)

Navigation with `Semantic` mode.

![Semantic](animations/semantic.gif)

Navigation with `Indentation` mode.

![Indentation](animations/indentation.gif)

Navigation with `Jump To Bracket` with block modes disabled.

![Jump To Bracket bracket scope mode](animations/jumptobracket.gif)

Navigation with `Raw` bracket mode.

![Raw bracket scope mode](animations/rawbrackets.gif)

## Future plan -- the big goal for v2.0: MarkMacs Mode

_Markmacs Mode_ will emulate TeXmacs-like WYSIWYG editing capabilities within preview panes. The LaTeX and Mermaid code will be postprocessed before being rendered, to add a cursor marker and a scope marker. Moreover, Markmacs Mode will add commands such as "cycle-through" which replaces a token to the left of the cursor with its alternatives.

### Planned features

- Postprocesses the previewed code:
- moves/adds LaTeX commands or Mermaid style to highlight the cursor position and the nearest scope encompassing the cursor, e.g. with a color split indicating the cursor position;
- renders the text of partially entered or edited commands (when the cursor is on/at the command text) by escaping the `\`.
- The actual cursor and edit actions happen in the markdown / latex pane, but user's focus can be fully in the preview pane.
- Adds snippets, keybindings for the snippets commands.
- Adds a command to cycle through alternatives of what's to the left of the cursor.
- E.g. $S$ -> $\Sigma$ -> $\sum$ -> $S$; $P$ -> $\Pi$ -> $\prod$ -> $P$; $f$ -> $\phi$ -> $\varphi$ -> $f$...
- Adds context-sensitive commands to extend the object at cursor to the right, bottom, left and up. For Markdown tables and LaTeX matrices, adds columns or rows; for Mermaid diagrams, adds siblings or children or parents.

Note: there's [a PanDoc filter](https://github.com/raghur/mermaid-filter) for [Mermaid](http://mermaid.js.org/#/).

You can [sponsor the development of Navi Parens](https://github.com/sponsors/lukstafi).

### Requirements

- [Mermaid VS Code extension](https://github.com/mjbvz/vscode-markdown-mermaid) to make full use of the graph editing functionality.

## Extension Settings

This extension contributes the following settings:

* `navi-parens.rebind`: How to deal with the `shift+alt+i` binding conflict.
* Defaults to `true`.
* If `true`:
* rebind `insertCursorAtEndOfEachLineSelected` from `shift+alt+i` to `shift+alt+p`
* bind `cursorUpSelect` to `shift+alt+i`
* do not make bindings for `ctrl+alt+o`.
* If `false`:
* bind `cursorUpSelect` to `ctrl+shift+alt+o`
* bind `cursorUp` to both `alt+i` and `ctrl+alt+o`.
* `navi-parens.blockScopeMode`: an enum selecting where the non-bracket structure information comes from.
* `Semantic`: the semantic analyzers integrated with VSCode. The default.
* `Indentation`: _Navi Parens_ constructs symbols based on indentation. Details below.
* `None`: same behavior as if there were no symbol definitions in text.
* `ctrl+shift+alt+p` toggles between `Semantic` and `Indentation`.
* `navi-parens.bracketScopeMode`: an enum selecting how to get the bracket structure information.
* `JumpToBracket`: uses `editor.action.jumpToBracket` (i.e. `ctrl+shift+\`). The default.
* `Raw`: only the bracket characters are considered, without context.
* `ctrl+shift+alt+p` toggles between `Semantic` and `Raw`.
* `navi-parens.separatorsNoMM`: The separators for commands like `goBeginScopeOrArg`, `goUpOneLiner` when not in Markmacs Mode.
* Defaults to `[",", ";", "/[^a-zA-Z0-9]let /"]`.
* Can be language specific.
* `navi-parens.closingBracketsRaw`: the closing delimiters for the `Raw` `bracketScopeMode`.
* Defaults to `[" *)", ")", "]", "}", "", ""]`.
* Can be language specific.
* `navi-parens.openingBracketsRaw`: the opening delimiters for the `Raw` `bracketScopeMode`.
* Defaults to `["(* ", "(", "[", "{", "

", "