Need help with dance?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

71
193 Stars 22 Forks ISC License 343 Commits 23 Opened issues

Description

Make your cursors dance with Kakoune-like editing in VS Code.

Services available

!
?

Need anything else?

Contributors list

# 87,146
F#
Rust
Zsh
keybind...
267 commits
# 51,957
Firebas...
TypeScr...
Google
C
64 commits
# 626,953
TypeScr...
CSS
Shell
kakoune
5 commits
# 49,256
C++
trading...
Postgre...
ESLint
1 commit
# 158,094
Jupyter...
Clojure
data-fr...
integra...
1 commit
# 157,597
kakoune
Vim
c-plus-...
modal-e...
1 commit
# 5,372
kakoune
modal-e...
ecmascr...
lodash
1 commit
# 72,099
Rust
Haskell
Vim
Neovim
1 commit

Dance

Kakoune-inspired key bindings, modes, menus and scripting for Visual Studio Code.

Important note

The next release of Dance (available in this branch) is a complete rewrite from the previous release. It adds many features (to list a few, custom modes, better commands, and a scripting API) and has many QOL improvements (better status bar buttons, better character mode, better history, support for multiple editors for one document, more tests, and better internal architecture).

While this will improve the quality of Dance over time, in the short term this will make it much less stable due to bugs. If you encounter a bug, please file an issue (or directly submit a PR) containing test cases for the command.

Thanks for bearing with me!

Huh?

Dance provides Kakoune-inspired commands and key bindings for Visual Studio Code, as well as support for custom modes and scripting.

Added key bindings are (mostly) compatible with Kakoune's, but are meant to be an addition to Visual Studio Code, rather than an emulation layer on top of it.

Why VS Code, and not Kakoune directly?

  • Kakoune is an efficient and lightweight editor with a very small ecosystem. VS Code is an entire IDE with a huge ecosystem and many existing extensions.
  • Kakoune is Unix-only.

Why Kakoune's key bindings, and not Vim's?

Why is it merely 'inspired' by Kakoune?

  • Unlike VSCodeVim which attempts to emulate Vim, Dance's only goal is to provide VS Code-native commands and key bindings that are inspired by Kakoune.
    • Some features are provided to mimic Kakoune's behavior (e.g. treating positions as coordinates of characters, rather than carets between characters like VS Code), but are optional.
  • Kakoune, Vim and VS Code are all fully-fledged text editors; therefore, they have overlapping features. For instance, where VSCodeVim provides its own multi-cursor and command engines to feel more familiar to existing Vim users, Dance leaves multi-cursor mode and editor commands to VS Code entirely.

User Guide

For most commands, the usage is the same as in Kakoune. However, the following changes have been made:

Custom modes

All modes are custom. By default, the

normal
and
insert
modes are defined, and many Kakoune-inspired keybindings are available. More modes can be created, though. These modes are configured with
dance.modes
.

Selection behaviors

Dance by default uses caret-based selections just like VS Code. This means a selection is anchored between two carets (i.e. positions between characters), and may be empty.

If you prefer character-based selections like Kakoune, please set

"selectionBehavior": "character"
in the configuration of the mode in which you wish to use character-based selections. This mode is designed to work with block-style cursors, so your configuration would typically look like:
"dance.modes": {
  "insert": {
    // ...
  },
  "normal": {
    "cursorStyle": "block",
    "selectionBehavior": "character",
    // ...
  }
},

If this is enabled, Dance will internally treat selections as inclusive ranges between two characters and imply that each selection contains at least one character.

Scripting

Most keybindings exposed by Dance are actually implemented by running several Dance commands in a row. For instance,

dance.modes.set.normal
is actually a wrapper around
dance.modes.set
with the argument
{ input: "normal" }
. Commands that take an input, like
dance.modes.set
, will prompt a user for a value if no argument is given.

Additionally to having commands with many settings, Dance also exposes the

