Yazım önerileri arasında geçiş yapma komutu


12

Ben eşlenen zziçin 1z=çoğu zaman büyük, ama her şimdi ve sonra ilk öneri doğru biri değil ki.

Ben tekrar tutmak istiyorum Yani zz(veya .diğer önerileri arasında geçiş yapmak için).

zzAynı kelime üzerinde bir saniye , o zaman, u2z=üçüncüsü zzgibi çalışır u3z=ve böyle devam eder.

Bunun nasıl yapılacağı hakkında bir fikrin var mı?


Düzenle:

@ Nobe4'ün harika cevabına dayanarak istediğimi yapmayı başardım, ancak herhangi bir iyileştirme veya öneri olması durumunda bir süre burada bırakacağım:

let s:spell_position = []
let s:spell_count = 0
let s:spell_word = ""

function! LoopSpell()

    if s:spell_position != getpos('.') ||
            \ (s:spell_count > 0 && s:spell_word !~ expand("<cword>"))
        let s:spell_count = 0
        let s:spell_position = getpos('.')
    endif

    if s:spell_count > 0
        silent execute "normal! u"
    endif

    let s:current_word = expand("<cword>")
    if len(s:current_word) <= 0
        return
    endif

    let s:spell_suggestions = spellsuggest(expand(s:current_word))
    if len(s:spell_suggestions) <= 0
        return
    endif

    if s:spell_count >= len(s:spell_suggestions)
        let s:spell_word = s:current_word
        let s:spell_count = 0
    else
        let s:spell_word = s:spell_suggestions[s:spell_count]
        let s:spell_count += 1
    endif
    silent execute "normal! ciw" . s:spell_word
    let s:spell_position = getpos('.')

endfunction

nnoremap <c-m> :call LoopSpell()<CR>

( <c-m>@ Vitor'in yorumu nedeniyle eşlemeyi değiştirdim . Ayrıca bu tuşları basılı tutmamı ve önerilerde hızlıca ilerlememi sağlıyor. Bunu düşünüyorum <c-mistake>.)


2
Bu sitenin bir kullanıcısı tarafından yapılan bu eklentiyi kontrol etmenizi öneririm . Kullanmak düzelterek başlamak için: Gerçekten yazım denetimi iş akışını artırır :CorrectBirlikte doğru kelimeleri oluk gezinmek mümkün olacak: komutu nve Nbir bölünmüş pencere tüm düzeltme önerileri yapabilirsiniz basitçe gezinme içlerinden ile açılır jve kve <CR>irade düzeltmeyi uygular.
statox

@statox Öneri için teşekkürler. Bunu kontrol edeceğim, ancak zzkomutumun belirli şeyleri hızlı bir şekilde düzeltmesini istiyorum .
dbmrq

3
Umarım zzpencereyi mevcut çizginin etrafında merkezler. Muhtemelen daha sık kullandığım kısayollardan biri. Ayrıca ödeme yapmalısınız zbve zt.
Vitor

@Vitor İlginç, bilmiyordum! Genellikle scrolloffoldukça yüksek tutuyorum, ama yine de faydalı görünüyor, başka bir harita düşüneceğim. Teşekkürler!
dbmrq

Bu vim komut dosyası sözcük tamamlama / yazım düzeltme / eşanlamlı (aspell, eş anlamlılar sözlüğü, sözlük kullanarak) stackoverflow.com/a/46645434/476175
mosh

Yanıtlar:


6

İşte ben geldim:

Büyü Döndürme

büyü döndürme

Özellikleri

  • '[Ve ']işaretler üzerinde çalışılan metnin izlemek için kullanılır. Başka bir yerde değişiklik yapılması, önerilen değişikliği etkin bir şekilde "kabul" edecektir.
  • Bir sayımı kabul eder.
  • Kullanarak geri gider zp
  • Vim-repeat kullanılarak tekrarlanabilir .
  • Kaç öneri döndürüldüğünden bağımsız olarak orijinal kelimeyi geri yüklemek için bir kez geri alın.
  • Bölünmüş kelimeler için öneriler almak üzere görsel modda çalışır (örn. "Başlık satırı" -> "başlık")
    • Metni takip etmek için kullanır '<ve '>işaretler.
    • Not : vim-repeat ile tekrarlanabilir gibi görünmüyor .
  • Değiştirilen orijinal kelime isimsiz kayıtta tutulur.
  • Orijinal, önceki, geçerli ve sonraki öneriler komut satırında görüntülenir.
  • :SpellRotateSubAllOrijinalle eşleşen tüm metni geçerli öneriyle değiştirmek için Naive komutu .

