neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

astro.vim (5926B)


      1 " Vim filetype plugin file
      2 " Language:     Astro
      3 " Maintainer:   Romain Lafourcade <romainlafourcade@gmail.com>
      4 " Last Change:  2024 Apr 21
      5 "               2024 May 24 by Riley Bruins <ribru17@gmail.com> ('commentstring')
      6 "               2025 Aug 29 by Vim project, add try/catch around json_decode(), #18141
      7 
      8 if exists("b:did_ftplugin")
      9    finish
     10 endif
     11 let b:did_ftplugin = 1
     12 
     13 let s:cpo_save = &cpo
     14 set cpo-=C
     15 
     16 function! s:IdentifyScope(start, end) abort
     17    let pos_start = searchpairpos(a:start, '', a:end, 'bnW')
     18    let pos_end = searchpairpos(a:start, '', a:end, 'nW')
     19 
     20    return pos_start != [0, 0]
     21                \ && pos_end != [0, 0]
     22                \ && pos_start[0] != getpos('.')[1]
     23 endfunction
     24 
     25 function! s:AstroComments() abort
     26    if s:IdentifyScope('^---\n\s*\S', '^---\n\n')
     27                \ || s:IdentifyScope('^\s*<script', '^\s*<\/script>')
     28        " ECMAScript comments
     29        setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
     30        setlocal commentstring=//\ %s
     31 
     32    elseif s:IdentifyScope('^\s*<style', '^\s*<\/style>')
     33        " CSS comments
     34        setlocal comments=s1:/*,mb:*,ex:*/
     35        setlocal commentstring=/*\ %s\ */
     36 
     37    else
     38        " HTML comments
     39        setlocal comments=s:<!--,m:\ \ \ \ ,e:-->
     40        setlocal commentstring=<!--\ %s\ -->
     41    endif
     42 endfunction
     43 
     44 " https://code.visualstudio.com/docs/languages/jsconfig
     45 function! s:CollectPathsFromConfig() abort
     46    let config_json = findfile('tsconfig.json', '.;')
     47 
     48    if empty(config_json)
     49        let config_json = findfile('jsconfig.json', '.;')
     50 
     51        if empty(config_json)
     52            return
     53        endif
     54    endif
     55 
     56    try
     57        let paths_from_config = config_json
     58                \ ->readfile()
     59                \ ->filter({ _, val -> val =~ '^\s*[\[\]{}"0-9]' })
     60                \ ->join()
     61                \ ->json_decode()
     62                \ ->get('compilerOptions', {})
     63                \ ->get('paths', {})
     64    catch /^Vim\%((\a\+)\)\=:E491:/ " invalid json
     65        let paths_from_config = {}
     66    catch /^Vim\%((\a\+)\)\=:E474:/ " invalid json in Nvim
     67        let paths_from_config = {}
     68    endtry
     69 
     70    if !empty(paths_from_config)
     71        let b:astro_paths = paths_from_config
     72                    \ ->map({key, val -> [
     73                    \     key->glob2regpat(),
     74                    \     val[0]->substitute('\/\*$', '', '')
     75                    \   ]})
     76                    \ ->values()
     77    endif
     78 
     79    let b:undo_ftplugin ..= " | unlet! b:astro_paths"
     80 endfunction
     81 
     82 function! s:AstroInclude(filename) abort
     83    let decorated_filename = a:filename
     84                \ ->substitute("^", "@", "")
     85 
     86    let found_path = b:
     87                \ ->get("astro_paths", [])
     88                \ ->indexof({ key, val -> decorated_filename =~ val[0]})
     89 
     90    if found_path != -1
     91        let alias = b:astro_paths[found_path][0]
     92        let path  = b:astro_paths[found_path][1]
     93                    \ ->substitute('\(\/\)*$', '/', '')
     94 
     95        return decorated_filename
     96                    \ ->substitute(alias, path, '')
     97    endif
     98 
     99    return a:filename
    100 endfunction
    101 
    102 let b:undo_ftplugin = "setlocal"
    103            \ .. " formatoptions<"
    104            \ .. " path<"
    105            \ .. " suffixesadd<"
    106            \ .. " matchpairs<"
    107            \ .. " comments<"
    108            \ .. " commentstring<"
    109            \ .. " iskeyword<"
    110            \ .. " define<"
    111            \ .. " include<"
    112            \ .. " includeexpr<"
    113 
    114 " Create self-resetting autocommand group
    115 augroup Astro
    116    autocmd! * <buffer>
    117 augroup END
    118 
    119 " Set 'formatoptions' to break comment lines but not other lines,
    120 " and insert the comment leader when hitting <CR> or using "o".
    121 setlocal formatoptions-=t
    122 setlocal formatoptions+=croql
    123 
    124 " Remove irrelevant part of 'path'.
    125 setlocal path-=/usr/include
    126 
    127 " Seed 'path' with default directories for :find, gf, etc.
    128 setlocal path+=src/**
    129 setlocal path+=public/**
    130 
    131 " Help Vim find extension-less filenames
    132 let &l:suffixesadd =
    133            \ ".astro"
    134            \ .. ",.js,.jsx,.es,.es6,.cjs,.mjs,.jsm"
    135            \ .. ",.json"
    136            \ .. ",.scss,.sass,.css"
    137            \ .. ",.svelte"
    138            \ .. ",.ts,.tsx,.d.ts"
    139            \ .. ",.vue"
    140 
    141 " From $VIMRUNTIME/ftplugin/html.vim
    142 setlocal matchpairs+=<:>
    143 
    144 " Matchit configuration
    145 if exists("loaded_matchit")
    146    let b:match_ignorecase = 0
    147 
    148    " From $VIMRUNTIME/ftplugin/javascript.vim
    149    let b:match_words =
    150                \ '\<do\>:\<while\>,'
    151                \ .. '<\@<=\([^ \t>/]\+\)\%(\s\+[^>]*\%([^/]>\|$\)\|>\|$\):<\@<=/\1>,'
    152                \ .. '<\@<=\%([^ \t>/]\+\)\%(\s\+[^/>]*\|$\):/>'
    153 
    154    " From $VIMRUNTIME/ftplugin/html.vim
    155    let b:match_words ..=
    156                \ '<!--:-->,'
    157                \ .. '<:>,'
    158                \ .. '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,'
    159                \ .. '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,'
    160                \ .. '<\@<=\([^/!][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>'
    161 
    162    let b:undo_ftplugin ..= " | unlet! b:match_ignorecase b:match_words"
    163 endif
    164 
    165 " Change what constitutes a word, mainly useful for CSS/SASS
    166 setlocal iskeyword+=-
    167 setlocal iskeyword+=$
    168 setlocal iskeyword+=%
    169 
    170 " Define paths/aliases for module resolution
    171 call s:CollectPathsFromConfig()
    172 
    173 " Find ESM imports
    174 setlocal include=^\\s*\\(import\\\|import\\s\\+[^\/]\\+from\\)\\s\\+['\"]
    175 
    176 " Process aliases if file can't be found
    177 setlocal includeexpr=s:AstroInclude(v:fname)
    178 
    179 " Set 'define' to a comprehensive value
    180 " From $VIMRUNTIME/ftplugin/javascript.vim and
    181 " $VIMRUNTIME/ftplugin/sass.vim
    182 let &l:define =
    183            \ '\(^\s*(*async\s\+function\|(*function\)'
    184            \ .. '\|^\s*\(\*\|static\|async\|get\|set\|\i\+\.\)'
    185            \ .. '\|^\s*\(\ze\i\+\)\(([^)]*).*{$\|\s*[:=,]\)'
    186 
    187 
    188 " Set &comments and &commentstring according to current scope
    189 autocmd Astro CursorMoved <buffer> call s:AstroComments()
    190 
    191 let &cpo = s:cpo_save
    192 unlet s:cpo_save
    193 
    194 " vim: textwidth=78 tabstop=8 shiftwidth=4 softtabstop=4 expandtab