Merge remote-tracking branch 'sjjf/sh_indent_v2'

This commit is contained in:
Maxime Coste 2019-07-01 22:00:31 +10:00
commit 5c219cc743
48 changed files with 250 additions and 0 deletions

View File

@ -5,6 +5,10 @@ hook global BufCreate .*\.(z|ba|c|k|mk)?sh(rc|_profile)? %{
hook global WinSetOption filetype=sh %{ hook global WinSetOption filetype=sh %{
require-module sh require-module sh
set-option window static_words %opt{sh_static_words} set-option window static_words %opt{sh_static_words}
hook window ModeChange insert:.* -group sh-trim-indent sh-trim-indent
hook window InsertChar \n -group sh-indent sh-indent-on-new-line
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window sh-.+ }
} }
hook -group sh-highlight global WinSetOption filetype=sh %{ hook -group sh-highlight global WinSetOption filetype=sh %{
@ -48,4 +52,128 @@ add-highlighter shared/sh/code/function regex ^\h*(\w+)\h*\(\) 1:function
add-highlighter shared/sh/code/unscoped_expansion regex \$(\w+|#|@|\?|\$|!|-|\*) 0:value add-highlighter shared/sh/code/unscoped_expansion regex \$(\w+|#|@|\?|\$|!|-|\*) 0:value
add-highlighter shared/sh/double_string/expansion regex \$(\w+|\{.+?\}) 0:value add-highlighter shared/sh/double_string/expansion regex \$(\w+|\{.+?\}) 0:value
# Commands
# ‾‾‾‾‾‾‾‾
define-command -hidden sh-trim-indent %{
# remove trailing white spaces
try %{ execute-keys -draft -itersel <a-x> s \h+$ <ret> d }
}
# This is at best an approximation, since shell syntax is very complex.
# Also note that this targets plain sh syntax, not bash - bash adds a whole
# other level of complexity. If your bash code is fairly portable this will
# probably work.
#
# Of necessity, this is also fairly opinionated about indentation styles.
# Doing it "properly" would require far more context awareness than we can
# bring to this kind of thing.
define-command -hidden sh-indent-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 }
# preserve previous line indent
try %{ execute-keys -draft \; K <a-&> }
# filter previous line
try %{ execute-keys -draft k : sh-trim-indent <ret> }
# Indent loop syntax, e.g.:
# for foo in bar; do
# things
# done
#
# or:
#
# while foo; do
# things
# done
#
# or equivalently:
#
# while foo
# do
# things
# done
#
# indent after do
try %{ execute-keys -draft <space> k <a-x> <a-k> do$ <ret> j <a-gt> }
# deindent after done
try %{ execute-keys -draft <space> k <a-x> <a-k> done$ <ret> <a-lt> j K <a-&> }
# Indent if/then/else syntax, e.g.:
# if [ $foo = $bar ]; then
# things
# else
# other_things
# fi
#
# or equivalently:
# if [ $foo = $bar ]
# then
# things
# else
# other_things
# fi
#
# indent after then
try %{ execute-keys -draft <space> k <a-x> <a-k> then$ <ret> j <a-gt> }
# deindent after fi
try %{ execute-keys -draft <space> k <a-x> <a-k> fi$ <ret> <a-lt> j K <a-&> }
# deindent and reindent after else - deindent the else, then back
# down and return to the previous indent level.
try %{ execute-keys -draft <space> k <a-x> <a-k> else$ <ret> <a-lt> j }
# Indent case syntax, e.g.:
# case "$foo" in
# bar) thing1;;
# baz)
# things
# ;;
# *)
# default_things
# ;;
# esac
#
# or equivalently:
# case "$foo"
# in
# bar) thing1;;
# esac
#
# indent after in
try %{ execute-keys -draft <space> k <a-x> <a-k> in$ <ret> j <a-gt> }
# deindent after esac
try %{ execute-keys -draft <space> k <a-x> <a-k> esac$ <ret> <a-lt> j K <a-&> }
# indent after )
try %{ execute-keys -draft <space> k <a-x> <a-k> ^\s*\(?[^(]+[^)]\)$ <ret> j <a-gt> }
# deindent after ;;
try %{ execute-keys -draft <space> k <a-x> <a-k> ^\s*\;\;$ <ret> j <a-lt> }
# Indent compound commands as logical blocks, e.g.:
# {
# thing1
# thing2
# }
#
# or in a function definition:
# foo () {
# thing1
# thing2
# }
#
# We don't handle () delimited compond commands - these are technically very
# similar, but the use cases are quite different and much less common.
#
# Note that in this context the '{' and '}' characters are reserved
# words, and hence must be surrounded by a token separator - typically
# white space (including a newline), though technically it can also be
# ';'. Only vertical white space makes sense in this context, though,
# since the syntax denotes a logical block, not a simple compound command.
try %= execute-keys -draft <space> k <a-x> <a-k> (\s|^)\{$ <ret> j <a-gt> =
# deindent closing }
try %= execute-keys -draft <space> k <a-x> <a-k> ^\s*\}$ <ret> <a-lt> j K <a-&> =
]
]
] ]

View File

@ -0,0 +1 @@
gei<ret>

View File

@ -0,0 +1,3 @@
while true; do
thing1
done

View File

@ -0,0 +1,4 @@
while true; do
thing1
done

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1,5 @@
case $foo in
bar)
thing1
thing2
;;

View File

@ -0,0 +1,6 @@
case $foo in
bar)
thing1
thing2
;;
esac

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>fi<ret>

View File

@ -0,0 +1,2 @@
if [ $foo ]; then
thing1

View File

@ -0,0 +1,4 @@
if [ $foo ]; then
thing1
fi

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>;;<ret>*)

View File

@ -0,0 +1,5 @@
case $foo in
bar) thing1;;
baz)
thing1
thing2

View File

@ -0,0 +1,7 @@
case $foo in
bar) thing1;;
baz)
thing1
thing2
;;
*)

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>

View File

@ -0,0 +1,3 @@
foo () {
thing1
}

View File

@ -0,0 +1,4 @@
foo () {
thing1
}

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>baz)

View File

@ -0,0 +1,2 @@
case $foo in
bar) thing1;;

View File

@ -0,0 +1,3 @@
case $foo in
bar) thing1;;
baz)

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>baz

View File

@ -0,0 +1,3 @@
if [ $foo ]; then
bar
else

View File

@ -0,0 +1,4 @@
if [ $foo ]; then
bar
else
baz

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>thing1

View File

@ -0,0 +1 @@
while true; do

View File

@ -0,0 +1,2 @@
while true; do
thing1

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>bar)

View File

@ -0,0 +1 @@
case $foo in

View File

@ -0,0 +1,2 @@
case $foo in
bar)

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>thing1

View File

@ -0,0 +1 @@
if [ $foo ]; then

View File

@ -0,0 +1,2 @@
if [ $foo ]; then
thing1

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>thing1<ret>thing2

View File

@ -0,0 +1,3 @@
case $foo in
bar) thing1;;
baz)

View File

@ -0,0 +1,5 @@
case $foo in
bar) thing1;;
baz)
thing1
thing2

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh

View File

@ -0,0 +1 @@
gei<ret>thing1

View File

@ -0,0 +1 @@
foo () {

View File

@ -0,0 +1,2 @@
foo () {
thing1

View File

@ -0,0 +1,3 @@
source "%val{runtime}/colors/default.kak"
source "%val{runtime}/rc/filetype/sh.kak"
set buffer filetype sh