Blocco del movimento per qualsiasi tipo di parentesi?


8

Se voglio, per esempio cancellare un blocco, posso usare i movimenti di oggetti di testo.

Vale a dire se il mio testo è simile al seguente:

(let [a 1 b {:x 3  :y 4}]
      a)

E il cursore si trova ad esempio sul personaggio 3.

Se scrivo, diBallora :x 3 :y 4verrebbe cancellato Se è daBallora vengono eliminati sia il blocco che le parentesi circostanti:{:x 3 :y 4}

Quindi, il modello è:

operation inclusion block-motion

Dove l'operazione può essere:

  • d - Elimina

  • c - modificare

  • y - copia ...

l'inclusione è:

  • i - interno (senza parentesi) o

  • a - tutti

e blocco-movimento:

  • b, (O )per ()parens

  • B, {O }per {}curlies

  • [o ]e <o >per le proprie rispettive staffe, ecc ..

Ora, la domanda è: esiste un movimento di blocco per il blocco più interno con parentesi di uno di questi tipi?

Mi piacerebbe poter fare da?con ?il movimento che sto cercando. E se il cursore nel mio esempio sopra è dentro {}dire su 3eliminerei solo il {}ma se il mio cursore fosse su beliminerei il []blocco, ecc.

Risposte:


3

Ecco perché la domanda avrebbe dovuto essere su SO: sono richiesti script non banali ...

" Public Mappings {{{1
onoremap <silent> i% :<c-u>call <sid>SelectFirstPair(1,0)<cr>
xnoremap <silent> i% :<c-u>call <sid>SelectFirstPair(1,1)<cr><esc>gv
onoremap <silent> a% :<c-u>call <sid>SelectFirstPair(0,0)<cr>
xnoremap <silent> a% :<c-u>call <sid>SelectFirstPair(0,1)<cr><esc>gv
" Public Mappings }}}1
"------------------------------------------------------------------------
" Private Functions {{{1
" Note: most functions are best placed into
" autoload/«your-initials»/«omap_any_bracket».vim
" Keep here only the functions are are required when the plugin is loaded,
" like functions that help building a vim-menu for this plugin.
let s:k_pairs = {
      \ '(': ')',
      \ '[': ']',
      \ '{': '}',
      \ '<': '>'
      \ }

let s:k_begin = '[([{<]'
let s:k_end   = '[)\]}>]'

function! s:SelectFirstPair(inner, visual)
  " In case we already are in visual mode, we may have to extend the current
  " zone if it selects a pair of brackets
  if a:visual
    let char_b = lh#position#char_at_mark("'<")
    if char_b =~ s:k_begin
      \ && s:k_pairs[char_b] == lh#position#char_at_mark("'>")
      call search('.', 'bW') " previous char
    elseif a:inner
      " handle case the case "vi%i%i%"
      let current_pos = getpos('.')
      call setpos('.', getpos("'<"))
      call search('.', 'bW') " previous char
      let pos_b = getpos('.')
      call setpos('.', getpos("'>"))
      call search('.', 'W') " next char
      let pos_e = getpos('.')
      let char_b = lh#position#char_at_pos(pos_b)
      let char_e = lh#position#char_at_pos(pos_e)
      echomsg "chars = ".char_b.char_e
      if char_b =~ s:k_begin
        \ && s:k_pairs[char_b] == char_e
    call setpos('.', pos_b) " restore start_pos
    call search('.', 'bW') " previous char
      else
    call setpos('.', current_pos) " restore init_pos
      endif
    endif
  endif

  " Searching the n outer blocks requested
  let cnt = v:count <= 0 ? 1 : v:count
  while cnt > 0
    let cnt -= 1
    let char_c = lh#position#char_at_pos(getpos('.'))
    let accept_at_current = char_c =~ s:k_begin ? 'c' : ''

    " Begin of the current outer block
    if 0 ==searchpair(s:k_begin, '', s:k_end, 'bW'.accept_at_current, 'lh#syntax#skip()')
      throw "No outer bloc"
    endif
    if cnt > 0
      call search('.', 'bW') " previous char
    endif
  endwhile

  let char_b = lh#position#char_at_pos(getpos('.'))

  normal! v

  " End of the outer block
  let pos_e = searchpair(s:k_begin, '', s:k_end, 'W', 'lh#syntax#skip()')
  let char_e = lh#position#char_at_pos(getpos('.'))
  if pos_e == 0
    throw "pos_e == 0"
  elseif s:k_pairs[char_b] != char_e
    echomsg "unbalanced blocks"
  endif

  " Adjusting the extremities
  if a:inner
    call search('.', 'b')
    normal! o
    call search('.')
    normal! o
  endif
