จะลดตัวอักษรตัวที่สองของคำโดยอัตโนมัติได้อย่างไร


13

เมื่อฉันต้องพิมพ์ข้อความจำนวนมากฉันมักจะกดนิ้วของฉันshiftเมื่อฉันเขียนตัวอักษรตัวแรกของประโยคที่มักจะให้:

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

ที่นี่EของNEwที่ควรจะเป็นกรณีที่ต่ำกว่า ฉันพยายามสร้างฟังก์ชั่นที่จะตรวจสอบว่าตัวอักษรตัวที่สองของคำแรกของประโยคที่ฉันพิมพ์เป็นตัวพิมพ์ใหญ่และตัวพิมพ์เล็กหรือไม่ ส่วนที่สำคัญคือการแก้ไขควรทำโดยอัตโนมัติในขณะที่ฉันพิมพ์ตอนท้ายของประโยค

จนถึงตอนนี้ฉันได้ลองเล่นกับเหตุการณ์บันทึกอัตโนมัติInsertCharPreก่อนที่จะทราบว่าข้อความไม่สามารถแก้ไขได้โดยฟังก์ชันที่ทริกเกอร์โดยเหตุการณ์นี้

อะไรจะเป็นทางออกที่ดี?

หมายเหตุจนถึงตอนนี้ฉันไม่จำเป็นต้องมุ่งเน้นไปที่ตัวกล่องขอบเช่นตัวย่อซึ่งควรเป็นตัวพิมพ์ใหญ่หรือของแบบนี้

แก้ไขฉันทำสิ่งนี้ซึ่งเป็นวิธีแก้ปัญหาที่ไม่สมบูรณ์:

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:chartolower(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 น้อยที่สุดเท่าที่จะทำได้ ดังนั้นบางทีไวยากรณ์ 2 (ซึ่งอาจจะนับเป็นคำสั่ง 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>และเขียนประโยคของคุณต่อไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.