Come Ctrl-A e Ctrl-X ma modifica solo la prima cifra


10

C'è un modo per aumentare / diminuire la prima cifra dopo / sotto il cursore, non l'intero numero.

So che non funziona come vim, ma c'è un plugin che lo fa? Non sono riuscito a trovarlo.

È molto utile durante la modifica di CSS e anche in altri casi.

Dato:

▐margin: 10px

Quando premo CTRL-Avoglio vedere:

▐margin: 20px

Effettivo:

▐margin: 11px

10
Puoi anche fare 10<C-a>per aggiungere 10 o r2sostituire 1 con un 2.
jamessan

Risposte:


6

Questo sembra funzionare abbastanza bene e fa cose abbastanza sane quando si usa <C-a>un 9 (95 diventa 105) o si usa <C-x>uno 0 (105 diventa 95):

nnoremap g<C-a> :call search('\d', 'c')<CR>a <Esc>h<C-a>lxh
nnoremap g<C-x> :call search('\d', 'c')<CR>a <Esc>h<C-x>lxh
  • Innanzitutto, cerchiamo qualsiasi cifra, search()ha il vantaggio di non reimpostare @/.
  • a <Esc>h - Passa alla modalità di inserimento, aggiungi uno spazio dopo la cifra e vai a sinistra in modo che il cursore si trovi sulla parte superiore della cifra.
  • Ora possiamo usare <C-a>o <C-x>.
  • Usiamo lxhper rimuovere lo spazio che abbiamo aggiunto.

Ho mappato questo su g<C-a>e g<C-x>, quindi puoi ancora chiamare l'originale.

Una versione leggermente diversa che cercherà solo i numeri sulla riga corrente (ma lascerà uno spazio penzolante se non ci sono numeri sulla riga corrente):

nnoremap g<C-a> :call search('\d', 'c', line('.'))<CR>a <Esc>h<C-a>lxh
nnoremap g<C-x> :call search('\d', 'c', line('.'))<CR>a <Esc>h<C-x>lxh

Ed ecco un'altra versione che utilizza lo stesso concetto di prima, ma aggiunge anche uno spazio prima della cifra. Questo farà g<C-a>ignorare qualsiasi segno di munis prima del numero (per impostazione predefinita, <C-a>su -42lo "incrementerà" a -41.

Accetta anche un conteggio, quindi 5g<C-a>aumenterà il numero di 5:

fun! Increment(dir, count)
    " No number on the current line
    if !search('\d', 'c', getline('.'))
        return
    endif

    " Store cursor position
    let l:save_pos = getpos('.')

    " Add spaces around the number
    s/\%#\d/ \0 /
    call setpos('.', l:save_pos)
    normal! l

    " Increment or decrement the number
    if a:dir == 'prev'
        execute "normal! " . repeat("\<C-x>"), a:count
    else
        execute "normal! " . repeat("\<C-a>", a:count)
    endif

    " Remove the spaces
    s/\v (\d{-})%#(\d) /\1\2/

    " Restore cursor position
    call setpos('.', l:save_pos)
endfun

nnoremap <silent> g<C-a> :<C-u>call Increment('next', v:count1)<CR>
nnoremap <silent> g<C-x> :<C-u>call Increment('prev', v:count1)<CR>

9

Incremento di base

Ecco una semplice macro per eseguire l'azione:

:nnoremap <leader>a m`lv$xh<c-a>p``
:nnoremap <leader>x m`lv$xh<c-x>p``

