I'm trying to change cursor from block to vertical bar (I-beam) when entering Vim command line.
I was trying with this separate codes:
" with these two codes nothing happens
autocmd CmdlineEnter * let &t_SI
autocmd CmdlineEnter * execute &t_SI
" this last one produce "E20: Mark not set" error
autocmd CmdlineEnter * execute '!echo -ne "' . &t_SI . '"'
Is something like that even possible or vim uses same cursor for cmd line like it uses in normal mode.
I've changed normal mode (&t_EI) to vertical bar and in that case cursor was vertical bar in cmd line.
Can cursor be changed in cmd line regardles of normal mode?
Can someone help with this?
In Vim 8.2.0258 or newer, the echoraw() function can be used
autocmd CmdlineEnter * call echoraw(&t_SI)
autocmd CmdlineLeave * call echoraw(&t_EI)
I've found solution.
It turns out it's possible to change cursor when entering and leaving cmd line.
This code will change cursor to vertical bar when entering cmd line and revert it back to block when leaving cmd line.
" vim cursor escape codes for the terminal emulator
" INSERT (&t_SI) - vertical bar (I-beam)
" REPLACE (&t_SR) - underscore
" VISUAL (&t_EI) - block
let &t_SI = "\<Esc>[5 q"
let &t_SR = "\<Esc>[3 q"
let &t_EI = "\<Esc>[1 q"
" set cursor to vertical bar when entering cmd line and
" revert cursor back to block when leaving cmd line
autocmd CmdlineEnter * execute 'silent !echo -ne "' . &t_SI . '"'
autocmd CmdlineLeave * execute 'silent !echo -ne "' . &t_EI . '"'
Related
I'm used to work with gvim, but I want to use the benefits of vim+tmux. Therefor I want to change to vim. But in vim the cursor style does not change depending in which mode I am, a useful feature of gvim. I use the zsh (oh-my-zsh) and below the gnome-terminal.
I tried this answer: http://vim.wikia.com/wiki/Change_cursor_shape_in_different_modes
if has("autocmd")
au InsertEnter * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
au InsertLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape block"
au VimLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
endif
but that changes the cursor globaly. Definitely something I don't want
next I tried this plugin: http://www.vim.org/scripts/script.php?script_id=4403 , but it hasn't worked neither.
Probably, wincent/terminus vim plugin is what you need:
In insert mode, the cursor shape changes to a thin vertical bar. In replace mode, it changes to an underline. On returning to normal mode, it reverts to the standard "block" shape. Configuration options are provided to select among the different shapes.
For colours, which is what I use:
let &t_SI = "\<Esc>]12;yellow\x7"
let &t_SR = "\<Esc>]12;red\x7"
let &t_EI = "\<Esc>]12;blue\x7"
Other options:
" solid underscore
" let &t_SI .= "\<Esc>[4 q"
" solid block
" let &t_EI .= "\<Esc>[1 q"
" 1 or 0 -> blinking block
" 3 -> blinking underscore
" Recent versions of xterm (282 or above) also support
" 5 -> blinking vertical bar
" 6 -> solid vertical bar
These are termcap codes, see help termcap-cursor-color. The codes themselves are console_codes(4). Thus, these are interactions with the terminal itself, not the vim session.
I have unfortunately not solved an issue about leaving Vim and having the original cursor colour returned. I have tried the following and many variants thereof:
au VimLeave * let &t_EI = "\<Esc>]12;white\x7"
au VimLeavePre * :!echo -ne "\033]12;white\000"
au VimLeavePre * let &t_SI = "\<Esc>]12;white\x7"
but with no success. Anyway, this is how one can change the cursor shape and colour in relation to the editing mode.
For more general changes (eg, the colorscheme changes) upon change of mode, I use
au InsertEnter * call ColoursBasedOnMode(v:insertmode)
au InsertLeave * call ColoursBasedOnMode('n')
autocmd BufWinEnter,BufNew * call ColoursBasedOnMode('n')
in which I have :
:
:
elseif a:mode == 'i'
"echo " ColoursBasedOnMode insert mode"
"set nonumber
"set norelativenumber
colorscheme railscasts
:
:
Set the terminal options just for this terminal emulator.
As pointed here: https://stackoverflow.com/a/25327689/2544873.
let &t_SI = "\<Esc>]12;orange\x7"
let &t_EI = "\<Esc>]12;red\x7"
autocmd VimLeave * silent !echo -ne "\033]112\007"
Set terminal cursor on enter insert mode
Set terminal cursor on leave insert mode
Reset default (gray) color on leave vim
I'm trying to update some text lines containing filenames in specific file in Vim. To do that I've added this in my .vimrc:
let logs_pat = "/ARCHIVE/logs/db_agent.log*"
au! BufEnter *_search.txt execute "/\\[DBA_LOGS\\]/,$d | $put = '[DBA_LOGS]' | $r!ls -t " . logs_pat . " | head "
It works fine except some artifacts. And question is about how to eliminate those artifacts.
Every time when I get into a buffer with file *_search.txt,
1) the contents of the register "" is replaced by the text been added by autocmd to file *_search.txt 2) a message appears on the vim status line: "10 more lines" or "search hit BOTTOM, continuing at TOP"
Thanks
The /\\[DBA_LOGS\\]/,$d command deletes the range of lines into the default register. To avoid that, append the black hole register (_). To suppress the message, prepend :silent.
au! BufEnter *_search.txt execute "silent /\\[DBA_LOGS\\]/,$delete _ | $put = '[DBA_LOGS]' | silent $r!ls -t " . logs_pat . " | head "
To maintain the original cursor position, you can wrap this with either:
:mark z
...
:normal! g`z
or
:let pos = getpos('.')
...
:call setpos('.', pos)
Over on askubuntu.com I was told how to run python on Vim. I am testing the set up which works with the code 1st or 2nd code python code at using python to solve a non linear equation.
The only thing I have done different was added print(a) as the last line. I ran this yesterday from the shell and it worked perfectly. Could someone let me know what is going wrong?
Ok so I corrected the vimrc with the appropriate question marks,
chmod +x ~/path/to/file/hw6problem2.py
Then from vim I ran
:Shell ./#
but I received the same syntax error again. (Does the file have to be saved as .sh because I can't get any .py files to run?)
dustin#dustin:~$ vim /home/dustin/Documents/School/UVM/Engineering/OrbitalMechanics/hw6problem2.py
File "hw6problem2.py", line 14
a0 = max(s/2, (s - c)/2)
^
SyntaxError: invalid syntax
shell returned 1
Press ENTER or type command to continue
vimrc
syntax on
au BufWinLeave * mkview "records settings
au BufWinEnter * silent loadview "reloads settings
set nu "puts line numbers on
set ic "case insensitive
set foldmethod=syntax "for the latex-suite
set autoread "autoload when files in the buffer have been modified
set autochdir "autochange directory
"set wrap
set wrap
" set lines=50 columns=80
" resizes window
:map g1 :set lines=20<CR>:set columns=80<CR>
:map g2 :set lines=50<CR>:set columns=80<CR>
:map g3 :set lines=50<CR>:set columns=170<CR>
:map <F6> :! firefox % &<CR>
:map E Ea
"set autoindent
set tabstop=4
set shiftwidth=2
set expandtab
set smartindent
"
" Stuff for latex-suite
" REQUIRED. This makes vim invoke Latex-Suite when you open a tex file.
" It also allows you to set different actions for different filetypes
" in ~/.vim/after/ftplugin/*.vim
filetype plugin on
set shellslash
" IMPORTANT: grep will sometimes skip displaying the file name if you
" search in a singe file. This will confuse Latex-Suite. Set your grep
" program to always generate a file-name.
set grepprg=grep\ -nH\ $*
" OPTIONAL: This enables automatic indentation as you type.
filetype indent on
" OPTIONAL: Starting with Vim 7, the filetype of empty .tex files defaults to
" 'plaintex' instead of 'tex', which results in vim-latex not being loaded.
" The following changes the default filetype back to 'tex':
let g:tex_flavor='latex'
let g:Tex_ViewRule_pdf = 'okular'
"""""""""""""""""""""""""""""""""""""""
" => Shell command
"""""""""""""""""""""""""""""""""""""""
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
function! s:RunShellCommand(cmdline)
let isfirst = 1
let words = []
for word in split(a:cmdline)
if isfirst
let isfirst = 0 " don't change first word (shell command)
else
if word[0] =~ '\v[%#<]'
let word = expand(word)
endif
let word = shellescape(word, 1)
endif
call add(words, word)
endfor
let expanded_cmdline = join(words)
rightbelow new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !'. expanded_cmdline
1
endfunction
This is likely to be a python issue.
On a side not, there's a great shell function for executing scripts and redirecting output to vim buffer (split window).
Syntax to execute current script (you should have chmod +x and shebang line):
:Shell ./#
In order to add the function, add this to .vimrc:
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
function! s:RunShellCommand(cmdline)
let isfirst = 1
let words = []
for word in split(a:cmdline)
if isfirst
let isfirst = 0 " don't change first word (shell command)
else
if word[0] =~ '\v[%#<]'
let word = expand(word)
endif
let word = shellescape(word, 1)
endif
call add(words, word)
endfor
let expanded_cmdline = join(words)
rightbelow new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !'. expanded_cmdline
1
endfunction
https://github.com/ruslanosipov/dotfiles/blob/master/.vimrc#L137
Can anybody help me to get solution for my requirement?
Requirement is when a user exits from vim, cppcheck should happen and if any warning or error occurs then it should be prompted to a user.
Thanks in advance.
I assume you don't care if the command is executed asynchronously, since you're quitting the buffer anyway. You can use the :! command to run shell commands and :read to capture the output to a new window:
function! s:RunShellCommand(cmdline)
let first = 1
let words = []
" Expand and escape cmd arguments.
" shellescape() should work with '\'
for part in split(a:cmdline)
if first
" skip the cmd. ugly, i know.
let first = 0
else
if part[0] =~ '\v[%#<]'
let part = expand(part)
endif
let part = shellescape(part, 1)
endif
call add(words, part)
endfor
let expanded_cmdline = join(words)
" Create the new window
botright new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'Showing output from cmd: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
" This is where actual work is getting done :-)
silent execute '$read !'. expanded_cmdline
" Uncomment the line below if you want the buffer to be
" non-modifiable
" setlocal nomodifiable
1
endfunction
Then you can define an autocommand for when a buffer is unloading:
au BufUnload *.cpp s:RunShellCommand('cppcheck %')
or a somewhat more generic command which you can call at any time:
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
Now, to prevent closing your buffer, you have to remap :wq or :q to a function that will perform the aforementioned (plus perhaps some confirmation?), since once :quit is invoked, it cannot be aborted.
My question is similar to this how to monitor a text file in realtime
but I want to do it in vim. I know I can read an opened file use tail -f sample.xml file, and when new content is written to the file, it'll also write the new content to my screen. Can I have vim automatically fill the new data when a file is updated?
You can :set autoread so that vim reads the file when it changes. However (depending on your platform), you have to give it focus.
From the help:
When a file has been detected to have
been changed outside of Vim and it
has not been changed inside of Vim,
automatically read it again. When the
file has been deleted this is not
done.
Don't know about automatically, but you can type:
:e!
to reload the file
Put the following in your .vimrc:
" check one time after 4s of inactivity in normal mode
set autoread
au CursorHold * checktime
like #flukus said in a comment to a previous answer you can call feedkeys["lh"] (it moves the cursor to the right and back to the left, which normaly doesn't do harm when viewing a log file)
So, if you combine the rest of the answer you have a oneliner you can run from ex (whithin vim) when needed:
:set autoread | au CursorHold * checktime | call feedkeys("lh")
***(if you would want to jump (nearly) to the end of the file, just use "G" instead of "lh" with feedkeys)***
Explanation:
autoread: reads the file when changed from the outside (but it doesnt work on its own, there is no internal timer or something like that. It will only read the file when vim does an action, like a command in ex :!
CursorHold * checktime: when the cursor isn't moved by the user for the time specified in 'updatetime' (which is 4000 miliseconds by default) checktime is executed, which checks for changes from outside the file
call feedkeys("lh"): the cursor is moved once, right and back left. and then nothing happens (... which means, that CursorHold is triggered, which means we have a loop)
Additionally you can :set syntax=logtalk to color the log
To stop the scrolling when using call feedkeys("G"), execute :set noautoread - now vim will tell, that the file was change ans ask if one wants to read the changes or not)
(Does this have any sideeffects?)
Edit: I see one side-effect: if one uses "G" as the feedkey, it will scroll down every currently opened buffer?! So, it's not possible to work in the left buffer of a splittet window while having the right buffer scroll down a logfile automatically
Edit2: Another side effect is that when you enter the command line window(by using q:) an error message always pops up.
Stick this in your .vimrc and it should work like a boss. (Taken from: http://vim.wikia.com/wiki/Have_Vim_check_automatically_if_the_file_has_changed_externally)
" Function to Watch for changes if buffer changed on disk
function! WatchForChanges(bufname, ...)
" Figure out which options are in effect
if a:bufname == '*'
let id = 'WatchForChanges'.'AnyBuffer'
" If you try to do checktime *, you'll get E93: More than one match for * is given
let bufspec = ''
else
if bufnr(a:bufname) == -1
echoerr "Buffer " . a:bufname . " doesn't exist"
return
end
let id = 'WatchForChanges'.bufnr(a:bufname)
let bufspec = a:bufname
end
if len(a:000) == 0
let options = {}
else
if type(a:1) == type({})
let options = a:1
else
echoerr "Argument must be a Dict"
end
end
let autoread = has_key(options, 'autoread') ? options['autoread'] : 0
let toggle = has_key(options, 'toggle') ? options['toggle'] : 0
let disable = has_key(options, 'disable') ? options['disable'] : 0
let more_events = has_key(options, 'more_events') ? options['more_events'] : 1
let while_in_this_buffer_only = has_key(options, 'while_in_this_buffer_only') ? options['while_in_this_buffer_only'] : 0
if while_in_this_buffer_only
let event_bufspec = a:bufname
else
let event_bufspec = '*'
end
let reg_saved = #"
"let autoread_saved = &autoread
let msg = "\n"
" Check to see if the autocommand already exists
redir #"
silent! exec 'au '.id
redir END
let l:defined = (#" !~ 'E216: No such group or event:')
" If not yet defined...
if !l:defined
if l:autoread
let msg = msg . 'Autoread enabled - '
if a:bufname == '*'
set autoread
else
setlocal autoread
end
end
silent! exec 'augroup '.id
if a:bufname != '*'
"exec "au BufDelete ".a:bufname . " :silent! au! ".id . " | silent! augroup! ".id
"exec "au BufDelete ".a:bufname . " :echomsg 'Removing autocommands for ".id."' | au! ".id . " | augroup! ".id
exec "au BufDelete ".a:bufname . " execute 'au! ".id."' | execute 'augroup! ".id."'"
end
exec "au BufEnter ".event_bufspec . " :checktime ".bufspec
exec "au CursorHold ".event_bufspec . " :checktime ".bufspec
exec "au CursorHoldI ".event_bufspec . " :checktime ".bufspec
" The following events might slow things down so we provide a way to disable them...
" vim docs warn:
" Careful: Don't do anything that the user does
" not expect or that is slow.
if more_events
exec "au CursorMoved ".event_bufspec . " :checktime ".bufspec
exec "au CursorMovedI ".event_bufspec . " :checktime ".bufspec
end
augroup END
let msg = msg . 'Now watching ' . bufspec . ' for external updates...'
end
" If they want to disable it, or it is defined and they want to toggle it,
if l:disable || (l:toggle && l:defined)
if l:autoread
let msg = msg . 'Autoread disabled - '
if a:bufname == '*'
set noautoread
else
setlocal noautoread
end
end
" Using an autogroup allows us to remove it easily with the following
" command. If we do not use an autogroup, we cannot remove this
" single :checktime command
" augroup! checkforupdates
silent! exec 'au! '.id
silent! exec 'augroup! '.id
let msg = msg . 'No longer watching ' . bufspec . ' for external updates.'
elseif l:defined
let msg = msg . 'Already watching ' . bufspec . ' for external updates'
end
echo msg
let #"=reg_saved
endfunction
let autoreadargs={'autoread':1}
execute WatchForChanges("*",autoreadargs)
Tail Bundle should do what you want. Note, haven't used it myself.
There is a plugin also:
https://github.com/djoshea/vim-autoread
This was the only way I could make this work on OSX.
If unix + neovim
:term tail -f <filename>
Obviously this won't work for everyone, but it's how I do it.
To enable reloading if you open a specific file, you can add this to your .vimrc and use a modeline like vim: set ft+=.watch:. It takes advantage of the feature to set multiple filetypes for a buffer (see below):
vim9script
command WatchFiles {
autocmd! AUWatchFile FocusGained,VimResume,BufEnter,WinEnter,CursorHold * checktime
autocmd! AUWatchFile BufEnter,InsertEnter,CursorHold,CursorHoldI <buffer> checktime
setlocal autoread
checktime
}
command UnwatchFiles {
autocmd! AUWatchFile
set autoread<
}
# To enable this, you may use e.g. a modeline: `vim: set ft+=.watch`
def WatchAutomatically()
# Check if the "list" of filetypes (a dot separated string) contains 'watch'.
if -1 != match(&filetype, "\\(^\\|\\.\\)watch\\($\\|\\.\\)")
WatchFiles
endif
enddef
augroup AUWatchFile | augroup END
autocmd BufWinEnter * call WatchAutomatically()
More details
You are able to set multiple filetypes separated by .:
When a dot appears in the value then this separates two filetype
names. Example:
/* vim: set filetype=c.doxygen : */ ~
See :help 'filetype'.
Keep in mind that you should manipulate the filetype first and set additional options after that in the modeline. Otherwise these options may be overridden by the settings specific for the filetype.
Btw, the above is a Vim9 script (which I discovered today). Translating it back to a good-old Vim script is trivial:
Use " for comments.
Transform multi-line commands like this:
command UnwatchFiles
\ autocmd! AUWatchFile
\ | set autoread<
Remove the vim9script line.
See :help Vim9-script for details.
Shortcomings
Reloading is not limited to the buffer which contains the modeline. You may disable it again with :UnwatchFiles.
It is still dump polling.
VIM will warn you when a file has been updated so that you don't overwrite changes that have been made since you opened it. It will prompt you at that point to reload the file.