2

I'm trying to create a highlight that changes the text color of a strikethrough syntax, like ~~hello~~ should turn the whole thing gray.

Here's what I've put in my vimrc:

au BufRead,BufNewFile *.n syntax match StrikeoutMatch /\~\~.*\~\~/
hi def StrikeoutColor ctermbg=0 ctermfg=15 guibg=0 guifg=15
hi link StrikeoutMatch StrikeoutColor

This mostly works - in a file named test.n if the content is the following, then the ~~test~~ is correctly highlighted:

~~test~~
hello what's up

But, in the following case, the ~~test~~ text does not get highlighted - instead, # test is highlighted (as a comment):

# test
~~test~~

If I open a file without a # comment and then type a # test, that line is not highlighted. When I relaunch vim into that file it swaps to highlight # and not the ~~.

What I want is for the ~~test~~ syntax to not interfere with anything else. I should be able to write that in any file matching the .n extension, while other things like # still get highlighted as usual. Would really appreciate some guidance on how to accomplish this.

Some images:

  1. Opened a file with the # test comment already there. ~~test~~ is not highlighted, 3rd line is highlighted on the fly as I typed it

  2. File originally with just the one ~~test~~ line. I typed the # comment, which is not highlighted, and then typed the 3rd line which is highlighted

  1. Closed and re-opened the file from above. Highlights have swapped

  2. Deleting the comment line doesn't help

  3. But once I've deleted the comment line, I can close and re-open the file and it works again.

6
  • 1
    I would first try looking in :help contains and :help containedin, as that might be an avenue to explore for solutions. I tried reproducing your error, but could not. Is # as a comment only for a single line?
    – Vee
    Dec 1 '20 at 2:15
  • Oh ok, will look into those. I was hoping that it was some default behavior haha.. Yes, the # comment is just one line. I just edited my question with some screenshots to more clearly illustrate the behavior if that helps.
    – rococo
    Dec 1 '20 at 2:23
  • 1
    Interesting. Can you check what the filetype is after you go through the 1-5 steps since you open and close things? set ft? to check it. I wonder if adding the # on the first line is making vim think the filetype is sh, and that's why you get different behavior when you open, save, close, and reopen? Maybe?
    – Vee
    Dec 1 '20 at 2:30
  • 1
    Update: so... moving the config commands to the end of my vimrc seems to have fixed all this! Now even with filetype=conf the highlighting is correct (both the # and ~~ lines are highlighted). Probably should've tried that earlier!
    – rococo
    Dec 1 '20 at 5:36
  • 1
    Good to hear! I'd check out Maxim Kim's response because he has what looks like the full explanation of what is happening and he has a better fix.
    – Vee
    Dec 1 '20 at 14:56
2

There is filetype detection vim uses to autodetect filetype and set proper syntax:

https://github.com/vim/vim/blob/004d9b00ba600a167746ad7af88e0baa77c95d8f/runtime/filetype.vim#L2243

Your autocommand is run before the filetype detection (where you add some syntax). Then filetype detection finds out this looks like conf file and current filetype is not set -- it sets conf filetype, overriding your syntax.

For me it looks like you need to create a new filetype with syntax (filetype detection will not override it).

Non-suggested way to do it is (following your code snippet):

au BufRead,BufNewFile *.n set ft=n | call SetupNSyntax()

func! SetupNSyntax()
    syntax match StrikeoutMatch /\~\~.*\~\~/
    hi StrikeoutColor ctermbg=0 ctermfg=15 guibg=NONE guifg=#7777f7
    hi def link StrikeoutMatch StrikeoutColor
endfunc

Suggested way is it create a separate syntax file in ~/.vim/syntax/n.vim:

syntax match StrikeoutMatch /\~\~.*\~\~/
hi StrikeoutColor ctermbg=0 ctermfg=15 guibg=NONE guifg=#7777f7
hi def link StrikeoutMatch StrikeoutColor

and add filetype detection in ~/.vim/ftdetect/n.vim

au BufRead,BufNewFile *.n set ft=n

:h new-filetype for reference.

PS, when vim sets filetype that is in ftplugin/somefiletype.vim file, it will also call the syntax file with the same name syntax/somefiletype.vim. More to it, you can only have a syntax file syntax/somefiletype.vim -- setting filetype with :set filetype=somefiletype will apply syntax with the same base filename.

PPS, your hi definition looks wrong to me:

hi def StrikeoutColor ctermbg=0 ctermfg=15 guibg=0 guifg=15

in Gui vim it errors with "cannot allocate color 0".

1
  • Thank you very much for the thorough and informative answer! Will do as you suggested, it certainly seems more organized.
    – rococo
    Dec 3 '20 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.