Удалить обратный непрерывный пробел или непрерывный непробел до конца строки - PullRequest
0 голосов
/ 19 мая 2018

Vim часто создает строки с множеством непрерывных пробелов, поэтому я удивлен, что не существует простого способа удаления назад до конца предыдущего слова.Я пропустил что-то очевидное?

hello this is a line       |

удаляет обратно сюда:

hello this is a line|

или непустой пробел перед курсором:

hello this is a line|

удаляет обратно вздесь:

hello this is a |

Таким образом, я мог бы сопоставить ключ в режиме вставки и просто назад удалить слова или не-слова.

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Хорошо, эта функция делает то, что мне нужно:

function! BackspaceContiguousInsertMode()
python << EOF
import vim  
try:
    line = vim.current.line
    row, deleteto = vim.current.window.cursor
    if deleteto==0:
        vim.current.line = ""
        vim.command("startinsert")
    elif line[deleteto] == " ":
        deletefrom=deleteto
        while deletefrom-1>0 and vim.current.line[deletefrom-1] == " ":
            deletefrom=deletefrom-1
        vim.current.line=line[:deletefrom] + line[deleteto+1:]
        if len(line)-1 == deleteto:
            vim.current.window.cursor = (row,deletefrom+1)
            vim.command("startinsert!")
        else:
            vim.current.window.cursor = (row,deletefrom)
            vim.command("startinsert")
    else:
        eol=deleteto+1 >= len(line)
        if not eol and line[deleteto+1] != " ":
            trailingline = line[deleteto+1:]
            vim.current.line=line[:deleteto+1] + " " + trailingline
            vim.command("normal diw")
            leadingto=len(vim.current.line)-len(trailingline)-1
            vim.current.line=vim.current.line[:leadingto] + trailingline
            vim.command("startinsert")
        elif eol:    
            vim.command("normal diw")
            vim.command("startinsert!")
        else: 
            vim.command("normal diw")
            vim.command("startinsert")

except Exception as e:
    print("Error: {}".format(e))
EOF
endfunction
inoremap <C-b> <Esc>:call BackspaceContiguousInsertMode()<CR>

В режиме вставки (из которого я хотел ее вызвать) я могу нажать <C-b>, чтобы удалить обратно каждый блок слов или блок пробелов.в начале строки.Учитывая следующую строку, каждый раз, когда я нажимаю <C-b>, вот что происходит:

alskdjf       a;sjdf a kjkdjd        |kja sdf
alskdjf       a;sjdf a kjkdjd|kja sdf
alskdjf       a;sjdf a |kja sdf
alskdjf       a;sjdf a|kja sdf
alskdjf       a;sjdf |kja sdf
alskdjf       a;sjdf|kja sdf
alskdjf       a;|kja sdf
alskdjf       a|kja sdf
alskdjf       |kja sdf
alskdjf|kja sdf
|kja sdf
|... (stays on the same line)
0 голосов
/ 21 мая 2018

Хотя vim не поставляется с такой командой, он поставляется с командами, которые очень близки к тому, что вы хотите: ge и gE, найдите их в справке.К счастью, это означает, что тривиально обернуть их в следующие нормальные, визуальные и операторы, ожидающие отображения:

noremap <expr> <leader>e 'h'.v:count1.'gel'
noremap <expr> <leader>E 'h'.v:count1.'gEl'
onoremap <expr> <silent> <leader>e ':<c-u>normal! vh'.v:count1.'gel<cr>'
onoremap <expr> <silent> <leader>E ':<c-u>normal! vh'.v:count1.'gEl<cr>'

Очевидно, сопоставьте их с тем, что вы хотите, лично у меня первый сопоставлен с <BS>.Разница между e и E заключается в том, что они вызывают ge (перемещение на word) и gE (перемещение на WORD) соответственно.См. :h word и :h WORD для получения подробной информации о том, что это значит.

Это не совсем то, что вы просили: они не учитывают то, где мы находимся, когда мы начинаем, поэтому, например, удаление с помощью этого оператора приведет кзамените

this is a line|

на

this is a|

вместо

this is a |

Вы, конечно, можете это исправить, если хотите написать более сложный vimscript, но вряд ли стоитесли для одного пробела.

Материал, перемещаемый картой, ожидающей оператора, также будет слегка изменяться в зависимости от значения 'selection', если это вас беспокоит.

Редактировать: Это то, как ясоздаст точное решение, запрашиваемое для

function! s:Backup(mode)
  let str  = a:mode == 2 ? 'g' : ''
  let str .= a:mode ? 'v' : ''

  let at_end = col('.') >= col('$') - 1
  let str .= getline('.') =~ '\%'.(col('.') - !at_end).'c\S' ? 'b' : 'gel'
  let str .= !at_end && a:mode == 1 ? 'oho' : ''

  execute 'normal!' str
endfunction

. Это не удаляет само по себе, но объединяется с любой командой vim, такой как операторы d, y, c, и работает ввсе режимы, пока вы передаете правильный параметр.Чтобы воспроизвести сопоставление, используемое в ответе аскеров:

inoremap <silent> <c-b> <c-o>d:<c-u>call <SID>Backup(1)<cr>

А вот привязки для нормального, визуального, ожидающего оператора режима на <leader>e

nnoremap <silent> <leader>e :<c-u>call <SID>Backup(0)<cr>
onoremap <silent> <leader>e :<c-u>call <SID>Backup(1)<cr>
xnoremap <silent> <leader>e :<c-u>call <SID>Backup(2)<cr>

Обозначения NB должны быть определеныв том же сценарии, что и функция для использования s: и <SID>, в противном случае удалите их.

Редактировать 2: исправлено имя функции: /
Редактировать 3: настроено для исправления операции, когда она не завершеналинии.Очевидно, vim думает, что курсор находится в другом месте при добавлении в конце строки, как при вставке.

...