# Making a vi layer and the leader plugin

**URL:** https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891
**Category:** Plugins
**Created:** [December 20, 2017, 10:58pm UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891 "2017-12-20T22:58:10Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)
#### Post date: [December 20, 2017, 10:58pm UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891/1 "2017-12-20T22:58:10Z")

</div>

So I want to make a layer that emulates the vi movement and editing commands.  
I was thinking it would be best to use the Leader plugin to make a lookup table aliasing each vi command to a sequence of keys that does what I need it to.  
For instance 2dw would get mapped to shift-control right arrow right arrow delete.

Now do I need to separately define 2dw, 3dw, 4dw, etc. or is there a way to recognize a one or two digit number typed and repeat a command that many times?

I don’t want to have to enter the leader key for each new command - is there a way to make it automatic?

One possibility might be to set up a macro where the “switch to vi layer” key automatically presses the leader key and then each defined sequence ends with the leader key - but is there a time delay to enter a sequence after pressing the leader key?

Or is there a better way to do this than using Leader?

---

<div class="post-metadata">

### Author: ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)
#### Post date: [December 21, 2017, 12:25am UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891/2 "2017-12-21T00:25:02Z")

</div>

> [@fire](#):
>
> Now do I need to separately define 2dw, 3dw, 4dw, etc. or is there a way to recognize a one or two digit number typed and repeat a command that many times?

With the `Leader` plugin, yes.

> [@fire](#):
>
> Or is there a better way to do this than using Leader?

I think the most practical thing would be to have a “vi layer”, where you have a couple of macros: numbers would be macros that do nothing, but accumulate the numbers you press. `d` would flip a boolean that will signal deletion, but do nothing otherwise. `w` would be the trigger that executes the command, by looking at the boolean that `d` set, and repeating the command N times.

Something along these lines:

```c++
static struct {
  uint8_t repeat_number;
  enum {
    NOTHING,
    DELETE
  } command;
} vi_state;

// add the following to the macro enum:
enum {
  VI_0,
  VI_1,
  // ...
  VI_D,
  VI_W,
};

void macroViNumber(uint8_t macro_index, uint8_t key_state) {
  if (!keyToggledOn(key_state))
    return;
  vi_state.repeat_number = vi_state.repeat_number * 10 + (macro_index - VI_0);
}

void viExecute(void) {
  switch (vi_state.command) {
    case NOTHING:
      break;
    case DELETE:
      // Press Shift + Control
      Macro.play(MACRO(D(LeftShift), D(LeftControl)));
      // Press & Release RightArrow N times
      for (uint8_t i = 0; i < vi_state.repeat_number; i++) {
        Macro.play(MACRO(T(RightArrow)));
      }
      // Release Shift + Control, then tap Delete
      Macro.play(MACRO(U(LeftShift), U(LeftControl), T(Delete)));
      break;
  }
}

void macroViCommand(uint8_t macro_index, uint8_t key_state) {
  if (!keyToggledOn(key_state))
    return;
  switch (macro_index) {
    case VI_D:
      vi_state.command = DELETE;
      break;
    case VI_W: {
      viExecute();
      vi_state.command = NOTHING;
      vi_state.repeat_number = 0;
    }
}

const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
  switch (macroIndex) {
    case VI_0 ... VI_9:
      macroViNumber(macroIndex, keyState);
      break;
    case VI_D:
    case VI_W:
      macroViCommand(macroIndex, keyState);
      break;
  }

  return MACRO_NONE;
}

// On the VI layer:
M(VI_1), M(VI_2), ....

```

---

<div class="post-metadata">

### Author: ![craigdissel](https://avatars.discourse-cdn.com/v4/letter/c/b5ac83/32.png) [@craigdissel](https://community.keyboard.io/u/craigdissel)
#### Post date: [December 27, 2017, 4:17am UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891/3 "2017-12-27T04:17:54Z")

</div>

Belatedly, I would also point to [Kaleidoscope-PrefixLayer](https://github.com/jamesnvc/Kaleidoscope-PrefixLayer); it won’t do everything you want out of the box but it may be a better start than Leader

---

<div class="post-metadata">

### Author: ![amos](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/amos/32/639_2.png) [@amos](https://community.keyboard.io/u/amos)
#### Post date: [February 10, 2018, 7:07pm UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891/4 "2018-02-10T19:07:09Z")

</div>

I would think the biggest hurdle would be that you can’t delete words because the keyboard has no idea where the words are on the screen. You would have to find a way to communicate back to the keyboard where the next is.

---

<div class="post-metadata">

### Author: ![andre](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/andre/32/137_2.png) [@andre](https://community.keyboard.io/u/andre)
#### Post date: [June 10, 2018, 7:22pm UTC](https://community.keyboard.io/t/making-a-vi-layer-and-the-leader-plugin/891/5 "2018-06-10T19:22:29Z")

</div>

You can definitely delete one word at a time, by issuing option-delete on a Mac, ctrl-w in many Unix contexts, etc.