Eklenti: spellrotate.vim

function! s:spell_rotate(dir, visual) abort
  if a:visual
    " Restore selection.  This line is seen throughout the function if the
    " selection is cleared right before a potential return.
    normal! gv
    if getline("'<") != getline("'>")
      echo 'Spell Rotate: can''t give suggestions for multiple lines'
      return
    endif
  endif

  if !&spell
    echo 'Spell Rotate: spell not enabled.'
    return
  endif

  " Keep the view to restore after a possible jump using the change marks.
  let view = winsaveview()
  let on_spell_word = 0

  if exists('b:_spell') && getline("'[") == getline("']")
    let bounds = b:_spell.bounds
    " Confirm that the cursor is between the bounds being tracked.
    let on_spell_word = bounds[0][0] == bounds[1][0]
          \ && view.lnum == bounds[0][0]
          \ && view.col >= bounds[0][1]
          \ && view.col <= bounds[1][1]
  endif

  " Make sure the correct register is used
  let register = &clipboard == 'unnamed'
        \ ? '*' : &clipboard == 'unnamedplus'
        \ ? '+' : '"'

  " Store the text in the unnamed register.  Note that yanking will clear
  " the visual selection.
  if on_spell_word
    if a:visual
      keepjumps normal! y
    else
      keepjumps normal! `[v`]y
    endif
    call winrestview(view)
  elseif a:visual
    keepjumps normal! y
  else
    keepjumps normal! viwy
  endif

  let cword = getreg(register)

  if !on_spell_word || b:_spell.alts[b:_spell.index] != cword
    " Start a new list of suggestions.  The word being replaced will
    " always be at index 0.
    let spell_list = [cword] + spellsuggest(cword)
    let b:_spell = {
          \ 'index': 0,
          \ 'bounds': [[0, 0], [0, 0]],
          \ 'cword': cword,
          \ 'alts': spell_list,
          \ 'n_alts': len(spell_list),
          \ }

    if len(b:_spell.alts) > 1
      " Do something to change the buffer and force a new undo point to be
      " created.  This is because `undojoin` is used below and it won't
      " work if we're not at the last point of the undo history.
      if a:visual
        normal! xP
      else
        normal! ix
        normal! x
      endif
    endif
  endif

  if a:visual
    normal! gv
  endif

  if len(b:_spell.alts) < 2
    echo 'Spell Rotate: No suggestions'
    return
  endif

  " Force the next changes to be part of the last undo point
  undojoin

  " Setup vim-repeat if it exists.
  silent! call repeat#set(printf("\<Plug>(SpellRotate%s%s)",
        \ a:dir < 0 ? 'Backward' : 'Forward', a:visual ? 'V' : ''))

  " Get the suggested, previous, and next text
  let i = (b:_spell.index + (a:dir * v:count1)) % b:_spell.n_alts
  if i < 0
    let i += b:_spell.n_alts
  endif

  let next = (i + 1) % b:_spell.n_alts
  let prev = (i - 1) % b:_spell.n_alts
  if prev < 0
    let prev += b:_spell.n_alts
  endif

  let next_word = b:_spell.alts[next]
  let prev_word = b:_spell.alts[prev]

  let b:_spell.index = i
  call setreg(register, b:_spell.alts[i])

  if a:visual
    normal! p`[v`]
  else
    keepjumps normal! gvp
  endif

  " Keep the original word in the unnamed register
  call setreg(register, b:_spell.cword)

  let b:_spell.bounds = [
        \ getpos(a:visual ? "'<" : "'[")[1:2],
        \ getpos(a:visual ? "'>" : "']")[1:2],
        \ ]

  echon printf('Suggestion %*s of %s for "', strlen(b:_spell.n_alts - 1), b:_spell.index, b:_spell.n_alts - 1)
  echohl Title
  echon b:_spell.cword
  echohl None
  echon '":  '

  if a:dir < 0
    echohl String
  else
    echohl Comment
  endif
  echon prev_word
  echohl None

  echon ' < '

  echohl Keyword
  echon b:_spell.alts[i]
  echohl None

  echon ' > '

  if a:dir > 0
    echohl String
  else
    echohl Comment
  endif
  echon next_word
  echohl None

  redraw
