Memblokir gerakan untuk semua jenis braket?

8

Jika saya mau, katakan hapus blok, saya bisa menggunakan gerakan objek teks.

Yaitu jika teks saya terlihat seperti ini:

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

Dan kursor misalnya pada karakter 3.

Jika saya mengetik diBmaka :x 3 :y 4akan dihapus Jika daBkemudian blok dan kurung di sekitarnya dihapus:{:x 3 :y 4}

Jadi polanya adalah:

operation inclusion block-motion

Di mana operasi mungkin:

  • d - menghapus

  • c - ubah

  • y - salin ...

inklusi adalah:

  • i - bagian dalam (tidak ada tanda kurung) atau

  • a - semua

dan blok-gerak:

  • b, (atau )untuk ()orangtua

  • B, {atau }untuk {}ikal

  • [atau ]dan <atau >untuk tanda kurung masing-masing, dll.

Sekarang, pertanyaannya adalah: Apakah ada gerakan blok untuk blok paling dalam dengan tanda kurung dari salah satu dari jenis ini?

Saya ingin bisa melakukan da?dengan ?menjadi gerakan yang saya cari. Dan jika kursor dalam contoh saya di atas berada dalam {}katakan pada 3saya akan menghapus hanya {}tetapi jika kursor saya pada bsaya akan menghapus []blok, dll.

Goran Jovic
sumber

Jawaban:

3

Inilah mengapa pertanyaannya seharusnya pada SO: skrip non sepele diperlukan ...

" 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: Saya telah menggunakan kembali fungsi dari lh-vim-lib - BTW, ada sedikit bug dalam versi lh#position#char_at_pos()di conf: col()tidak boleh digunakan.

Luc Hermitte
sumber
Saya mendapatkan kesalahan sintaksis dengan kode Anda: line 13: E15: Invalid expression: E15: Invalid expression: {(...). Saya memiliki vim 7.2, apakah kode Anda memerlukan 7.3? Omong-omong, sementara pertanyaan pemrograman biasanya dialihkan ke SO, jawaban skrip (untuk shell, editor, dan program skrip lainnya) adalah umum di sini.
Gilles 'SO- stop being evil'
Apakah Anda vim mendukung kamus? Jika ya, apa yang terjadi jika Anda menambahkan set cpo&vimdi awal skrip - yang telah diuji dan dikembangkan pada vim 7.2.148 pada ... Windows XP. (Saya agak lelah dengan penyebaran komunitas vim ini, lihat komentar pada jawaban ini stackoverflow.com/questions/4488979/… )
Luc Hermitte
Terima kasih! Bagaimana saya memohonnya? Saya mencoba menggunakan buntuk semua blok tetapi masih memilih hanya ()tipe blok. Apakah saya harus menyebutnya secara berbeda, atau saya salah menginstalnya?
Goran Jovic
ibsudah berarti sesuatu. Anda menggunakan salah satu ini dengan i%atau a%(lihat pemetaan) => di%, va%i%, c2a%, dll
Luc Hermitte
1

Tidak secara default, tetapi mungkin ada beberapa mekanisme untuk menambahkan fungsionalitas itu. Di visual.txt, bagian tentang pengoperasian pada area visual, ia memiliki ini:

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
sumber
0

Ada addon vim yang disebut pengguna textobj yang mendukung .. um, sesuatu seperti ini. Sebenarnya saya tidak yakin saya mengerti apa yang Anda cari, tetapi saya pikir addon dimaksudkan untuk membuatnya lebih mudah untuk menulis addon untuk mengimplementasikan apa yang Anda inginkan.

intuisi
sumber