Mixing two syntax highlighting scripts - vim

I write blog posts with Jekyll, and for that I end up using three different languages in the same file: YAML at the start for post metadata, Markdown in the body, and C++ in code snippets.
I tried to setup a script so that I can have vim highlight all three properly for me, and ended up with something like this in syntax/jekyll.vim:
" Build upon Markdown syntax
runtime! syntax/markdown.vim
" pretend there's no syntax loaded
unlet b:current_syntax
" Bring in YAML syntax for front matter
syntax include #Yaml syntax/yaml.vim
syntax region yamlFrontmatter start=/\%^---$/ end=/^---$/ keepend contains=#Yaml
" pretend there's no syntax loaded
unlet b:current_syntax
" Bring in C++11 syntax for code snippets
syntax include #Cpp syntax/cpp.vim
syntax region cppCodeSnippet matchgroup=Comment start=/^{% highlight cpp %}$/ end=/^{% endhighlight %}$/ keepend contains=#Cpp
let b:current_syntax='jekyll'
I also set up a file detection script to set ft to this syntax.
It almost works. When I open a file that gets detected as this type, I get everything correct except for the C++ highlights. However, if I type :syn on after that, everything works fine. I can delete the buffer and open the file again and all highlights are ok. If I close vim and start it again, I need to run :syn on again.
What am I missing? How can I debug this issue?

Quick fix: append syntax on to the last line of your .vimrc, which is the same as setting :syn on in the live session.
Not So Quick:
Looks like you might have installed the custom 'jekyll' syntax alongside the default syntax files in $VIMRUNTIME.
According to Vim wiki section on custom syntax, it's preferable to keep all personal customizations within ~/.vim. For example, putting your jekyll.vim syntax in ~/.vim/syntax/.
Do not use a directory containing the files distributed with Vim because that will be overwritten during an upgrade (in particular, do not use the $VIMRUNTIME directory).
In the Vim syntax docs:
:syntax enable runs ':source $VIMRUNTIME/syntax/DEFAULT_SYNTAX.vim'.
:syn on (or :syntax on) will "overrule your settings with the defaults".
So if setting :syntax on makes your custom syntax work, it must be contained in the default syntax set.
Try keeping all the custom stuff in ~/.vim and see if that settles things.

Related

Vim syntax doesn't highlight in real time

I have enabled vim syntax on (in ~/.vimrc syntax on) and it works but only on files with a code in when I view them. When I create a new file with vim and write there some code - no syntax highlight. After saving this file and reopening with vim - syntax highlight works perfect.
I am using manjaro KDE.
When you open a new file without an extension (vim mynewfile) none of vim’s filetype detection mechanisms can recognize it (they all use either extensions or first-couple-of-lines heuristics, which don’t work here).
When you enter code and reopen the file, the line-checks for filetypes work, causing the syntax to be set correctly, causing highlights to apply.
You can always set syntax=mine (though set filetype=mine is better) to set it manually.
This problem shouldnt happen when you do vim some.c or similar, because the extension will force detection based on extension rules.
Vim must know how to highlight your syntax in order to actually highlight it. One way to do this, is for Vim to check the file name and sometimes inspect the contents of the file, and set the file type. The file type is then used to highlight the syntax.
To enable detection of the file type (and load plugin and indent files), add the following to your vimrc:
filetype on plugin indent
If Vim is unable to detect the file type, and you have not yet saved your file with a known extension, you can set the file type manually, like this:
:set filetype=html
Vim will then highlight the syntax of the file as HTML syntax.
More information is available in the help pages.

Set spelling exception in vimrc

When editing a text in markdown, I don't want to highlight bibliography entries. This can be achieved with the following command:
:syn match CitNoSpell '\[#[^[:space:]]\+\]' contains=#NoSpell
However, if I enter this command to .vimrc, it is ignored. I assume that is because spell file is loaded after vimrc has been read, and this definition is not kept.
How should I force vim to ignore this pattern? I prefer it to stay in .vimrc, as I synchronize the file across multiple systems, but another solution would also be welcome.
As the ~/.vimrc is loaded first (before any files), the syntax of an opened file is set only later, and syntax scripts :syntax clear any existing syntax stuff, including your definition.
The right place for your customization would be the :help after-directory; i.e. ~/.vim/after/syntax/markdown.vim, as this will be sourced after $VIMRUNTIME/syntax/markdown.vim.
If you insist on configuring this within your ~/.vimrc, you can try the following autocmd, which has to be put somewhere after :syntax on:
autocmd Syntax markdown syn match CitNoSpell ...
PS: For consistency, as you're tweaking the Markdown syntax, your added syntax group should also start with the syntax name, i.e. markdownCitNoSpell.

