" Vim filetype plugin file " Language: Astro " Maintainer: Romain Lafourcade " Last Change: 2024 Apr 21 " 2024 May 24 by Riley Bruins ('commentstring') if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 let s:cpo_save = &cpo set cpo-=C function! s:IdentifyScope(start, end) abort let pos_start = searchpairpos(a:start, '', a:end, 'bnW') let pos_end = searchpairpos(a:start, '', a:end, 'nW') return pos_start != [0, 0] \ && pos_end != [0, 0] \ && pos_start[0] != getpos('.')[1] endfunction function! s:AstroComments() abort if s:IdentifyScope('^---\n\s*\S', '^---\n\n') \ || s:IdentifyScope('^\s*') " ECMAScript comments setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// setlocal commentstring=//\ %s elseif s:IdentifyScope('^\s*') " CSS comments setlocal comments=s1:/*,mb:*,ex:*/ setlocal commentstring=/*\ %s\ */ else " HTML comments setlocal comments=s: setlocal commentstring= endif endfunction " https://code.visualstudio.com/docs/languages/jsconfig function! s:CollectPathsFromConfig() abort let config_json = findfile('tsconfig.json', '.;') if empty(config_json) let config_json = findfile('jsconfig.json', '.;') if empty(config_json) return endif endif let paths_from_config = config_json \ ->readfile() \ ->filter({ _, val -> val =~ '^\s*[\[\]{}"0-9]' }) \ ->join() \ ->json_decode() \ ->get('compilerOptions', {}) \ ->get('paths', {}) if !empty(paths_from_config) let b:astro_paths = paths_from_config \ ->map({key, val -> [ \ key->glob2regpat(), \ val[0]->substitute('\/\*$', '', '') \ ]}) \ ->values() endif let b:undo_ftplugin ..= " | unlet! b:astro_paths" endfunction function! s:AstroInclude(filename) abort let decorated_filename = a:filename \ ->substitute("^", "@", "") let found_path = b: \ ->get("astro_paths", []) \ ->indexof({ key, val -> decorated_filename =~ val[0]}) if found_path != -1 let alias = b:astro_paths[found_path][0] let path = b:astro_paths[found_path][1] \ ->substitute('\(\/\)*$', '/', '') return decorated_filename \ ->substitute(alias, path, '') endif return a:filename endfunction let b:undo_ftplugin = "setlocal" \ .. " formatoptions<" \ .. " path<" \ .. " suffixesadd<" \ .. " matchpairs<" \ .. " comments<" \ .. " commentstring<" \ .. " iskeyword<" \ .. " define<" \ .. " include<" \ .. " includeexpr<" " Create self-resetting autocommand group augroup Astro autocmd! * augroup END " Set 'formatoptions' to break comment lines but not other lines, " and insert the comment leader when hitting or using "o". setlocal formatoptions-=t setlocal formatoptions+=croql " Remove irrelevant part of 'path'. setlocal path-=/usr/include " Seed 'path' with default directories for :find, gf, etc. setlocal path+=src/** setlocal path+=public/** " Help Vim find extension-less filenames let &l:suffixesadd = \ ".astro" \ .. ",.js,.jsx,.es,.es6,.cjs,.mjs,.jsm" \ .. ",.json" \ .. ",.scss,.sass,.css" \ .. ",.svelte" \ .. ",.ts,.tsx,.d.ts" \ .. ",.vue" " From $VIMRUNTIME/ftplugin/html.vim setlocal matchpairs+=<:> " Matchit configuration if exists("loaded_matchit") let b:match_ignorecase = 0 " From $VIMRUNTIME/ftplugin/javascript.vim let b:match_words = \ '\:\,' \ .. '<\@<=\([^ \t>/]\+\)\%(\s\+[^>]*\%([^/]>\|$\)\|>\|$\):<\@<=/\1>,' \ .. '<\@<=\%([^ \t>/]\+\)\%(\s\+[^/>]*\|$\):/>' " From $VIMRUNTIME/ftplugin/html.vim let b:match_words ..= \ ',' \ .. '<:>,' \ .. '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' \ .. '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' \ .. '<\@<=\([^/!][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>' let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words" endif " Change what constitutes a word, mainly useful for CSS/SASS setlocal iskeyword+=- setlocal iskeyword+=$ setlocal iskeyword+=% " Define paths/aliases for module resolution call s:CollectPathsFromConfig() " Find ESM imports setlocal include=^\\s*\\(import\\\|import\\s\\+[^\/]\\+from\\)\\s\\+['\"] " Process aliases if file can't be found setlocal includeexpr=s:AstroInclude(v:fname) " Set 'define' to a comprehensive value " From $VIMRUNTIME/ftplugin/javascript.vim and " $VIMRUNTIME/ftplugin/sass.vim let &l:define = \ '\(^\s*(*async\s\+function\|(*function\)' \ .. '\|^\s*\(\*\|static\|async\|get\|set\|\i\+\.\)' \ .. '\|^\s*\(\ze\i\+\)\(([^)]*).*{$\|\s*[:=,]\)' " Set &comments and &commentstring according to current scope autocmd Astro CursorMoved call s:AstroComments() let &cpo = s:cpo_save unlet s:cpo_save " vim: textwidth=78 tabstop=8 shiftwidth=4 softtabstop=4 expandtab