#duat #editor #editing-mode

nightly duat-kak

A Kakoune inspired editing mode for Parsec

7 unstable releases (3 breaking)

Uses new Rust 2024

new 0.4.0 Apr 14, 2025
0.3.0 Mar 5, 2025
0.2.1 Nov 12, 2024
0.1.3 Jul 17, 2024
0.1.0 Oct 30, 2023

#294 in Text editors

AGPL-3.0-or-later

795KB
15K SLoC

duat-kak License: AGPL-3.0-or-later duat-kak on crates.io duat-kak on docs.rs Source Code Repository

duat-kak is the implementation of the kakoune editing model for Duat. It’s still a work in progress, but it already implements most of the common commands from Kakoune, with some modifications that I thought made sense.

The plugin currently has 2 options: insert_tabs and set_cursor_forms. insert_tabs will make the Tab key insert a \t character, instead of an appropriate amount of spaces. set_cursor_forms will create a hook to set the MainCursor, ExtraCursor, MainSelection and ExtraSelection forms to mode specific varieties, e.g. MainCursorInsert.

Keymaps

This is a list of currently mapped keys, not the ones that appear in Kakoune.

When reading keys, they follow Duat’s mapping rules, that is:

  • <A-{key}> is a chord of Alt + {key}, same with <C-{key}> and Control and <S-{key}> with Shift (although that one is not usually needed).
  • Special keys are enclosed in < > pairs (e.g. <Home>).
  • Multiple keys in a row represent a sequence.

In any mode, the <Esc> key will take you back to normal mode.

In this plugin, a moment contains all of the changes performed by each Cursor, so if you press u, multiple changes may be undone.

Normal mode

The keys in normal mode follow the following patterns:

  • All actions will be done to all selections.
  • word characters follow Duat’s word chars, which are normally used to define where lines wrap.
  • WORD characters are just any non-whitespace character.
  • All keys that say “select”, when typed with <Shift> will extend the selection instead (not necessarily growing it).
  • Yanked selections are always pasted in the order they were yanked, looping around if there are less yanks than Cursors.

Object selection

h, <Left>
Selects the character to the left. Wraps around lines.

j
Selects the character below on the next line.

<Down>
Selects the character below on the next wrapped line (i.e vim’s gj).

k
Selects the character above on the previous line.

<Up>
Selects the character above on the previous wrapped line (i.e. vim’s gk).

l, <Right>
Selects the character to the right. Wraps around lines.

w
Selects the word and following space to the right of the selection.

b
Selects the word followed by spaces to the left of the selection.

e
Selects to the end of the next word to the right of the selection.

<A-(w|b|e)>
The same as (w|b|e), but over a WORD.

f{key}
Selects to the next occurrence of the {key} character.

t{key}
Selects until the next occurrence of the {key} character.

<A-(f|t)>{key}
Same as (f|t), but in the opposite direction.

x
Extends selection to encompass full lines.

%
Selects the whole buffer.

<A-h>, <Home>
Selects to the start of the line.

<A-l>, <End>
Selects until the end of the line.

;
Reduces selections to just the caret.

<A-;>
Flips the caret and anchor of Cursors around.

<A-:>
Places the caret ahead of the anchor in all selections.

<A-s>
Divides selection into multiple selections, one per line.

<A-S>
Splits into two Cursors, one at each end of the selection.

Changing text

i
Enter insert mode before selections, keys inserted (except for <Delete>) will only move the selection.

a
Enter insert mode after selection, keys inserted will extend the selection.

I
Moves to the beginning of the line (after indent) and enters insert mode.

A
Moves to the end of the line and enters insert mode.

y
Yanks selections.

d
Deletes and yanks the selections.

c
Deletes, yanks, and enter insert mode.

p
Pastes after end of each selection (multi line selections are placed on the next line).

P
Pastes at the start of each selection (multi line pastes are placed on the previous line).

R
Replaces with the pasted text, without yanking.

<A-d>
Deletes selections without yanking.

<A-c>
Deletes selections without yanking, then enters insert mode.

o
Creates a new line below and enters insert mode in it.

O
Creates a new line above and enters insert mode in it.

<A-(o|O)>
Same as (o|O), but just adds the new line.

r{key}
Replaces each character with {key}

u
Undoes the last moment

U
Redoes the next moment

`
Changes to lowercase.

~
Changes to uppercase.

<A->
Swaps the case of each character.

<A-)>
Rotates each selection’s content forwards.

<A-(>
Rptates each selection’s content backwards.

|
Changes mode to PipeSelections, letting you pipe each selection to an external program.

The searching in this plugin is done through the IncSearch Mode from Duat, with some IncSearchers defined in this crate. This means that search will be done incrementally over a Regex pattern.

/
Searches forward for the next pattern, on each Cursor.

<A-/>
Searches backwards for the previous pattern, on each Cursor.

(?|<A-?>)
Follows the Shift pattern described above, so its the same as (/|<A-/>), but extending the selection instead.

s
Selects the pattern from within current selections.

S
Splits current selections by the pattern.

goto mode

goto mode is entered with the g or G keys in normal mode. The G follows the same Shift pattern described above.

h
Go to the beginning of the line (before indents, column 0).

l
Go to the end of the line.

i
Go to the beginning of the line, after indents.

g,k
Go to the first line.

j
Go to the last line.

a
Go to the previous File.

n
Go to the next File (includes other windows).

N
Go to the previous File (includes other windows).

Dependencies

~490MB
~14M SLoC