How to put vim syntax definitions in a ftdetect script? - vim

Since my filetype is very simple, I would prefer not to create a separate .vim/syntax file and just put the definitions in my .vim/ftdetect script. That way I can install my filetype with a single symlink to my source dir.
I can do this using autocmd BufRead *.log:
autocmd BufRead *.log syn match Heading "^## .*$"
autocmd BufRead *.log syn match Comment "^//.*$"
...
However this doesn't work when I read from stdin because of the *.log condition. Ideally I should be able to do :set filetype=vimjournal to get the syntax highlighting, however the following does not work:
autocmd FileType vimjournal syn match Heading "^## .*$"
autocmd FileType vimjournal syn match Comment "^//.*$"
...
Note, all the other autocmd FileType settings do work for this script.
Is it possible to put filetype syntax descriptions in a ftdetect script? I don't see much difference from the *.log case.
Full script on github: https://github.com/rogerkeays/vimjournal/blob/main/vimjournal.vim

Ideally I should be able to do :filetype vimjournal
:h :filetype is not used this way. What you want is :setf[iletype] vimjournal or :set ft=vimjournal (the difference between the two is really negligible in your case).
put the definitions in my .vim/ftdetect script
The whole purpose of :h ftdetect is to set :h 'filetype' automatically (based on file name and/or contents). As you want the manual setting you don't need it.
Instead, put your syntax commands under ~/.vim/syntax or ~/.vim/after/syntax where they ought to be. The file should look like this
" standard "guard", just in case
if exists('b:current_syntax')
finish
endif
" some syntax stuff
syn match ...
syn match ...
" set arbitrary syntax name
let b:current_syntax = '...'

Related

Vim colorscheme not loading when using autocommand BufNewFile

When trying to automatically open the corresponding .cpp or .h file using autocommand I encounter no colorscheme on the corresponding file that is opened.
I'm not too familiar with vimscript but I believe Vim is opening the file thinking it is of file type ".txt" and therefore using a default colorscheme.
Two autocommand lines in ~/.vimrc:
au BufRead,BufNewFile *.cpp exe "bel vsplit" fnameescape(expand("%:r").".h")
au BufRead,BufNewFile *.h exe "vsplit" fnameescape(expand("%:r").".cpp")
Any help would be appreciated.
Your answer is a workaround (though you should use :setlocal instead of :set to avoid that the syntax leaks out to new buffers that are opened from that one), but it doesn't attack the root cause, which you'll find explained at :help autocmd-nested:
By default, autocommands do not nest. If you use ":e" or ":w" in an autocommand, Vim does not execute the BufRead and BufWrite autocommands for those commands. If you do want this, use the "nested" flag for those commands in which you want nesting.
Syntax highlighting (you say colorscheme in your title, but that's actually just the color and font attributes that are then used by syntax highlighting) is based on :autocmd events (same goes for filetype plugins, so any C++-related settings you also wouldn't find in the split file, assuming you have :filetype plugin on in your ~/.vimrc). Without the nested attribute, the split file will be opened, but none of the usual actions will be run on them. Though nesting in general can be problematic, this is one of those cases where it is needed.
au BufRead,BufNewFile *.cpp nested exe "bel vsplit" fnameescape(expand("%:r").".h")
au BufRead,BufNewFile *.h nested exe "vsplit" fnameescape(expand("%:r").".cpp")
Unfortunately, this introduces another problem: The one autocmd will trigger the other one, and vice versa (up to a limit). You need to guard the actions so that a split is only done if the file isn't open yet. (This also improves on the usability in a general way, when you open a file with the other already open.) :help bufwinnr() checks whether the target buffer is already visible in a window:
au BufRead,BufNewFile *.cpp nested if bufwinnr("^" . expand("%:r").".h$") == -1 | exe "bel vsplit" fnameescape(expand("%:r").".h") | endif
au BufRead,BufNewFile *.h nested if bufwinnr("^" . expand("%:r").".cpp$") == -1 | exe "vsplit" fnameescape(expand("%:r").".cpp") | endif
If anyone cares to look at this in the future the solution was that Vim was loading the second file as syntax=none. So adding | set syntax=cpp at the end of each auto command fixed it.

Disable syntax highlighting for certain filenames

