mirror of
				https://github.com/vim/vim.git
				synced 2025-10-30 09:47:20 -04:00 
			
		
		
		
	patch 9.1.1307: make syntax does not reliably detect different flavors
Problem:  GNU extensions, such as `ifeq` and `wildcard` function, are
          highlighted in BSDmakefile
Solution: detect BSD, GNU, or Microsoft implementation according to
	  filename, user-defined global variables, or file contents
closes: #17089
Co-authored-by: Roland Hieber <rohieb@users.noreply.github.com>
Signed-off-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
			
			
This commit is contained in:
		
				
					committed by
					
						 Christian Brabandt
						Christian Brabandt
					
				
			
			
				
	
			
			
			
						parent
						
							32f2bb6e1e
						
					
				
				
					commit
					f35bd76b31
				
			
							
								
								
									
										40
									
								
								runtime/autoload/dist/ft.vim
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								runtime/autoload/dist/ft.vim
									
									
									
									
										vendored
									
									
								
							| @@ -557,17 +557,47 @@ export def FTm() | ||||
| enddef | ||||
|  | ||||
| export def FTmake() | ||||
|   # Check if it is a Microsoft Makefile | ||||
|   unlet! b:make_microsoft | ||||
|   # Check if it is a BSD, GNU, or Microsoft Makefile | ||||
|   unlet! b:make_flavor | ||||
|  | ||||
|   # 1. filename | ||||
|   if expand('%:t') == 'BSDmakefile' | ||||
|     b:make_flavor = 'bsd' | ||||
|     setf make | ||||
|     return | ||||
|   elseif expand('%:t') == 'GNUmakefile' | ||||
|     b:make_flavor = 'gnu' | ||||
|     setf make | ||||
|     return | ||||
|   endif | ||||
|  | ||||
|   # 2. user's setting | ||||
|   if exists('g:make_flavor') | ||||
|     b:make_flavor = g:make_flavor | ||||
|     setf make | ||||
|     return | ||||
|   elseif get(g:, 'make_microsoft') | ||||
|     echom "make_microsoft is deprecated; try g:make_flavor = 'microsoft' instead" | ||||
|     b:make_flavor = 'microsoft' | ||||
|     setf make | ||||
|     return | ||||
|   endif | ||||
|  | ||||
|   # 3. try to detect a flavor from file content | ||||
|   var n = 1 | ||||
|   while n < 1000 && n <= line('$') | ||||
|     var line = getline(n) | ||||
|     if line =~? '^\s*!\s*\(ifn\=\(def\)\=\|include\|message\|error\)\>' | ||||
|       b:make_microsoft = 1 | ||||
|       b:make_flavor = 'microsoft' | ||||
|       break | ||||
|     elseif line =~ '^ *ifn\=\(eq\|def\)\>' || line =~ '^ *[-s]\=include\s' | ||||
|     elseif line =~ '^\.\%(export\|error\|for\|if\%(n\=\%(def\|make\)\)\=\|info\|warning\)\>' | ||||
|       b:make_flavor = 'bsd' | ||||
|       break | ||||
|     elseif line =~ '^ *\w\+\s*[!?:+]=' | ||||
|     elseif line =~ '^ *\%(ifn\=\%(eq\|def\)\|define\|override\)\>' | ||||
|       b:make_flavor = 'gnu' | ||||
|       break | ||||
|     elseif line =~ '\$[({][a-z-]\+\s\+\S\+'  # a function call, e.g. $(shell pwd) | ||||
|       b:make_flavor = 'gnu' | ||||
|       break | ||||
|     endif | ||||
|     n += 1 | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| *filetype.txt*	For Vim version 9.1.  Last change: 2025 Mar 15 | ||||
| *filetype.txt*	For Vim version 9.1.  Last change: 2025 Apr 15 | ||||
|  | ||||
|  | ||||
| 		  VIM REFERENCE MANUAL    by Bram Moolenaar | ||||
| @@ -158,6 +158,8 @@ variables can be used to overrule the filetype used for certain extensions: | ||||
| 	*.inc		g:filetype_inc | ||||
| 	*.lsl		g:filetype_lsl | ||||
| 	*.m		g:filetype_m		|ft-mathematica-syntax| | ||||
| 	*[mM]makefile,*.mk,*.mak,[mM]akefile* | ||||
| 			g:make_flavor		|ft-make-syntax| | ||||
| 	*.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md | ||||
| 			g:filetype_md		|ft-pandoc-syntax| | ||||
| 	*.mod		g:filetype_mod | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| *syntax.txt*	For Vim version 9.1.  Last change: 2025 Apr 13 | ||||
| *syntax.txt*	For Vim version 9.1.  Last change: 2025 Apr 15 | ||||
|  | ||||
|  | ||||
| 		  VIM REFERENCE MANUAL	  by Bram Moolenaar | ||||
| @@ -2393,11 +2393,16 @@ 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: > | ||||
| There are various Make implementations, which add extensions other than the | ||||
| POSIX specification and thus are mutually incompatible.  If the filename is | ||||
| BSDmakefile or GNUmakefile, the corresponding implementation is automatically | ||||
| determined; otherwise vim tries to detect it by the file contents.  If you see | ||||
| any wrong highlights because of this, you can enforce a flavor by setting one | ||||
| of the following: > | ||||
|  | ||||
| 	:let make_microsoft = 1 | ||||
| 	:let g:make_flavor = 'bsd'  " or | ||||
| 	:let g:make_flavor = 'gnu'  " or | ||||
| 	:let g:make_flavor = 'microsoft' | ||||
|  | ||||
|  | ||||
| MAPLE						*maple.vim* *ft-maple-syntax* | ||||
|   | ||||
| @@ -3186,7 +3186,7 @@ au BufNewFile,BufRead */etc/sensors.d/[^.]*	call s:StarSetf('sensors') | ||||
| au BufNewFile,BufRead */etc/logcheck/*.d*/*	call s:StarSetf('logcheck') | ||||
|  | ||||
| " Makefile | ||||
| au BufNewFile,BufRead [mM]akefile*		call s:StarSetf('make') | ||||
| au BufNewFile,BufRead [mM]akefile*		if expand('<afile>:t') !~ g:ft_ignore_pat | call dist#ft#FTmake() | endif | ||||
|  | ||||
| " Ruby Makefile | ||||
| au BufNewFile,BufRead [rR]akefile*		call s:StarSetf('ruby') | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| " Previous Maintainer:	Claudio Fleiner <claudio@fleiner.com> | ||||
| " URL:		https://github.com/vim/vim/blob/master/runtime/syntax/make.vim | ||||
| " Last Change:	2022 Nov 06 | ||||
| " 2025 Apr 15 by Vim project: rework Make flavor detection (#17089) | ||||
|  | ||||
| " quit when a syntax file was already loaded | ||||
| if exists("b:current_syntax") | ||||
| @@ -13,6 +14,9 @@ endif | ||||
| let s:cpo_save = &cpo | ||||
| set cpo&vim | ||||
|  | ||||
| " enable GNU extension when b:make_flavor is not set—detection failed or Makefile is POSIX-compliant | ||||
| let s:make_flavor = 'gnu' | ||||
|  | ||||
| " some special characters | ||||
| syn match makeSpecial	"^\s*[@+-]\+" | ||||
| syn match makeNextLine	"\\\n\s*" | ||||
| @@ -21,14 +25,16 @@ syn match makeNextLine	"\\\n\s*" | ||||
| syn region makeDefine start="^\s*define\s" end="^\s*endef\s*\(#.*\)\?$" | ||||
| 	\ contains=makeStatement,makeIdent,makePreCondit,makeDefine | ||||
|  | ||||
| " Microsoft Makefile specials | ||||
| syn case ignore | ||||
| syn match makeInclude	"^!\s*include\s.*$" | ||||
| syn match makePreCondit "^!\s*\(cmdswitches\|error\|message\|include\|if\|ifdef\|ifndef\|else\|else\s*if\|else\s*ifdef\|else\s*ifndef\|endif\|undef\)\>" | ||||
| syn case match | ||||
| if get(b:, 'make_flavor', s:make_flavor) == 'microsoft' | ||||
|   " Microsoft Makefile specials | ||||
|   syn case ignore | ||||
|   syn match makeInclude	"^!\s*include\s.*$" | ||||
|   syn match makePreCondit "^!\s*\(cmdswitches\|error\|message\|include\|if\|ifdef\|ifndef\|else\|else\s*if\|else\s*ifdef\|else\s*ifndef\|endif\|undef\)\>" | ||||
|   syn case match | ||||
| endif | ||||
|  | ||||
| " identifiers | ||||
| if exists("b:make_microsoft") || exists("make_microsoft") | ||||
| if get(b:, 'make_flavor', s:make_flavor) == 'microsoft' | ||||
|   syn region makeIdent	start="\$(" end=")" contains=makeStatement,makeIdent | ||||
|   syn region makeIdent	start="\${" end="}" contains=makeStatement,makeIdent | ||||
| else | ||||
| @@ -59,13 +65,31 @@ syn match makeTarget           "^[~A-Za-z0-9_./$(){}%*@-][A-Za-z0-9_./\t $(){}%* | ||||
| 	\ skipnl nextgroup=makeCommands,makeCommandError | ||||
|  | ||||
| syn region makeSpecTarget	transparent matchgroup=makeSpecTarget | ||||
| 	\ start="^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|EXPORT_ALL_VARIABLES\|KEEP_STATE\|LIBPATTERNS\|NOTPARALLEL\|DELETE_ON_ERROR\|INTERMEDIATE\|POSIX\|SECONDARY\|ONESHELL\)\>\s*:\{1,2}[^:=]"rs=e-1 | ||||
| 	\ start="^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|NOTPARALLEL\|POSIX\)\>\s*:\{1,2}[^:=]"rs=e-1 | ||||
| 	\ end="[^\\]$" keepend | ||||
| 	\ contains=makeIdent,makeSpecTarget,makeNextLine,makeComment skipnl nextGroup=makeCommands | ||||
| syn match makeSpecTarget	"^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|EXPORT_ALL_VARIABLES\|KEEP_STATE\|LIBPATTERNS\|NOTPARALLEL\|DELETE_ON_ERROR\|INTERMEDIATE\|POSIX\|SECONDARY\|ONESHELL\)\>\s*::\=\s*$" | ||||
| syn match makeSpecTarget	"^\.\(SUFFIXES\|PHONY\|DEFAULT\|PRECIOUS\|IGNORE\|SILENT\|NOTPARALLEL\|POSIX\)\>\s*::\=\s*$" | ||||
| 	\ contains=makeIdent,makeComment | ||||
| 	\ skipnl nextgroup=makeCommands,makeCommandError | ||||
|  | ||||
| if get(b:, 'make_flavor', s:make_flavor) == 'bsd' | ||||
|   syn region makeSpecTarget	transparent matchgroup=makeSpecTarget | ||||
| 	\ start="^\.DELETE_ON_ERROR\>\s*:\{1,2}[^:=]"rs=e-1 | ||||
| 	\ end="[^\\]$" keepend | ||||
| 	\ contains=makeIdent,makeSpecTarget,makeNextLine,makeComment skipnl nextGroup=makeCommands | ||||
|   syn match makeSpecTarget	"^\.DELETE_ON_ERROR\>\s*::\=\s*$" | ||||
| 	\ contains=makeIdent,makeComment | ||||
| 	\ skipnl nextgroup=makeCommands,makeCommandError | ||||
| elseif get(b:, 'make_flavor', s:make_flavor) == 'gnu' | ||||
|   syn region makeSpecTarget	transparent matchgroup=makeSpecTarget | ||||
| 	\ start="^\.\(EXPORT_ALL_VARIABLES\|DELETE_ON_ERROR\|INTERMEDIATE\|KEEP_STATE\|LIBPATTERNS\|ONESHELL\|SECONDARY\)\>\s*:\{1,2}[^:=]"rs=e-1 | ||||
| 	\ end="[^\\]$" keepend | ||||
| 	\ contains=makeIdent,makeSpecTarget,makeNextLine,makeComment skipnl nextGroup=makeCommands | ||||
|   syn match makeSpecTarget	"^\.\(EXPORT_ALL_VARIABLES\|DELETE_ON_ERROR\|INTERMEDIATE\|KEEP_STATE\|LIBPATTERNS\|ONESHELL\|SECONDARY\)\>\s*::\=\s*$" | ||||
| 	\ contains=makeIdent,makeComment | ||||
| 	\ skipnl nextgroup=makeCommands,makeCommandError | ||||
| endif | ||||
|  | ||||
| syn match makeCommandError "^\s\+\S.*" contained | ||||
| syn region makeCommands contained start=";"hs=s+1 start="^\t" | ||||
| 	\ end="^[^\t#]"me=e-1,re=e-1 end="^$" | ||||
| @@ -74,17 +98,19 @@ syn region makeCommands contained start=";"hs=s+1 start="^\t" | ||||
| syn match makeCmdNextLine	"\\\n."he=e-1 contained | ||||
|  | ||||
| " some directives | ||||
| syn match makePreCondit	"^ *\(ifn\=\(eq\|def\)\>\|else\(\s\+ifn\=\(eq\|def\)\)\=\>\|endif\>\)" | ||||
| syn match makeInclude	"^ *[-s]\=include\s.*$" | ||||
| syn match makeStatement	"^ *vpath" | ||||
| syn match makeExport    "^ *\(export\|unexport\)\>" | ||||
| syn match makeOverride	"^ *override\>" | ||||
| " Statements / Functions (GNU make) | ||||
| 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 | ||||
| if get(b:, 'make_flavor', s:make_flavor) == 'gnu' | ||||
|   " Statements / Functions (GNU make) | ||||
|   syn match makePreCondit	"^ *\(ifn\=\(eq\|def\)\>\|else\(\s\+ifn\=\(eq\|def\)\)\=\>\|endif\>\)" | ||||
|   syn match makeStatement	"^ *vpath\>" | ||||
|   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\|intcmp\|join\|lastword\|let\|notdir\|or\|origin\|patsubst\|realpath\|shell\|sort\|strip\|subst\|suffix\|value\|warning\|wildcard\|word\|wordlist\|words\)\>"ms=s+1 | ||||
| endif | ||||
|  | ||||
| " Comment | ||||
| if !exists("make_no_comments") | ||||
|   if exists("b:make_microsoft") || exists("make_microsoft") | ||||
|   if get(b:, 'make_flavor', s:make_flavor) == 'microsoft' | ||||
|     syn match   makeComment	"#.*" contains=@Spell,makeTodo | ||||
|   else | ||||
|     syn region  makeComment	start="#" end="^$" end="[^\\]$" keepend contains=@Spell,makeTodo | ||||
|   | ||||
| @@ -2857,15 +2857,48 @@ endfunc | ||||
| func Test_make_file() | ||||
|   filetype on | ||||
|  | ||||
|   " BSD Makefile | ||||
|   call writefile([''], 'BSDmakefile', 'D') | ||||
|   split BSDmakefile | ||||
|   call assert_equal('bsd', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   call writefile(['.ifmake all', '.endif'], 'XMakefile.mak', 'D') | ||||
|   split XMakefile.mak | ||||
|   call assert_equal('bsd', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   " GNU Makefile | ||||
|   call writefile([''], 'GNUmakefile', 'D') | ||||
|   split GNUmakefile | ||||
|   call assert_equal('gnu', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   call writefile(['ifeq ($(foo),foo)', 'endif'], 'XMakefile.mak', 'D') | ||||
|   split XMakefile.mak | ||||
|   call assert_equal('gnu', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   call writefile(['define foo', 'endef'], 'XMakefile.mak', 'D') | ||||
|   split XMakefile.mak | ||||
|   call assert_equal('gnu', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   call writefile(['vim := $(wildcard *.vim)'], 'XMakefile.mak', 'D') | ||||
|   split XMakefile.mak | ||||
|   call assert_equal('gnu', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   " 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)) | ||||
|   call assert_equal('microsoft', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   " BSD or GNU | ||||
|   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)) | ||||
|   call assert_notequal('microsoft', get(b:, 'make_flavor', '')) | ||||
|   bwipe! | ||||
|  | ||||
|   filetype off | ||||
|   | ||||
| @@ -704,6 +704,8 @@ static char *(features[]) = | ||||
|  | ||||
| static int included_patches[] = | ||||
| {   /* Add new patch number below this line */ | ||||
| /**/ | ||||
|     1307, | ||||
| /**/ | ||||
|     1306, | ||||
| /**/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user