I have a shortcut in my .vimrc file that generates a uuid and inserts it into my buffer:
com! Uuid r ! uuidgen | tr "[:upper:]" "[:lower:]"
When I invoke it, it inserts the uuid on the next line. However, I want vim to insert the uuid where my cursor is, not on the next line. How would I do this?
Here is the command:
:com! Uuid exe "normal! i".system('uuidgen | tr "[:upper:]" "[:lower:]" | tr -d "\n"')
Related
I am looking for a way to save to a new text file a file that is folded, with all the folds closed. In other words, just as I see it on the screen.
Is it possible?
(I will have to print the code later, and parts of it are irrelevant to my purposes; the folding mechanism would be ideal for this, my other alternative is manually adding "[X lines omitted]" to the saved text.)
Fold your text as needed and then use :TOhtml to convert to an HTML file. This will preserve your folding. If you need it as a plain text file, you can post-process e.g. with w3m, which renders HTML to text and allows to dump it to a text file.
Here is a custom :RenderClosedFolds command, which will modify the current buffer / range. It also attempts to maintain the Folded highlighting of the original folds.
":[range]RenderClosedFolds
" Replace all lines currently hidden inside closed folds
" with a single line representing 'foldtext'.
function! s:RenderClosedFolds()
if line('.') == foldclosed('.')
let l:result = foldtextresult('.')
call setline('.', l:result)
execute printf('syntax match renderedFold "\V\^%s\$" containedin=ALL keepend', escape(l:result, '"\'))
else
delete _
endif
endfunction
command! -bar -range=% RenderClosedFolds
\ highlight def link renderedFold Folded |
\ let g:ingocommands_IsEntireBuffer = (<line1> == 1 && <line2> == line('$')) |
\ if g:ingocommands_IsEntireBuffer | syntax clear renderedFold | endif |
\ let g:save_foldmethod = &l:foldmethod | setlocal foldmethod=manual |
\ execute '<line1>,<line2>folddoclosed call <SID>RenderClosedFolds()' |
\ if g:ingocommands_IsEntireBuffer | setlocal nofoldenable | endif |
\ let &l:foldmethod = g:save_foldmethod | unlet g:save_foldmethod g:ingocommands_IsEntireBuffer
I have once created a script, that saves all folds to a new buffer.
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)
I am trying to set the cursor in insert mode to be a thin vertical line and I am unable to. I have tried this in my .vimrc file:
set guicursor+=i:ver100-iCursor
It does not set the cursor to a vertical bar on insert mode.
What am I missing and how do I do this?
This code in my /home/el/.vimrc worked for my console:
if $TERM_PROGRAM =~ "iTerm"
let &t_SI = "\<Esc>]50;CursorShape=1\x7" " Vertical bar in insert mode
let &t_EI = "\<Esc>]50;CursorShape=0\x7" " Block in normal mode
endif
Which does this for me:
Source:
https://hamberg.no/erlend/posts/2014-03-09-change-vim-cursor-in-iterm.html
For gnome terminal version>3.15
Add this to your ~/.vimrc.
if has("autocmd")
au VimEnter,InsertLeave * silent execute '!echo -ne "\e[2 q"' | redraw!
au InsertEnter,InsertChange *
\ if v:insertmode == 'i' |
\ silent execute '!echo -ne "\e[6 q"' | redraw! |
\ elseif v:insertmode == 'r' |
\ silent execute '!echo -ne "\e[4 q"' | redraw! |
\ endif
au VimLeave * silent execute '!echo -ne "\e[ q"' | redraw!
endif
You will get a block cursor in normal mode and a thin one in insert mode.
This did the trick:
set guicursor=i:ver25-iCursor
I had to reduce the 100 to 25
I use iTerm2 on mac and none of the above worked. Silly (vim and interface ain't right) but works. To switch between vertical bar or box. Profiles -> Open Profiles... -> Edit Profiles... -> Text
I've discovered this great command from the documentation:
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
\ | wincmd p | diffthis
So I've come up with this:
command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis | wincmd p
map <Leader>do :DiffOrig<cr>
map <leader>dc :q<cr>:diffoff!<cr>
The problem is, when I se \dc, it will jump back to the beginning of the file, not where I left it prior to issuing \do. How to fix this?
Please try this yourself, see what the problems are and how to fix them. And tell me how to fix them too :-)
You could try:
command DiffOrig let g:diffline = line('.') | vert new | set bt=nofile | r # | 0d_ | diffthis | :exe "norm! ".g:diffline."G" | wincmd p | diffthis | wincmd p
nnoremap <Leader>do :DiffOrig<cr>
nnoremap <leader>dc :q<cr>:diffoff<cr>:exe "norm! ".g:diffline."G"<cr>
You can :q in the window you want to close, and then :diffoff to turn off the diff formatting in the remaining window. Not sure if it can be done in one command.
To close the diff windows and go back to the file you were editing, you could try adding this to your .vimrc file:
if !exists(":DiffOff")
command DiffOff diffoff <bar> only
endif
Then enter :DiffOff to close the diff windows.
What I have so far:
function! GetMarker()
return system('echo $random `date` | md5sum | cut -d" " -f1')
endfunction
I would like to be able to do a :getmarker and have it insert the output of that system command at my cursor, with no new lines.
Also what is the difference between function! and function?
Edit: before any of you ask, I need the random string to mark sections in my code so I can find them again by referencing my notes in my todo wiki.
Edit1. Take two. Trying to absorb the feedback from Luc. Without temp file (readfile() turned out to be not available in VIM 6.x I have on some systems).
:function InsertCmd( cmd )
: let l = system( a:cmd )
: let l = substitute(l, '\n$', '', '')
: exe "normal a".l
: redraw!
:endfunction
:imap <silent> <F5> <C-O>:call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
:map <silent> <F5> :call InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
:put can't be used because it works line-wise. I replaced <Esc>...<Insert> with the all better <C-O>. I left redraw in, as it helps for the cases of called command produces output to the stderr.
Or using <C-R>=:
:function InsertCmd( cmd )
: let l = system( a:cmd )
: let l = substitute(l, '\n$', '', '')
: return l
:endfunction
:imap <silent> <F5> <C-R>=InsertCmd( 'echo date \| md5sum \| cut -d" " -f1' )<CR>
Also what is the difference between function! and function?
Exclamation on the end of command most of the time means force to execute. (Looking in the :help is advised since different commands use ! differently, but VIM tries to document all forms of the commands.) In the case of the function it tells VIM to override previous definition of the function. E.g. if you put the code above into the func1.vim file, first time :source func1.vim would work fine, but the second time it would fail with error that function InsertCmd is already defined.
I did once before try to implement something similar here. I'm not good at VIM programming, thus it looks lame and the suggestion from Luc should take precedence.
Here it goes anyway:
:function InsertCmd( cmd )
: exe ':silent !'.a:cmd.' > /tmp/vim.insert.xxx 2>/dev/null'
: let l = readfile( '/tmp/vim.insert.xxx', '', 1 )
: exe "normal a".l[0]
: redraw!
:endfunction
:imap <silent> <F5> <Esc>:call InsertCmd( 'hostname' )<CR><Insert>
:map <silent> <F5> :call InsertCmd( 'hostname' )<CR>
Despite being lame, it works though.
You can trim/chomp the last newline with matchstr(), substitute, [:-2], etc
function s:GetMarker()
let res = system('echo $random `date` | md5sum | cut -d" " -f1')
" then either
let res = matchstr(res, '.*\ze\n')
" or
let res = res[:-2]
" or
let res = substitute(res, '\n$', '', '')
return res
endfunction
command! -nargs=0 GetMarker put=s:GetMarker()
Banging the function/command definition (with '!') will permit you to source the script where it is defined several times and thus to update the function/command you are maintaining without having to exit vim.
I was running into similar problems with trying to map a hotkey to insert the current date and time. I solved the newline problem by just including a <backspace>, but this still inserted newlines when I was indented (backspace would kill the last character, but when I was indented I got newline+tab and only the tab would go away).
So I did this -- just turned smartindent off, insert the string, then turn it back on:
imap <F5> <esc>:set nosmartindent<CR>a<C-R>=system('echo $random `date` \| md5sum \| cut -d" " - f1')<CR><Backspace><esc>:set smartindent<CR>a
...which works, but it gets un-indented if you're sitting on a new, auto-indented line. To get around that, insert a character to hold your place, then escape, turn off smartindent, get rid of the extra character, and do the rest:
imap <F5> x<esc>:set nosmartindent<CR>a<backspace><C-R>=system('echo $random `date` \| md5sum \| cut -d" " -f1')<CR><Backspace><esc>:set smartindent<CR>a
This seems to work.