0

I wrote a (perl) script that generates a syntax highlight vim script (tags.vim) from the tags file (generated by ctags). However, when I open a file I have to manually load it. I can fix that by starting vim with the right command line, but once inside vim every time I switch source file (for example by pressing ^] to jump to a definition in another file) the syntax highlighting is lost and I need to re-source my generated tags.vim.

Is there a way to execute a command (:so tags.vim) or source a script etc, automatically whenever the current source file changes (by :n, :N, ^] or :tnext etc.)?

2
  • This might be an XY problem. What kind of highlights do you generate, and how? If you're using :highlight, which is Vim-global, it might make more sense to change the syntax definition for your filetype (or make a custom filetype for your custom syntax). This way, your syntax definition (and consequently highlights) are buffer-local, and would persist across buffer switching... Commented Jul 9, 2018 at 2:17
  • @Amadan What I said, I generate highlighting from a ctags file; so, my own namespace, classes, structs, functions, enums, etc. Those vary from project to project so it isn't something you want to put in your ~/.vim/syntax directory. If I'd ever open two windows to different projects at the same time then really they should source different tags.vim files. Commented Jul 9, 2018 at 14:43

2 Answers 2

4

This is what autocommands are for, see :h autocommand

In this case you're likely to want the BufEnter autocommand, triggered whenever vim goes to a different file (:h BufEnter). Probably something like this:

augroup UpdatePerlSyntax  " :h autocmd-group
    autocmd!  " Clear autocommands for this group - prevents defining the same
              " autocommand multiple times
    autocmd BufEnter * source /path/to/tags.vim  " Or whatever action you want
    "       |        | |
    "       |        | +- Command to execute
    "       |        +- Pattern (:h autocmd-patterns), * matches everything
    "       +- :h autocmd-events
augroup END

In addition to BufEnter, there is the FileType autocommand, which might suit you needs a bit better (:h filetype).

In order to use the name of the current file in the autocommand, look at :h <afile>


Another (possibly more elegant) solution is to write a syntax file for the filetypes you are concerned with that uses the generated syntax (:h mysyntaxfile).

Sign up to request clarification or add additional context in comments.

2 Comments

It's taken me longer than I thought; but I intend to accept your answer as soon as I actually used it - I'm still wrestling with the syntax files themselves, so this can take a while :/. Just wanted to add a comment showing that I didn't forget this ;). I'm working on it like full time!
+1 For me, the :h mysyntaxfile and after/syntax/c.vim was the way to do it. Project-specific syntax needs set runtimepath+=./after in ~/.vimrc.
0

In lh-tags, I update tag database on the autocommands BufWritePost and FileWritePost. On the way I update the syntax highlighting for the current buffer.

What I should also do (but did completely forgot), is to update the highlighting in the buffers already opened. But beware, this highlighting update shall not be done every time we enter a buffer (:h BufEnter), but only if it hasn't already been done. IOW, if you source a file, you'll need to check its timestamp (:h getftime())

Indeed, I benched the syntax updating when the ctags database is updated. The slower part isn't the fetching of all the tags, but the actual call to syn keyword (which is the fastest of the lot), 100,000 times (on a real project).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.