The preface

I was already a proven Emacs user before I started using VS Code, so when I started using VS Code, I first turned on its Emacs Keymap. But it soon became apparent that the key mapping lacked an important shortcut — Ctrl-L.

In Emacs, the command for Ctrl-L is recenter-top-bottom, which is used to rotate the cursor line to the middle, top, and bottom of the visible area (Windows in Emacs) (as shown in the figure below)

This is a feature I use a lot, especially after jumping to the first line of a function definition. I have a habit of pressing twice to scroll to the top of the window to see as much as possible on one screen.

To avoid reinventing the wheel, I did some searching and found an extension that claims to do just that: Recenter Top Bottom. Unfortunately, this does not work after installation.

Do you have to use the mouse to carefully roll the cursor to the top of the line? Of course not. Since it’s not available out of the box, write your own VS Code extension to implement this functionality.

Young people’s first VS Code extension

Create a VS Code extension project

To get started with VS Code extension development, there is a good tutorial. An extension has a lot of “eight-part” code that can be quickly generated with YO and Generator-code

npm install -g yo generator-code
yo code
Copy the code

At this point, you get a directory called HelloWorld. Open it up with VS Code, and make a big deal out of it.

The realization of the cursor in the line of vertical center function

The core logic for VS Code extensions is defined in the file SRC /extension.ts. In the sample Code generated by Yo, registerCommand registers a command called helloWorld.Helloworld, whose logic simply pops up Hello VS Code from HelloWorld in the bottom right corner! . This callback function is where the business logic stops.

To enable the ability to scroll the cursor line to the middle, it’s important to know what support VS Code has for developers. After exploring the VS Code API documentation, I came up with the following clues:

  1. throughvscode.window.activeTextEditorCan get the currently focused editor — its value may be empty (undefined);
  2. TextEditorProperties of an instance.selection.activeCan get the current cursor position;
  3. TextEditorThe instance has a methodrevealRangeYou can scroll through the text to change the scope of the presentation, it needs onevscode.RangeClass, and avscode.TextEditorRevealTypeEnum value of type;
  4. vscode.TextEditorRevealType.InCenterIs to show the given range in the middle,vscode.TextEditorRevealType.AtTopIs the top.

With this knowledge base, implementing such a callback function is a snap

function recenterTop() {
  const editor = vscode.window.activeTextEditor;
  if(! editor) {return;
  }
  const cursorPosition = editor.selection.active;
  editor.revealRange(new vscode.Range(cursorPosition, cursorPosition), vscode.TextEditorRevealType.InCenter);
}
Copy the code

Since there is no shortcut key configured for this command, it can only be invoked from the VS Code command panel

To achieve the cursor on the top of the line function

Next I will invoke helloWorld. Helloworld twice in succession, scrolling the cursor line to the top. In Emacs, it’s easy to know if a command has been run consecutively — Emacs has a variable called last-command that stores the name of the last command, just check if it equals recenter-top-bottom. But VS Code didn’t expose this power, so it had to find another way.

My policy is that if the helloWorld.HelloWorld time indicator is called at the same location as the last time the command was called, it is considered a continuous call. To do this, we need two variables defined outside of the recenterTop function:

  1. previousPositionResponsible for recording the last callrecenterTopThe position of the time marker, its initial value is zeronull;
  2. revealTypeStores the last time the display range was adjusted toTextEditorThe instancerevealRangeMethod, which also has an initial value ofnull.

My goal is to try to emulate the alternating center and top effects of recentr-top-bottom in Emacs, so:

  1. ifrevealTypefornull, which means this is the first callrecenterTop“Then the effect is centered. Otherwise;
  2. If the cursor is at a different position this time than the last time, that means it was called last timerecenterTopAfter calling other commands, the effect is still centered. Otherwise;
  3. ifrevealTypeIt was already in the middle, so it was placed at the top. Otherwise;
  4. willrevealTypeCenter.

Talk is cheap. Show me the code.

let previousPosition: null|vscode.Position = null;
let revealType: null|vscode.TextEditorRevealType = null;

function recenterTop() {
  const editor = vscode.window.activeTextEditor;
  if(! editor) {return;
  }
  const cursorPosition = editor.selection.active;
  if(! revealType) { revealType = vscode.TextEditorRevealType.InCenter; }else if(previousPosition && ! cursorPosition.isEqual(previousPosition)) { revealType = vscode.TextEditorRevealType.InCenter; }else if (revealType === vscode.TextEditorRevealType.InCenter) {
    revealType = vscode.TextEditorRevealType.AtTop;
  } else {
    revealType = vscode.TextEditorRevealType.InCenter;
  }
  previousPosition = cursorPosition;
  editor.revealRange(new vscode.Range(cursorPosition, cursorPosition), revealType);
}
Copy the code

Define shortcut keys

Using the command panel is not my final goal, using shortcuts is. According to the VS Code documentation, all you need to do is add a keybindings attribute to the package.json contributes object and define the command and key sequence.

{
  // Omit other unnecessary attributes
  "contributes": {
    "keybindings": {// Add attributes
      "command": "helloworld.helloWorld"."key": "ctrl+l"}}}Copy the code

Afterword.

Those of you who read my previous post, “Write code for Sore Fingers,” will remember that I defected from Emacs Keymap to Vim Keymap. So, I didn’t really use the VS Code extension above. Instead, High Frequencies now use Vim Keymap’s built-in Z -. And Z – Mappings — the former for vertical Center, the latter for top Setting.

To love your fingers, start by using Vim Keymap.

Read the original