endfunction


function! s:spell_rotate_suball() abort
  if !exists('b:_spell') || len(b:_spell.alts) < 2
    return
  endif
  execute '%s/'.b:_spell.cword.'/'.b:_spell.alts[b:_spell.index].'/g'
endfunction


command! SpellRotateSubAll call s:spell_rotate_suball()

nnoremap <silent> <Plug>(SpellRotateForward) :<c-u>call <sid>spell_rotate(v:count1, 0)<cr>
nnoremap <silent> <Plug>(SpellRotateBackward) :<c-u>call <sid>spell_rotate(-v:count1, 0)<cr>
vnoremap <silent> <Plug>(SpellRotateForwardV) :<c-u>call <sid>spell_rotate(v:count1, 1)<cr>
vnoremap <silent> <Plug>(SpellRotateBackwardV) :<c-u>call <sid>spell_rotate(-v:count1, 1)<cr>

nmap <silent> zz <Plug>(SpellRotateForward)
nmap <silent> zp <Plug>(SpellRotateBackward)
vmap <silent> zz <Plug>(SpellRotateForwardV)
vmap <silent> zp <Plug>(SpellRotateBackwardV)

1
Vay canına, şimdi konuşuyoruz! Gelecekteki değişiklikleri ve geliştirmeleri aynı yerde tutabilmemiz için bunu bağımsız bir eklentiye dönüştürmelisiniz. Ya da ilgilenmiyorsanız bunu yapmaya çalışabilirim.
dbmrq

@danielbmarques Yeterince kolay, işte başlıyoruz
Tommy A

Harika, teşekkürler! Tam olarak istediğim ve daha fazlası olduğu için cevabınızı doğru olarak kabul edeceğim ve tüm çabası ve yardımı için @ nobe4'e ödül vereceğim.
dbmrq

@danielbmarques Sorun değil. İlginç sorular ve çözümler için varım 😄
Tommy A

5

@Statox'un önerdiği gibi, yazdığım eklentiyi kullanabilirsiniz: vimcorrect .

Temel olarak nasıl çalıştığını açıklayacağım, bu yüzden bir kısmını tekrar kullanmak isterseniz yapabilirsiniz.

Bir sonraki yanlış yazılmış kelimeye odaklanmak için doğrudan ]sve bir [ssonraki / önceki maça atlarken kullanıyorum. Mevcut kelimeyi vurgulamak için özel bir eşleme fonksiyonu tanımladım:

resim açıklamasını buraya girin

matchadd('error', '\%'.line('.').'l'.'\%'.col('.').'c'.s:current_word)

Hangi eşleme grubuna errorgeçerli satır / sütundaki geçerli sözcüğü ekler (aynı satırda birden fazla eşleşmeyi önlemek için).


spellbadword()Fonksiyon imlecin altındaki kelime için olası düzeltme listesini döndürür.

Basitçe bu listeyi bir arabellekte görüntülerim <CR>ve yanlış yazılmış kelimeyi geçerli satırla değiştirmek için eşleştiririm (yani olası bir düzeltilmiş sözcük).


Ben de harita nve ben N, ]sve [sonları aramak için basmaya alışkınım olarak.

q eklentiden çıkmak, bölünmeyi kapatmak ve vurgulamayı kaldırmak için eşlenir.

Not : Hala oldukça kararsız, ama yakında biraz değişiklik yapmayı planlıyorum. Bu eklentiyi geliştirebileceğinizi / geliştirmek istediğinizi düşünüyorsanız, çekme isteğini çatallamak / açmaktan çekinmeyin.


Açıklama için teşekkürler. Eklentiniz harika görünüyor, kesinlikle kullanacağım. Yine de zzkomutumu istiyorum , böylece özel bir moda girmeden işleri hızlı bir şekilde düzeltebilirim. Belki anlayabilirsem bunu ekleyebiliriz vimcorrect. :)
dbmrq

