8

I have discovered an interesting edge-case in Vim syntax highlighting. Consider the following snippet from a company Makefile:

LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))

The above line simply removes double quotes from a given LDSCRIPT. Nothing syntactically wrong; the make runs as expected and without issue.

The Problem

Since the above line only contains one double quote, the highlighting rules mistakenly think that the rest of the body of the Makefile is quoted text and colors it as such. For simple Makefiles, this is an inconvenience; for 1KLOC+ Makefiles, this becomes a real hassle (especially since this preprocessing is near the top of the file).

The Question

Is there any way to either disable syntax highlighting based on lines that match some given regular expression (eg. subst[ \t]*['"],.*) or something similar? Failing that, is there some way to restart Vim's highlighting at some arbitrary line while preserving the highlights above?

If at all possible, I would like to avoid edits to the Makefile as this script is shared across a number of departments.

I am willing to write / modify vimscript to achieve this, however I have not done so before (to any reasonable degree). Any tips, pointers or other helpful hints would be much appreciated.

What I have Tried

:syntax sync minlines=1
:syntax sync fromstart
:syntax sync clear

None of the above seems to have any effect on the highlighting when run in the editor. Looking through the Vim help docs, it seems that :syn-sync-fourth may be able to do what I am after, however I am uncertain as to how this would function in an inverse manner (eg. to disable highlighting rather than to apply it).

MysteryMoose
  • 2,211
  • 4
  • 23
  • 47

2 Answers2

3

I think the best you can do is add an additional syntax rule (in ~/.vim/after/syntax/make.vim) to match the offending construct. This seems to work:

syn match makeIgnore /subst[ \t]*['"],,/ containedin=makeIdent

The containedin= is necessary because it's used in a $(...) construct.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • Awesome, that worked like a charm. One minor platform-specific difference: on my Fedora 18 box the file to edit is `/usr/share/vim/vim73/syntax/make.vim`. – MysteryMoose Nov 07 '14 at 00:14
  • Don't edit the package-provided system files! You'll lose your changes on the next update. If you absolutely need to edit the original file, create a clone in `~/.vim/syntax/make.vim`. But for the, the use of the _after_ location worked just fine, no need to mess with the original script. – Ingo Karkat Nov 07 '14 at 07:45
  • Sorry for the delay; was out of the country. I tried adding just the above line at `~/.vim/after/syntax/make.vim` (I had to create the file in the first place), but it did not seem to work. Do I need to copy the system `make.vim` into my home location and modify that? – MysteryMoose Nov 19 '14 at 17:13
  • For me, just adding the line to the after file worked. Try copying the system `make.vim` to `~/.vim/syntax/make.vim`. If that still doesn't work, edit in the single line change there (and don't use the after file). Any of that is still better than modifying the original in place. – Ingo Karkat Nov 20 '14 at 07:35
  • Copying the system `make.vim` and making the edit there worked for me. Thanks again for the help! – MysteryMoose Nov 21 '14 at 01:21
0

Also, you can modify your makefile to have the double quotes balanced, like this:

dquote := $(firstword " ")
LDSCRIPT := $(subst $(dquote),,$(CONFIG_SYS_LDSCRIPT))

Something similar can be used to balance other characters, like single quotes.

The resulting makefile may be more verbose but will not confuse any text editor (and perhaps will be less confusing for humans too).

roy
  • 463
  • 5
  • 10