I have syntax highlighting enabled in .vimrc, but that makes loading certain files too long. So I need to disable (or, to be precise, not enable... enabling it and then disabling is not a solution) syntax highlighting for these files. I tried
au BufNewFile,BufRead !*.inc syntax enable
but that made just no syntax highlighting applied ever. The solution presented here does not work for me, since I can't make a distinction by filetype. I tried adapting to no avail, which might or might not be connected to the events needed for "syntax enable".
Thanks for any pointers!
The mentioned solution points to the right direction: Define an autocmd for all buffers, and then (instead of 'filetype'), match with the filename via expand('<afile>'):
au BufNewFile,BufRead * if expand('<afile>:e') !=? 'inc' | syntax enable | endif
Here, I've used your example of *.inc extensions in the condition. If you find the matching cumbersome and would rather use the autocmd syntax, you can do that with an intermediate buffer flag, too, using the fact that autocmds are executed in order of definition:
au BufNewFile,BufRead *.inc let b:isOmitSyntax = 1
au BufNewFile,BufRead * if ! exists('b:isOmitSyntax') | syntax enable | endif
If you want to show syntax only for .c files. Put
syntax off
autocmd! bufreadpost *.c syntax on
in your vimrc.
Also you can map a key for enabling syntax (Ctrl+s in this case)
nnoremap <C-S> :syntax on<CR>
In you question you want to disable syntax only for .inc file. Do it like this:
syntax on
autocmd! bufreadpost *.inc set syntax=off
To disable syntax highlighting for files with .inc extension, you can basically use:
syntax on
au BufNewFile,BufRead *.inc setlocal syntax=OFF
To disable it for multiple extensions, e.g. also for py:
au BufNewFile,BufRead *.{inc,py} setlocal syntax=OFF

Vim: How to disable syntax altogether for certain filetype

I'm trying to disable syntax for Markdown files using autocmd in Vim. I have the following in my .vimrc:
function! SyntaxOff()
echom "one"
syntax off
echom "two"
endfunction
autocmd filetype markdown exe "call SyntaxOff()"
When I open a Markdown file and check :messages, I can see the one and two, and yet the syntax is still on. If I open a dummy file and subsequently open a Markdown file, then I can see that syntax is disabled. If I then open a file of a different filetype, then syntax is still disabled. My guess is that something else in my .vimrc is re-enabling the syntax when I open Vim up for the first time, but then after the function runs syntax is permanently shut off.
So my questions are (1) How can I disable syntax for Markdown files when I open them directly (i.e. not using the maneuver described above)? (2) How can I get Vim to re-enable syntax when I then open another file of a different filetype?
You should wrap your auto commands in a check and also in a group or else you will set multiple auto commands (resource leak) and Vim will slow down after a long time of use. It's also better to use FileTypes instead of regular expressions/matchers for auto commands. However, in some cases the regular expressions make sense. In this case I think you want to use a regex to match *.md as well as markdown files because Vim doesn't detect *.md as markdown.
if has("autocmd")
augroup standard
autocmd!
autocmd BufNewFile,BufRead *.markdown,*.md setlocal setfiletype disabled
augroup END
endif
#kev's answer shows you how to disable the Markdown filetype completely by modifying the filetype detection.
If you want to keep the filetype and indent plugins, and just disable the syntax, you can either:
turn off after-the-fact
Create ~/.vim/after/syntax/markdown.vim with:
setlocal syntax=
avoid turning on
Create ~/.vim/syntax/markdown.vim with:
if exists("b:current_syntax")
finish
endif
let b:current_syntax = "markdown"

Vim inconsistently syntax highlighting bash files

