Як автоматично писати маленьку літеру другої літери слова?


13

Коли мені доводиться вводити багато тексту, я часто прагну натискати на палець, shiftколи пишу першу букву речення, яке часто дають:

[...]end of sentence. NEw sentence[...]

Тут Eз NEwповинна бути в нижньому регістрі. Тоді я намагаюся створити функцію, яка б виявила, якби друга літера першого слова речення, яке я вводя, є великим регістром, і яка мала би малою літерою. Важливою частиною було б те, що виправлення потрібно робити автоматично, коли я набираю кінець свого речення.

Поки я намагався грати з події автокоманди, InsertCharPreперш ніж зрозумів, що текст не може бути змінений функцією, викликаною цією подією.

Що було б хорошим рішенням?

Зауважте, що поки що мені не потрібно зосереджуватись на кращих випадках, таких як абревіатури, які мають бути у верхньому регістрі або подібні речі.

EDIT Я зробив це, що є не ідеальним рішенням:

autocmd CursorMovedI * call RemoveUnwantedUpper()

function! RemoveUnwantedUpper()
    " Get the current sentence
    " Based on http://stackoverflow.com/a/23315227/4194289
    let l:save_clipboard = &clipboard
    set clipboard= " Avoid clobbering the selection and clipboard registers.
    let l:save_reg = getreg('"')
    let l:save_regmode = getregtype('"')

    normal! y(
    normal! ``

    let l:sentence =getreg('"') 

    call setreg('"', l:save_reg, l:save_regmode)
    let &clipboard = l:save_clipboard

    " Check that we entered a new word (space inserted)
    if l:sentence[len(l:sentence)-1] != " "
       return
    endif 

    " Check if the word is the first one of the sentence
    let l:size = len(split(l:sentence, " "))
    if l:size > 1 
        return
    endif

    " If the last char entered is a space (new word) remove the unwanted Upper case
   normal! bl
   normal! vu
   normal! ``

endfunction

У нього є проблема, оскільки перший символ, який я ввожу в режимі вставки, переміщений до кінця рядка, але я думаю, що це можна виправити.

Я думаю, тепер моє запитання стає питанням перегляду коду :

  • Як я можу позбутися побічного ефекту, який рухає перший вставлений символ?
  • Чи можливий найкращий метод?
  • Цей метод, здається, уповільнює Vim: як його можна вдосконалити?

Відповіді:


6

Ось трохи чогось приготували по-справжньому швидко. Я менш міцний, я думаю, але він також набагато легший. Може, ви могли б включити його у своє, щоб зробити це швидше? Я, мабуть, трохи перегляну це, коли встигну.

inoremap <Space> <C-o>:call CheckCase()<CR><Space>

function! CheckCase()
   normal! may2b
   let l:words = getreg('"')
   if l:words[0] == '.'
      normal! wlvu
   endif
   normal! `a
endfunction

Думаю, не повне рішення, але я подумав, що я спробую інший підхід і побачу, чи це щось для вас викликало. :)


4
Ідея перевпорядкування <Space>видається досить цікавою, оскільки зменшує кількість викликів функцій. Я також спробую працювати таким чином!
statox

4

Я не знаю, наскільки це надійно, але ви можете спробувати це:

augroup FixDoubleUppercase
    autocmd!
    autocmd InsertCharPre * if v:char =~ '\u' && getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c' | let v:char = tolower(v:char) | endif
augroup END

Він встановлює autocmd, який виконує наступну команду перед тим, як вставити символ:

if v:char =~ '\u' && getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c' | let v:char = tolower(v:char) | endif

Символ, який ви збираєтеся вставити, зберігається у внутрішній змінній v:char, і якщо тест:

v:char =~ '\u' && getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c'

... вдається, тоді autocmd присвоює нове значення v:char, яке є tolower(v:char).

Тест перевіряє, чи збираєтесь ви вставити велику літеру ( v:char =~ '\u'), і ваш курсор після першого символу першого слова речення:

getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c'

Редагувати: Я не знаю, чи є різниця (залежно від продуктивності) між цими 2 синтаксисами: :let myvar = test ? new_value : old_valueта :if test | let myvar = new_value | endif.

Я колись читав, що, коли ви хочете оптимізувати свій код, вам доведеться використовувати якомога менше Ex команд. Тому , можливо, другий синтаксис (який може бути розцінений як 3 команди Ex: :if, :let, :endif) відбувається повільніше , як 1 - ий, я не знаю.

Але якщо це так, ви можете замінити autocmd на:

autocmd InsertCharPre * let v:char = (v:char =~ '\u' && getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c') ? tolower(v:char) : v:char

1
Тепер це елегантне рішення! За моїми першими тестами, це працює добре. Мені доведеться використовувати його деякий час, щоб бути впевненим, що він надійний. Мені подобається, як ти модифікував v:charцю ідею, яку я пропустив під час своєї першої спроби.
statox

1

Ще один спосіб зробити це (не такий автоматичний і не такий універсальний; просто коротший):

  • оскільки ви пишете речення / прозу, а не код, попросіть Vim активувати перевірку орфографії у ваших текстових буферах
  • створити комбінований ключ режиму швидкої вставки, який повертається до останніх помилок правопису, виправляє його, а потім відновлює позицію / стан; наприклад:

    inoremap <C-s> <Esc>[s1z=gi
    

Отже, скажіть, ви почнете писати

"THis is a mistake|"

... і ти просто усвідомлюєш помилку - що робити? - просто натисніть <C-s>і продовжуйте писати своє речення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.