Bagaimana cara huruf kecil huruf kedua kata secara otomatis?

13

Ketika saya harus mengetik banyak teks, saya sering cenderung terus menekan jari shiftketika saya menulis huruf pertama dari sebuah kalimat yang sering memberi:

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

Di sini Edari NEwharus huruf kecil. Saya kemudian mencoba untuk membuat fungsi yang akan mendeteksi jika huruf kedua dari kata pertama dari kalimat yang saya ketikkan adalah huruf besar dan yang akan huruf kecil. Bagian yang penting adalah bahwa koreksi harus dilakukan secara otomatis saat saya mengetik akhir kalimat saya.

Sejauh ini saya sudah mencoba bermain dengan event autocommand InsertCharPresebelum menyadari bahwa teks tidak dapat dimodifikasi oleh fungsi yang dipicu oleh event ini.

Apa solusi yang baik?

Perhatikan bahwa sejauh ini saya tidak perlu fokus pada kasus tepi seperti akronim yang harus dalam huruf besar atau hal-hal semacam ini.

EDIT Saya sudah membuat ini, yang merupakan solusi yang tidak sempurna:

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

Ini memiliki masalah karena karakter pertama yang saya masukkan dalam mode insert dipindahkan ke akhir baris, tetapi saya pikir itu dapat diperbaiki.

Saya kira sekarang pertanyaan saya menjadi pertanyaan ulasan kode :

  • Bagaimana saya bisa menghilangkan efek samping yang menggerakkan karakter pertama yang dimasukkan?
  • Apakah ini metode terbaik?
  • Metode ini tampaknya memperlambat Vim: bagaimana bisa ditingkatkan?
statox
sumber

Jawaban:

6

Ini sedikit sesuatu yang dimasak dengan sangat cepat. Rasanya kurang kuat, tapi juga lebih ringan. Mungkin Anda bisa memasukkannya ke dalam milik Anda untuk membuatnya lebih cepat? Saya mungkin akan merevisi ini sedikit ketika saya punya waktu.

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

Kurasa bukan solusi lengkap, tetapi kupikir aku akan mencoba pendekatan yang berbeda dan melihat apakah itu memicu sesuatu untukmu. :)

Tumbler41
sumber
4
Gagasan memetakan ulang <Space>tampaknya cukup menarik karena mengurangi jumlah pemanggilan fungsi. Saya akan mencoba bekerja dengan cara ini juga!
statox
4

Saya tidak tahu seberapa andal itu, tetapi Anda bisa mencoba ini:

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

Itu menginstal autocmd yang mengeksekusi perintah berikut sebelum Anda memasukkan karakter:

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

Karakter yang akan Anda masukkan disimpan dalam variabel internal v:char, dan jika pengujian:

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

... berhasil, maka autocmd memberikan nilai baru v:char, yaitu tolower(v:char).

Tes memeriksa apakah Anda akan memasukkan huruf besar ( v:char =~ '\u') dan kursor Anda adalah setelah karakter pertama dari kata pertama kalimat:

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

Sunting: Saya tidak tahu apakah ada perbedaan (berdasarkan kinerja) antara 2 sintaks ini: :let myvar = test ? new_value : old_valuedan :if test | let myvar = new_value | endif.

Saya pernah membaca bahwa ketika Anda ingin mengoptimalkan kode Anda, Anda harus menggunakan perintah Ex sesedikit mungkin. Jadi mungkin 2 sintaks (yang bisa dihitung sebagai 3 perintah Ex: :if, :let, :endif) lebih lambat dari 1 satu, saya tidak tahu.

Tetapi jika ini masalahnya, Anda dapat mengganti autocmd dengan:

autocmd InsertCharPre * let v:char = (v:char =~ '\u' && getline('.') =~ '\v(\.\s+|^\s*)\u%' . col('.') . 'c') ? tolower(v:char) : v:char
pengguna9433424
sumber
1
Nah, itu solusi yang elegan! Menurut tes pertama saya itu bekerja dengan baik. Saya harus menggunakannya untuk beberapa waktu untuk memastikan itu kuat. Saya suka bagaimana Anda memodifikasi v:charide yang saya lewatkan pada percobaan pertama saya.
statox
1

Cara lain untuk melakukannya (tidak begitu otomatis, dan tidak terlalu universal; hanya lebih pendek):

  • karena Anda menulis kalimat / prosa, bukan kode, minta Vim mengaktifkan pemeriksaan ejaan di buffer teks Anda
  • buat tombol kombo mode sisipan cepat yang kembali ke kesalahan ejaan terakhir, memperbaikinya, lalu melanjutkan posisi / keadaan; misalnya:

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

Jadi sekarang, katakan Anda mulai menulis

"THis is a mistake|"

... dan Anda baru menyadari kesalahannya - apa yang harus dilakukan? - cukup tekan <C-s>dan lanjutkan menulis kalimat Anda.

VanLaser
sumber