Bir kelimenin ikinci harfini otomatik olarak nasıl küçültür?


13

Çok fazla metin yazmam gerektiğinde shift, genellikle bir cümlenin ilk harfini yazarken parmağımı basılı tutmaya eğilimliyim :

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

İşte Ebir NEwküçük harf olmalıdır. Daha sonra yazdığım cümlenin ilk sözcüğünün ikinci harfinin büyük ve küçük harf olacağını belirleyen bir işlev oluşturmaya çalışıyorum. Önemli olan, cümlenin sonunu yazarken düzeltmenin otomatik olarak yapılmasıdır.

Şimdiye kadar InsertCharPremetnin bu olay tarafından tetiklenen bir işlevle değiştirilemeyeceğini fark etmeden önce autocommand olayıyla oynamayı denedim .

İyi bir çözüm ne olurdu?

Not şimdiye kadar ben büyük harf veya şeylerin bu tür olmalıdır kısaltmalar gibi kenarları durumlarda odaklanmak gerek kalmayacak.

EDIT Mükemmel olmayan bir çözüm olan bunu yaptım:

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

Ekleme moduna girdiğim ilk karakter satırın sonuna taşındığı için bir sorunu var, ama bence bu düzeltilebilir.

Sanırım şimdi sorum kod inceleme sorusu haline geliyor :

  • Eklenen ilk karakteri hareket ettiren yan etkiden nasıl kurtulabilirim?
  • Mümkün olan en iyi yöntem mi?
  • Bu yöntem Vim'i yavaşlatıyor gibi görünüyor: nasıl geliştirilebilir?

Yanıtlar:


6

İşte biraz hızlı pişmiş bir şey. Bence daha az sağlam, ama aynı zamanda çok daha hafif. Belki daha hızlı hale getirmek için sizinkine dahil edebilirsiniz? Zamanım olduğunda bunu muhtemelen biraz revize edeceğim.

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

Bence tam bir çözüm değil, ama farklı bir yaklaşım deneyip sizin için bir şey yaratıp yaratmadığına bakacağımı düşündüm. :)


4
Yeniden eşleştirme fikri <Space>, işlevlerin çağrılma sayısını azalttığı için oldukça ilginç görünüyor. Ben de bu şekilde çalışmaya çalışacağım!
statox

4

Ne kadar güvenilir olduğunu bilmiyorum, ama bunu deneyebilirsiniz:

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

Bir karakter eklemeden önce aşağıdaki komutu yürüten bir autocmd yükler:

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

Eklemek üzere olduğunuz karakter dahili değişkende saklanır v:charve eğer test:

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

... başarılı, daha sonra autocmd yeni bir değer atar v:charolan tolower(v:char).

Test, büyük harf ( v:char =~ '\u') eklemek isteyip istemediğinizi kontrol eder ve imleciniz cümlenin ilk kelimesinin ilk karakterinden sonradır:

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

Düzenleme: Bu 2 sözdizimi arasında bir fark (performans açısından) olup olmadığını bilmiyorum: :let myvar = test ? new_value : old_valueve :if test | let myvar = new_value | endif.

Bir keresinde, kodunuzu optimize etmek istediğinizde, mümkün olduğunca az Ex komutu kullanmanız gerektiğini okudum. Yani belki (3 Ex komutlar olarak sayılabilir: 2 sözdizimi :if, :let, :endif) 1 olandan daha yavaştır, bilmiyorum.

Ancak bu durumda, autocmd'yi aşağıdakilerle değiştirebilirsiniz:

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

1
Şimdi bu zarif bir çözüm! İlk testlerime göre iyi çalışıyor. Sağlam olduğundan emin olmak için bir süre kullanmam gerekecek. v:charİlk denememde eksik olduğum fikrini nasıl değiştirdiğini seviyorum .
statox

1

Bunu yapmanın başka bir yolu (çok otomatik ve çok evrensel değil; sadece daha kısa):

  • kod değil cümle / nesir yazdığınız için, Vim'in metin tamponlarınızda yazım denetimini etkinleştirmesini sağlayın
  • son yazım hatalarına geri dönen, düzelten, ardından konumu / durumu sürdüren hızlı bir ekleme modu birleşik anahtar oluşturun; Örneğin:

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

Şimdi, yazmaya başladığınızı söyleyin

"THis is a mistake|"

... ve siz sadece hatayı fark edersiniz - ne yapmalı? - sadece <C-s>cümle vurmak ve yazmaya devam.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.