Skip to content
Grégoire Geis edited this page Oct 15, 2021 · 1 revision

Similarly to kakoune-mirror, the following key binding opens a sticky menu for growing and shrinking selections, inserting surrounding characters, and removing edges of the current selection.

[
  {
    "key": "'",
    "command": "dance.openMenu",
    "args": {
      "menu": {
        "items": {
          "l": {
            "text": "character left",
            "command": "dance.run",
            "args": {
              "commands": [
                ".select.left.extend",
                ".selections.changeDirection",
                ".select.right.extend",
                ".selections.changeDirection",
              ],
            },
          },
          "h": {
            "text": "character right",
            "command": "dance.run",
            "args": {
              "commands": [
                ".select.right.extend",
                ".selections.changeDirection",
                ".select.left.extend",
                ".selections.changeDirection",
              ],
            },
          },
          "j": {
            "text": "line down",
            "command": "dance.run",
            "args": {
              "commands": [
                ".select.down.extend",
                ".selections.changeDirection",
                ".select.up.extend",
                ".selections.changeDirection",
              ],
            },
          },
          "k": {
            "text": "line up",
            "command": "dance.run",
            "args": {
              "commands": [
                ".select.up.extend",
                ".selections.changeDirection",
                ".select.down.extend",
                ".selections.changeDirection",
              ],
            },
          },
          "(": {
            "text": "(surround)",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '(' + x + ')')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "(" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": ")" }],
              ],
            },
          },
          "{": {
            "text": "{surround}",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '{' + x + '}')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "{" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": "}" }],
              ],
            },
          },
          "[": {
            "text": "[surround]",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '[' + x + ']')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "[" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": "]" }],
              ],
            },
          },
          "<": {
            "text": "<surround>",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '<' + x + '>')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "<" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": ">" }],
              ],
            },
          },
          "\"": {
            "text": "\"surround\"",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '\"' + x + '\"')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "\"" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": "\"" }],
              ],
            },
          },
          "'": {
            "text": "'surround'",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => `'` + x + `'`)",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "'" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": "'" }],
              ],
            },
          },
          "`": {
            "text": "`surround`",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => '`' + x + '`')",
              "commands": [
                [".edit.insert", { "where": "start", "shift": "extend", "text": "`" }],
                [".edit.insert", { "where": "end", "shift": "extend", "text": "`" }],
              ],
            },
          },
          "d": {
            "text": "delete surround",
            "command": "dance.run",
            "args": {
              "input": "await replace((x) => x.slice(1, -1))",
              "commands": [
                ".selections.save",
                ".selections.reduce.edges",
                ".edit.delete",
                ".selections.restore",
              ],
            },
          },
        },
      },
      "locked": true,
    },
    "when": "editorTextFocus && dance.mode == 'normal'",
  },
]

Note that when both input and commands are specified, input is the more straightforward and efficient implementation, and commands is the fallback implementation for users with arbitrary code execution disabled.

The command above requires e5d7752 (Dance 0.5.8).