| 
									
										
										
										
											2024-04-21 15:44:10 +02:00
										 |  |  | " Vim filetype plugin file | 
					
						
							|  |  |  | " Language:     Astro | 
					
						
							|  |  |  | " Maintainer:   Romain Lafourcade <romainlafourcade@gmail.com> | 
					
						
							|  |  |  | " Last Change:  2024 Apr 21 | 
					
						
							| 
									
										
										
										
											2024-06-03 20:40:45 +02:00
										 |  |  | "               2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring') | 
					
						
							| 
									
										
										
										
											2024-04-21 15:44:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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*<script', '^\s*<\/script>') | 
					
						
							|  |  |  |         " ECMAScript comments | 
					
						
							|  |  |  |         setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:// | 
					
						
							| 
									
										
										
										
											2024-06-03 20:40:45 +02:00
										 |  |  |         setlocal commentstring=//\ %s | 
					
						
							| 
									
										
										
										
											2024-04-21 15:44:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     elseif s:IdentifyScope('^\s*<style', '^\s*<\/style>') | 
					
						
							|  |  |  |         " CSS comments | 
					
						
							|  |  |  |         setlocal comments=s1:/*,mb:*,ex:*/ | 
					
						
							| 
									
										
										
										
											2024-06-03 20:40:45 +02:00
										 |  |  |         setlocal commentstring=/*\ %s\ */ | 
					
						
							| 
									
										
										
										
											2024-04-21 15:44:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         " HTML comments | 
					
						
							|  |  |  |         setlocal comments=s:<!--,m:\ \ \ \ ,e:--> | 
					
						
							| 
									
										
										
										
											2024-06-03 20:40:45 +02:00
										 |  |  |         setlocal commentstring=<!--\ %s\ --> | 
					
						
							| 
									
										
										
										
											2024-04-21 15:44:10 +02:00
										 |  |  |     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! * <buffer> | 
					
						
							|  |  |  | augroup END | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " Set 'formatoptions' to break comment lines but not other lines, | 
					
						
							|  |  |  | " and insert the comment leader when hitting <CR> 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 = | 
					
						
							|  |  |  |                 \ '\<do\>:\<while\>,' | 
					
						
							|  |  |  |                 \ .. '<\@<=\([^ \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 <buffer> call s:AstroComments() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let &cpo = s:cpo_save | 
					
						
							|  |  |  | unlet s:cpo_save | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " vim: textwidth=78 tabstop=8 shiftwidth=4 softtabstop=4 expandtab |