Disable warning in VIM? - vim

Is there a way to disable warnings in VIM?
In particular, I want to disable Warning 12 when a file turns from read-only to writable. I have a script which opens the file for edit in perforce, but vim thinks the file has changed and issues a warning.
Thanks

I have the following in my .vimrc; you should only need the second one. It echoes the message to the status bar instead of popping up a dialog.
autocmd FileChangedRO * echohl WarningMsg | echo "File changed RO." | echohl None
autocmd FileChangedShell * echohl WarningMsg | echo "File changed shell." | echohl None
Try :help FileChangedShell for more information.

add the following line to your .vimrc file :
set autoread
This will disable "read-only to writeable" warnings

I've been using FileChangedRO for a while now to automatically checkout files when starting to edit them and found the W12 warning annoying as well. The problem is that p4 edit updates the file attributes to remove the read only flag. If as part of the initial edit you also change the file, Vim sees this as a conflict since it's no longer read only. Here's the solution I use which is a bit more conservative about using FileChangedShell in case the file was changed externally for some other reason.
let s:IgnoreChange=0
autocmd! FileChangedRO * nested
\ let s:IgnoreChange=1 |
\ call system("p4 edit " . expand("%")) |
\ set noreadonly
autocmd! FileChangedShell *
\ if 1 == s:IgnoreChange |
\ let v:fcs_choice="" |
\ let s:IgnoreChange=0 |
\ else |
\ let v:fcs_choice="ask" |
\ endif

Related

Is it possible to prevent vim from quitting from the status of QuitPre autocommand? (e.g. prevent close on syntax issues)

I know that it is possible to use QuitPre to expedite quits (e.g. if there are no "ordinary" buffers left), but is it possible to have a "safety check" for a file that was just modified?
Applications of this would be:
checking that gitconfig is still valid before leaving
checking that sudoers file is still valid before leaving
checking that the crontab is still valid before leaving
checking that ALE has no errors for the given file before leaving
I make quick edits to ~/.gitconfig all the time, and it's quite jarring when it breaks and I have to navigate to it & edit it again later. It would be nice to run a quick check before absent-mindedly :wq'ing out of it and moving on.
EDIT:
echoerr does not seem to block it
opening a new tab seems to block it, but that's pretty cumbersome. It can't even be used for a "re-open", since it blocks the original close in that case. It's a bit of a Catch-22.
In a filetype plugin:
augroup TestGitConfigBeforeExit
autocmd!
autocmd
\ QuitPre
\ <buffer>
\ *
\ call system("git config -l") | if v:shell_error == 0 | echom "Safe to quit" | else | echoerr "invalid gitconfig" | tabe ~/SCRATCH | endif
augroup END
Alright this feels incredibly stupid so if someone else can think of a better solution, please post it for others:
augroup TestGitConfigBeforeExit
autocmd!
autocmd
\ QuitPre
\ <buffer>
\ call system("git config -l")
\| if v:shell_error == 0
\| echom "Safe to quit"
\| else
\| tabe %:p
\| tabclose #
\| echoerr "invalid gitconfig; fix before quitting"
\| endif
augroup END
No idea why tabe seems to block it, but it does. The tabclose # at least cleans-up the duplicate tab. This should be an extensible solution for any kind of "make sure I did not break the file before I quit-out and move on".

How do I get VIM to always open the last opened file?

I want vim to always open the last opened file instead of an empty un-named file with VIM - Vi IMproved... message.
How can I do that?
Add this autocmd into your .vimrc which will be triggered when executing vim from shell without arguments:
autocmd VimEnter * if
\ argc() == 0 &&
\ bufname("%") == "" |
\ exe "normal! `0" |
\ endif
Execute '0 at the startup of vim.

Error detected message while using Vim editor

