# http://fennel-lang.org # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ # Detection # ‾‾‾‾‾‾‾‾‾ hook global BufCreate .*[.]fnl %{ set-option buffer filetype fennel } # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ hook global WinSetOption filetype=fennel %{ require-module fennel fennel-configure-window } hook -group fennel-highlight global WinSetOption filetype=fennel %{ add-highlighter window/fennel ref fennel hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/fennel } } provide-module fennel %{ require-module lisp # Highlighters # ‾‾‾‾‾‾‾‾‾‾‾‾ add-highlighter shared/fennel regions add-highlighter shared/fennel/code default-region group add-highlighter shared/fennel/comment region '(?]' '(?![-\w?\\^_!$%&*+./@|<=>])' fill keyword add-highlighter shared/fennel/code/ regex \\(?:space|tab|newline|return|backspace|formfeed|u[0-9a-fA-F]{4}|o[0-3]?[0-7]{1,2}|.)\b 0:string evaluate-commands %sh{ # Grammar keywords="require-macros eval-compiler doc lua hashfn macro macros import-macros pick-args pick-values macroexpand macrodebug do values if when each for fn lambda λ partial while set global var local let tset set-forcibly! doto match or and not not= collect icollect rshift lshift bor band bnot bxor with-open" re_keywords='\\$ \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 \\$\\.\\.\\.' builtins="_G _VERSION arg assert bit32 collectgarbage coroutine debug dofile error getfenv getmetatable io ipairs length load loadfile loadstring math next os package pairs pcall print rawequal rawget rawlen rawset require select setfenv setmetatable string table tonumber tostring type unpack xpcall" 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 fennel_static_words $(join "${keywords} ${builtins} false nil true" ' ')" # Highlight keywords printf %s " add-highlighter shared/fennel/code/keywords regex \b($(join "${keywords} ${re_keywords}" '|'))\b 0:keyword add-highlighter shared/fennel/code/builtins regex \b($(join "${builtins}" '|'))\b 0:builtin " } add-highlighter shared/fennel/code/operator regex (\.|\?\.|\+|\.\.|\^|-|\*|%|/|>|<|>=|<=|=|\.\.\.|:|->|->>|-\?>|-\?>>) 0:operator add-highlighter shared/fennel/code/value regex \b(false|nil|true|[0-9]+(:?\.[0-9])?(:?[eE]-?[0-9]+)?|0x[0-9a-fA-F])\b 0:value add-highlighter shared/fennel/code/function_declaration regex \((?:fn|lambda|λ)\s+([\S]+) 1:function add-highlighter shared/fennel/code/method_call regex (?:\w+|\$[0-9]{0,1}):(\S+)\b 1:function # Commands # ‾‾‾‾‾‾‾‾ define-command -hidden fennel-configure-window %{ set-option window static_words %opt{fennel_static_words} hook window ModeChange pop:insert:.* -group fennel-trim-indent fennel-trim-indent hook window InsertChar \n -group fennel-indent fennel-indent-on-new-line set-option buffer extra_word_chars '_' . / * ? + - < > ! : "'" hook -once -always window WinSetOption filetype=.* %{ remove-hooks window fennel-.+ } } define-command -hidden fennel-trim-indent lisp-trim-indent declare-option \ -docstring 'regex matching the head of forms which have options *and* indented bodies' \ regex fennel_special_indent_forms \ '(?:if|when|each|for|fn|lambda|λ|partial|while|local|var|doto|let)' define-command -hidden fennel-indent-on-new-line %{ # registers: i = best align point so far; w = start of first word of form evaluate-commands -draft -save-regs '/"|^@iw' -itersel %{ execute-keys -draft 'gk"iZ' try %{ execute-keys -draft '[bl"i"wZ' try %{ # If a special form, indent another (indentwidth - 1) spaces execute-keys -draft '"wze[\s()\[\]\{\}]\A' %opt{fennel_special_indent_forms} '\z' execute-keys -draft '"wzes.{' %sh{printf $(( kak_opt_indentwidth - 1 ))} '}\K.*;"i' } catch %{ # If not special and parameter appears on line 1, indent to parameter execute-keys -draft '"wz[()[\]{}]e[\s()\[\]\{\}]s\h\K[^\s].*;"i' } } try %{ execute-keys -draft '[rl"i' } try %{ execute-keys -draft '[Bl"i' } execute-keys -draft ';"ia&' } } }