Kesinlikle daha fazla özelleştirme eklemem gerekiyor. Özel eşlemeyi tanımlamak isterseniz ekleyebilirsiniz bir gelişme olabilir :) (vimscript'de geliştirmeye başlarsanız öğrenmek için iyi bir yol olabilir)
nobe4

2

İşte çalışması gereken bir işlev:

let s:last_spell_changedtick = {}

function! LoopSpell()
  " Save current line and column
  let l:line = line('.')
  let l:col = col('.')

  " check if the current line/column is already in the last_spell_changedtick
  if has_key(s:last_spell_changedtick, l:line) == 0
    let s:last_spell_changedtick[l:line] = {}
  endif

  if has_key(s:last_spell_changedtick[l:line], l:col) == 0
    let s:last_spell_changedtick[l:line][l:col] = 0
  endif

  " If the value already exists, undo the change
  if s:last_spell_changedtick[l:line][l:col] != 0
    normal u
  endif

  " Get the current word
  let l:current_word = spellbadword()
  if len(l:current_word) == 0
    call <SID>Quit()
  endif

  " Get suggestions for the current word
  let s:current_word = l:current_word[0]
  let l:suggestions = spellsuggest(expand(s:current_word))

  " If the current word present no spelling suggestions, pass
  if len(suggestions) <= 0
    return
  endif

  " Replace the word with suggestion
  silent execute "normal! ce" . l:suggestions[s:last_spell_changedtick[l:line][l:col]]
  normal! b

  " Increment the count
  let s:last_spell_changedtick[l:line][l:col] = s:last_spell_changedtick[l:line][l:col] + 1

endfunction

function! LoopConfirm()
  let s:last_spell_changedtick = {}
endfunction

nnoremap zz :call LoopSpell()<CR>
nnoremap z= :call LoopConfirm()<CR>

Temel fikir, değiştirilen her kelimeyi bir satır / sütun çiftiyle eşleştirmek (yalnızca bir öğe için çalışmayacak şekilde) ve öğenin önceden değiştirilip değiştirilmediğini kontrol etmektir.

Değiştirmeyi yapmak için, eklentimin yaptığı hemen hemen budur:

  • geçerli yanlış yazılmış kelimeyi getir
  • düzeltmelerin olup olmadığını kontrol et
  • kelimeyi düzeltilmiş öneri ile değiştir

Bunu kullanırken, yanlış yazılmış kelimeye geri dönmek isterseniz, tuşuna basmanız yeterlidir u.

LoopConfirmFonksiyon Eğer metni değiştirmek eğer öyleyse, sen çarpışmaları önlemek için arayabileceğiniz, sözlük sıfırlayın.

Herhangi bir sorunla karşılaşırsanız / sorularınız olursa bize bildirin.


Uuh, bu iyi görünüyor. Yine de hala birçok sorunu var. "Tehlikeli ve sıkıcı" kelimelerini kullanın ve her kelimeyi bu şekilde düzeltmeye çalışın. Listede 4 numara olmasına rağmen asla "teh" için "alabilirsiniz". "qick" çalışır, ancak "brown" listede ilk sırada olsa bile "borwn" ifadesi başka bir şeye dönüşür ve sonra doğrudan "foz" e atlar. Bunu hiç geçemedim. Ayrıca ekstra z=kısmı sevmiyorum , ama geri kalanı işe yaradığında muhtemelen kendim için bir yol bulabiliriz. Bu benim istediğim şeye çok yaklaşıyor. Düzeltmeye çalışacağım. Teşekkürler!
dbmrq

Güncellememe bakın, çok yakında bir artış ekliyorum :) Evet z=ikisinden de memnun değilim . Ancak bu yöntemle nerede olduğunuzu referans almanız gerekir. Ancak tüm referansları aynı anda tutmanız gerekmiyorsa bunu basitleştirebilirim :)
nobe4

