Skip to content

Commit

Permalink
Make x just select the full lines
Browse files Browse the repository at this point in the history
`x` is often criticized as hard to predict due to its slightly complex
behaviour of selecting next line if the current one is fully selected.

Change `x` to use the previous `<a-x>` behaviour, and change `<a-x>` to
trim to fully selected lines as `<a-X>` did.

Adapt existing indentation script to the new behaviour
  • Loading branch information
mawww committed Jul 4, 2022
1 parent 046be3b commit ef8a11b
Show file tree
Hide file tree
Showing 82 changed files with 411 additions and 430 deletions.
3 changes: 3 additions & 0 deletions doc/pages/changelog.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ released versions.

* `!` and `<a-!>` commands now select the inserted text

* `x` now just extends the selection to contain full lines (as `<a-x>` did)
`<a-x>` trims partial lines from the selection (as `<a-X>` did)

== Kakoune 2021.11.07

* Support for curly and separately colored underlines (undocumented in 2021.10.28)
Expand Down
6 changes: 1 addition & 5 deletions doc/pages/keys.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,9 @@ the Shift modifier and moving will extend each selection instead.
characters, see the `matching_pairs` option in <<options#,`:doc options`>>

*x*::
select line on which the end of each selection lies (or next line when end lies
on an end-of-line)

*<a-x>*::
expand selections to contain full lines (including end-of-lines)

*<a-X>*::
*<a-x>*::
trim selections to only contain full lines (not including last
end-of-line)

