Bloquer le mouvement pour tout type de support?


8

Si je veux, disons supprimer un bloc, je peux utiliser des mouvements d'objets texte.

C'est-à-dire si mon texte ressemble à ceci:

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

Et le curseur est par exemple sur le caractère 3.

Si je tape diBalors :x 3 :y 4serait supprimé Si c'est le cas, daBle bloc et les crochets environnants sont supprimés:{:x 3 :y 4}

Ainsi, le modèle est:

operation inclusion block-motion

Où l'opération peut être:

  • d - supprimer

  • c - changement

  • y - copie ...

l'inclusion est soit:

  • i - intérieur (pas de supports) ou

  • a - tout

et bloc-mouvement:

  • b, (ou )pour ()parens

  • B, {ou }pour les {}curlies

  • [ou ]et <ou >pour leurs propres supports respectifs, etc.

Maintenant, la question est: y a-t-il un mouvement de bloc pour le bloc le plus à l'intérieur avec des crochets de l'un de ces types?

J'aimerais pouvoir faire da?avec ?la motion que je recherche. Et si le curseur dans mon exemple ci-dessus est à l'intérieur, {}disons que 3je supprimerais juste le {}mais si mon curseur était sur, bje supprimerais le []bloc, etc.

Réponses:


3

Voici pourquoi la question aurait dû être sur SO: un script non trivial est requis ...

" 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: J'ai réutilisé la fonction de lh-vim-lib - BTW, il y a un petit bug dans la version de lh#position#char_at_pos()in conf: col()ne doit pas être utilisé.


J'obtiens une erreur de syntaxe avec votre code: line 13: E15: Invalid expression: E15: Invalid expression: {(…). J'ai vim 7.2, votre code nécessite-t-il 7.3? Soit dit en passant, alors que les questions de programmation sont généralement redirigées vers SO, les réponses de script (pour les shells, les éditeurs et autres programmes scriptables) sont courantes ici.
Gilles 'SO- arrête d'être méchant'

Vim prend-il en charge les dictionnaires? Si oui, que se passe-t-il si vous ajoutez set cpo&vimau début du script - qui a été testé et développé sur un vim 7.2.148 sous ... Windows XP. (Je suis un peu fatigué de cette dispersion de la communauté vim, voir les commentaires sur cette réponse stackoverflow.com/questions/4488979/… )
Luc Hermitte

Merci! Comment l'invoquer? J'ai essayé d'utiliser bpour tous les blocs mais il ne sélectionne toujours que le ()type de bloc. Dois-je l'appeler différemment ou l'ai-je mal installé?
Goran Jovic

ibsignifie déjà quelque chose. Vous utilisez celui - ci avec i%ou a%(voir les correspondances) => di%, va%i%, c2a%, etc
Luc Hermitte

1

Pas par défaut, mais il peut y avoir un mécanisme pour ajouter cette fonctionnalité. Dans visual.txt, la section sur les opérations sur la zone visuelle, il a ceci:

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

Il y a un addon vim appelé textobj-user qui supporte .. euh, quelque chose comme ça. En fait, je ne suis pas sûr d'avoir compris ce que vous recherchez, mais je pense que l'addon est destiné à le rendre plus pratique pour écrire un addon pour implémenter ce que vous voulez.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.