Efficient way to remove a line containing specific text in vim with a hint

I can currently search for text

/text

and then delete the line with dd, and if I don't want to delete, I can move on to the next match with n.

But is there an even faster way to do this!

This command below deletes all lines containing text, but the problem is that it deletes all lines at once, sometimes this text is in some line, which is an exception.

:g/text/d

But I want something simple, sort of like

:%s/text/some_other_text/gc

because it makes it possible to replace or not with.

+4
source share
3 answers

You can mix :help globaland :help substitute:

:g/text/s/.*\n//c

, text:

enter image description here

+4

global :substitute, , , , .

, : , , , : :confirm global.

.

:

  • , , (, , ).
  • global , , .
    • don't-ask-again
    • StatusLineNC echo "\rmessage" + :redraw. , Vim 6 IIRC.

:

" Function: lh#ui#ask(message) {{{3
function! lh#ui#ask(message) abort
  redraw! " clear the msg line
  echohl StatusLineNC
  echo "\r".a:message
  echohl None
  let key = nr2char(getchar())
  return key
endfunction

" Function: lh#ui#confirm_command(command) {{{3
" states:
" - ask
" - ignore
" - always
function! s:check() dict abort
  if     self.state == 'ignore'
    return
  elseif self.state == 'always'
    let shall_execute_command = 1
  elseif self.state == 'ask'
    try
      let cleanup = lh#on#exit()
            \.restore('&cursorline')
            \.restore_highlight('CursorLine')
      set cursorline
      hi CursorLine   cterm=NONE ctermbg=black ctermfg=white guibg=black guifg=white
      let choice = lh#ui#ask(self.message)
      if     choice == 'q'
        let self.state = 'ignore'
        let shall_execute_command = 0
        " TODO: find how not to blink
        redraw! " clear the msg line
      elseif choice == 'a'
        let self.state = 'always'
        let shall_execute_command = 1
        " TODO: find how not to blink
        redraw! " clear the msg line
      elseif choice == 'y'
        " leave state as 'ask'
        let shall_execute_command = 1
      elseif choice == 'n'
        " leave state as 'ask'
        let shall_execute_command = 0
      elseif choice == 'l'
        let shall_execute_command = 1
        let self.state = 'ignore'
      endif
    finally
      call cleanup.finalize()
    endtry
  endif

  if shall_execute_command
    execute self.command
  endif
endfunction

function! s:getSID() abort
  return eval(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_getSID$'))
endfunction
let s:k_script_name      = s:getSID()

function! lh#ui#make_confirm_command(command, message) abort
  let res = lh#object#make_top_type(
        \ { 'state': 'ask'
        \ , 'command': a:command
        \ , 'message': a:message . ' (y/n/a/q/l/^E/^Y)'
        \ })
  call lh#object#inject_methods(res, s:k_script_name, 'check')
  return res
endfunction

" Function: lh#ui#global_confirm_command(pattern, command, message [, sep='/']) {{{3
" Exemple: to remove lines that match a pattern:
" > call lh#ui#global_confirm_command(pattern, 'd', 'delete line?')
function! lh#ui#global_confirm_command(pattern, command, message, ...) abort
  let cmd = lh#ui#make_confirm_command(a:command, a:message)
  let sep = get(a:, 1, '/')
  exe 'g'.sep.a:pattern.sep.'call cmd.check()'
endfunction

" Function: lh#ui#_confirm_global(param) {{{3
function! lh#ui#_confirm_global(param) abort
  let sep = a:param[0]
  let parts = split(a:param, sep)
  if len(parts) < 2
    throw "Not enough arguments to `ConfirmGlobal`!"
  endif
  let cmd = join(parts[1:])
  call lh#ui#global_confirm_command(parts[0], cmd, cmd . ' on line?', sep)
endfunction

command! -nargs=1 ConfirmGlobal call lh#ui#_confirm_global('<args>')

:

  • :call lh#ui#global_confirm_command(pattern, 'd', 'delete line?')
  • :ConfirmGlobal/pattern/d,
+3

You do not need a global team for this. Replace the team individually will be

  • add template
  • and adding the end of the line.

Example

%s/.*text.*\n//gc
+2
source

Source: https://habr.com/ru/post/1687600/


All Articles