diff --git a/runtime/ftplugin/skhd.vim b/runtime/ftplugin/skhd.vim new file mode 100644 index 0000000000..ecc932f581 --- /dev/null +++ b/runtime/ftplugin/skhd.vim @@ -0,0 +1,20 @@ +" Vim filetype plugin file +" Language: skhd(simple hotkey daemon for macOS) configuration file +" Maintainer: Kiyoon Kim +" Last Change: 2026 Jan 23 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal comments=:# commentstring=#\ %s +setlocal formatoptions-=t formatoptions+=croql + +let b:undo_ftplugin = "setl com< cms< fo<" + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 050e9fe207..69374acbbf 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1906,6 +1906,8 @@ local filename = { ['.tcshrc'] = detect.tcsh, ['tcsh.login'] = detect.tcsh, ['tcsh.tcshrc'] = detect.tcsh, + ['.skhdrc'] = 'skhd', + ['skhdrc'] = 'skhd', ['/etc/slp.conf'] = 'slpconf', ['/etc/slp.reg'] = 'slpreg', ['/etc/slp.spi'] = 'slpspi', diff --git a/runtime/syntax/skhd.vim b/runtime/syntax/skhd.vim new file mode 100644 index 0000000000..6bda7a60ac --- /dev/null +++ b/runtime/syntax/skhd.vim @@ -0,0 +1,137 @@ +" Vim syntax file +" Language: skhd configuration file +" Maintainer: Kiyoon Kim +" Last Change: 2025 Jan 22 + +if exists("b:current_syntax") + finish +endif + +" Comments: whole line from '#' +syn match skhdComment /^\s*#.*/ + +" Modifiers (shift, ctrl, alt, cmd, fn) +syn keyword skhdModifier + \ alt lalt ralt + \ shift lshift rshift + \ cmd lcmd rcmd + \ ctrl lctrl rctrl + \ fn hyper meh + \ option super +" highlight the '+' and '-' and ':' separators +syn match skhdOperator /->/ +syn match skhdOperator /[+:\-;<>,\[\]@~]/ + +" Hex keycode form: 0x3C etc +syn match skhdKeycode /\v0x[0-9A-Fa-f]+/ + +" Keys (a–z, digits, function‐keys, arrows…) +syn keyword skhdKey + \ return tab space backspace escape delete + \ home end pageup pagedown insert + \ left right up down + \ sound_up sound_down mute play previous next rewind fast + \ brightness_up brightness_down illumination_up illumination_down +syn match skhdKey /\vf([1-9]|1[0-9]|20)\>/ +syn match skhdKey /\v\<[A-Za-z0-9]\>/ + +" The yabai command and its subcommands +syn match skhdCommand /\\|\/ +syn match skhdSubCmd /\\|\\|\/ + +" ─────────────────────────────────────────────────────────────────── +" Treat anything after a single “:” (not double‑colon) as bash +" ─────────────────────────────────────────────────────────────────── +" load Vim’s built‑in shell rules +syntax include @bash syntax/bash.vim + +" After `:` (not `::`) is a bash command, but not when it is preceded by a `\` +syn region skhdBash + \ matchgroup=skhdOperator + \ start=/\v(^|[^:])\zs:\s*/ + \ end=/\v\s*$\ze/ + \ skip=/\v\\\s*$/ + \ keepend + \ contains=@bash + +" ──────────────────────────────────────────────────────────────── +" Key‑map group definitions and switches +" ──────────────────────────────────────────────────────────────── +" In skhd, you can define groups and assign hotkeys to them as follows: +" 1. Group‑definition lines that start with :: +" 2. Switch operator (<) +" 3. Target group names after the ; + +" Lines like `:: default` or `:: passthrough` +" match the whole thing as a GroupDef, but capture the group name +syn match skhdGroupDef /^::\s*\w\+/ +syn match skhdGroupName /::\s*\zs\w\+/ + +" The `<` switch token in lines like +" passthrough < cmd + shift + alt - b ; default +syn match skhdSwitch /<\s*/ + +" The target (or “fall‑through”) group after the semicolon +" ... ; default +syn match skhdTargetGroup /;\s*\zs\w\+/ + + +" ------------------------------------------------------------ +" Application-specific bindings block: [ ... ] +" ------------------------------------------------------------ + +" The whole block. This avoids grabbing .blacklist by requiring the line be just '[' at end. +syn region skhdProcMapBlock + \ matchgroup=skhdProcMapDelim + \ start=/\v\[\s*$/ + \ end=/^\s*\]\s*$/ + \ keepend + \ transparent + \ contains=skhdProcMapApp,skhdProcMapWildcard,skhdProcMapUnbind,skhdOperator,skhdComment,skhdBash,skhdString + +" App name on the left side: "Google Chrome" : +syn match skhdProcMapApp /^\s*\zs"[^"]*"\ze\s*:\s*/ contained + +" Wildcard entry: * : +syn match skhdProcMapWildcard /^\s*\zs\*\ze\s*:\s*/ contained + +" Unbind operator on the right side: "App" ~ or * ~ +syn match skhdProcMapUnbind /\v^\s*(\"[^"]*\"|\*)\s*\zs\~\ze\s*$/ contained + +syn keyword skhdDirective .load .blacklist +syn match skhdLoadLine /^\s*\.load\>\s\+/ contains=skhdDirective + +syn region skhdBlacklistBlock + \ start=/^\s*\.blacklist\>\s*\[\s*$/ + \ end=/^\s*\]\s*$/ + \ keepend + \ contains=skhdDirective,skhdComment,skhdString + +syn region skhdString start=/"/ skip=/\\"/ end=/"/ + +" ──────────────────────────────────────────────────────────────── +" Linking to standard Vim highlight groups +" ──────────────────────────────────────────────────────────────── +hi def link skhdComment Comment +hi def link skhdHeadline Title +hi def link skhdModifier Keyword +hi def link skhdOperator Operator +hi def link skhdWildcard Special +hi def link skhdKey Identifier +hi def link skhdKeycode Number +hi def link skhdCommand Function +hi def link skhdSubCmd Statement +hi def link skhdGroupDef Label +hi def link skhdGroupName Identifier +hi def link skhdSwitch Operator +hi def link skhdTargetGroup Type +hi def link skhdString String + +hi def link skhdProcMapDelim Operator +hi def link skhdProcMapApp Type +hi def link skhdProcMapWildcard Special +hi def link skhdProcMapUnbind Special + +hi def link skhdDirective PreProc + +let b:current_syntax = "skhd" diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index cf343ead21..faede101ba 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -738,6 +738,7 @@ func s:GetFilenameChecks() abort \ 'simula': ['file.sim'], \ 'sinda': ['file.sin', 'file.s85'], \ 'sisu': ['file.sst', 'file.ssm', 'file.ssi', 'file.-sst', 'file._sst', 'file.sst.meta', 'file.-sst.meta', 'file._sst.meta'], + \ 'skhd': ['.skhdrc', 'skhdrc'], \ 'skill': ['file.il', 'file.ils', 'file.cdf'], \ 'slang': ['file.sl'], \ 'slice': ['file.ice'],