In modalità normale tu

  • m` Segna la tua posizione
  • l sposta un personaggio a destra
  • v$x tagliato fino alla fine della linea
  • h tornare alla posizione originale
  • <c-a> incremento (o decremento)
  • p incolla il tuo taglio
  • `` tornare al segno

Passa al numero successivo

Se vuoi saltare al numero successivo (o rimanere nella posizione corrente se su un numero) hai bisogno di una funzione che controlli il carattere corrente e il possibile salto al numero successivo.

function! NextNum()
  let ch = getline(".")[col(".")-1]
  if ch !~ "[0-9]"
    execute "normal! /[0-9]\<cr>"
  endif
endfunction

nnoremap <leader>a :call NextNum()<cr>m`lv$xh<c-a>p``
nnoremap <leader>x :call NextNum()<cr>m`lv$xh<c-x>p``

NextNummette il carattere sotto il cursore, controlla se è un numero e se non cerca il numero successivo. Dopodiché il resto è lo stesso. Se si desidera che la mappatura sia diversa, cambiare nnoremap <leader>aad esempio ciò che si desidera nnoremap <c-a>.

Ignorando negativi e numeri superiori a 9

Se si desidera semplicemente scorrere le cifre e non farle agire come numeri interi con segno, le seguenti funzioni aumenteranno e diminuiranno e passeranno su 0 e 9.

function! NextNum()
  let ch = getline(".")[col(".")-1]
  if ch !~ "[0-9]"
    execute "normal! /[0-9]\<cr>"
  endif
endfunction

function! IncDec(val, dec)
  if a:dec
    if a:val == 0
      return 9
    else
      return a:val - 1
    endif
  else
    if a:val == 9
      return 0
    else
      return a:val + 1
    endif
  endif
endfunction

function! DoMath(dec)
  call NextNum()
  normal! x
  let @" = IncDec(@", a:dec)
  normal! P
endfunction

nnoremap <leader>a :call DoMath(0)<cr>
nnoremap <leader>x :call DoMath(1)<cr>

Ora quando sei acceso 8e digita <leader>a, ottieni 9. Farlo di nuovo si traduce in 0. Se si preme <leader>xsu 0si ottiene 9. Lo stesso vale per i numeri negativi. Le funzioni tagliano un singolo carattere, incrementano, diminuiscono o rotolano e poi incollano in posizione.


Qualcosa non è qui, ma terrò a mente quell'idea, forse può essere migliorata. Dovrebbe saltare alla prima cifra della riga corrente se presente e operare su di essa. Preferibilmente essere mappabile <c-a>/<c-x>anche a.
firedev,

La versione aggiornata Ora salta in avanti al numero successivo o se sei attualmente su una cifra ti consente di incrementarlo.
jecxjo,

Sì! Questo è fantastico, grazie! Non capisco perché la domanda sia stata sottovalutata, questo mi ha infastidito dal primo giorno e apparentemente molte persone ridefiniscono <c-a>e <c-x>qualcos'altro perché il comportamento predefinito non è così utile.
firedev,

Ho potuto vedere che viene annullato il voto perché la domanda era per qualcosa di molto specifico e la domanda originale è cambiata lungo la strada ... la necessità di saltare al primo numero. A parte questo, lo uso davvero <c-a>e <c-x>molto. Ogni volta che aggiorno una versione o aumento una variabile di intervallo, semplicemente [N]<c-a>invece di eliminare e sostituire.
jecxjo,

1
Sarebbe possibile ma sarebbe un insieme di funzioni molto più ampio. L'implementazione attuale ne trae vantaggio <c-a>e <c-x>che dovrebbe essere abbandonata per una funzione che fa lo stesso ma ignora il trattino.
jecxjo,

5

Ecco una versione che ho scritto usando un'espressione sostitutiva:

map <c-a> :s/\d/\=submatch(0) < 9 ? submatch(0) + 1 : submatch(0)/<CR>
map <c-x> :s/\d/\=submatch(0) > 0 ? submatch(0) - 1 : submatch(0)/<CR>

Ognuno cerca solo il carattere della prima cifra sulla linea e ne aggiunge o sottrae uno se è compreso nell'intervallo [0-8] o [1-9], rispettivamente. Ha tre problemi:

  1. Si tratta principalmente di manipolazione del testo e guarda solo il primo carattere, quindi non sa se un numero è negativo. Questo è risolvibile, ma mi piace il comportamento attuale così com'è.
  2. Blocca il registro di ricerca "/:, e se hai hlsearch attivo, tutti i numeri nel buffer corrente verranno evidenziati quando lo usi. È possibile aggiungere :noh<CR>a ciascuno dei mapcomandi sopra per interrompere l'evidenziazione, ma non so come impedire che il registro venga bloccato.
  3. Funziona sul primo numero sulla riga, non sul primo numero dopo il cursore.

Inoltre, se fossi in me, mapperei quanto sopra a <leader>ae <leader>x, piuttosto che a CTRL-A/X. In questo modo, hai entrambi i comportamenti a tua disposizione. <leader>è, per impostazione predefinita, il tasto barra rovesciata ( \).


Il fatto che ignori il numero negativo va bene, in effetti il ​​comportamento predefinito mi è sembrato strano. Penso che anche molto meglio :noh. Ma il vero problema è che non può usare la posizione del cursore come base e quindi è possibile incrementare solo la prima cifra della riga.
firedev,

Questo si ferma al numero 9 e sopra 10 aumenta di 11, non di 10 ... Penso che questo non sia intenzionale (cioè un bug)? Inoltre, si desidera sempre utilizzare la mappatura non ricorsiva ( noremap) e mai map . Vedi questa pagina per una spiegazione più dettagliata di ciò.
Martin Tournoij,
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.