vim-patch:9.1.1821: filetype: Not all PKL files are recognized (#36008)

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: vim/vim#18271
closes: vim/vim#18274

67a8f2945e

Co-authored-by: Jan Claußen <jan.claussen10@web.de>
This commit is contained in:
zeertzjq
2025-10-04 06:01:16 +08:00
committed by GitHub
parent 8151fc59cf
commit 2c76a50e20
4 changed files with 176 additions and 3 deletions

View File

@@ -2,13 +2,15 @@
" Language: Pkl " Language: Pkl
" Maintainer: Riley Bruins <ribru17@gmail.com> " Maintainer: Riley Bruins <ribru17@gmail.com>
" Last Change: 2025 Jul 14 " Last Change: 2025 Jul 14
" 2025 Oct 03 by Vim Project Add foldmethod #18274
if exists('b:did_ftplugin') if exists('b:did_ftplugin')
finish finish
endif endif
let b:did_ftplugin = 1 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 commentstring=//\ %s
setlocal foldmethod=syntax
let b:undo_ftplugin = 'setl com< cms<' let b:undo_ftplugin = 'setl com< cms< fdm<'

View File

@@ -949,6 +949,7 @@ local extension = {
pmod = 'pike', pmod = 'pike',
rcp = 'pilrc', rcp = 'pilrc',
pkl = 'pkl', pkl = 'pkl',
pcf = 'pkl',
PL = detect.pl, PL = detect.pl,
pli = 'pli', pli = 'pli',
pl1 = 'pli', pl1 = 'pli',
@@ -2683,6 +2684,7 @@ local pattern = {
['^pacman%.log'] = starsetf(function(path, _bufnr) ['^pacman%.log'] = starsetf(function(path, _bufnr)
return vim.uv.fs_stat(path) and 'pacmanlog' or nil return vim.uv.fs_stat(path) and 'pacmanlog' or nil
end), end),
['^pkl%-lsp://'] = 'pkl',
['printcap'] = starsetf(function(_path, _bufnr) ['printcap'] = starsetf(function(_path, _bufnr)
return require('vim.filetype.detect').printcap('print') return require('vim.filetype.detect').printcap('print')
end), end),

169
runtime/syntax/pkl.vim Normal file
View File

@@ -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

View File

@@ -612,7 +612,7 @@ func s:GetFilenameChecks() abort
\ 'pilrc': ['file.rcp'], \ 'pilrc': ['file.rcp'],
\ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'], \ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'],
\ 'pinfo': ['/etc/pinforc', '/.pinforc', 'any/.pinforc', 'any/etc/pinforc'], \ 'pinfo': ['/etc/pinforc', '/.pinforc', 'any/.pinforc', 'any/etc/pinforc'],
\ 'pkl': ['file.pkl'], \ 'pkl': ['file.pkl', 'file.pcf'],
\ 'pli': ['file.pli', 'file.pl1'], \ 'pli': ['file.pli', 'file.pl1'],
\ 'plm': ['file.plm', 'file.p36', 'file.pac'], \ 'plm': ['file.plm', 'file.p36', 'file.pac'],
\ 'plp': ['file.plp'], \ 'plp': ['file.plp'],