Làm thế nào để tự động viết thường chữ cái thứ hai của một từ?


13

Khi tôi phải gõ nhiều văn bản, tôi thường có xu hướng giữ ngón tay của mình shiftkhi tôi viết chữ cái đầu tiên của câu thường đưa ra:

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

Ở đây, Etrong NEwnên chữ thường. Sau đó tôi đang cố gắng tạo một chức năng sẽ phát hiện nếu chữ cái thứ hai của từ đầu tiên của câu tôi đang gõ là chữ hoa và chữ thường sẽ viết thường. Phần quan trọng là việc sửa lỗi sẽ được thực hiện tự động trong khi tôi đang gõ cuối câu.

Cho đến nay tôi đã thử chơi với sự kiện tự động InsertCharPretrước khi nhận ra rằng văn bản không thể được sửa đổi bởi một chức năng được kích hoạt bởi sự kiện này.

Điều gì sẽ là một giải pháp tốt?

Lưu ý rằng cho đến nay tôi không cần phải tập trung vào các trường hợp cạnh như các từ viết tắt nên viết hoa hoặc loại này.

EDIT Tôi đã thực hiện điều này, đó là một cách giải quyết không hoàn hảo:

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

Nó có vấn đề vì ký tự đầu tiên tôi nhập trong chế độ chèn được di chuyển đến cuối dòng, nhưng tôi nghĩ điều đó có thể được sửa.

Tôi đoán bây giờ câu hỏi của tôi trở thành một câu hỏi đánh giá mã :

  • Làm thế nào tôi có thể thoát khỏi hiệu ứng phụ di chuyển ký tự đầu tiên được chèn?
  • Đây có phải là phương pháp tốt nhất có thể?
  • Phương pháp này dường như làm chậm Vim: làm thế nào để cải thiện nó?

Câu trả lời:


6

Đây là một chút gì đó nấu chín rất nhanh. Tôi nghĩ nó kém mạnh mẽ hơn, nhưng nó cũng nhẹ hơn nhiều. Có lẽ bạn có thể kết hợp nó vào của bạn để làm cho nó nhanh hơn? Có lẽ tôi sẽ sửa lại điều này một chút khi tôi có thời gian.

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

Tôi nghĩ không phải là một giải pháp đầy đủ, nhưng tôi nghĩ rằng tôi sẽ thử một cách tiếp cận khác và xem liệu nó có gây ra bất cứ điều gì cho bạn không. :)


4
Ý tưởng ánh xạ lại <Space>có vẻ khá thú vị vì nó làm giảm số lượng các lệnh. Tôi cũng sẽ cố gắng làm việc theo cách này!
statox

4

Tôi không biết nó đáng tin cậy như thế nào, nhưng bạn có thể thử điều này:

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

Nó cài đặt một autocmd thực thi lệnh sau trước khi bạn chèn một ký tự:

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

Ký tự bạn sắp chèn được lưu trữ trong biến nội bộ v:charvà nếu kiểm tra:

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

... Thành công, sau đó autocmd gán một giá trị mới v:char, đó là tolower(v:char).

Kiểm tra kiểm tra xem bạn có định chèn một chữ cái viết hoa ( v:char =~ '\u') hay không và con trỏ của bạn nằm sau ký tự đầu tiên của từ đầu tiên của câu:

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

Chỉnh sửa: Tôi không biết liệu có sự khác biệt (hiệu suất-khôn ngoan) giữa 2 cú pháp này không: :let myvar = test ? new_value : old_value:if test | let myvar = new_value | endif.

Tôi đã từng đọc rằng khi bạn muốn tối ưu hóa mã của mình, bạn phải sử dụng càng ít lệnh Ex càng tốt. Vì vậy, có lẽ cú pháp thứ 2 (có thể được tính là 3 lệnh Ex: :if, :let, :endif) là chậm hơn so với đợt 1, tôi không biết.

Nhưng nếu đây là trường hợp, bạn có thể thay thế autocmd bằng:

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

1
Bây giờ đó là một giải pháp thanh lịch! Theo thử nghiệm đầu tiên của tôi, nó hoạt động tốt. Tôi sẽ phải sử dụng nó một thời gian để chắc chắn rằng nó mạnh mẽ. Tôi thích cách bạn sửa đổi v:charý tưởng mà tôi đã bỏ lỡ trong lần thử đầu tiên.
statox

1

Một cách khác để làm điều đó (không quá tự động và không quá phổ biến; chỉ ngắn hơn):

  • vì bạn đang viết câu / văn xuôi, không phải mã, hãy để Vim kích hoạt kiểm tra chính tả trong bộ đệm văn bản của bạn
  • tạo một phím kết hợp chế độ chèn nhanh quay lại các lỗi chính tả cuối cùng, sửa nó, sau đó tiếp tục vị trí / trạng thái; ví dụ:

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

Vì vậy, bây giờ, hãy nói rằng bạn bắt đầu viết

"THis is a mistake|"

... Và bạn chỉ nhận ra sai lầm - phải làm gì? - chỉ cần nhấn <C-s>và tiếp tục viết câu của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.