endfunction
" Private Functions }}}1

NB: Ho riutilizzato la funzione da lh-vim-lib - A proposito, c'è un piccolo bug nella versione di lh#position#char_at_pos()in conf: col()non deve essere usato.


Ottengo un errore di sintassi con il tuo codice: line 13: E15: Invalid expression: E15: Invalid expression: {(...). Ho vim 7.2, il tuo codice richiede 7.3? A proposito, mentre le domande di programmazione vengono generalmente reindirizzate a SO, le risposte di script (per shell, editor e altri programmi di scripting) sono comuni qui.
Gilles 'SO- smetti di essere malvagio' il

Vim supporta i dizionari? Se sì, cosa succede se aggiungi set cpo&vimall'inizio dello script - che è stato testato e sviluppato su un vim 7.2.148 su ... Windows XP. (Sono un po 'stanco di questa dispersione della comunità vim, si vedano i commenti su questa risposta stackoverflow.com/questions/4488979/... )
Luc Hermitte

Grazie! Come lo invoco? Ho provato a utilizzare bper tutti i blocchi ma seleziona ancora solo il ()tipo di blocco. Devo chiamarlo in modo diverso o l'ho installato in modo errato?
Goran Jovic,

ibsignifica già qualcosa. È possibile utilizzare questo uno con i%o a%(vedi le mappature) => di%, va%i%, c2a%, ecc
Luc Hermitte

1

Non per impostazione predefinita, ma potrebbe esserci qualche meccanismo per aggiungere quella funzionalità. In visual.txt, la sezione sull'operare nell'area visiva, ha questo:

The objects that can be used are:
    aw      a word (with white space)                       |v_aw|
    iw      inner word                                      |v_iw|
    aW      a WORD (with white space)                       |v_aW|
    iW      inner WORD                                      |v_iW|
    as      a sentence (with white space)                   |v_as|
    is      inner sentence                                  |v_is|
    ap      a paragraph (with white space)                  |v_ap|
    ip      inner paragraph                                 |v_ip|
    ab      a () block (with parenthesis)                   |v_ab|
    ib      inner () block                                  |v_ib|
    aB      a {} block (with braces)                        |v_aB|
    iB      inner {} block                                  |v_iB|
    at      a <tag> </tag> block (with tags)                |v_at|
    it      inner <tag> </tag> block                        |v_it|
    a<      a <> block (with <>)                            |v_a<|
    i<      inner <> block                                  |v_i<|
    a[      a [] block (with [])                            |v_a[|
    i[      inner [] block                                  |v_i[|
    a"      a double quoted string (with quotes)            |v_aquote|
    a'      a single quoted string (with quotes)            |v_a'|
    i'      inner simple quoted string                      |v_i'|
    a`      a string in backticks (with backticks)          |v_a`|
    i`      inner string in backticks                       |v_i`|

0

C'è un addon vim chiamato textobj-user che supporta .. um, qualcosa del genere. In realtà non sono sicuro di aver capito cosa stai cercando, ma penso che l'addon abbia lo scopo di rendere più conveniente scrivere un addon per implementare ciò che desideri.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.