Як і Ctrl-A і Ctrl-X, але змінюють лише першу цифру


10

Чи є спосіб збільшити / зменшити першу цифру після / під курсором, а не ціле число.

Я знаю, що це не так, як працює vim, але чи є плагін, який це робить? Я не зміг його знайти.

Це дуже корисно при редагуванні css та в інших випадках.

Подано:

▐margin: 10px

Коли я натискаю, CTRL-Aхочу побачити:

▐margin: 20px

Фактична:

▐margin: 11px

10
Ви також 10<C-a>можете додати 10 або r2замінити 1 на 2.
jamessan

Відповіді:


6

Це, здається, працює досить добре, і робить досить розумними речі при використанні <C-a>на 9 (95 стає 105) або при використанні <C-x>на 0 (105 стає 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
  • По-перше, ми шукаємо будь-яку цифру, search()має перевагу не скидання @/.
  • a <Esc>h - Перейдіть до режиму вставки, додайте пробіл після цифри та перейдіть ліворуч, щоб курсор знаходився вгорі цифри.
  • Тепер ми можемо використовувати <C-a>або <C-x>.
  • Ми використовуємо lxhдля видалення доданого місця.

Я відобразив це на g<C-a>і g<C-x>, тому ви все ще можете назвати оригінал.

Трохи інша версія, яка буде шукати номери лише в поточному рядку (але залишить висяче місце, якщо в поточному рядку немає номера):

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

Ось ще одна версія, яка використовує те саме поняття, що і раніше, але також додає пробіл перед цифрою. Це дозволить g<C-a>ігнорувати будь Муніс знак перед номером (за замовчуванням, <C-a>на -42волю «прирощення» до нього -41.

Він також приймає підрахунок, так що 5g<C-a>збільшить число на 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

Основний приріст

Ось простий макрос для виконання дії:

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

У звичайному режимі ви

  • m` Позначте своє місцезнаходження
  • l перемістіть один символ праворуч
  • v$x вирізати до кінця рядка
  • h повернутися до вихідного положення
  • <c-a> приріст (або декремент)
  • p вставте назад свій зріз
  • `` повернутися до своєї позначки

Перейти до наступного числа

Якщо ви хочете перейти до наступного числа (або залишитися у своєму поточному положенні, якщо на номері), вам потрібна функція, яка перевіряє поточний курсований символ і можливий перехід до наступного числа.

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``

NextNumотримує символ під курсором, перевіряє, чи є його число, а якщо не шукає наступне число. Після цього решта те саме. Якщо ви хочете, щоб відображення було різним, просто змініть, наприклад, те, nnoremap <leader>aщо ви хочете nnoremap <c-a>.

Ігнорування негативів та цифр вище 9

Якщо ви хочете просто перейти через цифри і не дати їм діяти як підписані цілі числа, наступні функції збільшуватимуться та зменшуватимуться та перекидатимуться на 0 та 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>

Тепер, коли ви ввімкнено 8та введіть <leader>aотриманий текст 9. Якщо це зробити знову, це призводить до 0. Якщо ви натиснете <leader>xна 0ви отримаєте 9. Те саме стосується і від’ємних чисел. Функції вирізають один символ, приріст, декремент або перевертають, а потім вставляють на місце.


Щось тут не так, але я пам’ятаю цю думку, можливо, її можна вдосконалити. Це має бути стрибок до першої цифри на поточному рядку, якщо такий є, і діяти на ньому. Переважно також можна відобразити <c-a>/<c-x>.
звільнений

Оновлена ​​версія. Тепер перескакує вперед до наступного числа, або якщо ви зараз перевищує цифру, ви можете збільшувати його.
jecxjo

Так! Це дивовижно, дякую! Я не розумію, чому питання було спростовано, але це мене дратувало з першого дня, і, очевидно, багато людей переосмислюють <c-a>і <c-x>щось інше, тому що поведінка за замовчуванням не є такою корисною.
звільнений

Я міг бачити, що це стає неприйнятним, тому що питання полягало в чомусь дуже специфічному, і початковий вид запитання змінився по ходу ... необхідність перейти до першого числа. Що вбік, я фактично використовую <c-a>і <c-x>багато. Кожен раз, коли я оновлюю версію або збільшую змінну діапазону, я просто [N]<c-a>замість видалення та заміни.
jecxjo

1
Це було б можливо, але це був би набагато більший набір функцій. Поточна реалізація використовує переваги, <c-a>і <c-x>яку потрібно було б відкинути для функції, яка робить те саме, але ігнорує тире.
jecxjo

5

Ось версія, яку я написав, використовуючи вираз-замінник:

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>

Кожен просто шукає першу цифру символу на рядку і додає або віднімає його, якщо він знаходиться в діапазоні [0-8] або [1-9] відповідно. У ньому є три випуски:

  1. Це в основному маніпуляція текстом і дивиться лише на першого символу, тож він не знає, чи число від’ємне. Це можна виправити, але мені подобається поточна поведінка такою, якою є.
  2. Він клобує реєстр пошуку: "/і якщо ви ввімкнули hlsearch, тоді всі числа в поточному буфері будуть виділені при використанні цього. Ви можете додати :noh<CR>до кожної з перерахованих вище mapкоманд, щоб зупинити виділення, але я не знаю, як красиво зупинити регістр від клобування.
  3. Він працює на першому номері в рядку, а не на першому номері після курсору.

Крім того , якщо б це було, я б карту вище , щоб <leader>aі <leader>x, замість того , щоб CTRL-A/X. Таким чином, у вас є обидва способи поведінки. <leader>за замовчуванням - клавіша зворотної косої риски ( \).


Те, що воно нехтує негативним числом, чудово, насправді поведінка за замовчуванням мені здавалася дивною. Я думаю, що це також виглядає набагато краще :noh. Але справжня проблема полягає в тому, що він не може використовувати позицію курсору в якості основи, і, таким чином, ви можете збільшувати лише першу цифру в рядку.
звільнений

Це зупиняється на цифрі 9, а вище 10 - з кроком на 11, а не на 10 ... Я думаю, це ненавмисне (тобто помилка)? Крім того, ви завжди хочете використовувати нерекурсивне відображення ( noremap) і ніколи map . Дивіться цю сторінку для більш детального пояснення цього.
Мартін Турнойж
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.