From 0e84cdb016b9044410008495fa386c2bbad75995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludvig=20B=C3=B6klin?= Date: Mon, 31 Aug 2020 08:13:18 +0200 Subject: [PATCH] Mercury-lang filetype support --- rc/filetype/mercury.kak | 124 ++++++++++++++++++++++++++++++++++++++++ rc/tools/comment.kak | 2 +- 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 rc/filetype/mercury.kak diff --git a/rc/filetype/mercury.kak b/rc/filetype/mercury.kak new file mode 100644 index 00000000..4605d84b --- /dev/null +++ b/rc/filetype/mercury.kak @@ -0,0 +1,124 @@ +# Detection +# ‾‾‾‾‾‾‾‾‾ + +hook global BufCreate .*[.](m) %{ + set-option buffer filetype mercury +} + +# Initialization +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +hook global WinSetOption filetype=mercury %{ + require-module mercury + + set-option window static_words %opt{mercury_static_words} + + hook window InsertChar \n -group mercury-insert mercury-insert-on-new-line + hook window InsertChar \n -group mercury-indent mercury-indent-on-new-line + # cleanup trailing whitespaces on current line insert end + hook window ModeChange pop:insert:.* -group mercury-trim-indent %{ try %{ execute-keys -draft s ^\h+$ d } } + hook -once -always window WinSetOption filetype=.* %{ remove-hooks window mercury-.+ } +} + +hook -group mercury-highlight global WinSetOption filetype=mercury %{ + add-highlighter window/mercury ref mercury + hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/mercury } +} + + +provide-module mercury %§ + + +# Highlighters +# ‾‾‾‾‾‾‾‾‾‾‾‾ + +add-highlighter shared/mercury regions +add-highlighter shared/mercury/code default-region group +add-highlighter shared/mercury/comment region '%' '$' fill comment +add-highlighter shared/mercury/line_comment region '%' '$' fill comment + +add-highlighter shared/mercury/string region '"' (?>|\+|\+\+|-|--|/\\|\\/|\.\.|:=|=\^|<|=|=\.\.|=:=|=<|==|=\\=|>|>=|@<|@=<|@>|@>=|\\=|\\==|~=|\\\+|~|<=|<=>|=>|,|&|->|\;|::|==>|--->|-->|:-|\?-) 0:operator + +evaluate-commands %sh{ + # Grammar + values="true fail" + + # There is overlap between all of these. Not sure what to do about that. + operators="event div mod rem for is and or impure semipure not when all arbitrary atomic disable_warning disable_warnings promise_equivalent_solutions promise_equivalent_solution_setspromise_exclusive promise_exclusive_exhaustive promise_exhaustive promise_impure promise_pure promise_semipure require_complete_switch require_switch_arms_det require_switch_arms_semidet require_switch_arms_multi require_switch_arms_nondet require_switch_arms_cc_multi require_switch_arms_cc_nondet require_switch_arms_erroneous require_switch_arms_failure require_det require_semidet require_multi require_nondet require_cc_multi require_cc_nondet require_erroneous require_failure trace try some or_else then if else where catch catch_any initialize finalize rule solver type pred func inst mode typeclass instance pragma promise initialise finalise mutable module import_module use_module include_module" + modes="free bound in out di mdi uo muo" + determinisms="erroneous failure det semidet multi cc_multi nondet cc_nondet" + reserved_insts="any bound bound_unique clobbered clobbered_any free ground is mostly_clobbered mostly_unique mostly_unique_any not_reached unique unique_any" + reserved_modes="any_func any_pred func is pred" + reserved_types="int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float character string pred func pure semipure impure" + + declarations="type solver type pred func inst mode typeclass instance pragma promise initialise finalise mutable module interface implementation import_module use_module include_module end_module" + + join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; } + + # Add the language's grammar to the static completion list + printf %s\\n "declare-option str-list mercury_static_words $(join "${values} ${declarations} ${operators} ${determinisms} ${modes} ${reserved_insts} ${reserved_modes}" ' ')" + + # Highlight keywords + printf %s " + add-highlighter shared/mercury/code/ regex '\b($(join "${values}" '|'))\b' 0:value + add-highlighter shared/mercury/code/ regex '^:-(\s+($(join "${declarations}" '|')))+\b' 1:keyword + add-highlighter shared/mercury/code/ regex '\b($(join "${operators}" '|'))\b' 0:operator + add-highlighter shared/mercury/code/ regex '\b($(join "${determinisms}" '|'))\b' 0:keyword + add-highlighter shared/mercury/code/ regex '\b($(join "${modes}" '|'))\b' 0:keyword + + # These overlap with previous. Not sure what the solution is. + # add-highlighter shared/mercury/code/ regex '\b($(join "${reserved_types}" '|'))\b' 0:type + # add-highlighter shared/mercury/code/ regex '\b($(join "${reserved_insts}" '|'))\b' 0:builtin + # add-highlighter shared/mercury/code/ regex '\b($(join "${reserved_modes}" '|'))\b' 0:builtin + + # Implementation-defined literals - don't know how to get these to work + # add-highlighter shared/mercury/code/ regex '\$(file|line|module|pred)' 0:keyword + " +} + +define-command -hidden mercury-insert-on-new-line %{ + evaluate-commands -draft -itersel %{ + # copy '%' comment prefix and following white spaces + try %{ execute-keys -draft k s ^\h*\%\h* y jgh P } + } +} + +define-command -hidden mercury-indent-on-char %< + evaluate-commands -draft -itersel %< + # align closer token to its opener when alone on a line + try %/ execute-keys -draft ^\h+[]}]$ m s \A|.\z 1 / + > +> + +define-command -hidden mercury-indent-on-new-line %< + evaluate-commands -draft -itersel %< + # preserve previous line indent + try %{ execute-keys -draft K } + # cleanup trailing whitespaces from previous line + try %{ execute-keys -draft k s \h+$ d } + # indent after line ending with :- + try %{ execute-keys -draft k :-$ j } + # deindent closing brace/bracket when after cursor + try %< execute-keys -draft ^\h*[}\])] gh / [}\])] m 1 > + > +> + +§ diff --git a/rc/tools/comment.kak b/rc/tools/comment.kak index 4560de16..449bbc06 100644 --- a/rc/tools/comment.kak +++ b/rc/tools/comment.kak @@ -64,7 +64,7 @@ hook global BufSetOption filetype=(html|xml) %{ set-option buffer comment_block_end '-->' } -hook global BufSetOption filetype=latex %{ +hook global BufSetOption filetype=(latex|mercury) %{ set-option buffer comment_line '%' }