Jak automatycznie wpisać małą literę drugiej litery słowa?


13

Kiedy muszę pisać dużo tekstu, często mam tendencję do przytrzymywania palca shiftpodczas pisania pierwszej litery zdania, które często daje:

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

Tutaj Eod NEwpowinny być małe. Usiłuję następnie utworzyć funkcję, która wykrywa, czy druga litera pierwszego słowa wpisywanego zdania jest wielka, a która pisałaby małą literą. Ważną częścią byłoby to, że korekta powinna być wykonana automatycznie podczas pisania końca zdania.

Do tej pory próbowałem grać ze zdarzeniem autocommand, InsertCharPrezanim zdałem sobie sprawę, że tekst nie może być modyfikowany przez funkcję wywoływaną przez to zdarzenie.

Jakie byłoby dobre rozwiązanie?

Zauważ, że do tej pory nie muszę skupiać się na przypadkach krawędzi, takich jak akronimy, które powinny być pisane wielkimi literami lub tego rodzaju rzeczy.

EDYCJA Zrobiłem to, co nie jest idealnym obejściem:

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

Ma problem, ponieważ pierwszy znak, który wprowadzam w trybie wstawiania, jest przenoszony na koniec linii, ale myślę, że można to poprawić.

Chyba teraz moje pytanie staje się pytaniem o weryfikację kodu :

  • Jak mogę pozbyć się efektu ubocznego, który porusza pierwszą wstawioną postać?
  • Czy to najlepsza możliwa metoda?
  • Ta metoda wydaje się spowalniać Vima: jak można ją ulepszyć?

Odpowiedzi:


6

Oto coś naprawdę szybko ugotowanego. Myślę, że jest mniej wytrzymały, ale jest też znacznie lżejszy. Może mógłbyś włączyć go do swojego, aby był szybszy? Prawdopodobnie zmienię to trochę, kiedy będę miał czas.

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

Myślę, że nie jest to pełne rozwiązanie, ale pomyślałem, że wypróbuję inne podejście i zobaczę, czy coś Ci to wywołało. :)


4
Pomysł mapowania <Space>wydaje się dość interesujący, ponieważ zmniejsza liczbę wywołań funkcji. Spróbuję też pracować w ten sposób!
statox

4

Nie wiem, jak wiarygodny jest, ale możesz spróbować:

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

Instaluje autocmd, który wykonuje następujące polecenie przed wstawieniem znaku:

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

Znak, który zamierzasz wstawić, jest przechowywany w zmiennej wewnętrznej v:char, a jeśli test:

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

... udaje się, a następnie autocmd przypisuje nową wartość v:char, czyli tolower(v:char).

Test sprawdza, czy zamierzałeś wstawić wielką literę ( v:char =~ '\u'), a kursor znajduje się za pierwszym znakiem pierwszego słowa zdania:

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

Edycja: Nie wiem, czy istnieje różnica (pod względem wydajności) między tymi 2 składniami: :let myvar = test ? new_value : old_valuei :if test | let myvar = new_value | endif.

Kiedyś przeczytałem, że jeśli chcesz zoptymalizować swój kod, musisz użyć jak najmniejszej liczby poleceń Ex. Więc może 2nd składnia (które mogą być liczone jako 3 komendy ex: :if, :let, :endif) jest mniejsza niż 1 jeden, nie wiem.

Ale jeśli tak jest, możesz zastąpić autocmd:

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

1
To eleganckie rozwiązanie! Według moich pierwszych testów działa dobrze. Będę musiał go użyć przez pewien czas, aby upewnić się, że jest solidny. Podoba mi się to, jak zmodyfikowałeś v:charten pomysł, którego mi brakowało za pierwszym razem.
statox

1

Innym sposobem na to (nie tak automatycznym i nie tak uniwersalnym; tylko krótszym):

  • skoro piszesz zdania / prozę, a nie kod, niech Vim aktywuje sprawdzanie pisowni w twoich buforach tekstowych
  • utwórz klucz kombi w trybie szybkiego wstawiania, który powraca do ostatnich błędów ortograficznych, naprawia go, a następnie wznawia pozycję / stan; na przykład:

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

Więc teraz powiedz, że zaczynasz pisać

"THis is a mistake|"

... i zdajesz sobie sprawę z błędu - co robić? - po prostu naciśnij <C-s>i kontynuuj pisanie zdania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.