diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index f7a8940a52..2a008cb50e 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -1806,7 +1806,7 @@ By default mail.vim synchronises syntax to 100 lines before the first displayed line. If you have a slow machine, and generally deal with emails with short headers, you can change this to a smaller value: > - :let mail_minlines = 30 + :let mail_minlines = 30 MAKE *make.vim* *ft-make-syntax* @@ -1817,6 +1817,16 @@ feature off by using: > :let make_no_commands = 1 +Comments are also highlighted by default. You can turn this off by using: > + + :let make_no_comments = 1 + +Microsoft Makefile handles variable expansion and comments differently +(backslashes are not used for escape). If you see any wrong highlights +because of this, you can try this: > + + :let make_microsoft = 1 + MAPLE *maple.vim* *ft-maple-syntax* diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 7cbf3a158d..bf00392087 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -693,8 +693,8 @@ local extension = { return not (path:find('html%.m4$') or path:find('fvwm2rc')) and 'm4' or nil end, eml = 'mail', - mk = 'make', - mak = 'make', + mk = detect.make, + mak = detect.make, page = 'mallard', map = 'map', mws = 'maple', @@ -2122,7 +2122,7 @@ local pattern = { ['^Containerfile%.'] = starsetf('dockerfile'), ['^Dockerfile%.'] = starsetf('dockerfile'), ['^[jJ]ustfile$'] = 'just', - ['[mM]akefile$'] = 'make', + ['[mM]akefile$'] = detect.make, ['^[mM]akefile'] = starsetf('make'), ['^[rR]akefile$'] = 'ruby', ['^[rR]akefile'] = starsetf('ruby'), diff --git a/runtime/lua/vim/filetype/detect.lua b/runtime/lua/vim/filetype/detect.lua index 1fe7db0e1f..cb953f9d0c 100644 --- a/runtime/lua/vim/filetype/detect.lua +++ b/runtime/lua/vim/filetype/detect.lua @@ -972,6 +972,24 @@ local function m4(contents) end end +--- Check if it is a Microsoft Makefile +--- @type vim.filetype.mapfn +function M.make(_, bufnr) + vim.b.make_microsoft = nil + for _, line in ipairs(getlines(bufnr, 1, 1000)) do + if matchregex(line, [[\c^\s*!\s*\(ifn\=\(def\)\=\|include\|message\|error\)\>]]) then + vim.b.make_microsoft = 1 + break + elseif + matchregex(line, [[^ *ifn\=\(eq\|def\)\>]]) + or findany(line, { '^ *[-s]?%s', '^ *%w+%s*[!?:+]=' }) + then + break + end + end + return 'make' +end + --- @type vim.filetype.mapfn function M.markdown(_, _) return vim.g.filetype_md or 'markdown' diff --git a/runtime/syntax/make.vim b/runtime/syntax/make.vim index b4573044ca..d3ddf78291 100644 --- a/runtime/syntax/make.vim +++ b/runtime/syntax/make.vim @@ -28,8 +28,13 @@ syn match makePreCondit "^!\s*\(cmdswitches\|error\|message\|include\|if\|ifdef\ syn case match " identifiers -syn region makeIdent start="\$(" skip="\\)\|\\\\" end=")" contains=makeStatement,makeIdent -syn region makeIdent start="\${" skip="\\}\|\\\\" end="}" contains=makeStatement,makeIdent +if exists("b:make_microsoft") || exists("make_microsoft") + syn region makeIdent start="\$(" end=")" contains=makeStatement,makeIdent + syn region makeIdent start="\${" end="}" contains=makeStatement,makeIdent +else + syn region makeIdent start="\$(" skip="\\)\|\\\\" end=")" contains=makeStatement,makeIdent + syn region makeIdent start="\${" skip="\\}\|\\\\" end="}" contains=makeStatement,makeIdent +endif syn match makeIdent "\$\$\w*" syn match makeIdent "\$[^({]" syn match makeIdent "^ *[^:#= \t]*\s*[:+?!*]="me=e-2 @@ -78,11 +83,13 @@ syn match makeOverride "^ *override\>" syn match makeStatement contained "(\(abspath\|addprefix\|addsuffix\|and\|basename\|call\|dir\|error\|eval\|file\|filter-out\|filter\|findstring\|firstword\|flavor\|foreach\|guile\|if\|info\|join\|lastword\|notdir\|or\|origin\|patsubst\|realpath\|shell\|sort\|strip\|subst\|suffix\|value\|warning\|wildcard\|word\|wordlist\|words\)\>"ms=s+1 " Comment -if exists("make_microsoft") - syn match makeComment "#.*" contains=@Spell,makeTodo -elseif !exists("make_no_comments") - syn region makeComment start="#" end="^$" end="[^\\]$" keepend contains=@Spell,makeTodo - syn match makeComment "#$" contains=@Spell +if !exists("make_no_comments") + if exists("b:make_microsoft") || exists("make_microsoft") + syn match makeComment "#.*" contains=@Spell,makeTodo + else + syn region makeComment start="#" end="^$" end="[^\\]$" keepend contains=@Spell,makeTodo + syn match makeComment "#$" contains=@Spell + endif endif syn keyword makeTodo TODO FIXME XXX contained diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim index 16c4130420..83aff0205b 100644 --- a/test/old/testdir/test_filetype.vim +++ b/test/old/testdir/test_filetype.vim @@ -2641,4 +2641,21 @@ func Test_pl_file() filetype off endfunc +func Test_make_file() + filetype on + + " Microsoft Makefile + call writefile(['# Makefile for Windows', '!if "$(VIMDLL)" == "yes"'], 'XMakefile.mak', 'D') + split XMakefile.mak + call assert_equal(1, get(b:, 'make_microsoft', 0)) + bwipe! + + call writefile(['# get the list of tests', 'include testdir/Make_all.mak'], 'XMakefile.mak', 'D') + split XMakefile.mak + call assert_equal(0, get(b:, 'make_microsoft', 0)) + bwipe! + + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab