Delegating vim filetype after removing suffix - vim

I know how to configure vim to select a particular filetype based upon an extension:
au BufNewFile,BufRead *.foo set filetype=foo
However, a common case for me is to wind up opening a file with an additional suffix. One specific scenario is resolving version control conflicts during a merge. I'll have up files like "foo.cpp.orig" or "foo.java.merge", etc. I'd like to configure vim so that if it opens a file ending in ".orig", etc. for it to strip that suffix and use remaining file extension to select the filetype.
And yes, I do know I could do something like
au BufNewFile,BufRead *.java.* set filetype=java
But that is less than ideal because I have to manually add an entry for all the possible filetypes I might be editing.

" Ignored extensions
if exists("*fnameescape")
au BufNewFile,BufRead ?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.dpkg-dist,?\+.dpkg-old,?\+.dpkg-new,?\+.dpkg-bak,?\+.rpmsave,?\+.rpmnew
\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r"))
au BufNewFile,BufRead *~
\ let s:name = expand("<afile>") |
\ let s:short = substitute(s:name, '\~$', '', '') |
\ if s:name != s:short && s:short != "" |
\ exe "doau filetypedetect BufRead " . fnameescape(s:short) |
\ endif |
\ unlet! s:name s:short
au BufNewFile,BufRead ?\+.in
\ if expand("<afile>:t") != "configure.in" |
\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r")) |
\ endif
elseif &verbose > 0
echomsg "Warning: some filetypes will not be recognized because this version of Vim does not have fnameescape()"
endif
actually, Vim already considered it. the above code is from filetype.vim

After looking at the code Dyno pointed me to, I think what I want is to add
au BufNewFile,BufRead ?\+.merge
\ exe "doau filetypedetect BufRead " . fnameescape(expand("<afile>:r"))
to my .vimrc. It isn't quite as nice as having some variable to set to extend the list of known patterns, but isn't as much of a hack as modifying the original filetype.vim.

Related

Vimrc: check if unix command is installed

I have these in my vimrc:
if has("autocmd")
augroup Misc
" Jump to the last known position when reopening a file
autocmd BufReadPost *
\ if line("'\"") > 1 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
augroup END
augroup FTOptions
autocmd!
autocmd FileType cpp,java setlocal commentstring=//\ %s
autocmd FileType markdown setlocal textwidth=78 formatprg=par\ -w78
augroup END
In markdown files I'd like to do the formatting using par. It works well, but I get a warning if "par" is not installed on the system. I'm wondering if there's a way to check and only set "formatprg=par\ -78" when par is installed, otherwise use VIM's default formatting.
I would be grateful for any suggestion.
if executable('par')
" stuff
endif

Special path of vim swap files for files in certain location

