How to permanently delete a specific entry from Vim's command-line history without losing the changelists of the recently edited files? -


when execute vim ex command, gets saved in command-line history, can access opening command-line window q:.

however, sometimes, want able remove of them permanently. example, if execute command :a, subsequent commands in command-line window recognized elements of syntax group viminsert, linked highlight group string, colored in cyan in colorscheme.

to fix syntax highlighting, try delete :a command command-line window hitting dd, entry removed while window opened. close it, , reopen later, :a command back. make removal permanent, tried add autocmd in vimrc:

augroup my_cmdline_window     au!     au cmdwinleave * call s:update_history() augroup end  fu! s:update_history() abort     let new_hist = getline(1, '$')     call histdel(':')     in new_hist         call histadd(':', i)     endfor endfu 

it calls function, updates command history reading current window, before closing it. works while current vim session running, quit start new one, deleted entries back.

i think reason why removal doesn't persist across sessions, because when quit session vim merges current command-line history 1 stored in ~/.viminfo.

what saved inside file controlled 'viminfo' option. value of 'viminfo' is:

viminfo='100,<50,s10,h 

it doesn't contain : parameter, sets maximum number of items in command-line history, saved. means vim should use 'history' option. default value of 'history' 1000.

so, force vim overwrite command-line history stored inside ~/.viminfo 1 of current session, tried use :wviminfo command inside autocmd:

augroup my_cmdline_window     au!     au cmdwinleave * call s:update_history() augroup end  fu! s:update_history() abort     let new_hist = getline(1, '$')     call histdel(':')     in new_hist         call histadd(':', i)     endfor     wviminfo! endfu 

i added bang :wviminfo, according :h :wviminfo:

when [!] used, old information not read first, internal info written. 

it seems work, because autocmd, removal of entry inside command-line window persists across sessions. however, seems erase changelists of edited files, because after starting new vim session, changelists empty.

and since :h 'viminfo explains when include ' item in 'viminfo', changelist , jumplist stored in ~/.viminfo, suspect jumplist , marks lost after using :wviminfo!.

is there way avoid loss of changelists/jumplists/marks, while still removing arbitrary entry command-line history?


edit:

i came this:

augroup my_cmdline_window     au!     au cmdwinenter * let s:old_cmdline_hist = getline(1, line('$')-1)     au cmdwinleave * call s:update_history() augroup end  fu! s:update_history() abort     let hist = filter(getline(1, '$'), 'v:val !~# "^\\s*$"')      call histdel(':')     in hist         call histadd(':', i)     endfor      let viminfo = expand('~/.viminfo')     if !filereadable(viminfo)         return     endif      let info = readfile(viminfo)     let deleted_entries = filter(copy(s:old_cmdline_hist), 'index(hist, v:val) == -1')      call map(deleted_entries, 'index(info, ":".v:val)')     call sort(filter(deleted_entries, 'v:val >= 0'))     if empty(deleted_entries)         return     endif      entry in reverse(deleted_entries)         call remove(info, entry, entry + 1)     endfor     call writefile(info, viminfo, 'b') endfu 

here's code does:

when enter command-line window, 1st autocmd captures command-line history inside s:old_cmdline_hist.

when leave it, 2nd autocmd updates history of current session, , tries remove deleted entries ~/.viminfo.

let hist = filter(getline(1, '$'), 'v:val !~# "^\\s*$"') call histdel(':') in hist     call histadd(':', i) endfor 

this block updates history of current session.

let viminfo = expand('~/.viminfo') if !filereadable(viminfo)     return endif 

this 1 checks whether ~/.viminfo readable. if it's not, function stops.

let info = readfile(viminfo) let deleted_entries = filter(copy(s:old_cmdline_hist), 'index(hist, v:val) == -1') 

this block gets contents of ~/.viminfo inside list info (1 item = 1 line). gets entries deleted invoking filter(). latter removes entries don't satisfy condition index(hist, v:val) == -1. expression true if entry of old history, on filter() operates, not inside new history.

call map(deleted_entries, 'index(info, ":".v:val)') 

this line converts deleted text entries line addresses inside ~/.viminfo.

call sort(filter(deleted_entries, 'v:val >= 0')) if empty(deleted_entries)     return endif 

this block sorts line addresses, , removes ones not positive, in case of them weren't found in previous step (index() returned -1). checks whether there still line addresses @ point, , if there aren't, again, function stops.

for entry in reverse(deleted_entries)     call remove(info, entry, entry + 1) endfor 

this block removes relevant lines info. deletes 2 lines (entry , entry + 1), because every command-line saved in ~/.viminfo, there's 2nd line seems timestamp. also, deletes in reverse order, not have update addresses of lines delete (every time delete line, addresses of next ones decreased one).

call writefile(info, viminfo, 'b') 

this line overwrites ~/.viminfo new contents, should same before, without lines deleted in command-line window.

i don't post answer, i'm not sure it's reliable , there aren't side-effects. did backup of ~/.viminfo before testing code.

edit2:

i don't think it's able delete line contains literal carriage return. there may other special characters causing similar issue (like null character ^@).


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -