Reputation: 5634
I have a custom file format for graphs which looks like this:
node1.link1 : node2
node1.attribute1 : an_attribute_for_node1
node2.my_attribute1 : an_attribute_for_node2
(there is nothing special about the attributes names, an attribute is a link iff one can find its value at the left of a dot. So node2
is a link, because there is a line somewhere in the file that begins with node2.<something>
).
I would like to highlight the attribute values if they are links (so I would like to highlight node2, but not attribute_for_node1
).
Obviously, this kind of syntax highlighting cannot be based only on line wide regexp, because one needs to read the entire file to do the correct highlighting.
I already have a python parser for this kind of files (which gives a dict of dict string -> (string -> string)
), but I don't know if python can interact with syntax highlighting in vim 7.
EDIT As a clarification, the dictionary produced for this example is:
d = { 'node1': {'link1' : 'node2', 'attribute1' : 'an_attribute_for_node1'}, 'node2': {'attribute2': 'an_attribute_for_node2'} }
By definition, l
is a link for node n
if and only if:
d[n][l] in d
Names are meaningless, the format is only structure dependant, and there is no language keywords.
I would like to highlight node2
in the first line, because it is the name for a node.
I hope it is clearer now.
Someone has an idea ?
Upvotes: 1
Views: 1512
Reputation: 72606
This should be very straightforward, but it's a little difficult to work out exactly what your dict looks like (what is 'string'? node1? attribute1? something else?). I have a plugin that I wrote called the ctags highlighter which does a fairly similar thing: it uses ctags to generate a list of keywords and then uses python to turn this into a simple vim script that highlights those keywords appropriately.
Basically, what you need to do is make your parser (or another python module that uses your parser) to generate a list of keywords (node1, node2 etc) and output them in this form (use as many per line as you like, but don't make the lines too long):
syn keyword GraphNode node1 node2
syn keyword GraphNode node3
Write this to a file and create an autocommand that does something like:
autocmd BufRead,BufNewFile *.myextension if filereadable('nodelist.vim') | source nodelist.vim | endif
Then do:
hi GraphNode guifg=blue
or whatever. If you want more details, post a little more information about your parser or have a look at the code in my plugin.
For more information, see
:help :autocmd
:help syn-keyword
:help BufEnter
:help BufNewFile
:help filereadable()
:help :source
:help :highlight
Edit
I'm still not completely sure I know what you want, but if I am understanding correctly, something like this should work:
Let's assume that your python parser is called mypyparser.py
, it takes one argument (the current filename) and the dictionary it creates is called MyPyDict
. You'll obviously have to modify the script to match the actual use of your parser. Add this script somewhere in your runtimepath (e.g. in .vimrc or in ~/.vim/ftplugin/myfiletype.vim) and then open your file and type :HighlightNodes
.
" Create a command for ease of use
command! HighlightNodes call HighlightNodes()
function! HighlightNodes()
" Run the parser to create MyPyDict
exe 'pyfile mypyparser.py ' . expand('%:p')
" Next block is python code (indent gone to keep python happy)
py <<EOF
# Import the Vim interface
import vim
# Iterate through the keys in the dictionary and highlight them in Vim
for key in MyPyDict.keys():
vim.command('syn keyword GraphNode ' + key)
endfor
EOF
" Make sure that the GraphNode is highlighted in some colour or other
hi link GraphNode Keyword
endfunction
Upvotes: 2