aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/dist/ft.vim71
-rw-r--r--runtime/doc/filetype.txt2
-rw-r--r--runtime/filetype.vim34
-rw-r--r--runtime/lua/vim/filetype.lua7
-rw-r--r--src/nvim/testdir/test_filetype.vim191
5 files changed, 276 insertions, 29 deletions
diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim
index f473d5f80b..0063e9da0b 100644
--- a/runtime/autoload/dist/ft.vim
+++ b/runtime/autoload/dist/ft.vim
@@ -112,6 +112,25 @@ func dist#ft#BindzoneCheck(default)
endif
endfunc
+" Returns true if file content looks like RAPID
+func IsRapid(sChkExt = "")
+ if a:sChkExt == "cfg"
+ return getline(1) =~? '\v^%(EIO|MMC|MOC|PROC|SIO|SYS):CFG'
+ endif
+ " called from FTmod, FTprg or FTsys
+ return getline(nextnonblank(1)) =~? '\v^\s*%(\%{3}|module\s+\k+\s*%(\(|$))'
+endfunc
+
+func dist#ft#FTcfg()
+ if exists("g:filetype_cfg")
+ exe "setf " .. g:filetype_cfg
+ elseif IsRapid("cfg")
+ setf rapid
+ else
+ setf cfg
+ endif
+endfunc
+
func dist#ft#FTlpc()
if exists("g:lpc_syntax_for_c")
let lnum = 1
@@ -173,7 +192,7 @@ endfunc
func dist#ft#FTent()
" This function checks for valid cl syntax in the first five lines.
- " Look for either an opening comment, '#', or a block start, '{".
+ " Look for either an opening comment, '#', or a block start, '{'.
" If not found, assume SGML.
let lnum = 1
while lnum < 6
@@ -415,6 +434,36 @@ func dist#ft#FTmm()
setf nroff
endfunc
+" Returns true if file content looks like LambdaProlog
+func IsLProlog()
+ " skip apparent comments and blank lines, what looks like
+ " LambdaProlog comment may be RAPID header
+ let l = nextnonblank(1)
+ while l > 0 && l < line('$') && getline(l) =~ '^\s*%' " LambdaProlog comment
+ let l = nextnonblank(l + 1)
+ endwhile
+ " this pattern must not catch a go.mod file
+ return getline(l) =~ '\<module\s\+\w\+\s*\.\s*\(%\|$\)'
+endfunc
+
+" Determine if *.mod is ABB RAPID, LambdaProlog, Modula-2, Modsim III or go.mod
+func dist#ft#FTmod()
+ if exists("g:filetype_mod")
+ exe "setf " .. g:filetype_mod
+ elseif IsLProlog()
+ setf lprolog
+ elseif getline(nextnonblank(1)) =~ '\%(\<MODULE\s\+\w\+\s*;\|^\s*(\*\)'
+ setf modula2
+ elseif IsRapid()
+ setf rapid
+ elseif expand("<afile>") =~ '\<go.mod$'
+ setf gomod
+ else
+ " Nothing recognized, assume modsim3
+ setf modsim3
+ endif
+endfunc
+
func dist#ft#FTpl()
if exists("g:filetype_pl")
exe "setf " . g:filetype_pl
@@ -531,6 +580,18 @@ func dist#ft#FTpp()
endif
endfunc
+" Determine if *.prg is ABB RAPID. Can also be Clipper, FoxPro or eviews
+func dist#ft#FTprg()
+ if exists("g:filetype_prg")
+ exe "setf " .. g:filetype_prg
+ elseif IsRapid()
+ setf rapid
+ else
+ " Nothing recognized, assume Clipper
+ setf clipper
+ endif
+endfunc
+
func dist#ft#FTr()
let max = line("$") > 50 ? 50 : line("$")
@@ -739,6 +800,14 @@ func dist#ft#FTperl()
return 0
endfunc
+func dist#ft#FTsys()
+ if IsRapid()
+ setf rapid
+ else
+ setf bat
+ endif
+endfunc
+
" Choose context, plaintex, or tex (LaTeX) based on these rules:
" 1. Check the first line of the file for "%&<format>".
" 2. Check the first 1000 non-comment lines for LaTeX or ConTeXt keywords.
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index 357c5d1cec..5f7c1b57f8 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -140,12 +140,14 @@ variables can be used to overrule the filetype used for certain extensions:
*.asm g:asmsyntax |ft-asm-syntax|
*.asp g:filetype_asp |ft-aspvbs-syntax| |ft-aspperl-syntax|
*.bas g:filetype_bas |ft-basic-syntax|
+ *.cfg g:filetype_cfg
*.dat g:filetype_dat
*.frm g:filetype_frm |ft-form-syntax|
*.fs g:filetype_fs |ft-forth-syntax|
*.i g:filetype_i |ft-progress-syntax|
*.inc g:filetype_inc
*.m g:filetype_m |ft-mathematica-syntax|
+ *.mod g:filetype_mod
*.p g:filetype_p |ft-pascal-syntax|
*.pl g:filetype_pl
*.pp g:filetype_pp |ft-pascal-syntax|
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 255414aca6..e0d24d73c8 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -201,11 +201,13 @@ au BufNewFile,BufRead *.iba,*.ibi setf ibasic
" FreeBasic file (similar to QBasic)
au BufNewFile,BufRead *.fb setf freebasic
-" Batch file for MSDOS.
-au BufNewFile,BufRead *.bat,*.sys setf dosbatch
+" Batch file for MSDOS. See dist#ft#FTsys for *.sys
+au BufNewFile,BufRead *.bat setf dosbatch
" *.cmd is close to a Batch file, but on OS/2 Rexx files also use *.cmd.
au BufNewFile,BufRead *.cmd
\ if getline(1) =~ '^/\*' | setf rexx | else | setf dosbatch | endif
+" ABB RAPID or Batch file for MSDOS.
+au BufNewFile,BufRead *.sys\c call dist#ft#FTsys()
" Batch file for 4DOS
au BufNewFile,BufRead *.btm call dist#ft#FTbtm()
@@ -356,13 +358,8 @@ au BufNewFile,BufRead *.eni setf cl
" Clever or dtd
au BufNewFile,BufRead *.ent call dist#ft#FTent()
-" Clipper (or FoxPro; could also be eviews)
-au BufNewFile,BufRead *.prg
- \ if exists("g:filetype_prg") |
- \ exe "setf " . g:filetype_prg |
- \ else |
- \ setf clipper |
- \ endif
+" Clipper, FoxPro, ABB RAPID or eviews
+au BufNewFile,BufRead *.prg\c call dist#ft#FTprg()
" Clojure
au BufNewFile,BufRead *.clj,*.cljs,*.cljx,*.cljc setf clojure
@@ -440,7 +437,7 @@ au BufNewFile,BufRead *quake[1-3]/*.cfg setf quake
au BufNewFile,BufRead *.qc setf c
" Configure files
-au BufNewFile,BufRead *.cfg setf cfg
+au BufNewFile,BufRead *.cfg\c call dist#ft#FTcfg()
" Cucumber
au BufNewFile,BufRead *.feature setf cucumber
@@ -976,7 +973,7 @@ au BufNewFile,BufRead *.latte,*.lte setf latte
" Limits
au BufNewFile,BufRead */etc/limits,*/etc/*limits.conf,*/etc/*limits.d/*.conf setf limits
-" LambdaProlog (*.mod too, see Modsim)
+" LambdaProlog (see dist#ft#FTmod for *.mod)
au BufNewFile,BufRead *.sig setf lprolog
" LDAP LDIF
@@ -1139,18 +1136,11 @@ au BufNewFile,BufRead *.mms call dist#ft#FTmms()
" Symbian meta-makefile definition (MMP)
au BufNewFile,BufRead *.mmp setf mmp
-" Modsim III (or LambdaProlog)
-au BufNewFile,BufRead *.mod
- \ if expand("<afile>") =~ '\<go.mod$' |
- \ setf gomod |
- \ elseif getline(1) =~ '\<module\>' |
- \ setf lprolog |
- \ else |
- \ setf modsim3 |
- \ endif
+" ABB Rapid, Modula-2, Modsim III or LambdaProlog
+au BufNewFile,BufRead *.mod\c call dist#ft#FTmod()
-" Modula-2 (.md removed in favor of Markdown)
-au BufNewFile,BufRead *.m2,*.DEF,*.MOD,*.mi setf modula2
+" Modula-2 (.md removed in favor of Markdown, see dist#ft#FTmod for *.MOD)
+au BufNewFile,BufRead *.m2,*.DEF,*.mi setf modula2
" Modula-3 (.m3, .i3, .mg, .ig)
au BufNewFile,BufRead *.[mi][3g] setf modula3
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 7958de97b1..9397788e9e 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -79,7 +79,6 @@ local extension = {
cfc = "cf",
cfm = "cf",
cfi = "cf",
- cfg = "cfg",
hgrc = "cfg",
chf = "ch",
chai = "chaiscript",
@@ -158,7 +157,6 @@ local extension = {
diff = "diff",
rej = "diff",
Dockerfile = "dockerfile",
- sys = "dosbatch",
bat = "dosbatch",
wrap = "dosini",
ini = "dosini",
@@ -395,7 +393,6 @@ local extension = {
mmp = "mmp",
DEF = "modula2",
["m2"] = "modula2",
- MOD = "modula2",
mi = "modula2",
ssc = "monk",
monk = "monk",
@@ -1429,9 +1426,13 @@ local pattern = {
return "git"
end
end,
+ [".*%.[Cc][Ff][Gg]"] = function() vim.fn["dist#ft#FTcfg"]() end,
[".*%.[Dd][Aa][Tt]"] = function() vim.fn["dist#ft#FTdat"]() end,
+ [".*%.[Mm][Oo][Dd]"] = function() vim.fn["dist#ft#FTmod"]() end,
[".*%.[Ss][Rr][Cc]"] = function() vim.fn["dist#ft#FTsrc"]() end,
[".*%.[Ss][Uu][Bb]"] = "krl",
+ [".*%.[Pp][Rr][Gg]"] = function() vim.fn["dist#ft#FTprg"]() end,
+ [".*%.[Ss][Yy][Ss]"] = function() vim.fn["dist#ft#FTsys"]() end,
-- Neovim only
[".*/queries/.*%.scm"] = "query", -- tree-sitter queries
-- END PATTERN
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 9feab735e4..1f76063aed 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -99,7 +99,7 @@ let s:filename_checks = {
\ 'cdrtoc': ['file.toc'],
\ 'cf': ['file.cfm', 'file.cfi', 'file.cfc'],
\ 'cfengine': ['cfengine.conf'],
- \ 'cfg': ['file.cfg', 'file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'],
+ \ 'cfg': ['file.hgrc', 'filehgrc', 'hgrc', 'some-hgrc'],
\ 'ch': ['file.chf'],
\ 'chaiscript': ['file.chai'],
\ 'chaskell': ['file.chs'],
@@ -150,7 +150,7 @@ let s:filename_checks = {
\ 'dircolors': ['.dir_colors', '.dircolors', '/etc/DIR_COLORS', 'any/etc/DIR_COLORS'],
\ 'dnsmasq': ['/etc/dnsmasq.conf', '/etc/dnsmasq.d/file', 'any/etc/dnsmasq.conf', 'any/etc/dnsmasq.d/file'],
\ 'dockerfile': ['Containerfile', 'Dockerfile', 'file.Dockerfile', 'Dockerfile.debian', 'Containerfile.something'],
- \ 'dosbatch': ['file.bat', 'file.sys'],
+ \ 'dosbatch': ['file.bat'],
\ 'dosini': ['.editorconfig', '/etc/pacman.conf', '/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file', '/etc/yum.repos.d/file', 'any/etc/pacman.conf', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap'],
\ 'dot': ['file.dot', 'file.gv'],
\ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe', 'drac.file', 'lpe', 'lvs', 'some-lpe', 'some-lvs'],
@@ -615,7 +615,7 @@ let s:filename_checks = {
\ }
let s:filename_case_checks = {
- \ 'modula2': ['file.DEF', 'file.MOD'],
+ \ 'modula2': ['file.DEF'],
\ 'bzl': ['file.BUILD', 'BUILD'],
\ }
@@ -807,6 +807,36 @@ func Test_bas_file()
filetype off
endfunc
+" Test dist#ft#FTcfg()
+func Test_cfg_file()
+ filetype on
+
+ " *.cfg defaults to cfg
+ call writefile(['looks like cfg'], 'cfgfile.cfg')
+ split cfgfile.cfg
+ call assert_equal('cfg', &filetype)
+
+ let g:filetype_cfg = 'other'
+ edit
+ call assert_equal('other', &filetype)
+ bwipe!
+ unlet g:filetype_cfg
+
+ " RAPID cfg
+ let ext = 'cfg'
+ for i in ['EIO', 'MMC', 'MOC', 'PROC', 'SIO', 'SYS']
+ call writefile([i .. ':CFG'], 'cfgfile.' .. ext)
+ execute "split cfgfile." .. ext
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('cfgfile.' .. ext)
+ " check different case of file extension
+ let ext = substitute(ext, '\(\l\)', '\u\1', '')
+ endfor
+
+ filetype off
+endfunc
+
func Test_d_file()
filetype on
@@ -1241,6 +1271,81 @@ func Test_m_file()
filetype off
endfunc
+func Test_mod_file()
+ filetype on
+
+ " *.mod defaults to Modsim III
+ call writefile(['locks like Modsim III'], 'modfile.mod')
+ split modfile.mod
+ call assert_equal('modsim3', &filetype)
+ bwipe!
+
+ " Users preference set by g:filetype_mod
+ let g:filetype_mod = 'lprolog'
+ split modfile.mod
+ call assert_equal('lprolog', &filetype)
+ unlet g:filetype_mod
+ bwipe!
+
+ " RAPID header start with a line containing only "%%%",
+ " but is not always present.
+ call writefile(['%%%'], 'modfile.mod')
+ split modfile.mod
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('modfile.mod')
+
+ " RAPID supports umlauts in module names, leading spaces,
+ " the .mod extension is not case sensitive.
+ call writefile([' module ÜmlautModule'], 'modfile.Mod')
+ split modfile.Mod
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('modfile.Mod')
+
+ " RAPID is not case sensitive, embedded spaces, sysmodule,
+ " file starts with empty line(s).
+ call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'modfile.MOD')
+ split modfile.MOD
+ call assert_equal('rapid', &filetype)
+ bwipe!
+
+ " Modula-2 MODULE not start of line
+ call writefile(['IMPLEMENTATION MODULE Module2Mod;'], 'modfile.MOD')
+ split modfile.MOD
+ call assert_equal('modula2', &filetype)
+ bwipe!
+
+ " Modula-2 with comment and empty lines prior MODULE
+ call writefile(['', '(* with', ' comment *)', '', 'MODULE Module2Mod;'], 'modfile.MOD')
+ split modfile.MOD
+ call assert_equal('modula2', &filetype)
+ bwipe!
+ call delete('modfile.MOD')
+
+ " LambdaProlog module
+ call writefile(['module lpromod.'], 'modfile.mod')
+ split modfile.mod
+ call assert_equal('lprolog', &filetype)
+ bwipe!
+
+ " LambdaProlog with comment and empty lines prior module
+ call writefile(['', '% with', '% comment', '', 'module lpromod.'], 'modfile.mod')
+ split modfile.mod
+ call assert_equal('lprolog', &filetype)
+ bwipe!
+ call delete('modfile.mod')
+
+ " go.mod
+ call writefile(['module example.com/M'], 'go.mod')
+ split go.mod
+ call assert_equal('gomod', &filetype)
+ bwipe!
+ call delete('go.mod')
+
+ filetype off
+endfunc
+
func Test_patch_file()
filetype on
@@ -1309,6 +1414,50 @@ func Test_pp_file()
filetype off
endfunc
+" Test dist#ft#FTprg()
+func Test_prg_file()
+ filetype on
+
+ " *.prg defaults to clipper
+ call writefile(['looks like clipper'], 'prgfile.prg')
+ split prgfile.prg
+ call assert_equal('clipper', &filetype)
+ bwipe!
+
+ " Users preference set by g:filetype_prg
+ let g:filetype_prg = 'eviews'
+ split prgfile.prg
+ call assert_equal('eviews', &filetype)
+ unlet g:filetype_prg
+ bwipe!
+
+ " RAPID header start with a line containing only "%%%",
+ " but is not always present.
+ call writefile(['%%%'], 'prgfile.prg')
+ split prgfile.prg
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('prgfile.prg')
+
+ " RAPID supports umlauts in module names, leading spaces,
+ " the .prg extension is not case sensitive.
+ call writefile([' module ÜmlautModule'], 'prgfile.Prg')
+ split prgfile.Prg
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('prgfile.Prg')
+
+ " RAPID is not case sensitive, embedded spaces, sysmodule,
+ " file starts with empty line(s).
+ call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'prgfile.PRG')
+ split prgfile.PRG
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('prgfile.PRG')
+
+ filetype off
+endfunc
+
func Test_src_file()
filetype on
@@ -1333,6 +1482,42 @@ func Test_src_file()
filetype off
endfunc
+func Test_sys_file()
+ filetype on
+
+ " *.sys defaults to Batch file for MSDOS
+ call writefile(['looks like dos batch'], 'sysfile.sys')
+ split sysfile.sys
+ call assert_equal('bat', &filetype)
+ bwipe!
+
+ " RAPID header start with a line containing only "%%%",
+ " but is not always present.
+ call writefile(['%%%'], 'sysfile.sys')
+ split sysfile.sys
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('sysfile.sys')
+
+ " RAPID supports umlauts in module names, leading spaces,
+ " the .sys extension is not case sensitive.
+ call writefile([' module ÜmlautModule'], 'sysfile.Sys')
+ split sysfile.Sys
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('sysfile.Sys')
+
+ " RAPID is not case sensitive, embedded spaces, sysmodule,
+ " file starts with empty line(s).
+ call writefile(['', 'MODULE rapidmödüle (SYSMODULE,NOSTEPIN)'], 'sysfile.SYS')
+ split sysfile.SYS
+ call assert_equal('rapid', &filetype)
+ bwipe!
+ call delete('sysfile.SYS')
+
+ filetype off
+endfunc
+
func Test_tex_file()
filetype on