Highlighting set of specific keywords in gvim

I have tried highlighting specific words by adding them in .vimrc, colorscheme file and also in syntax.vim(I changed one at a time, not altogether).
syn match mygroupwords '\c\<\(-word1\|-word2\)'
hi def link mygroupwords colo_words12
hi colo_words12 guifg=red1 gui=bold guibg=white
But somehow it seems to be getting overwritten by default syntax highlighting
i need to highlight keywords irrespective of color-scheme or file-type which have following words-
Ex; -word1 , -word2
Any suggestions?
explanation of your failed attempts
A colorscheme just provides color definitions for predefined highlight groups; that's the wrong place for actual syntax matches! ~/.vimrc is the first configuration that is read; if a filetype is detected and a corresponding syntax script is loaded, that will override your syntax definition.
syntax extensions
If your desired highlightings are extensions to an existing syntax, you can place :syntax match commands in a syntax script in the after directory. For example, to extend Python syntax, put it in ~/.vim/after/syntax/python.vim. That may still fail if the original syntax obscures the match; sometimes, this can be solved via containedin=...
independent marks
If your highlightings are independent of syntax and filetype, there's a different built-in mechanism: :match (and :2match, and additional variants via :call matchadd(...)):
:match mygroupwords /\c\<\(-word1\|-word2\)/
This goes on top of (and is independent of) syntax highlighting. However, it is local to the current window. So, if you put this into your .vimrc, it will only affect the first window (but any files viewed in there). To apply this globally to window splits and tab pages, you have to use :autocmds. It's not trivial to get this totally right. If you need such a full solution, have a look at my Mark plugin; this supports multiple colors, allows presetting with :[N]Mark /{pattern}/ (similar to :match), and highlights in all windows.

How can I apply custom syntax highlighting in VIM to all file types?

The most preferable way to do this would be in some like my .vimrc file or another location in my vimfiles that's easily persisted and not attached to an extra plugin.
The help files for VIM (along with almost all solutions found on the Internet abroad) relate directly to adding syntax highlighting for a specific file type.
However, how would one add highlights that apply to all files?
An example would be highlighting extra keywords as part of the Todo highlighting group - such as "NOTE", "INTERNAL", etc.
I've attempted to use vimfiles\after\syntax\..., but again, it seems to be predicated on the right file type getting used for the .vim file created in that directory.
So, something like vimfiles\after\syntax\cpp.vim with the following works to achieve this in C++:
syntax keyword cTodo contained NOTE INTERNAL IMPORTANT
for C++ files specifically, and this works how I would expect it to.
But how can this be generalized to all file types when a file is loaded into a buffer?
You can hook into the syntax script loading via the Syntax event. Be sure to define this after :syntax on in your .vimrc:
:autocmd Syntax * syntax keyword allTodo NOTE
If you also want to handle buffers that don't have any syntax (/ filetype) set, add the BufNewFile,BufReadPost events.
Alternative
Depending on the syntax, you may need to specify contained[in], or :syn cluster add=... to augment the existing syntax. That unfortunately cannot be generalized. An alternative approach would be using :match or :call matchadd(...), which goes on top of (and is totally independent of) syntax highlighting. Since this is window-local, the autocmd would be:
:autocmd VimEnter,WinEnter * match Todo /\<NOTE\>/

Override syntax highlighting settings

I have the following in a vim plugin, and I have also moved it to the end of my .vimrc:
syn keyword javaScriptIdentifier const
However, this doesn't work and const is not highlighted properly in JavaScript files. If I run :syn keyword javaScriptIdentifier const after opening a file, then it will be highlighted properly.
I am using pathogen with quite a few plugins, but I would think these all run before then end of my .vimrc. Some of them are using an after directory, but I don't see const anywhere in those plugins. I also don't see it in the system JavaScript syntax highlighting.
Is there any way to ensure that syntax highlighting or other operations take priority?
Putting syn in your vimrc will never work, since existing syntax rules are cleared when changing the syntax highlighting. Consider:
:set syntax=javascript
" Oops, this is a Python file, change the syntax
:set syntax=python
What would happen if existing syntax rules wouldn't get cleared?
You'll need to use the after directory, which you already seem to be familiar with, or use an autocommand:
autocmd Filetype javascript syn keyword javaScriptIdentifier const
You can view an autocommand as roughly similar to events in JavaScript, in the sense that they run a piece of code whenever the user does some action.
I am using pathogen with quite a few plugins, but I would think these all run before then end of my .vimrc
That depends on the plugin. You can hook into autocommands like above, and in addition to that many plugins use the autoload feature (meaning a file won't get loaded until it's needed).

Resources