diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2022-05-05 01:31:29 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2022-05-05 01:31:29 +1200 |
commit | 7809f6447b49be28e2cdaae02da66d79f6598146 (patch) | |
tree | bd901e25bdab99e2f519d63eb3ebdbee17220943 /vim | |
parent | Add checking, tidying, and linting for Python (diff) | |
download | dotfiles-7809f6447b49be28e2cdaae02da66d79f6598146.tar.gz dotfiles-7809f6447b49be28e2cdaae02da66d79f6598146.zip |
Add lang=-to-'spelllang' hooks for HTML filetype
Diffstat (limited to 'vim')
-rw-r--r-- | vim/after/ftplugin/html.vim | 18 | ||||
-rw-r--r-- | vim/autoload/html/spelllang.vim | 57 |
2 files changed, 75 insertions, 0 deletions
diff --git a/vim/after/ftplugin/html.vim b/vim/after/ftplugin/html.vim index 21a84a42..741f7b65 100644 --- a/vim/after/ftplugin/html.vim +++ b/vim/after/ftplugin/html.vim @@ -32,6 +32,24 @@ augroup END let b:undo_ftplugin .= '|execute ''autocmd! html_timestamp''' \ . '|augroup! html_timestamp' +" Set up hooks for divining 'spelllang' from lang= attributes +augroup html_spelllang + if exists('##TextChanged') + autocmd TextChanged * + \ if &modified + \| call html#spelllang#Set() + \|endif + else + autocmd InsertLeave * + \ if &modified + \| call html#spelllang#Set() + \|endif + endif +augroup END +call html#spelllang#Set() +let b:undo_ftplugin .= '|execute ''autocmd! html_spelllang''' + \ . '|augroup! html_spelllang' + " Stop here if the user doesn't want ftplugin mappings if exists('no_plugin_maps') || exists('no_html_maps') finish diff --git a/vim/autoload/html/spelllang.vim b/vim/autoload/html/spelllang.vim new file mode 100644 index 00000000..c01a57b2 --- /dev/null +++ b/vim/autoload/html/spelllang.vim @@ -0,0 +1,57 @@ +" Crude regular expression to match an <html> or <body> tag on one line with +" a lang= attribute set. This isn't exact, by any means, but I don't want to +" write an actual HTML parser for a mere 'spelllang' hook nicety that fails +" silently anyway. +" +" The first submatch is the language code, e.g. "en", "es". The second +" submatch is optional and follows a hyphen and is for the regional code, +" e.g. "US", "GB", "AR". +" +let s:pattern = '\m\c<\%(html\|body\)\>[^>]*\<lang=["'']\=' + \ . '\([a-z-]\{2,}\)\%(-\([a-z]\{2,}\)\)' + +" The line count limit for looking for the pattern; no sense churning through +" the whole document every time it's changed. +" +let s:lines = 128 + +" Look for a language code in the first lines of the current buffer, and if it +" looks understandable, adopt an appropriate spelling language. +" +function! html#spelllang#Set() abort + + " Loop through the first s:lines of the buffer + for line in getline(1, s:lines) + + " Check if this line has an <html lang=""> tag, or skip it + let matches = matchlist(line, s:pattern) + if empty(matches) + continue + endif + + " The line seems to match our pattern, and so we have a language code in + " matches[1], and possibly a region code in matches[2]. + " + " Next we need to check whether we'll attempt to use this to set + " a spelling language. Build the expected path for a spellfile; looks + " like `$VIMRUNTIME/spell/en.utf-8.spl`. Note that this path doesn't + " include any language region, per documentation. + " + let spellfile = 'spell/' . join([ + \ tolower(matches[1]), + \ &encoding, + \ 'spl', + \], '.') + + " If a spelling list file of the expected name exists in &runtimepath, try + " setting the local value of 'spelllang' to reflect what was in the lang= + " attribute; force it to lowercase and separate the region with an + " underscore rather than a hyphen (if there is a region). + " + if strlen(globpath(&runtimepath, spellfile)) + let &l:spelllang = tolower(join(matches[1:2], '_')) + endif + + endfor + +endfunction |