"Tüm referansları aynı anda tut" ile ne demek istediğinizden emin değilim ... ancak imleç hareket ettiğinde sözlüğü sıfırlayamadık mı? İşlev, imlecin son çağrıldığı yerle aynı yerde olup olmadığını kontrol eder ve eğer değilse sıfırlanır.
dbmrq

Ayrıca, imleç kelimenin başında olmadığında düzgün çalışmaz. İmleci her kelimenin ortasına yerleştirerek bu cümledeki her hatayı düzeltmeye çalışın. Hemen sonrakine geçiyorum.
dbmrq

1
Tamam, sanırım anladım! Son düzenlememi kontrol et. Bu hemen hemen mükemmel çalışıyor. Başka birinin ekleyecek bir şeyleri olup olmadığını görmek için soruyu biraz daha açık bırakacağım, ancak cevabınız harikaydı, teşekkür ederim. :)
dbmrq

2

Kenara diğer cevaplardan doğru Vim için yerleşik bir yol aslında vardır: <C-x>s. Bu, Vim'in ekleme modu tamamlama menüsünü kullanacaktır.

Ekleme <C-x>smodundan basmak , imlecin altındaki sözcüğü ilk öneriye düzeltmeli ve tamamlama menüsünü başka önerileri (varsa) göstermelidir. 'completeopt'Tamamlama menüsü için bazı ayarları özelleştirmek için ayarı kullanabilirsiniz .

Bunun yalnızca ekleme modundan çalışması biraz can sıkıcıdır ve kullanımı kullanmak <C-x><C-s>sorunlu olabilir (aşağıdaki nota bakın), böylece bunun için kendi eşlemenizi tanımlayabilirsiniz:

inoremap <expr> <C-@>  pumvisible() ?  "\<C-n>" : "\<C-x>s"
nnoremap <expr> <C-@> pumvisible() ?  "i\<C-n>" : "i\<C-x>s"

<C-@> Control + Space.

Ayrıca bakınız :help ins-completion :help i_CTRL-X_s


Şahsen çalışmayı yazım denetimi yapmak veya kod için düzenli otomatik tamamlamayı kullanmak istiyorsak "tahmin" edecek daha gelişmiş bir sürüm kullanıyorum:

fun! GuessType()
    " Use omnicomplete for Go
    if &filetype == 'go'
        let l:def = "\<C-x>\<C-o>"
    " Keyword complete for anything else
    else
        let l:def = "\<C-x>\<C-n>"
    endif

    " If we have spell suggestions for the current word, use that. Otherwise use
    " whatever we figured out above.
    try
        if spellbadword()[1] != ''
            return "\<C-x>s"
        else
            return l:def
        endif
    catch
        return l:def
    endtry
endfun

inoremap <expr> <C-@>  pumvisible() ?  "\<C-n>" : GuessType()
inoremap <expr> <Down> pumvisible() ? "\<C-n>" : "\<Down>"
inoremap <expr> <Up> pumvisible() ? "\<C-p>" : "\<Up>"
nnoremap <expr> <C-@> pumvisible() ?  "i\<C-n>" : 'i' . GuessType()

Ayrıca kabaca benzer şeyler yapan bazı eklentiler olduğuna inanıyorum (oldukça popüler olan SuperTab gibi), ancak asla istediğim gibi davranmalarını sağlayamadım.


Uyarı : Bir terminalden Vim kullanıyorsanız, <C-s>"çıkışı durdur" anlamına gelir. Bu yüzden hem <C-x><C-s> ve <C-x>s varsayılan olarak eşlenir. Kazayla <C-q>basarsanız çıktıya devam etmek için kullanın <C-s>. Kullanmıyorsanız da devre dışı bırakabilirsiniz <C-s>( bu soruya bakın ). GVim kullanıyorsanız bunu göz ardı edebilirsiniz.

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.