zGとzWを永続化する


7

編集:これを小さなプラグインに変えました。これは私の最初の試みであり、私が何をしているかわからないので、どんな助けでも大歓迎です。:)

ここにあります:https//github.com/danielbmarques/vim-dialect

----------

私が使用し続けたいzgzwグローバルのvimに単語を追加するspellfileのが、私が使用したいzGzWに単語を追加するためにspellfile 、私が編集していたファイルに固有。言い換えれば、私は各ファイルに対して永続的でzGありたいと思っzWています。

spellfile変更を設定するzgzwコマンドとコマンドが変更されますが、必要なのはコマンドzGzWコマンドのみを変更することです。

だから私はこれをやった:

:au BufNewFile,BufRead * let &l:spellfile = expand('%:p:h') . '/.' .
    \ substitute(expand('%:t'), '\(.*\)\..*', '\1', '') . '.utf-8.add'
nnoremap zG :call LocalSpell("zG")<cr>
nnoremap zW :call LocalSpell("zW")<cr>
nnoremap zuG :call LocalSpell("zuG")<cr>
nnoremap zuW :call LocalSpell("zuW")<cr>
nnoremap zg :call GlobalSpell("zg")<cr>
nnoremap zw :call GlobalSpell("zw")<cr>
nnoremap zug :call GlobalSpell("zug")<cr>
nnoremap zuw :call GlobalSpell("zuw")<cr>
vnoremap zG :call LocalSpell("gvzG")<cr>
vnoremap zW :call LocalSpell("gvzW")<cr>
vnoremap zuG :call LocalSpell("gvzuG")<cr>
vnoremap zuW :call LocalSpell("gvzuW")<cr>
vnoremap zg :call GlobalSpell("gvzg")<cr>
vnoremap zw :call GlobalSpell("gvzw")<cr>
vnoremap zug :call GlobalSpell("gvzug")<cr>
vnoremap zuw :call GlobalSpell("gvzuw")<cr>

function! LocalSpell(cmd)
    if &l:spellfile == ""
        execute "normal! " . a:cmd
    else
        execute "normal! " . tolower(a:cmd)
    endif
endfunction

function! GlobalSpell(cmd)
    let b:spellfile = &l:spellfile
    setlocal spellfile=
    execute "normal! " . a:cmd
    let &l:spellfile = b:spellfile
endfunction

そして、それは機能します…しかし、それは私にとって良い解決策のようには見えません(編集:それはすでに良くなっています:))。ですから、誰かがより良いアイデアや改善を提案する場合に備えて、ここに投稿すると思いました。どう思いますか?


上記のコードはどこに含めましたか?ファイルタイププラグイン?どのようにトリガー/読み取りされますか?
mMontu

@mMontuさて、今のところ、私はそれを私のvimrcに追加しました。小さなプラグインを作成して、そこから取り出すことを考えていました。なぜこのファイルタイプを特定にするのかわかりません。追加した単語を破棄したくありません。とにかくspellfile最初のファイルzGが実行されたときにのみ作成されます。
dbmrq 2016

あなたが言ったように、a spellfile specific to the file I'm editing私はあなたが複数のスペルファイルを使用していると思ったzG。spellfilenameはファイル名(let &l:spellfile = expand('%:p:h')...)から派生しているため、そのファイルを開くときにファイル名とマッピングを定義することにより、特定のファイルタイプに対してこれを実現できます(<buffer>マッピングに含める必要があります)。またzG、特定のファイルのみにこの変更を加えることを望んでいると想定しました。
mMontu

@mMontuああ、いいえ、spellfile特定のファイルタイプを意味するのではなく、ファイルspellfileごとに1つです。そのため、単語を追加することができます。そのファイルをもう一度開くと、それらは引き続き追加されますが、その特定のファイルだけに適用され、他のファイルには追加されません。それも興味深いアイデアです。残念ながら、それは複数のスペルファイルを調達する方法ではないようです。それ以外の場合は、両方を実行して、現在のファイルに単語を追加するコマンドと現在のファイルタイプに単語を追加するコマンドを使用できます。
dbmrq

私はまさにについて話していましたone spellfile for each file。多分私は何かを見逃したかもしれませんが、コードをあなたに追加した場合.vimrc:source再度それを明示的に再評価しない限り、複数のスペルファイルを持つことはできませんでした%
mMontu 2016

