단어의 두 번째 문자를 자동으로 소문자로 바꾸는 방법은 무엇입니까?


13

많은 텍스트를 입력해야 할 때 종종 다음 shift과 같은 문장의 첫 글자를 쓸 때 손가락을 계속 누르는 경향이 있습니다 .

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

여기서 ENEw소문자한다. 그런 다음 입력하는 문장의 첫 단어의 두 번째 문자가 대문자인지 소문자인지 감지하는 함수를 만들려고합니다. 중요한 부분은 문장의 끝을 입력하는 동안 수정이 자동으로 수행되어야한다는 것입니다.

지금 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:char되는, tolower(v:char).

테스트는 대문자 ( v:char =~ '\u') 를 삽입하려고했는지 와 커서가 문장의 첫 단어의 첫 문자 뒤에 오는지 확인합니다.

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

편집 : 거기에이 두 구문의 차이 (성능 현명한)가 있는지 나도 몰라 :let myvar = test ? new_value : old_value하고 :if test | let myvar = new_value | endif.

코드를 최적화하려면 가능한 한 적은 Ex 명령을 사용해야한다는 것을 한 번 읽었습니다. 그래서 어쩌면 (3 개 예 명령으로 계산 될 수있다 : 2 구문 :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.