Expand Down
2 changes: 1 addition & 1 deletion rc/detection/modeline.kak
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ define-command -hidden modeline-parse-impl %{
define-command modeline-parse -docstring "Read and interpret vi-format modelines at the beginning/end of the buffer" %{
try %{ evaluate-commands -draft %{
execute-keys <percent> "s(?S)\A(.+\n){,%opt{modelines}}|(.+\n){,%opt{modelines}}\z<ret>" \
s^\S*?\s+?\w+:\s?[^\n]+<ret> <a-x>
s^\S*?\s+?\w+:\s?[^\n]+<ret> x
evaluate-commands -draft -itersel modeline-parse-impl
} }
}
8 changes: 4 additions & 4 deletions rc/filetype/awk.kak
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,16 @@ define-command -hidden awk-indent-on-new-line %[
# preserve previous line indent
try %[ execute-keys -draft <semicolon> K <a-&> ]
# cleanup trailing whitespaces from previous line
try %[ execute-keys -draft k <a-x> s \h+$ <ret> d ]
try %[ execute-keys -draft k x s \h+$ <ret> d ]
# indent after line ending in opening curly brace
try %[ execute-keys -draft k<a-x> <a-k>\{\h*(#.*)?$<ret> j<a-gt> ]
try %[ execute-keys -draft kx <a-k>\{\h*(#.*)?$<ret> j<a-gt> ]
# deindent closing brace when after cursor
try %[ execute-keys -draft <a-x> <a-k> ^\h*\} <ret> gh / \} <ret> m <a-S> 1<a-&> ]
try %[ execute-keys -draft x <a-k> ^\h*\} <ret> gh / \} <ret> m <a-S> 1<a-&> ]
]
]

define-command -hidden awk-trim-indent %{
try %{ execute-keys -draft <semicolon> <a-x> s ^\h+$ <ret> d }
try %{ execute-keys -draft <semicolon> x s ^\h+$ <ret> d }
}

@
46 changes: 23 additions & 23 deletions rc/filetype/c-family.kak
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ provide-module c-family %§

define-command -hidden c-family-trim-indent %{
# remove the line if it's empty when leaving the insert mode
try %{ execute-keys -draft <a-x> 1s^(\h+)$<ret> d }
try %{ execute-keys -draft x 1s^(\h+)$<ret> d }
}

define-command -hidden c-family-indent-on-newline %< evaluate-commands -draft -itersel %<
Expand All @@ -75,31 +75,31 @@ define-command -hidden c-family-indent-on-newline %< evaluate-commands -draft -i
> catch %<
# else if previous line closed a paren (possibly followed by words and a comment),
# copy indent of the opening paren line
execute-keys -draft k<a-x> 1s(\))(\h+\w+)*\h*(\;\h*)?(?://[^\n]+)?\n\z<ret> m<a-semicolon>J <a-S> 1<a-&>
execute-keys -draft kx 1s(\))(\h+\w+)*\h*(\;\h*)?(?://[^\n]+)?\n\z<ret> m<a-semicolon>J <a-S> 1<a-&>
> catch %<
# else indent new lines with the same level as the previous one
execute-keys -draft K <a-&>
>
# remove previous empty lines resulting from the automatic indent
try %< execute-keys -draft k <a-x> <a-k>^\h+$<ret> Hd >
try %< execute-keys -draft k x <a-k>^\h+$<ret> Hd >
# indent after an opening brace or parenthesis at end of line
try %< execute-keys -draft k <a-x> <a-k>[{(]\h*$<ret> j <a-gt> >
try %< execute-keys -draft k x <a-k>[{(]\h*$<ret> j <a-gt> >
# indent after a label
try %< execute-keys -draft k <a-x> s[a-zA-Z0-9_-]+:\h*$<ret> j <a-gt> >
try %< execute-keys -draft k x s[a-zA-Z0-9_-]+:\h*$<ret> j <a-gt> >
# indent after a statement not followed by an opening brace
try %< execute-keys -draft k <a-x> s\)\h*(?://[^\n]+)?\n\z<ret> \
try %< execute-keys -draft k x s\)\h*(?://[^\n]+)?\n\z<ret> \
<a-semicolon>mB <a-k>\A\b(if|for|while)\b<ret> <a-semicolon>j <a-gt> >
try %< execute-keys -draft k <a-x> s \belse\b\h*(?://[^\n]+)?\n\z<ret> \
try %< execute-keys -draft k x s \belse\b\h*(?://[^\n]+)?\n\z<ret> \
j <a-gt> >
# deindent after a single line statement end
try %< execute-keys -draft K <a-x> <a-k>\;\h*(//[^\n]+)?$<ret> \
K <a-x> s\)(\h+\w+)*\h*(//[^\n]+)?\n([^\n]*\n){2}\z<ret> \
try %< execute-keys -draft K x <a-k>\;\h*(//[^\n]+)?$<ret> \
K x s\)(\h+\w+)*\h*(//[^\n]+)?\n([^\n]*\n){2}\z<ret> \
MB <a-k>\A\b(if|for|while)\b<ret> <a-S>1<a-&> >
try %< execute-keys -draft K <a-x> <a-k>\;\h*(//[^\n]+)?$<ret> \
K <a-x> s \belse\b\h*(?://[^\n]+)?\n([^\n]*\n){2}\z<ret> \
try %< execute-keys -draft K x <a-k>\;\h*(//[^\n]+)?$<ret> \
K x s \belse\b\h*(?://[^\n]+)?\n([^\n]*\n){2}\z<ret> \
<a-S>1<a-&> >
# deindent closing brace(s) when after cursor
try %< execute-keys -draft <a-x> <a-k> ^\h*[})] <ret> gh / [})] <esc> m <a-S> 1<a-&> >
try %< execute-keys -draft x <a-k> ^\h*[})] <ret> gh / [})] <esc> m <a-S> 1<a-&> >
# align to the opening parenthesis or opening brace (whichever is first)
# on a previous line if its followed by text on the same line
try %< evaluate-commands -draft %<
Expand All @@ -118,7 +118,7 @@ define-command -hidden c-family-indent-on-opening-curly-brace %[
# align indent with opening paren when { is entered on a new line after the closing paren
try %[ execute-keys -draft -itersel h<a-F>)M <a-k> \A\(.*\)\h*\n\h*\{\z <ret> <a-S> 1<a-&> ]
# align indent with opening paren when { is entered on a new line after the else
try %[ execute-keys -draft -itersel hK <a-x> s \belse\b\h*(?://[^\n]+)?\n\h*\{<ret> <a-S> 1<a-&> ]
try %[ execute-keys -draft -itersel hK x s \belse\b\h*(?://[^\n]+)?\n\h*\{<ret> <a-S> 1<a-&> ]
]

define-command -hidden c-family-indent-on-closing-curly-brace %[
Expand All @@ -134,47 +134,47 @@ define-command -hidden c-family-indent-on-closing-curly-brace %[

define-command -hidden c-family-insert-on-closing-curly-brace %[
# add a semicolon after a closing brace if part of a class, union or struct definition
try %[ execute-keys -itersel -draft hm<a-x>B<a-x> <a-K>\A[^\n]+\)\h*(\{|$)<ret> <a-k>\A\h*(class|struct|union|enum)<ret> '<a-;>;i;<esc>' ]
try %[ execute-keys -itersel -draft hmxBx <a-K>\A[^\n]+\)\h*(\{|$)<ret> <a-k>\A\h*(class|struct|union|enum)<ret> '<a-;>;i;<esc>' ]
]

define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel -draft %[
execute-keys <semicolon>
try %[
evaluate-commands -draft -save-regs '/"' %[
# copy the commenting prefix
execute-keys -save-regs '' k <a-x>1s^\h*(//+\h*)<ret> y
execute-keys -save-regs '' k x1s^\h*(//+\h*)<ret> y
try %[
# if the previous comment isn't empty, create a new one
execute-keys <a-x><a-K>^\h*//+\h*$<ret> j<a-x>s^\h*<ret>P
execute-keys x<a-K>^\h*//+\h*$<ret> jxs^\h*<ret>P
] catch %[
# if there is no text in the previous comment, remove it completely
execute-keys d
]
]

# trim trailing whitespace on the previous line
try %[ execute-keys -draft k <a-x> s\h+$<ret> d ]
try %[ execute-keys -draft k x s\h+$<ret> d ]
]
try %[
# if the previous line isn't within a comment scope, break
execute-keys -draft k<a-x> <a-k>^(\h*/\*|\h+\*(?!/))<ret>
execute-keys -draft kx <a-k>^(\h*/\*|\h+\*(?!/))<ret>

# find comment opening, validate it was not closed, and check its using star prefixes
execute-keys -draft <a-?>/\*<ret><a-H> <a-K>\*/<ret> <a-k>\A\h*/\*([^\n]*\n\h*\*)*[^\n]*\n\h*.\z<ret>

try %[
# if the previous line is opening the comment, insert star preceeded by space
execute-keys -draft k<a-x><a-k>^\h*/\*<ret>
execute-keys -draft kx<a-k>^\h*/\*<ret>
execute-keys -draft i*<space><esc>
] catch %[
try %[
# if the next line is a comment line insert a star
execute-keys -draft j<a-x><a-k>^\h+\*<ret>
execute-keys -draft jx<a-k>^\h+\*<ret>
execute-keys -draft i*<space><esc>
] catch %[
try %[
# if the previous line is an empty comment line, close the comment scope
execute-keys -draft k<a-x><a-k>^\h+\*\h+$<ret> <a-x>1s\*(\h*)<ret>c/<esc>
execute-keys -draft kx<a-k>^\h+\*\h+$<ret> x1s\*(\h*)<ret>c/<esc>
] catch %[
# if the previous line is a non-empty comment line, add a star
execute-keys -draft i*<space><esc>
Expand All @@ -183,9 +183,9 @@ define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel
]

# trim trailing whitespace on the previous line
try %[ execute-keys -draft k <a-x> s\h+$<ret> d ]
try %[ execute-keys -draft k x s\h+$<ret> d ]
# align the new star with the previous one
execute-keys K<a-x>1s^[^*]*(\*)<ret>&
execute-keys Kx1s^[^*]*(\*)<ret>&
]
] ]

Expand Down
8 changes: 4 additions & 4 deletions rc/filetype/cabal.kak
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ add-highlighter shared/cabal/code/ regex ^\h*([A-Za-z][A-Za-z0-9_-]*)\h*: 1:vari

define-command -hidden cabal-trim-indent %{
# remove trailing white spaces
try %{ execute-keys -draft -itersel <a-x> s \h+$ <ret> d }
try %{ execute-keys -draft -itersel x s \h+$ <ret> d }
}

define-command -hidden cabal-insert-on-new-line %[
evaluate-commands -draft -itersel %[
# copy '--' comment prefix and following white spaces
try %[ execute-keys -draft k <a-x> s ^\h*\K--\h* <ret> y gh j P ]
try %[ execute-keys -draft k x s ^\h*\K--\h* <ret> y gh j P ]
]
]

Expand All @@ -65,9 +65,9 @@ define-command -hidden cabal-indent-on-new-line %[
# filter previous line
try %[ execute-keys -draft k : cabal-trim-indent <ret> ]
# indent after lines ending with { or :
try %[ execute-keys -draft <space> k <a-x> <a-k> [:{]$ <ret> j <a-gt> ]
try %[ execute-keys -draft <space> k x <a-k> [:{]$ <ret> j <a-gt> ]
# deindent closing brace when after cursor
try %[ execute-keys -draft <a-x> <a-k> \h*\} <ret> gh / \} <ret> m <a-S> 1<a-&> ]
try %[ execute-keys -draft x <a-k> \h*\} <ret> gh / \} <ret> m <a-S> 1<a-&> ]
]
]

Expand Down
6 changes: 3 additions & 3 deletions rc/filetype/coffee.kak
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ add-highlighter shared/coffee/code/ regex \b(break|case|catch|class|const|contin

define-command -hidden coffee-trim-indent %{
evaluate-commands -draft -itersel %{
execute-keys <a-x>
execute-keys x
# remove trailing white spaces
try %{ execute-keys -draft s \h + $ <ret> d }
}
Expand All @@ -74,7 +74,7 @@ define-command -hidden coffee-trim-indent %{
define-command -hidden coffee-insert-on-new-line %{
evaluate-commands -draft -itersel %{
# copy '#' comment prefix and following white spaces
try %{ execute-keys -draft k <a-x> s '^\h*\K#\h*' <ret> y gh j P }
try %{ execute-keys -draft k x s '^\h*\K#\h*' <ret> y gh j P }
}
}

Expand All @@ -85,7 +85,7 @@ define-command -hidden coffee-indent-on-new-line %{
# filter previous line
try %{ execute-keys -draft k : coffee-trim-indent <ret> }
# indent after start structure
try %{ execute-keys -draft k <a-x> <a-k> ^ \h * (case|catch|class|else|finally|for|function|if|switch|try|while|with) \b | (=|->) $ <ret> j <a-gt> }
try %{ execute-keys -draft k x <a-k> ^ \h * (case|catch|class|else|finally|for|function|if|switch|try|while|with) \b | (=|->) $ <ret> j <a-gt> }
}
}

Expand Down
4 changes: 2 additions & 2 deletions rc/filetype/coq.kak
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ evaluate-commands %sh{
# Hence here only a simple mechanism of copying indent is done.
define-command -hidden coq-copy-indent-on-newline %{
evaluate-commands -draft -itersel %{
try %{ execute-keys -draft k <a-x> s ^\h+ <ret> y gh j P }
try %{ execute-keys -draft k x s ^\h+ <ret> y gh j P }
}
}

define-command -hidden coq-trim-indent %{
evaluate-commands -no-hooks -draft -itersel %{
execute-keys <a-x>
execute-keys x
# remove trailing white spaces
try %{ execute-keys -draft s \h + $ <ret> d }
}
Expand Down
22 changes: 11 additions & 11 deletions rc/filetype/crystal.kak
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ evaluate-commands %sh[

define-command -hidden crystal-trim-indent %{
evaluate-commands -no-hooks -draft -itersel %{
execute-keys <a-x>
execute-keys x
# remove trailing white spaces
try %{ execute-keys -draft s \h+$ <ret> d }
}
Expand All @@ -190,15 +190,15 @@ define-command -hidden crystal-trim-indent %{
define-command -hidden crystal-indent-on-char %{
evaluate-commands -no-hooks -draft -itersel %{
# align 'else' to 'if/case'
try %{ execute-keys -draft <a-x> <a-k> ^\h*else$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:if|case) <ret> <a-S> 1<a-&> }
try %{ execute-keys -draft x <a-k> ^\h*else$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:if|case) <ret> <a-S> 1<a-&> }
# align 'elsif' to 'if'
try %{ execute-keys -draft <a-x> <a-k> ^\h*elsif$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:if) <ret> <a-S> 1<a-&> }
try %{ execute-keys -draft x <a-k> ^\h*elsif$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:if) <ret> <a-S> 1<a-&> }
# align 'when' to 'case'
try %{ execute-keys -draft <a-x> <a-k> ^\h*when$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:case) <ret> <a-S> 1<a-&> }
try %{ execute-keys -draft x <a-k> ^\h*when$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:case) <ret> <a-S> 1<a-&> }
# align 'rescue' to 'begin/def'
try %{ execute-keys -draft <a-x> <a-k> ^\h*rescue$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:begin|def) <ret> <a-S> 1<a-&> }
try %{ execute-keys -draft x <a-k> ^\h*rescue$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:begin|def) <ret> <a-S> 1<a-&> }
# align 'end' to opening structure
try %{ execute-keys -draft <a-x> <a-k> ^\h*end$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:begin|case|class|def|for|if|module|unless|until|while) <ret> <a-S> 1<a-&> }
try %{ execute-keys -draft x <a-k> ^\h*end$ <ret> <a-a>i <a-semicolon> <a-?> ^\h*(?:begin|case|class|def|for|if|module|unless|until|while) <ret> <a-S> 1<a-&> }
}
}

Expand All @@ -209,23 +209,23 @@ define-command -hidden crystal-indent-on-new-line %{
# Remove previous line's trailing spaces
try %{ execute-keys -draft k :crystal-trim-indent <ret> }
# Indent after start structure/opening statement
try %{ execute-keys -draft k <a-x> <a-k> ^\h*(?:begin|case|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while|.+\bdo$|.+\bdo\h\|.+(?=\|))[^0-9A-Za-z_!?] <ret> j <a-gt> }
try %{ execute-keys -draft k x <a-k> ^\h*(?:begin|case|class|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|while|.+\bdo$|.+\bdo\h\|.+(?=\|))[^0-9A-Za-z_!?] <ret> j <a-gt> }
}
}

define-command -hidden crystal-insert-on-new-line %[
evaluate-commands -no-hooks -draft -itersel %[
# copy _#_ comment prefix and following white spaces
try %{ execute-keys -draft k <a-x> s '^\h*\K#\h*' <ret> y j <a-x><semicolon> P }
try %{ execute-keys -draft k x s '^\h*\K#\h*' <ret> y j x<semicolon> P }
# wisely add end structure
evaluate-commands -save-regs x %[
try %{ execute-keys -draft k <a-x> s ^ \h + <ret> \" x y } catch %{ reg x '' }
try %{ execute-keys -draft k x s ^ \h + <ret> \" x y } catch %{ reg x '' }
try %[
evaluate-commands -draft %[
# Check if previous line opens a block
execute-keys -draft k<a-x> <a-k>^<c-r>x(?:begin|case|class|def|for|if|module|unless|until|while|.+\bdo$|.+\bdo\h\|.+(?=\|))[^0-9A-Za-z_!?]<ret>
execute-keys -draft kx <a-k>^<c-r>x(?:begin|case|class|def|for|if|module|unless|until|while|.+\bdo$|.+\bdo\h\|.+(?=\|))[^0-9A-Za-z_!?]<ret>
# Check that we do not already have an end for this indent level which is first set via `crystal-indent-on-new-line` hook
execute-keys -draft }i J <a-x> <a-K> ^<c-r>x(?:end|else|elsif|rescue|when)[^0-9A-Za-z_!?]<ret>
execute-keys -draft }i J x <a-K> ^<c-r>x(?:end|else|elsif|rescue|when)[^0-9A-Za-z_!?]<ret>
]
execute-keys -draft o<c-r>xend<esc> # insert a new line with containing end
]
Expand Down
Loading

5 comments on commit ef8a11b

@ewtoombs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YEEEEESSSSS!!!!!!!!!!!!!!!!!!!!

I've been doing that ever since I started using kakoune.

Merci, Maxime!

@mawww
Copy link
Owner Author

@mawww mawww commented on ef8a11b Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries :)

@2xsaiko
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the replacement for e.g. 5X to select 5 lines downwards from the cursor? x4J seems to work fine, is that the intended way of doing it?

@mawww
Copy link
Owner Author

@mawww mawww commented on ef8a11b Dec 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@2xsaiko Yes, or 4Jx would work as well.

@2xsaiko
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks!

Please sign in to comment.