dance.run
command, which runs JavaScript code. That code has access to the Dance API, and can perform operations with more control than Dance commands. Where Dance commands in the
dance.selections
namespace operate the same way on all selections at once,
dance.run
can be used to individually manipulate selections.

Finally, the Dance API is exported by Dance. Other VS Code extensions can specify that they depend on Dance (with the

extensionDependencies
property), and then access the API by calling
activate
:

const { api } = await vscode.extensions.getExtension("gregoire.dance").activate();

Pipes

Pipes no longer accept shell commands, but instead accept "expressions", those being: -

#
: Pipes each selection into a shell command (the shell is taken from the
terminal.external.exec
value). -
/[/[/]
: A RegExp literal, as defined in JavaScript. Do note the addition of a
replacement
, for commands that add or replace text. -
: A JavaScript expression in which the following variables
  are available:
  - 
$
: Text of the current selection. -
$$
: Array of the text of all the selections. -
i
: Index of the current selection. -
n
: Number of selections in
$$
.

Depending on the result of the expression, it will be inserted differently: -

string
: Inserted directly. -
number
: Inserted in its string representation. -
boolean
: Inserted as
true
or
false
. -
null
: Inserted as
null
. -
undefined
: Inserted as an empty string. -
object
: Inserted as JSON. - Any other type: Leads to an error.

Examples

  • /(\d+),(\d+)/$1.$2/g
    replaces
    12,34
    into
    12.34
    .
  • i + 1
    replaces
    1,1,1,1,1
    into
    1,2,3,4,5
    , assuming that each selection is on a different digit.

Status bar

Dance provides several status bar segments (left-aligned) exposing info similar to Kakoune's default mode-line. Most of them are hidden by default and only shown contextually:

  • current mode: click to switch to another mode
  • macro recording status: click to stop recording
  • current count prefix: click to reset to 0
  • current register: click to unset
  • dance error: click to copy the full description of the last error

Miscellaneous changes

A few changes were made from Kakoune, mostly out of personal preference, and to make the extension integrate better with VS Code.

  • The default yank register
    "
    maps to the system clipboard.
  • Registers can have arbitrary names. If the name of a register starts with a single space character, it will be local to the current document.
  • When using the default configuration (that is to say, these settings can be modified):
    • The cursor is not a block, but a line: Dance focuses on selections, and using a line instead of a block makes it obvious whether zero or one characters are selected. Besides, the line-shaped cursor is the default in VS Code.
    • Changing the mode will also change the
      editor.lineNumbers
      configuration value to
      on
      in
      insert
      mode, and
      relative
      in normal mode.

Troubleshooting

  • Dance uses the built-in VS Code key bindings, and therefore does not override the
    type
    command. However, it sometimes needs access to the
    type
    command, in dialogs and register selection, for instance. Consequently, it is not compatible with extensions that always override the
    type
    command, such as VSCodeVim; these extensions must therefore be disabled.
  • If you're on Linux and your keybindings don't work as expected (for instance,
    swapescape
    is not respected), take a look at the VS Code guide for troubleshooting Linux keybindings. TL;DR: adding
    "keyboard.dispatch": "keyCode"
    to your VS Code settings will likely fix it.

Contributing

Bugs

There are unfortunately still bugs lurking around. If you find one, please ensure that it has not been reported yet and submit a test that does not pass and can be used to reliably reproduce the bug.

Features

If you'd like to add or improve a feature, please make sure that no similar feature has been requested in the issues and file a new issue for it. This will ensure that no two people work on the same feature at the same time, and will be a good place to ask for help in case you want to tackle this yourself.
Since some features are not general enough, it may be requested of you to make a plugin that uses the Dance API or to simply use scripts in the meantime.

When contributing, please be mindful of the existing coding conventions and naming.

Your PR will be rebased on top of

master
in order to keep a clean commit history. Please avoid unnecessary commits (
git commit --amend
is your friend).

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.