When I try to open a file for editing using vim I get this following message and error detected message.
Jashs-MacBook-Pro:hello jashjacob$ vim hello.rb
--- Auto-Commands ---
filetypedetect BufRead
*if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat | runtime! scripts.vim | endif
*if !did_filetype() && expand("<amatch>") !~ g:ft_ignore_pat && (getline(1) =~ '^#' || getline(2) =~ '^#' || getline(3) =~ '^#'^I|| getline(4) =~ '^#' || getline(5) =~ '^#') | setf conf | endif
Error detected while processing /usr/share/vim/vimrc:
line 18:
E116: Invalid arguments for function line("'"") > 0 && line ("'"") <= line("$") |
E15: Invalid expression: line("'"") > 0 && line ("'"") <= line("$") |
Press ENTER or type command to continue
Have my vim editor files been damaged/modified ? How can i fix the error detected while processing /usr/share/vim/vimrc ?
/usr/share/vim/vimrc config file contains the following
" Configuration file for vim
set modelines=0 " CVE-2007-2438
" Normally we use vim-extensions. If you want true vi-compatibility
" remove change the following statements
set nocompatible " Use Vim defaults instead of 100% vi compatibility
set backspace=2 " more powerful backspacing
set ai " auto indenting
set history=100 " keep 100 lines of history
set ruler " show the cursor position
syntax on " syntax highlighting
set hlsearch " highlight the last searched term
filetype plugin on " use the file type plugins
" When editing a file, always jump to the last cursor position
autocmd BufReadPost *
if ! exists("g:leave_my_cursor_position_alone") |
if line("'"") > 0 && line ("'"") <= line("$") |
exe "normal g'"" |
endif |
endif
" Don't write backup file if vim is being called by "crontab -e"
au BufWrite /private/tmp/crontab.* set nowritebackup
" Don't write backup file if vim is being called by "chpass"
au BufWrite /private/etc/pw.* set nowritebackup
I'm not a vimscript guru, so perhaps someone will be able to offer more of a fix, but I can suggest that if you just want to get vim working again you could comment out the function that's causing the trouble. Precede each line with a double-quote symbol (") and you should be able to get on with things.
Like so:
" When editing a file, always jump to the last cursor position
"autocmd BufReadPost *
" if ! exists("g:leave_my_cursor_position_alone") |
" if line("'"") > 0 && line ("'"") <= line("$") |
" exe "normal g'"" |
" endif |
" endif
If you want to preserve this functionality, you might have to learn a little vimscript. :)
I think these error messages could also come from the fact that you missed or miss-placed "set nocompatible" in your .vimrc. That will cause your Vim misunderstood the backslashes used to continue long lines in it's scripting files. It's better to put "set nocompatible" at the very beginning of your .vimrc file.
If you see "if !did_filetype() ..." in the error message and compared it with the code in /usr/share/vim/vim{yourversion}/filetype.vim you can tell that there should be a "\" in between "" and "if".
see this entry for more details
YOU ARE NOT SUPPOSED TO DO ANYTHING IN /usr/share/vim/.
That file you have edited is not yours and should not be changed at all. These are the files and places where you can do whatever you want:
~/.vim/ <-- put your plugins and colorschemes in this directory
~/.vimrc <-- add your options and mappings to this file
As for your question:
Those lines were not added by a plugin, they were added by you or someone else who has access to your machine.
They throw an error because the dumbass who pasted them somehow thought it was a good idea to remove the line-continuation backslashes that are in the "original" (or this "original", or that one, or the older link in the post that leads to a 404, or the simpler version that is in $VIMRUNTIME/vimrc_example.vim).
Never run a command you find on the internet unless you are sure it won't cause troubles.

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.

How can I make vim check automatically if the file has changed externally?

I usually open many files in tabs with vim -p. Is it possible to check if any of the files was changed outside of Vim since editing started?
Add these lines to your .vimrc:
au FocusGained,BufEnter * :silent! checktime
au FocusLost,WinLeave * :silent! w
Basically, check for and reload (or discard) external changes when Vim or the current buffer gains focus, and optionally, auto-save when leaving focus.
Source: Vim Wiki.
I came across an interesting find related to this question today...
Hidden in /usr/share/vim/vim71/vimrc_example.vim there is this command:
" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
\ | wincmd p | diffthis
It will open a vimdiff-like window with the current buffer and the underlying file highlighting all of the changes between the two.
vim usually warns me automatically if it detects an external change to a file; however, from perusing the documentation it looks like you can invoke that check manually with :checktime
Unfortunately I don't know how to disable that aforementioned automatic check to test and see if checktime does the right thing, so this answer might be completely off-base.
Use :edit
:help :edit for more info.
You can find out if the buffer in the active window is modified by running the command:
:set mod?
If it returns nomodified, then the contents of the buffer match those of the corresponding file. If it returns modified, then the buffer has unsaved changes.
By default, the status-line shows a [+] symbol if the current buffer has been modified. The status line is generally only visible if you have split windows. If you want to show the status line, even when you have just a single window, run:
:set laststatus=2
There's a good article about customizing your status line on Vim Recipes.
let s:pid=system("ps -p $$ -o ppid=")+0
if !exists('g:watches')
let g:watches={}
else
finish
endif
function! ModWatch(fname, match)
let fname=fnamemodify(a:fname, ':p')
if has_key(g:watches, fname)
return
endif
let shellscript=
\"while true ; do".
\" inotifywait ".shellescape(fname)." ; ".
\" kill -WINCH ".s:pid." ; ".
\"done"
echo shellscript
echo shellescape(shellscript)
let pid=system("sh -c ".shellescape(shellscript)." &>/dev/null & echo $!")+0
call extend(g:watches, { fname : pid })
augroup ModWatch
execute "autocmd! BufWipeOut ".a:match
execute "autocmd BufWipeOut ".a:match.' call DeleteWatch("'.
\escape(fname, '\"|').'")'
augroup END
endfunction
function! DeleteWatch(fname)
call system("kill ".g:watches[a:fname])
unlet g:watches[a:fname]
endfunction
augroup ModWatch
autocmd!
autocmd VimResized * checktime
autocmd BufNew * call ModWatch(expand("<afile>"), expand("<amatch>"))
augroup END

Resources