Due to my configuration, vim stores swap files in the same directory as the edited file. In general, that is ok, but not in the folder ~/ftp_mount (and all directories below). In this directory I mount an ftp server.
With
:set dir=/some/path
one can change the location in which vim stores the swap files (vim documentation). Is it possible to restrict this configuration to ~/ftp_mount and all directories below?
Disabling swapfile, setting directory, and enabling it back seems to work:
autocmd BufNewFile,BufReadPre *
\ setl noswapfile noundofile |
\ if expand('%:p') =~ "/my/custom/path" |
\ setl undodir=. directory=. |
\ else |
\ setl undodir=~/.cache/nvim/undo directory=~/.cache/nvim/swap |
\ endif |
\ setl swapfile undofile
I am matching *, not my path particularly, because I want it to work if I:
Open a file under my custom path.
Load a new file from elsewhere.
How about using an autocmd on the directory you want to apply this setting to (~/ftp_mount)
autocmd BufNewFile,BufRead ~/ftp_mount/* set dir=/some/path

set vim filetype for files with no extension, only

How do I set up filetype and/or syntax for files that have no extension in vim?
Note
This is a duplicate of vim default syntax for files with no extension. I'm asking again because no one has answered it properly in my view.
I don't want to know how to set the default syntax for unrecognized file types, I want to know how to set it only for extensionless files.
You can create an autocommand that checks if the filename contains a ., and if not, switches to a given syntax:
autocmd BufNewFile,BufRead * if expand('%:t') !~ '\.' | set syntax=perl | endif
This one picks perl as a default syntax, but you can simply use whichever is appropriate.
:help ftdetect will show the part of the vim documentation about how to write filetype detection scripts.
Here's what I suggest for this case:
Create a file in ~/.vim/ftdetect named after your filetype, e.g. myfiletype.vim.
In this file put
au BufRead,BufNewFile * if expand('<afile>:e') == '' | set ft=myfiletype | end
This will cause vim to set the filetype for files without any extension to myfiletype. If you want it to only be used if no other filetype was detected use setfiletype myfiletype instead of set ft=myfiletype.
Then create the syntax file ~/.vim/syntax/myfiletype.vim. This is just a normal vim syntax defintion file, nothing special. If you do not want to create your own filetype, just use the normal filetype in the autocommand instead of myfiletype. For example
au BufRead,BufNewFile * if expand('<afile>:e') == '' | set ft=html | end
would set the html file type which would load the html syntax file.
1) Hit escape to make sure you're in normal mode
2) Type ":set syntax=java" (or equivalent language)
3) :set filetype=FILETYPE, where FILETYPE is the filetype.
If you're looking to do this automatically, try using the solution from previous answer:
autocmd BufNewFile,BufRead * if expand('%:t') !~ '\.' | set syntax=perl | endif
In the end, I've chosen this for my C++ configuration:
let s:reserved = '^NERD_tree\|^GoToFile$'
au BufNewFile,BufRead *
\ if expand('%:e') =~ '^\(h\|hh\|hxx\|hpp\|ii\|ixx\|ipp\|inl\|txx\|tpp\|tpl\|cc\|cxx\|cpp\)$' ||
\ expand('%:t') !~ '\.\|'.s:reserved && expand('%:t') =~ '[a-z]' |
\ if &ft != 'cpp' |
\ set ft=cpp |
\ endif |
\ set syntax=cpp11 |
\ call CSyntaxAfter() |
\ endif
Instead of only checking for the lack of . in the tail. This avoids several non cpp files from being set like COMMIT_EDITMSG, README, GoToFile from CommandT and NERD_tree* from NERD tree.
EDIT
I just gave up on this idea.

Is it possible to disable the LargeFile Vim plugin for certain filetypes?

I am mostly happy with the LargeFile plugin, but have recently had a need to selectively disable it for a specific filetype. The LargeFile plugin disables the FileType event; and the filetype in question is determined from the file contents, not the file extension, so I need to use the BufReadPost event like so:
au BufReadPost * if &ft == "myfiletype" | let g:LargeFile=100 | endif
But setting g:LargeFile has no effect there. I also tried calling the :Unlarge command with no effect. How can I disable the LargeFile plugin or modify its settings based on the filetype?
Your auto-command does not work because at the moment of its execution
the filetype of the current buffer is not detected yet. If the target
filetype can be deduced from the filename, use an auto-command pattern
instead of testing against the filetype.
Here is an example for CĀ files:
autocmd BufRead *.c Unlarge
If the filename pattern detection is not sufficient, manually trigger
the filetype detection first:
autocmd BufRead *.c
\ if !did_filetype() | filetype detect | endif |
\ if &ft is# 'c' | Unlarge | endif

To change TYPE to nothing from conf in Vim

My syntax -highlighting is broken for a file which Type is conf as follows:
File where the syntax highlighting does not work
alt text http://files.getdropbox.com/u/175564/bugs/vim-bug-type.png
The syntax highlighting works for all other files with the extension .markdown. However, the only difference between these files is that the other files' type is nothing, while that of a file, which has bug, its Conf.
File where the syntax highlighting works
alt text http://files.getdropbox.com/u/175564/bugs/vim-bug-syntax2.png
How can you change the Type to nothing from Conf in Vim?
Try:
:setf none
or (equivalently):
:set ft=
If you want to do it automatically, you'll need to configure the syntax detection. Create a file (if it doesn't exist): vimfiles/after/filetype.vim or ~/.vim/after/filetype.vim. In this file, add the following line:
au BufNewFile,BufRead *.markdown set ft=none
Alternatively, download the markdown syntax from here (I've not tried this) and configure with:
au BufNewFile,BufRead *.markdown set ft=mkd
For more information:
:help :setf
:help 'filetype'
:help :autocmd
:help BufRead
:help BufNewFile
For information, the problem arises because the .markdown extension is not recognised, so Vim looks at the contents to try to determine what the file type is. Presumably there is something in your file that looks a little like a configuration file, so it does its best guess. The guess is carried out in the system filetype.vim, typically in c:\vim\vim72 or /usr/share/vim/vim72/filetype.vim (I think) and looks like this:
" Generic configuration file (check this last, it's just guessing!)
au BufNewFile,BufRead,StdinReadPost *
\ if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat
\ && (getline(1) =~ '^#' || getline(2) =~ '^#' || getline(3) =~ '^#'
\ || getline(4) =~ '^#' || getline(5) =~ '^#') |
\ setf conf |
\ endif
This checks whether any of the first five lines start with a # and if they do and no other filetype has been matched, it sets the filetype to conf.
:set filetype=
will set the file type to none.

Resources