0

I was writing a simple Vim plug-in for a generic code generator called Templaty. The generator can theoretically work with any programming language, and I'd like Vim to automatically apply the correct highlighting.

From experiments, I have noticed Vim automatically loads the correct highlighter if I do something like set ft=c.templaty. Now, I was wondering if there's a generic way to auto-detect the first part of this string. Right now, I brute-force it by keeping track of a small dictionary of file extensions and their corresponding file type, then doing exec "setfiletype" (filetype . ".templaty"), but this is far from ideal.

Vim already has ftdetect-logic, quite possibly with lots of user-defined ones. How would I be able to query this information programmatically?

Edit:

As suggested in the comments, I could just read b:current_syntax, but the problem is that the additional .tply file extension might prevent the default ftdetect-logic from working. Would it be possible to tell Vim to try detecting the correct file type as if the file was without the .tply extension?

  • Actually, your problem is that you unlet b:current_syntax inside your code. Just don't do this and you can read it afterwards. – Matt Feb 1 at 13:07
  • Actually ... That's so simple that I totally forgot about it! Will try it out later today; thanks! – samvv Feb 1 at 13:13
  • It looks like you may already have solved your problem, but in case you haven't, I have a question about Now, I was wondering if there's a generic way to auto-detect the first part of this string. Could you explain a bit more about the scenario in which you need to run auto-detection? Is there a buffer? Is it saved? Does it have contents? – Rich Feb 3 at 10:00
  • @Rich I haven't had time to test it yet, but I believe the problem is solved with @Matt's comment. To answer your question, the logic should be in ftdetect/, so I suppose this is right after a file is loaded. – samvv Feb 3 at 10:14
  • So you just wanted to know how to query the current filetype? – Rich Feb 3 at 10:16
2

So the whole point is that if &filetype is of the form x.y then Vim automatically loads indents and syntaxes from both x.vim and y.vim.

Then the code in syntax/y.vim must take this into account and keep the previous value of b:current_syntax. So instead of usual: if exists('b:current_syntax') | finish | endif, or unlet b:current_syntax it should start with something like that:

if !exists('b:current_syntax')
    " cannot be the first syntax!
    finish
endif
" append the new syntax instead of overwriting it
let b:current_syntax .= '.y'

As suggested in the comments, I could just read b:current_syntax, but the problem is that the additional .tply file extension might prevent the default ftdetect-logic from working. Would it be possible to tell Vim to try detecting the correct file type as if the file was without the .tply extension?

If you want to also make an auto-detection working then you have to write a file-detection script and put it under ftdetect/ subdirectory (the file name does not matter, as detection scripts are always preloaded):

au BufNewFile,BufRead ?\+.tply
    \ exe 'doau filetypedetect BufRead' fnameescape(expand('<afile>:r')) |
    \ if did_filetype() |
    \     let &ft .= '.templaty' |
    \ endif

Note that filetype will be set twice, but it should not be important, as "standard" syntaxes/indents have a guard against double inclusion.

|improve this answer|||||
  • That last snippet is exactly what I was looking for! Thank you so much! I'll try to integrate it in a patch tomorrow. – samvv Feb 3 at 16:59

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.