diff options
author | Marc Coquand <marc@mccd.space> | 2024-09-05 12:27:17 -0500 |
---|---|---|
committer | Marc Coquand <marc@mccd.space> | 2024-09-05 12:27:17 -0500 |
commit | e233e7f028366ce8f5d58fe1cc8a88210664ddb3 (patch) | |
tree | 2c1cec3a19866bc39706de8a38035e15813018ed /config/kak/auto-pairs.kak | |
parent | 3783cab095a9167256afcbfe987d11f35a7003b1 (diff) | |
download | bsd-e233e7f028366ce8f5d58fe1cc8a88210664ddb3.tar.gz bsd-e233e7f028366ce8f5d58fe1cc8a88210664ddb3.tar.bz2 bsd-e233e7f028366ce8f5d58fe1cc8a88210664ddb3.zip |
add kak
Diffstat (limited to 'config/kak/auto-pairs.kak')
-rw-r--r-- | config/kak/auto-pairs.kak | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/config/kak/auto-pairs.kak b/config/kak/auto-pairs.kak new file mode 100644 index 0000000..16798d2 --- /dev/null +++ b/config/kak/auto-pairs.kak @@ -0,0 +1,185 @@ +# Auto-pairing of characters +# Heavily based on Visual Studio Code. +# https://code.visualstudio.com +# +# Public commands: ["enable-auto-pairs", "disable-auto-pairs"] +# Public options: ["auto_pairs"] +# +# Usage: +# +# enable-auto-pairs +# +# Configuration: +# +# set-option global auto_pairs ( ) { } [ ] '"' '"' "'" "'" ` ` “ ” ‘ ’ « » ‹ › +# +# How does it work? +# +# The script installs insert hooks on opening pair characters, such as brackets and quotes. +# When auto-closing has been triggered, it activates the following functionalities: +# +# – {closing-pair} ⇒ Insert closing pair or move right in pair +# – Enter ⇒ Insert a new indented line in pair (only for the next key) +# – Control+Enter ⇒ Prompt a count for new indented lines in pair (only for the next key) +# +# When moving or leaving insert mode, the functionalities deactivate. +# +# Technical details: +# +# – Insert hooks are added on opening pair characters from %opt{auto_pairs} option. +# – Evaluates %opt{auto_close_trigger} option to activate auto-pairing. +# – Provides %opt{opening_pair} expansion in expressions. +# – Uses %opt{inserted_pairs} count to keep track of inserted pairs for inserting or moving in pair. +# – Uses the same implementation for nestable (such as brackets) and non-nestable (such as quotes) pairs. +# Since insert hooks are added on opening pair characters (for auto-pairing) and mappings on closing pair characters (for moving in pair), +# we can distinguish same pair characters once auto-pairing has been activated. + +# Configuration ──────────────────────────────────────────────────────────────── + +# List of surrounding pairs +declare-option -docstring 'list of surrounding pairs' str-list auto_pairs ( ) { } [ ] '"' '"' "'" "'" ` ` “ ” ‘ ’ « » ‹ › + +# Auto-pairing of characters activates only when this expression does not fail. +# By default, it avoids non-nestable pairs (such as quotes), escaped pairs and word characters. +declare-option -docstring 'auto-pairing of characters activates only when this expression does not fail' str auto_close_trigger '<a-h><a-K>(\w["''`]|""|''''|``).\z<ret><a-k>[^\\]?\Q%opt{opening_pair}<a-!>\E\W\z<ret>' + +# Internal variables ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + +# Retain inserted pairs +declare-option -hidden str opening_pair +declare-option -hidden int inserted_pairs + +# Commands ───────────────────────────────────────────────────────────────────── + +define-command -override enable-auto-pairs -docstring 'enable auto-pairs' %{ + remove-hooks global auto-pairs + evaluate-commands %sh{ + set -- ${kak_opt_auto_pairs} + while [ "$2" ] + do + printf 'auto-close-pair %%<%s> %%<%s>\n' "$1" "$2" + shift 2 + done + } +} + +define-command -override disable-auto-pairs -docstring 'disable auto-pairs' %{ + remove-hooks global auto-pairs +} + +# Internal commands ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + +define-command -override -hidden auto-close-pair -params 2 %{ + hook -group auto-pairs global InsertChar "\Q%arg{1}" "handle-inserted-opening-pair %%<%arg{1}> %%<%arg{2}>" + hook -group auto-pairs global InsertDelete "\Q%arg{1}" "handle-deleted-opening-pair %%<%arg{1}> %%<%arg{2}>" +} + +# Internal hooks ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + +define-command -override -hidden handle-inserted-opening-pair -params 2 %{ + try %{ + # Test whether the commands contained in the option pass. + # If not, it will throw an exception and execution will jump to + # the “catch” block below. + set-option window opening_pair %arg{1} + execute-keys -draft %opt{auto_close_trigger} + + # Action: Close pair + execute-keys %arg{2} + + # Keep the track of inserted pairs + increment-inserted-pairs-count + + # Move back in pair (preserve selected text): + try %{ + execute-keys -draft '<a-k>..<ret>' + execute-keys '<a-;>H' + } catch %{ + execute-keys '<a-;>h' + } + + # Add insert mappings + map -docstring 'insert closing pair or move right in pair' window insert %arg{2} "<a-;>:insert-closing-pair-or-move-right-in-pair %%🐈%arg{2}🐈<ret>" + map -docstring 'insert a new indented line in pair' window insert <ret> '<a-;>:insert-new-line-in-pair<ret>' + map -docstring 'prompt a count for new indented lines in pair' window insert <c-ret> '<a-;>:prompt-insert-new-line-in-pair<ret>' + + # Enter is only available on next key. + hook -group auto-pairs -once window InsertChar '.*' %{ + unmap window insert <ret> + unmap window insert <c-ret> + } + + # Clean insert mappings and remove hooks + hook -group auto-pairs -once window WinSetOption 'inserted_pairs=0' " + unmap window insert %%🐈%arg{2}🐈 + unmap window insert <ret> + unmap window insert <c-ret> + remove-hooks window auto-pairs + " + + # Clean state when moving or leaving insert mode + hook -group auto-pairs -once window InsertMove '.*' %{ + reset-inserted-pairs-count + } + + hook -always -once window ModeChange 'pop:insert:normal' %{ + reset-inserted-pairs-count + } + } +} + +# Backspace ⇒ Erases the whole bracket +define-command -override -hidden handle-deleted-opening-pair -params 2 %{ + try %{ + execute-keys -draft "<space>;<a-k>\Q%arg{2}<ret>" + execute-keys '<del>' + decrement-inserted-pairs-count + } +} + +# Internal mappings ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + +# {closing-pair} ⇒ Insert closing pair or move right in pair +define-command -override -hidden insert-closing-pair-or-move-right-in-pair -params 1 %{ + try %{ + execute-keys -draft "<space>;<a-k>\Q%arg{1}<ret>" + # Move right in pair + execute-keys '<a-;>l' + decrement-inserted-pairs-count + } catch %{ + # Insert character with hooks + execute-keys -with-hooks %arg{1} + } +} + +# Enter ⇒ Insert a new indented line in pair (only for the next key) +define-command -override -hidden insert-new-line-in-pair %{ + execute-keys '<a-;>;<ret><ret><esc>KK<a-&>j<a-gt>' + execute-keys -with-hooks A + reset-inserted-pairs-count +} + +# Control+Enter ⇒ Prompt a count for new indented lines in pair (only for the next key) +define-command -override -hidden prompt-insert-new-line-in-pair %{ + prompt count: %{ + execute-keys '<a-;>;<ret><ret><esc>KK<a-&>j<a-gt>' + execute-keys "xHyx<a-d>%val{text}O<c-r>""<esc>" + execute-keys -with-hooks A + reset-inserted-pairs-count + } +} + +# ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + +# Increment and decrement inserted pairs count +define-command -override -hidden increment-inserted-pairs-count %{ + set-option -add window inserted_pairs 1 +} + +define-command -override -hidden decrement-inserted-pairs-count %{ + set-option -remove window inserted_pairs 1 +} + +define-command -override -hidden reset-inserted-pairs-count %{ + set-option window inserted_pairs 0 +} |