]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1821: filetype: Not all PKL files are recognized v9.1.1821
authorJan Claußen <jan.claussen10@web.de>
Fri, 3 Oct 2025 08:41:32 +0000 (08:41 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 3 Oct 2025 08:47:07 +0000 (08:47 +0000)
Problem:  filetype: Not all PKL files are recognized
Solution: Detect *.pcf as pkl filetype, detect using the pkl-lsp://
          protocol as pkl filetype, include PKL syntax script
          (Jan Claußen)

This adds basic syntax support for the new PKL language by Apple.

What works:
- Shebang support
- Comment support
- Integers (decimal, hex, octal and binary) support
- Floating point support including exponentials
- Basic datatype support
- Unicode escape delimiters
- Escape code support
- String interpolation
- Support up to five pounds for custom delimiters
- Folding of multi-line comments and blocks

What doesn't work:

  The language heavily uses parameterized type declarations, which can get
  very complex. It is very hard to highlight this properly. There is
  official Tree-sitter support for this. Since it is hard to pull this off
  in a vim syntax file, I opted for basic support of the data types.

References:
  https://github.com/apple/pkl-pantry

fixes: #18271
closes: #18274

Signed-off-by: Jan Claußen <jan.claussen10@web.de>
Signed-off-by: Christian Brabandt <cb@256bit.org>
.github/MAINTAINERS
runtime/filetype.vim
runtime/ftplugin/pkl.vim
runtime/syntax/pkl.vim [new file with mode: 0644]
src/testdir/test_filetype.vim
src/version.c

index 0bcacc9e5455148bd66560a642c9fe28e1798f85..f76fca089a892063762a2390ef79a0109fd50c85 100644 (file)
@@ -585,6 +585,7 @@ runtime/syntax/pbtxt.vim                            @lakshayg
 runtime/syntax/pdf.vim                                 @tpope
 runtime/syntax/perl.vim                                        @petdance
 runtime/syntax/php.vim                                 @TysonAndre
+runtime/syntax/pkl.vim                                 @jclsn
 runtime/syntax/plsql.vim                               @lee-lindley
 runtime/syntax/pod.vim                                 @petdance
 runtime/syntax/poefilter.vim                           @ObserverOfTime
index ede8dd47b871c52b967e991dc0d682cdb78a1699..662c3deac3505bb5ddc519ed883ccb72e2e06dc4 100644 (file)
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:          The Vim Project <https://github.com/vim/vim>
-" Last Change:         2025 Sep 14
+" Last Change:         2025 Oct 03
 " Former Maintainer:   Bram Moolenaar <Bram@vim.org>
 
 " Listen very carefully, I will say this only once
@@ -1971,7 +1971,7 @@ au BufNewFile,BufRead Pipfile.lock                setf json
 au BufNewFile,BufRead pixi.lock                        setf yaml
 
 " Pkl
-au BufNewFile,BufRead *.pkl                    setf pkl
+au BufNewFile,BufRead *.pkl,*.pcf,pkl-lsp://*  setf pkl
 
 " PL/1, PL/I
 au BufNewFile,BufRead *.pli,*.pl1              setf pli
index 52cf6b8b4486a92f7a9b59a403ee9d5b01ffcdf7..128af1ec924a19f73655c83533a61b6690d04be9 100644 (file)
@@ -2,13 +2,15 @@
 " Language:    Pkl
 " Maintainer:  Riley Bruins <ribru17@gmail.com>
 " Last Change: 2025 Jul 14
+" 2025 Oct 03 by Vim Project Add foldmethod #18274
 
 if exists('b:did_ftplugin')
   finish
 endif
 let b:did_ftplugin = 1
 
-setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,:///,://
 setlocal commentstring=//\ %s
+setlocal foldmethod=syntax
 
-let b:undo_ftplugin = 'setl com< cms<'
+let b:undo_ftplugin = 'setl com< cms< fdm<'
diff --git a/runtime/syntax/pkl.vim b/runtime/syntax/pkl.vim
new file mode 100644 (file)
index 0000000..3565082
--- /dev/null
@@ -0,0 +1,169 @@
+" Vim syntax file
+" Language:            PKL
+" Maintainer:          Jan Claußen <jan DOT claussen10 AT web DOT de>
+" Last Change:         2025 Sep 24
+
+if exists("b:current_syntax")
+  finish
+endif
+
+" We use line-continuation here
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Needed to properly highlight multiline strings
+syn sync fromstart
+
+" PKL supports non-Unicode identifiers. So we modify the keyword character
+" class to include them
+syn iskeyword @,48-57,192-255,$,_
+
+" Declare a variable for identifiers
+let s:id  = '\%(\K\+\d*[_$]*\K*\d*[_$]*\)'
+
+" --- Decorator ---
+exe $'syn match        pklDecorator     "@{s:id}\{{1,}}"'
+
+" --- Comments ---
+syn match      pklComment      "\/\{2}.*"
+syn match      pklDocComment   "\/\{3}.*"
+syn region     pklMultiComment start="\/\*" end="\*\/" keepend fold
+
+" --- Strings ---
+syn region     pklString       start=+"+ end=+"+ contains=pklEscape,pklUnicodeEscape,pklStringInterpolation oneline
+syn region     pklMultiString  start=+"""+ skip=+\\."+ end=+"""+ contains=pklEscape,pklUnicodeEscape keepend fold
+syn match      pklEscape       "\\[\\nt0rbaeuf"']" contained containedin=pklString,pklMultiString
+syn match      pklUnicode      "[0-9A-Fa-f]\+" contained
+
+" --- String interpolation ---
+" Standard interpolation
+syn region     pklStringInterpolation matchgroup=pklDelimiter
+         \ start=+\\(+ end=+)+ contains=pklNumbers,pklOperator,pklIdentifier,pklFunction,pklParen,pklString
+         \ contained containedin=pklString,pklMultiString oneline
+" Unicode escape sequences
+syn region     pklUnicodeEscape matchgroup=pklDelimiter
+         \ start=+\\u{+ end=+}+ contains=pklUnicode
+         \ contained containedin=pklString,pklMultiString
+
+" --- Basic data types ---
+syn keyword    pklType
+         \ UInt UInt8 UInt16 UInt32 UInt64 UInt128
+         \ Int Int8 Int16 Int32 Int64 Int128
+         \ Float
+         \ Number
+         \ String
+         \ Boolean
+         \ Null
+         \ Any
+
+syn keyword    pklCollections
+         \ Map Mapping
+         \ List Listing
+         \ Set
+
+" --- Custom string delimiters ---
+function! s:DefineCustomStringDelimiters(n)
+  for x in range(1, a:n)
+    exe $'syn region pklString{x}Pound start=+{repeat("#", x)}"+ end=+"{repeat("#", x)}+ contains=pklStringInterpolation{x}Pound,pklEscape{x}Pound oneline'
+    exe $'hi def link pklString{x}Pound String'
+
+    exe $'syn region pklMultiString{x}Pound start=+{repeat("#", x)}"""+ end=+"""{repeat("#", x)}+ contains=pklStringInterpolation{x}Pound,pklEscape{x}Pound keepend fold'
+    exe $'hi def link pklMultiString{x}Pound String'
+
+    exe $'syn match pklEscape{x}Pound "\\{repeat("#", x) }[\\nt0rbaeuf"'']" contained containedin=pklString{x}Pound,pklMultiString{x}Pound'
+    exe $'hi def link pklEscape{x}Pound SpecialChar'
+
+    exe $'syn region pklStringInterpolation{x}Pound matchgroup=pklDelimiter start=+\\{repeat("#", x)}(+ end=+)+ contains=pklNumbers,pklOperator,pklIdentifier,pklFunction,pklParen,pklString contained containedin=pklString{x}Pound,pklMultiString{x}Pound oneline'
+
+    exe $'syn region pklUnicodeEscape{x}Pound matchgroup=pklDelimiter start=+\\{repeat("#", x)}u{{+ end=+}}+ contains=pklUnicode contained containedin=pklString{x}Pound,pklMultiString{x}Pound'
+    exe $'hi def link pklUnicodeEscape{x}Pound SpecialChar'
+  endfor
+endfunction
+
+call s:DefineCustomStringDelimiters(5)
+
+" --- Keywords ---
+syn keyword    pklBoolean       false true
+syn keyword    pklClass         outer super this module new
+syn keyword    pklConditional   if else when
+syn keyword    pklConstant      null NaN Infinity
+syn keyword    pklException     throw
+syn keyword    pklInclude       amends import extends as
+syn keyword    pklKeyword       function let out is
+syn keyword    pklModifier      abstract const external fixed hidden local open
+syn keyword    pklReserved      case delete override protected record switch vararg
+syn keyword    pklRepeat        for in
+syn keyword    pklSpecial       nothing unknown
+syn keyword    pklStatement     trace read
+syn keyword    pklStruct        typealias class
+
+" Include all unicode letters
+exe $'syn match pklIdentifier "{s:id}"'
+
+" Explicitely make keywords identifiers with backticks
+syn region     pklIdentifierExplicit   start=+`+ end=+`+
+
+syn match      pklOperator      ",\||\|+\|*\|->\|?\|-\|==\|=\|!=\|!" contained containedin=pklType
+
+" --- Numbers ---
+" decimal numbers
+syn match      pklNumbers      display transparent "\<\d\|\.\d" contains=pklNumber,pklFloat,pklOctal
+syn match      pklNumber       display contained "\d\%(\d\+\)*\>"
+" hex numbers
+syn match      pklNumber       display contained "0x\x\%('\=\x\+\)\>"
+" binary numbers
+syn match      pklNumber       display contained "0b[01]\%('\=[01]\+\)\>"
+" octal numbers
+syn match      pklOctal        display contained "0o\o\+\>"
+
+"floating point number, with dot, optional exponent
+syn match      pklFloat        display contained "\d\+\.\d\+\%(e[-+]\=\d\+\)\="
+"floating point number, starting with a dot, optional exponent
+syn match      pklFloat        display contained "\.\d\+\%(e[-+]\=\d\+\)\=\>"
+"floating point number, without dot, with exponent
+syn match      pklFloat        display contained "\d\+e[-+]\=\d\+\>"
+
+" --- Brackets, operators, functions ---
+syn region     pklParen        matchgroup=pklBrackets start='(' end=')' contains=ALLBUT,pklUnicode transparent
+syn region     pklBracket      matchgroup=pklBrackets start='\[\|<::\@!' end=']\|:>' contains=ALLBUT,pklUnicode transparent
+syn region     pklBlock        matchgroup=pklBrackets start="{" end="}" contains=ALLBUT,pklUnicode fold transparent
+
+exe $'syn match        pklFunction     "\<\h{s:id}*\>\ze\_s*[?|\*]\?(" contains=pklType'
+
+" --- Highlight links ---
+hi def link    pklBoolean                       Boolean
+hi def link    pklBrackets                      Delimiter
+hi def link    pklClass                         Statement
+hi def link    pklCollections                   Type
+hi def link    pklComment                       Comment
+hi def link    pklConditional                   Conditional
+hi def link    pklConstant                      Constant
+hi def link    pklDecorator                     Special
+hi def link    pklDelimiter                     Delimiter
+hi def link    pklDocComment                    Comment
+hi def link    pklEscape                        SpecialChar
+hi def link    pklException                     Exception
+hi def link    pklFloat                         Number
+hi def link    pklFunction                      Function
+hi def link    pklInclude                       Include
+hi def link    pklKeyword                       Keyword
+hi def link    pklModifier                      StorageClass
+hi def link    pklMultiComment                  Comment
+hi def link    pklMultiString                   String
+hi def link    pklNumber                        Number
+hi def link    pklNumbers                       Number
+hi def link    pklOctal                         Number
+hi def link    pklRepeat                        Repeat
+hi def link    pklReserved                      Error
+hi def link    pklShebang                       Comment
+hi def link    pklSpecial                       Special
+hi def link    pklStatement                     Statement
+hi def link    pklString                        String
+hi def link    pklStruct                        Structure
+hi def link    pklType                          Type
+hi def link    pklUnicodeEscape                 SpecialChar
+
+let b:current_syntax = "pkl"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
index 91bdffda51163cf0b9b79f0314cb7f4d893adc12..19dd807822b32c6a66b9016d523761bf612d5c84 100644 (file)
@@ -615,7 +615,7 @@ def s:GetFilenameChecks(): dict<list<string>>
     pilrc: ['file.rcp'],
     pine: ['.pinerc', 'pinerc', '.pinercex', 'pinercex'],
     pinfo: ['/etc/pinforc', '/.pinforc', 'any/.pinforc', 'any/etc/pinforc'],
-    pkl: ['file.pkl'],
+    pkl: ['file.pkl', 'file.pcf'],
     pli: ['file.pli', 'file.pl1'],
     plm: ['file.plm', 'file.p36', 'file.pac'],
     plp: ['file.plp'],
index 773c66b1b63de87c1929b0981fb31b195d252df4..eef97100c73cb796ee2c49d6205566e74fe807d6 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1821,
 /**/
     1820,
 /**/