回答:


2

クールなアイデア!

あなたは自分のコードの何が悪いと思うかについては言及しません。それは私にはかなりよさそうだ!

おそらく他の方法で行います。変更するのはローカルの動作のみなので、理想的には、GlobalSpell関数とすべてのグローバルマッピングを削除し、ローカルのスペル機能を変更するだけです。

残念ながら、このアプローチ'spellfile'は、自動コマンドが実行される前にが空でない場合にのみ機能します。(空のの場合'spellfile'、Vim 'runtimepath'はスペルを追加したときにの場所を計算しますが、そのパスにアクセスする方法はありません。)が既にリストである場合も機能しません。'spellfile'実際にエントリをカウントし、zgそれに応じてカウントを変更します。

したがって、次のアプローチは.vimrcでの個人的な使用には問題ありませんが、プラグインで実際に使用することはできません。

set spell
set spellfile=~/global.utf-8.add

augroup persistent_spelling
  autocmd!
  autocmd BufNewFile,BufRead * let &l:spellfile .= ',' . expand('%:p:h') . '/.' .
    \ substitute(expand('%:t'), '\(.*\)\..*', '\1', '') . '.utf-8.add'
augroup END

function! LocalSpell(cmd)
  if &l:spellfile !~ ","
    execute "normal! " . a:cmd
  else
    execute "normal! 2" . tolower(a:cmd)
  endif
endfunction

nnoremap zG :call LocalSpell("zG")<cr>
nnoremap zW :call LocalSpell("zW")<cr>
nnoremap zuG :call LocalSpell("zuG")<cr>
nnoremap zuW :call LocalSpell("zuW")<cr>
vnoremap zG :call LocalSpell("gvzG")<cr>
vnoremap zW :call LocalSpell("gvzW")<cr>
vnoremap zuG :call LocalSpell("gvzuG")<cr>
vnoremap zuW :call LocalSpell("gvzuW")<cr>

上記autocommandではaugroup、あなたをで囲みました。これは常に良い考えです。

式マッピングの使用を検討することもできます。次にif、関数からブロックを削除し、代わりに次のようなマッピングを記述します。

nnoremap <expr> zG if &l:spellfile !~ ',' ? 'zG' : ':call LocalSpell("zG")<CR>'

ただし、この場合、実際に価値があるかどうかはわかりません。複雑さを関数からマッピングに移しているだけです。

突出している他の唯一のものは、非常によく似たmapコマンドの長いシリーズです。これをループで少し減らすことができます(上記とは異なり、プラグインでこのアプローチを使用できます)。

for lhs in ['zG', 'zW', 'zuG', 'zuW']
  execute 'nnoremap' lhs ':call LocalSpell("'.lhs.'")<cr>'
  execute 'vnoremap' lhs ':call LocalSpell("gv'.lhs.'")<cr>'
  let lhs = tolower(lhs)
  execute 'nnoremap' lhs ':call GlobalSpell("'.lhs.'")<cr>'
  execute 'vnoremap' lhs ':call GlobalSpell("gv'.lhs.'")<cr>'
endfor

あなたが超乾燥を感じているなら、あなたは1 :execute行ですべてのマッピングを作成することができますが、これは実際には悪い考えだと思います:オリジナルとほぼ同じ長さのはるかに複雑なコードになるでしょう!とにかく私はそれを試しました:

for [map_type, gv_type] in items({'n': '', 'v': 'gv'})
  for scope_type in ['Local', 'Global']
    for undo_type in ['', 'u']
      for spell_type in ['G', 'W']
        if scope_type == 'Global'
          let spell_type = tolower(spell_type)
        endif
        let lhs = 'z'.undo_type.spell_type
        execute map_type.'noremap' lhs
          \ ':call' scope_type.'Spell("'.gv_type.lhs.'")<cr>'
      endfor
    endfor
  endfor
endfor

最後に、編集しているファイルの名前にアンダースコアが含まれている場合、上記のいずれも機能しないことに注意してください。スペルファイル名にはアンダースコアを使用できないためです。これらを取り除いたり変換したりするには、オートコマンドを変更する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.