Add support for R
This commit is contained in:
parent
0cc89b2b9f
commit
bd3ec61784
143
rc/filetype/R.kak
Normal file
143
rc/filetype/R.kak
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# http://kakoune.org
|
||||||
|
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
# Detection
|
||||||
|
# ‾‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
hook global BufCreate (.*/)?(\.Rprofile|.*\.[rR]) %{
|
||||||
|
set-option buffer filetype R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Highlighters & Completion
|
||||||
|
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
add-highlighter shared/R regions
|
||||||
|
add-highlighter shared/R/code default-region group
|
||||||
|
add-highlighter shared/R/double_string region '"' (?<!\\)(\\\\)*" fill string
|
||||||
|
add-highlighter shared/R/single_string region "'" (?<!\\)(\\\\)*' fill string
|
||||||
|
add-highlighter shared/R/comment region '#' '$' fill comment
|
||||||
|
add-highlighter shared/R/identifier region '`' (?<!\\)(\\\\)*` fill attribute
|
||||||
|
|
||||||
|
# see base::NumericConstants
|
||||||
|
add-highlighter shared/R/code/ regex '(?i)\b(?<![.\d])\d+(\.\d*)?(e[-+]?\d+)?(?I)[iL]?(?![\d.e\w])' 0:value
|
||||||
|
add-highlighter shared/R/code/ regex '(?i)(?<![.\d\w])\.\d+(e[-+]?\d+)?(?I)[iL]?(?![\d.e])' 0:value
|
||||||
|
add-highlighter shared/R/code/ regex '(?i)\b(?<![.\d])0x[0-9a-f]+?(p[-+]?\d+)?(?I)[iL]?(?![\d.e\w])' 0:value
|
||||||
|
|
||||||
|
evaluate-commands %sh{
|
||||||
|
# see base::Reserved
|
||||||
|
values="TRUE|FALSE|NULL|Inf|NaN|NA|NA_integer_|NA_real_|NA_complex_|NA_character_|\.{3}|\.{2}\d+|"
|
||||||
|
keywords="if|else|repeat|while|function|for|in|next|break"
|
||||||
|
|
||||||
|
# Add the language's grammar to the static completion list
|
||||||
|
printf %s\\n "hook global WinSetOption filetype=python %{
|
||||||
|
set-option window static_words ${values} ${keywords}
|
||||||
|
}" | tr '|' ' '
|
||||||
|
|
||||||
|
printf %s "
|
||||||
|
add-highlighter shared/R/code/ regex '\b(${values})\b' 0:value
|
||||||
|
add-highlighter shared/R/code/ regex '\b(${keywords})\b' 0:keyword
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
# see base::Syntax
|
||||||
|
add-highlighter shared/R/code/ regex (?<=[\w\s\d'"_)])(\$|@|\^|-|\+|%[^%]+%|\*|/|<(?![<-])|(?<![->])>|<=|>=|==|!=|!|&{1,2}|\|{1,2}|~|\?) 0:operator
|
||||||
|
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
# ‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
define-command -hidden R-trim-indent %{
|
||||||
|
# remove the line if it's empty when leaving the insert mode
|
||||||
|
try %{ execute-keys -draft <a-x> 1s^(\h+)$<ret> d }
|
||||||
|
}
|
||||||
|
|
||||||
|
define-command -hidden R-indent-on-newline %< evaluate-commands -draft -itersel %<
|
||||||
|
execute-keys \;
|
||||||
|
try %<
|
||||||
|
# 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-\;>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 >
|
||||||
|
# indent after an opening brace or parenthesis at end of line
|
||||||
|
try %< execute-keys -draft k <a-x> s[{(]\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> \
|
||||||
|
<a-\;>mB <a-k>\A\b(if|for|while)\b<ret> <a-\;>j <a-gt> >
|
||||||
|
try %< execute-keys -draft k <a-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> \
|
||||||
|
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> \
|
||||||
|
<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 %<
|
||||||
|
# Go to opening parenthesis and opening brace, then select the most nested one
|
||||||
|
try %< execute-keys [c [({],[)}] <ret> >
|
||||||
|
# Validate selection and get first and last char
|
||||||
|
execute-keys <a-k>\A[{(](\h*\S+)+\n<ret> <a-K>"(([^"]*"){2})*<ret> <a-K>'(([^']*'){2})*<ret> <a-:><a-\;>L <a-S>
|
||||||
|
# Remove possibly incorrect indent from new line which was copied from previous line
|
||||||
|
try %< execute-keys -draft <space> <a-h> s\h+<ret> d >
|
||||||
|
# Now indent and align that new line with the opening parenthesis/brace
|
||||||
|
execute-keys 1<a-&> &
|
||||||
|
> >
|
||||||
|
> >
|
||||||
|
|
||||||
|
define-command -hidden R-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-&> ]
|
||||||
|
]
|
||||||
|
|
||||||
|
define-command -hidden R-indent-on-closing-curly-brace %[
|
||||||
|
# align to opening curly brace when alone on a line
|
||||||
|
try %[
|
||||||
|
# in case open curly brace follows a closing paren, align indent with opening paren
|
||||||
|
execute-keys -itersel -draft <a-h><a-:><a-k>^\h+\}$<ret>hm <a-F>)M <a-k> \A\(.*\)\h\{.*\}\z <ret> <a-S>1<a-&>
|
||||||
|
] catch %[
|
||||||
|
# otherwise align with open curly brace
|
||||||
|
execute-keys -itersel -draft <a-h><a-:><a-k>^\h+\}$<ret>hm<a-S>1<a-&>
|
||||||
|
] catch %[]
|
||||||
|
]
|
||||||
|
|
||||||
|
define-command -hidden R-insert-on-newline %[ evaluate-commands -itersel -draft %[
|
||||||
|
execute-keys \;
|
||||||
|
try %[
|
||||||
|
evaluate-commands -draft -save-regs '/"' %[
|
||||||
|
# copy the commenting prefix
|
||||||
|
execute-keys -save-regs '' k <a-x>1s^\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
|
||||||
|
] catch %[
|
||||||
|
# if there is no text in the previous comment, remove it completely
|
||||||
|
execute-keys d
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
] ]
|
||||||
|
|
||||||
|
# Initialization
|
||||||
|
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||||
|
|
||||||
|
hook -group R-highlight global WinSetOption filetype=R %{
|
||||||
|
add-highlighter window/R ref R
|
||||||
|
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/R }
|
||||||
|
}
|
||||||
|
|
||||||
|
hook global WinSetOption filetype=R %~
|
||||||
|
hook window ModeChange insert:.* R-trim-indent
|
||||||
|
hook window InsertChar \n R-insert-on-newline
|
||||||
|
hook window InsertChar \n R-indent-on-newline
|
||||||
|
hook window InsertChar \{ R-indent-on-opening-curly-brace
|
||||||
|
hook window InsertChar \} R-indent-on-closing-curly-brace
|
||||||
|
|
||||||
|
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window R-.+ }
|
||||||
|
~
|
Loading…
Reference in New Issue
Block a user