Blockbewegung für jeden Bracket-Typ?

8

Wenn ich beispielsweise einen Block löschen möchte, kann ich Textobjektbewegungen verwenden.

Dh wenn mein Text so aussieht:

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

Und der Cursor ist zum Beispiel auf Zeichen 3.

Wenn ich tippe, wird diBdann :x 3 :y 4gelöscht. Wenn dies der Fall ist, werden daBsowohl der Block als auch die umgebenden Klammern gelöscht:{:x 3 :y 4}

Das Muster lautet also:

operation inclusion block-motion

Wo der Betrieb sein kann:

  • d - löschen

  • c - Veränderung

  • y - Kopieren ...

Aufnahme ist entweder:

  • i - innen (keine Klammern) oder

  • a - alle

und Blockbewegung:

  • b, (Oder )für ()Pars

  • B, {Oder }für {}curlies

  • [oder ]und <oder >für ihre jeweiligen Klammern usw ..

Die Frage ist nun: Gibt es eine Blockbewegung für den innersten Block mit Klammern eines dieser Typen?

Ich möchte in der Lage sein zu tun , da?mit ?wobei die Bewegung , die ich suche. Und wenn sich der Cursor in meinem obigen Beispiel innerhalb von {}say on befindet, 3würde ich nur den löschen, {}aber wenn mein Cursor auf bwäre, würde ich den []Block usw. löschen .

Goran Jovic
quelle

Antworten:

3

Hier ist der Grund, warum die Frage auf SO gestellt werden sollte: Nicht triviales Scripting ist erforderlich ...

" 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: Ich habe die Funktion von lh-vim-lib wiederverwendet - Übrigens, es gibt einen kleinen Fehler in der Version von lh#position#char_at_pos()in conf: col()darf nicht verwendet werden.

Luc Hermitte
quelle
Ich erhalte einen Syntaxfehler mit Ihrem Code: line 13: E15: Invalid expression: E15: Invalid expression: {(…). Ich habe vim 7.2, benötigt Ihr Code 7.3? Während Programmierfragen normalerweise an SO umgeleitet werden, sind Skriptantworten (für Shells, Editoren und andere skriptfähige Programme) hier häufig.
Gilles 'SO - hör auf böse zu sein'
Unterstützt Sie Wörterbücher? Wenn ja, was passiert, wenn Sie set cpo&vimzu Beginn des Skripts hinzufügen - das auf einem vim 7.2.148 unter ... Windows XP getestet und entwickelt wurde? (Ich bin ein bisschen müde von dieser Zerstreuung der Vim-Community, siehe die Kommentare zu dieser Antwort stackoverflow.com/questions/4488979/… )
Luc Hermitte
Vielen Dank! Wie rufe ich es auf? Ich habe versucht, bfür alle Blöcke zu verwenden, aber es wird immer noch nur ()der Blocktyp ausgewählt. Muss ich es anders nennen oder habe ich es falsch installiert?
Goran Jovic
ibbedeutet schon etwas. Sie verwenden diesen mit i%oder a%(siehe die Abbildungen) => di%, va%i%, c2a%, etc
Luc Hermitte
1

Nicht standardmäßig, aber es gibt möglicherweise einen Mechanismus, um diese Funktionalität hinzuzufügen. In visual.txt, dem Abschnitt über das Bearbeiten des visuellen Bereichs, gibt es Folgendes:

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`|
Shawn J. Goff
quelle
0

Es gibt ein vim-Addon namens textobj-user , das .. ähm, so etwas unterstützt. Eigentlich bin ich mir nicht sicher, ob ich verstanden habe, wonach Sie suchen, aber ich denke, dass das Addon es bequemer machen soll, ein Addon zu schreiben, um das zu implementieren, was Sie wollen.

intuitiv
quelle