When I open some bash script files with vim it sometimes identifies them as conf files, that's okay, I can just correct that by setting the filetype to sh with :setf sh.
That great, except I've noticed that this doesn't fix things entirely:
Notice that shopt is properly highlighted on the left, but not on the right, where I manually set the filetype to sh.
This means that when a file is identified as bash or sh by vim, it sets the filetype to sh but then does some extra steps that I'm not doing when I set the filetype manually.
Any one know what that might be, and how I could fix it?
vim already recognizes many file types by default. Most of them work by file extensions, but in a case like this, vim will also analyze the content of the file to guess the correct type.
vim sets the filetype for specific file names like .bashrc, .tcshrc, etc. automatically. But a file with a .sh extension will be recognized as either csh, ksh or bash script. To determine what kind of script this is exactly, vim reads the first line of the file to look at the #! line.
If the first line contains the word bash, the file is identified as a bash script. Usually you see #!/bin/bash if the script is meant to be executed directly, for some other shell configuration file you should use the file extensions .bash.
The help in vim explains this as well at :help ft-bash-syntax. You can also use let g:is_bash=1 in your .vimrc to make bash syntax highlighting the default for all files with filetype=sh. If you want to look at the details, this is implemented in $VIMRUNTIME/filetype.vim.
It turns out that syntax/sh.vim includes specific highlighting for Korn, Bash and sh, you just have to tell it which you're using. This is done with b:is_kornshell, b:is_bash and b:is_sh respectively.
Depending on the situation I figure I'll use the following:
ftdetect/bash.vim:
au BufRead,BufNewFile *bash* let g:is_bash=1
au BufRead,BufNewFile *bash* setf sh
Modeline:
# vim:let g:is_bash=1:set filetype=sh:
Key Mapping
nmap <silent> <leader>b :let g:is_bash=1<cr> :setf sh<cr>
Similar to Peter Coulton's solution and documented as well as an alternative in the section "new-filetype" of the "filetype" Vim help the ~/.vim/filetype.vim file could contain the following code:
if exists("did_load_filetypes")
finish
endif
augroup filetypedetect
au! BufRead,BufNewFile *bash* let b:is_bash = 1 | setfiletype sh
augroup END
This approach has the following implications:
There is one ~/.vim/filetype.vim file instead of one for each file type under the ~/.vim/ftdetect directory.
The b:is_bash variable is set local to the buffer as opposed to global by referring to it as g:is_bash.
Try viewing the effective syntax setting
:windo echo b:current_syntax
(I kind of expect the first window to say bash, and the second to say sh...?)
Also try mucking with the synatx synchronisation:
:windo syn sync fromstart
:windo syn sync minlines=300
In general
:he syn-sync
for more information
PS.
A long shot, but some other highlighting might be interfering:
:windo se #/=''
:match none
:2match none
:3match none

Unable to set syntax highlighting automatically in Vim

I have the following in my .vimrc
syntax on
filetype plugin indent on # Thanks to Jeremy
I run
vim ~/.vimrc
I get the right syntax highlighting.
I source many files in my .vimrc. My .vimrc is a like a roadmap for me where I navigate by
CTRL-W f
The problem occurs when I navigate to a file which I have sourced: no colors.
All my sourced files contain the word Vim in their PATHs.
It may be possible to use this fact in solving the problem.
How can you provide a syntax highlighting automatically for the sourced files?
Do the files in question end in ".vim"? If not, then vim's filetype detection may not be able to determine that these files contain vim-script. You can either rename the files so that they end in .vim, or add an autocommand to set the filetype appropriately.
To do the latter, you can add something like this to your .vimrc:
au! BufNewFile,BufRead PATTERN set filetype=vim
replacing "PATTERN" with a file pattern that will match the files in question.
EDIT:
See :help autocmd-patterns for how the patterns work:
The file pattern {pat} is tested for a match against the file name in one of
two ways:
1. When there is no '/' in the pattern, Vim checks for a match against only
the tail part of the file name (without its leading directory path).
2. When there is a '/' in the pattern, Vim checks for a match against the
both short file name (as you typed it) and the full file name (after
expanding it to a full path and resolving symbolic links).
In particular, note this example:
Note: To match part of a path, but not from the root directory, use a '*' as
the first character. Example: >
:autocmd BufRead */doc/*.txt set tw=78
This autocommand will for example be executed for "/tmp/doc/xx.txt" and
"/usr/home/piet/doc/yy.txt". The number of directories does not matter here.
In your case you probably want something like:
au! BufNewFile,BufRead */Vim/* set filetype=vim
To make vi consider my jQuery (.jq) files are actually javascript (.js) I did: -
Create and/or or edit your vimrc file ...
e#dev3:~$ vi ~/.vimrc
Add the following text (press i to insert) ...
if has("syntax")
syntax on
filetype on
au BufNewFile,BufRead *.jq set filetype=javascript
endif
Save the vimrc file ...
[esc]:wq[enter]
Further, to find supported filetypes look in filetype.vim ...
e#dev3:~$ sudo locate filetype.vim
/usr/share/vim/vim72/filetype.vim
e#dev3:~$ sudo grep "\.js[, ]" `locate filetype.vim`
au BufNewFile,BufRead *.js,*.javascript,*.es,*.jsx setf javascript
... the filetype is the setf arg ...
e#dev3:~$ sudo grep "\.js[, ]" `locate filetype.vim` | cut -d " " -f 4
javascript
Have fun.
What is the extension of the files you source? The extension is the usual way for Vim to detect what syntax highlighting it neds to use, and for source-able files (vimscript) it should be .vim. It sounds like that's not the case, if you only see the problem with the sourced files, and not with any others.
One obvious question is there's no line saying "syntax off" in the files you're sourcing?
It could be:
the "filetype" option
the filetype might not be auto-detected by vim
filetype on sorts the first, and the second is fixable with autocmds based on the file extensions.

Resources