From 9e2f378b6d255cd4b02a39b1a1dc5aea2df1a84c Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 1 May 2024 18:46:10 +0200 Subject: [PATCH] vim-patch:9.1.0386: filetype: stylus files not recognized Problem: filetype: stylus files not recognized Solution: Detect '*.styl' and '*.stylus' as stylus filetype, include indent, filetype and syntax plugin (Philip H) closes: vim/vim#14656 https://github.com/vim/vim/commit/2d919d2744a99c9bb9e79984e85b8e8f5ec14c07 Co-authored-by: Philip H <47042125+pheiduck@users.noreply.github.com> --- runtime/ftplugin/stylus.vim | 54 +++++++++++++ runtime/indent/stylus.vim | 121 +++++++++++++++++++++++++++++ runtime/lua/vim/filetype.lua | 2 + runtime/syntax/stylus.vim | 61 +++++++++++++++ test/old/testdir/test_filetype.vim | 1 + 5 files changed, 239 insertions(+) create mode 100644 runtime/ftplugin/stylus.vim create mode 100644 runtime/indent/stylus.vim create mode 100644 runtime/syntax/stylus.vim diff --git a/runtime/ftplugin/stylus.vim b/runtime/ftplugin/stylus.vim new file mode 100644 index 00000000000000..1c5f14eebe4e02 --- /dev/null +++ b/runtime/ftplugin/stylus.vim @@ -0,0 +1,54 @@ +" Vim filetype plugin +" Language: Stylus +" Maintainer: Marc Harter +" Credits: Tim Pope + +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") + finish +endif + +let s:save_cpo = &cpo +set cpo-=C + +" Define some defaults in case the included ftplugins don't set them. +let s:undo_ftplugin = "" +let s:browsefilter = "All Files (*.*)\t*.*\n" + +runtime! ftplugin/html.vim ftplugin/html_*.vim ftplugin/html/*.vim +unlet! b:did_ftplugin + +" Override our defaults if these were set by an included ftplugin. +if exists("b:undo_ftplugin") + let s:undo_ftplugin = b:undo_ftplugin + unlet b:undo_ftplugin +endif +if exists("b:browsefilter") + let s:browsefilter = b:browsefilter + unlet b:browsefilter +endif + +" Change the browse dialog on Win32 to show mainly Styl-related files +if has("gui_win32") + let b:browsefilter="Stylus Files (*.styl)\t*.styl\n" . s:browsefilter +endif + +setlocal comments= commentstring=//\ %s +setlocal suffixesadd=.styl +setlocal formatoptions+=r + +" Add '-' and '#' to the what makes up a keyword. +" This means that 'e' and 'w' work properly now, for properties +" and valid variable names. +setl iskeyword+=#,- + +" Add a Stylus command (to see if it's valid) +command -buffer Stylus !clear; cat % |stylus + + +let b:undo_ftplugin = "setl sua< isk< cms< com< fo< " + \ " | unlet! b:browsefilter b:match_words | " . s:undo_ftplugin + +let &cpo = s:save_cpo + +" vim:set sw=2: diff --git a/runtime/indent/stylus.vim b/runtime/indent/stylus.vim new file mode 100644 index 00000000000000..89634f0914a815 --- /dev/null +++ b/runtime/indent/stylus.vim @@ -0,0 +1,121 @@ +" Vim indent file +" Language: Stylus +" Maintainer: Marc Harter +" Last Change: 2010 May 21 +" Based On: sass.vim from Tim Pope +" +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetStylusIndent() +setlocal indentkeys=o,O,*,},],0),!^F +let b:undo_indent = "setl indentexpr< indentkeys<" + +if exists("*GetStylusIndent") " only define once + finish +endif + +function s:prevnonblanknoncomment(lnum) + let lnum = a:lnum + while lnum > 1 + let lnum = prevnonblank(lnum) + let line = getline(lnum) + if line =~ '\*/' + while lnum > 1 && line !~ '/\*' + let lnum -= 1 + endwhile + if line =~ '^\s*/\*' + let lnum -= 1 + else + break + endif + else + break + endif + endwhile + return lnum +endfunction + +function s:count_braces(lnum, count_open) + let n_open = 0 + let n_close = 0 + let line = getline(a:lnum) + let pattern = '[{}]' + let i = match(line, pattern) + while i != -1 + if synIDattr(synID(a:lnum, i + 1, 0), 'name') !~ 'css\%(Comment\|StringQ\{1,2}\)' + if line[i] == '{' + let n_open += 1 + elseif line[i] == '}' + if n_open > 0 + let n_open -= 1 + else + let n_close += 1 + endif + endif + endif + let i = match(line, pattern, i + 1) + endwhile + return a:count_open ? n_open : n_close +endfunction + +" function CheckCSSIndent() +" let line = getline(v:lnum) +" if line =~ '^\s*\*' +" return cindent(v:lnum) +" endif +" +" let pnum = s:prevnonblanknoncomment(v:lnum - 1) +" if pnum == 0 +" return 0 +" endif + +function! GetStylusIndent() + let line = getline(v:lnum) + if line =~ '^\s*\*' + return cindent(v:lnum) + endif + + let pnum = s:prevnonblanknoncomment(v:lnum - 1) + if pnum == 0 + return 0 + endif + + let lnum = prevnonblank(v:lnum-1) + if lnum == 0 + return 0 + endif + + let pline = getline(pnum) + + if pline =~ '[}{]' + return indent(pnum) + s:count_braces(pnum, 1) * &sw - s:count_braces(v:lnum, 0) * &sw + endif + + let line = substitute(getline(lnum),'[\s()]\+$','','') " get last line strip ending whitespace + let cline = substitute(substitute(getline(v:lnum),'\s\+$','',''),'^\s\+','','') " get current line, trimmed + let lastcol = strlen(line) " get last col in prev line + let line = substitute(line,'^\s\+','','') " then remove preceeding whitespace + let indent = indent(lnum) " get indent on prev line + let cindent = indent(v:lnum) " get indent on current line + let increase = indent + &sw " increase indent by the shift width + if indent == indent(lnum) + let indent = cindent <= indent ? indent : increase + endif + + let group = synIDattr(synID(lnum,lastcol,1),'name') + + " if group !~? 'css.*' && line =~? ')\s*$' " match user functions + " return increase + if group =~? '\v^%(cssTagName|cssClassName|cssIdentifier|cssSelectorOp|cssSelectorOp2|cssBraces|cssAttributeSelector|cssPseudo|stylusId|stylusClass)$' + return increase + elseif (group == 'stylusUserFunction') && (indent(lnum) == '0') " mixin definition + return increase + else + return indent + endif +endfunction + +" vim:set sw=2; diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 3cb634256bcbcb..77b3d29d011917 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1015,6 +1015,8 @@ local extension = { mata = 'stata', ado = 'stata', stp = 'stp', + styl = 'stylus', + stylus = 'stylus', quark = 'supercollider', sface = 'surface', svelte = 'svelte', diff --git a/runtime/syntax/stylus.vim b/runtime/syntax/stylus.vim new file mode 100644 index 00000000000000..fd0f33b65a9f51 --- /dev/null +++ b/runtime/syntax/stylus.vim @@ -0,0 +1,61 @@ +" Vim syntax file +" Language: Stylus +" Maintainer: Hsiaoming Yang , Marc Harter +" Filenames: *.styl, *.stylus +" Based On: Tim Pope (sass.vim) +" Created: Dec 14, 2011 +" Modified: Apr 29, 2024 + +if main_syntax == "css" + syn sync minlines=10 +endif + +" let b:current_syntax = "css" +" +if main_syntax == 'css' + unlet main_syntax +endif + +syn case ignore + +syn cluster stylusCssSelectors contains=cssTagName,cssSelector,cssPseudo +syn cluster stylusCssValues contains=cssValueLength,cssValueInteger,cssValueNumber,cssValueAngle,cssValueTime,cssValueFrequency,cssColorVal,cssCommonVal,cssFontVal,cssListVal,cssTextVal,cssVisualVal,cssBorderVal,cssBackgroundVal,cssFuncVal,cssAdvancedVal +syn cluster stylusCssProperties contains=cssProp,cssBackgroundProp,cssTableProp,cssBorderProp,cssFontProp,cssColorProp,cssBoxProp,cssTextProp,cssListProp,cssVisualProp,cssAdvancedProp,cssCommonProp,cssSpecialProp + +syn match stylusVariable "$\?[[:alnum:]_-]\+" +syn match stylusVariableAssignment "\%([[:alnum:]_-]\+\s*\)\@<==" nextgroup=stylusCssAttribute,stylusVariable skipwhite + +syn match stylusProperty "\%([{};]\s*\|^\)\@<=\%([[:alnum:]-]\|#{[^{}]*}\)\+:" contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute contained containedin=cssDefineBlock +syn match stylusProperty "^\s*\zs\s\%(\%([[:alnum:]-]\|#{[^{}]*}\)\+[ :]\|:[[:alnum:]-]\+\)"hs=s+1 contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute +syn match stylusProperty "^\s*\zs\s\%(:\=[[:alnum:]-]\+\s*=\)"hs=s+1 contains=@stylusCssProperties,@stylusCssSelectors skipwhite nextgroup=stylusCssAttribute + +syn match stylusCssAttribute +\%("\%([^"]\|\\"\)*"\|'\%([^']\|\\'\)*'\|#{[^{}]*}\|[^{};]\)*+ contained contains=@stylusCssValues,cssImportant,stylusFunction,stylusVariable,stylusControl,stylusUserFunction,stylusInterpolation,cssString,stylusComment,cssComment + +syn match stylusInterpolation %{[[:alnum:]_-]\+}% + +syn match stylusFunction "\<\%(red\|green\|blue\|alpha\|dark\|light\)\>(\@=" contained +syn match stylusFunction "\<\%(hue\|saturation\|lightness\|push\|unshift\|typeof\|unit\|match\)\>(\@=" contained +syn match stylusFunction "\<\%(hsla\|hsl\|rgba\|rgb\|lighten\|darken\)\>(\@=" contained +syn match stylusFunction "\<\%(abs\|ceil\|floor\|round\|min\|max\|even\|odd\|sum\|avg\|sin\|cos\|join\)\>(\@=" contained +syn match stylusFunction "\<\%(desaturate\|saturate\|invert\|unquote\|quote\|s\)\>(\@=" contained +syn match stylusFunction "\<\%(operate\|length\|warn\|error\|last\|p\|\)\>(\@=" contained +syn match stylusFunction "\<\%(opposite-position\|image-size\|add-property\)\>(\@=" contained + +syn keyword stylusVariable null true false arguments +syn keyword stylusControl if else unless for in return + +syn match stylusImport "@\%(import\|require\)" nextgroup=stylusImportList +syn match stylusImportList "[^;]\+" contained contains=cssString.*,cssMediaType,cssURL + +syn match stylusAmpersand "&" +syn match stylusClass "[[:alnum:]_-]\+" contained +syn match stylusClassChar "\.[[:alnum:]_-]\@=" nextgroup=stylusClass +syn match stylusEscape "^\s*\zs\\" +syn match stylusId "[[:alnum:]_-]\+" contained +syn match stylusIdChar "#[[:alnum:]_-]\@=" nextgroup=stylusId + +syn region stylusComment start="//" end="$" contains=cssTodo,@Spell fold + +let b:current_syntax = "stylus" + +" vim:set sw=2: diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 6a8482d4ace409..893c5d382d76f4 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -687,6 +687,7 @@ func s:GetFilenameChecks() abort \ 'starlark': ['file.ipd', 'file.star', 'file.starlark'], \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'], \ 'stp': ['file.stp'], + \ 'stylus': ['a.styl', 'file.stylus'], \ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'], \ 'supercollider': ['file.quark'], \ 'surface': ['file.sface'],