71 / dance Goto Github PK
View Code? Open in Web Editor NEWMake your cursors dance with Kakoune-like modal editing in VS Code.
Home Page: https://marketplace.visualstudio.com/items?itemName=gregoire.dance
License: ISC License
Make your cursors dance with Kakoune-like modal editing in VS Code.
Home Page: https://marketplace.visualstudio.com/items?itemName=gregoire.dance
License: ISC License
This makes repeated use of [
or {
idempotent.
.
should just repeat the last command, without entering insert mode.
Moving with e
over the last word on a line should not select the newline but end at the words end.
It would be nice to have easy access to the list of versions. The releases don't have to be published on GitHub, but just creating the tags would already populate the listing at https://github.com/71/dance/releases (example).
For convenience, here's the list of releases so far:
(If you're feeling generous, a CHANGELOG.md file would be nice as well!)
Using .
replays all insert keys but does not take care of any corrections made during insertion and of auto inserted parens/brackets.
To reproduce:
i
and type funk<backspace>c(arg)
and hit <escape>
.
to repeat the command.Expected output:
func(arg)
Actual output:
funkc()arg)
Selecting a paragraph with <a-p>
and <i-p>
doesn't make a difference. <a-p>
should select empty lines after the paragraph.
Sorry to bother you again 😉 . In regular Kakoune you can use C
(shift-c) and alt-C
(alt-shift-c) to copy selections to the following/previous line, which creates a multi-cursor.
Key Description ALT + key CTRL + key g key (goto) C copy selection on next lines copy selection on previous lines
Would it be possible to add this command too? Thanks!
Thanks for publishing the extension to the marketplace, it's working great!
One thing I noticed is that the behavior of j
/J
seems to have changed from regular Kakoune. As far as I can tell, in regular Kakoune j
acts similar to the arrow key: it only performs movements, while J
can be used to extend a selection.
In dance j
extends the selection, where as J
goes into insert mode. Is this intentional, or maybe something that I can configure?
Hey there! In VSCodeVim we keep track of the column that the cursor wants to be on in addition to the one it's actually on (VimState.desiredColumn
). So $
will set the desired column to MAX_INT
- that way, motions like j
and k
will go to the end of the line, when coming from a shorter line.
It does seem dance has that concept, but gh
and gl
don't set it to 0
and MAX_INT
like kakoune does.
(Very cool extension, by the way! I'll definitely try to find some time to contribute)
To reproduce run the Dance: toggle
command from either normal or insert mode.
Expected behaviour: Line numbering reverts to the editor.lineNumbers
setting.
Actual behaviour: Line numbering stays as relative
(if toggled from normal mode) or switch back to relative
(if toggled from insert mode)
Thank you very much for making this and putting it on the marketplace!
I've found that when in normal mode, moving the cursor off the top or bottom of the window does not cause the window to scroll.
To reproduce:
The same applies when the top of the file is not visible and I move the cursor to the start of the file using gg.
I've disabled all extensions except Dance.
I've observed the issue on Linux and Windows.
Version info (Linux):
Dance: 0.1.4
Ubuntu 18.04.2 LTS
VSCode:
Version: 1.39.2
Commit: 6ab598523be7a800d7f3eb4d92d7ab9a66069390
Date: 2019-10-15T15:33:40.634Z
Electron: 4.2.10
Chrome: 69.0.3497.128
Node.js: 10.11.0
V8: 6.9.427.31-electron.0
OS: Linux x64 4.15.0-70-generic
Thank you, and let me know if there's any other info I can provide etc.!
I noticed some strange behavior when trying to use the dance.split.lines command (Alt+S):
If you have the cursor at the end of the selection it looks like it works as intended:
But if you put it at the beginning you get this weird behavior where only the first and last line are selected:
Assuming this is unintended behavior, I think the issue is probably with this bit of code:
dance/src/commands/multiple.ts
Lines 83 to 89 in f890335
To reproduce:
1 2
.2
by hitting b
, hit c
and change it to 3
.1
by hitting bb
, hit .
.Expected output:
3 3
: 1
is changed to 3
as well (repeat last edit action)Actual output:
1 33
: the edit is repeated at the last insert positionKakoune has view commands to help navigating: https://github.com/mawww/kakoune/blob/master/doc/pages/keys.asciidoc#view-commands
Would love to see those commands implemented in Dance.
In vanilla Kakoune and also in Dance I tend to mix up which mode I'm in. I know the status bar shows me "Normal" or "Insert", but it is usually far away from the cursor, where my eyes are, and I have to search for the text between all the other information VSCode shows in the status bar.
I love how in Vim you can spot the difference just by looking at the cursor: a block for normal mode, and a line for insert mode. However, this is not an option for Dance, because of the (very well founded!) choice to support zero width selections.
I was thinking about other ways to visually distinguish normal mode and insert mode. Till now, I've come up with two ideas:
"editor.renderLineHighlight": "line"
"editor.renderLineHighlight": "none"
What do you think of these options?
In kakoune, 9w
(lower case w
) moves forward by 9 words, selecting the 9th word. However, in dance it will select from current active to 9 words later, for a total selection of 9 words (as if 9W
with Shift+W were used).
Is this something worth fixing? I can draft a PR for this.
I try to build the plugin with
vsce package
Executing prepublish script 'npm run vscode:prepublish'...
ERROR Command failed: npm run vscode:prepublish
warning [email protected]: The engine "vscode" appears to be invalid.
/bin/sh: ts-node: command not found
error Command failed with exit code 127.
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! [email protected] vscode:prepublish: `yarn run generate && yarn run compile`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] vscode:prepublish script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR! /home/jjk/.npm/_logs/2019-06-17T12_21_36_192Z-debug.log
Any ideas on what might be the problem?
Unlike Kakoune, one-character selections are treated as directional rather than non-directional. In practice, this means that changing the cursor position with a one-character selection may not work correctly in some cases (see #48 (comment) for context).
To reproduce:
/
and type a search phrase. The cursor jumps to the location on screen.N
. The next hit will be selected.N
again, nothing happens.Some keybindings are set to unknown
by VSCode. This probably has to do something with the generate script and the yaml source.
Till now I've found these keys do not work out of the box (including their alt-counterparts):
I could not find dance plugin in https://marketplace.visualstudio.com/
Why is it not there?
a+O
and a+o
should add a line above and below without switching into insert mode.
When using this command, only the other selections are cleared.
Search for some text using /
, then press a+n
. Now Dance will not accept any input in normal mode any more.
Correct me if I'm wrong - I'm very new to kakoune-style bindings, but I thought d
without explicitly selecting anything should delete the character under the cursor. Dance doesn't seem to do that.
To reproduce:
[
{
a
}
]
{
.alt+a {
to select including the braces.alt+x
to extend lines.Expected output:
Actual output:
When performing instead:
3. Hit alt+;
to swap the position of the cursor.
4. Hit alt+x
to extend lines.
Everything works fine.
4x
: select 4th line down.4X
: select 4 lines down.Actual output: both select just one line.
It seems like the cursor can get 'stuck' at the end of a document while in normal mode. I don't know exactly what triggers it; it only seems to happen sometimes.
Here's a set of steps to reproduce. It's a bit of a strange sequence but it was the minimal set of steps I could find.
This last k doesn't move the cursor up, and it is now 'stuck'. If the cursor becomes stuck on a line that does contain text, it can't be moved left with h either.
Entering insert mode or jumping (e.g., gg) makes the cursor 'unstuck' and free to move again.
Thanks again!
Dance: 0.1.4
Ubuntu 18.04.2 LTS
VSCode:
Version: 1.39.2
Commit: 6ab598523be7a800d7f3eb4d92d7ab9a66069390
Date: 2019-10-15T15:33:40.634Z
Electron: 4.2.10
Chrome: 69.0.3497.128
Node.js: 10.11.0
V8: 6.9.427.31-electron.0
OS: Linux x64 4.15.0-70-generic
Some commands result in an error:
Unable to listen to keyboard events; is an extension overriding the "type" command (e.g VSCodeVim)?
Known commands with this behaviour:
To reproduce:
<i-w>
Expected output:
Actual output:
This happens in the new single char selection mode as well as the empty selection mode.
0.2.0 is awesome! Thanks for all the work on single char selections and the customisation options added. There are a few small bugs however. I'll fill in separate issues.
The Normal Mode: Cursor Style option is not respected when starting VSCode. I.e. the default cursor is rendered instead. After entering insert mode and normal mode again, it works correct.
Kakoune keeps track of selections when entering insert mode, Dance doesn't. To reproduce:
hello
i
to enter insert modeExpected output:
Actual output:
(When hitting a
instead of i
, the selection gets extended with the entered text.)
I'm not entirely sure if implementing this matches the philosophy that "Dance's only goal is to provide VS Code-native commands and key bindings that are inspired by Kakoune" or not. My use case was adding quotes around every selection. Maybe there is a better way to do this.
To reproduce:
*
.n
.Expected output:
Actual output:
Proposed solution:
*
.s-i
should go to the first non-whitespace character of the line. Right now it goes to the first character.
Commands n
, N
, a+n
, a+N
are not yet implemented.
(Don't know if this is already on your todo list. Just making an issue to track this unimplemented feature.)
First, I have to say how super awesome I find this plugin! It is exactly what I was looking for. Wanted to have this for a long time. Combines best of all the worlds of VSCode and Kakoune and Vim :-)
Took me some time to find this plugin however. Think adding the word "Kakoune" to the description will make the plugin way more discoverable on the marketplace!
Currently I use this in my keybindings.json
{
"key": "ctrl+u",
"command": "cursorMove",
"args": {
"to": "up",
"by": "line",
"value": 20
},
"when": "editorTextFocus && dance.mode == 'normal'"
},
{
"key": "ctrl+d",
"command": "cursorMove",
"args": {
"to": "down",
"by": "line",
"value": 20
},
"when": "editorTextFocus && dance.mode == 'normal'"
},
Maybe it should be default ?
To reproduce:
{a}
.a
.alt+a {
to select including the braces.Expected output:
{a}
should be selectedObserved output:
{a
is selectedThe same thing happens when braces are put on a newline or different types of braces are used.
I'd like to start a discussion about linewise operations.
Currently, when you yank/delete some lines (technically: text which happens to end with a newline char), and you'd like to paste it, three things can happen, depending on the position of your cursor in a line. In all cases, when your selection is empty, hitting p
or P
doesn't make a difference:
This seems all very logical, if you think about the shape of the selection you yanked/deleted and compare this to a contemporary text editor when you're using ctrl+c/x
and ctrl+v
.
However, coming from Vim, this is strange behaviour. What you probably want to achieve, is yank/delete and paste text linewise. I.e. in Vim, yanking/deleting some lines with yy
/dd
, and then pasting it somewhere does (at least for me) the sensible thing:
P
pastes the lines before the current line.p
pastes the lines after the current line.All without mingling with the line the cursor is on.
The developers of Kakoune acknowledged this issue, and altered the behaviour of paste likewise, depending on the pasted text ending in a newline or not. I think we should do this as well.
Then, I think there is at least one more case where linewise operations come at hand: the equivalent of Vim's change line command cc
. For example, if you hit 2Xc
, Kakoune deletes 2 lines including the line end and starts insert mode at column 0 with the contents of the next line after the cursor. I find this particularly annoying for a couple of reasons:
This happens because the current behaviour of c
is equivalent to di
. However, when the selected text ends with a newline, the sensible thing (again, in my opinion and also what Vim does) would be that c
executes dO
: delete+yank the selected lines and open a new line in insert mode with the correct indentation without joining in text from the next line.
I'm curious what you think about these mechanics. I found this a serious flaw of Kakoune. Maybe there are more instances of linewise operations that I didn't think of yet, but I think yy
, dd
and cc
from Vim are the most apparent.
Implementation wise this would not be a difficult thing to do, I think. Just check if the line in the register or the currently selection ends with a newline character.
Using /
at the end of file does not wrap around. (Likewise for a-/
at begin of file.)
dance.select.word
and dance.select.word.previous
do not work for the last and first word in the document.
How can I access the position of the last change?
In vscodevim it is implemented like:
// src/actions/commands/actions.ts
@RegisterAction
class CommandGoLastChange extends BaseCommand {
modes = [ModeName.Normal];
keys = [['`', '.'], ["'", '.']];
isJump = true;
public async exec(position: Position, vimState: VimState): Promise<VimState> {
const lastPos = vimState.historyTracker.getLastHistoryStartPosition();
if (lastPos !== undefined) {
vimState.cursorStopPosition = lastPos[0];
}
return vimState;
}
}
and
// src/history/historyTracker.ts
/**
* Gets the ending cursor position of the last Change of the last Step.
*
* In practice, this sets the cursor position to the end of
* the most recent text change.
*/
getLastChangeEndPosition(): Position | undefined {
if (this.currentHistoryStepIndex === 0) {
return undefined;
}
const lastChangeIndex = this.historySteps[this.currentHistoryStepIndex].changes.length;
if (lastChangeIndex === 0) {
return undefined;
}
return this.historySteps[this.currentHistoryStepIndex].changes[lastChangeIndex - 1].end();
}
getLastHistoryStartPosition(): Position[] | undefined {
if (this.currentHistoryStepIndex === 0) {
return undefined;
}
return this.historySteps[this.currentHistoryStepIndex].cursorStart;
}
So there are two things needed a VimState
and a HistoryTracker
.
Is there already something like a state
that stores information about the extension independent of the document? (I'm not experienced with vscode extensions yet).
And I guess that we have to adapt the HistoryTracker, also to implement Goto previous buffer
and Goto File
.
On macOS the alt/option key is used as a second shift like key: one can enter special characters as ∂, ƒ, ¬, ø (option+d
, option+f
, option+l
, option+o
). Problematic are the keys option+\``,
option+e,
option+u,
option+i, option+n
which are dead keys to compose diacritics like è, é, ë, ê and ñ. These can't be used to map Kakoune/Dance chords.
This solution only adds support to use option as meta in the terminal emulator of VSCode. Using something like this in the editor is currently not supported and should probably be fixed in core VSCode.
When using b
to move back over a word and pressing i
, insert mode starts at the end of the selection instead of at the beginning. Same for pressing a
, but the other way around.
The lineNumbers
setting is changed on each mode changed; on
if in insert mode, or relative
if in normal mode. This seems to cause problems with decorations that don't get removed even though they should.
To reproduce:
o
to insert a new line and go back to insert mode. All text that will be written will be incorrectly shown in red highlight, as if it was trailing whitespace.I don't know yet if this is a problem with Dance, with Trailing Spaces, or with VS Code itself.
Typing Option+e, Option+i, Option+u, Option+n, and maybe some other keys on macOS will wait for the next character and put some diacritic mark on it (acute, circumflex, umlaut and tilde respectively). When using kakoune keybindings that are bound to these keys in vscode, such as the OS will insert the diacritic mark before Dance gets invoked, and this makes those keybindings unusable.
To reproduce:
N
a couple of times.n
Expected outcome:
Actual outcome:
In dance deleting and pasting :
1
2
3
produce:
1
1
1
However in vscode multiple selection and kakoune :
1
2
3
is restored.
Is there an easy way to add new key bindings under the goto subspace? Adding something like this:
{
"key": "g n",
"command": "editor.action.marker.next",
"when": "editorTextFocus && dance.mode == 'normal'"
},
will render all existing goto bindings useless.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.