Tornar zG e zW persistentes


7

Edit : Eu transformei isso em um pequeno plugin. Esta é a minha primeira tentativa de escrever uma e não tenho idéia do que estou fazendo, portanto qualquer ajuda é muito apreciada. :)

Aqui está: https://github.com/danielbmarques/vim-dialect

----------

Quero continuar usando zge zwadicionando palavras aos vim globais spellfile, mas quero usar zGe zWadicionar palavras a um spellfile específico do arquivo que estou editando . Em outras palavras, eu quero zGe zWseja persistente para cada arquivo.

Definir as spellfilemudanças nos comandos zge zw, enquanto o que eu quero é mudar apenas os comandos zGe zW.

Então, eu fiz isso:

: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

E funciona ... mas não parece uma boa solução para mim (editar: já está ficando melhor :)). Por isso, pensei em publicá-lo aqui, caso alguém tenha idéias ou melhorias melhores para sugerir. O que você acha?


Onde você incluiu o código acima? Um plugin de tipo de arquivo? Como é acionado / lido?
— MMontu

@ mMontu Bem, por enquanto acabei de adicioná-lo ao meu vimrc. Eu estava pensando em escrever um pequeno plugin apenas para tirá-lo de lá. Não vejo por que tornar esse tipo de arquivo específico, nunca quero que as palavras adicionadas sejam descartadas e spellfilesó é criada quando a primeira zGé executada.
— dbmrq

Como você mencionou a spellfile specific to the file I'm editing, pensei que estava usando vários arquivos de ortografia para zG; como o nome do arquivo ortográfico é derivado do nome do arquivo ( let &l:spellfile = expand('%:p:h')...), você pode conseguir isso para um tipo de arquivo específico, definindo o nome do arquivo e os mapeamentos ao abrir esse arquivo (você precisará incluir <buffer>nos mapeamentos). Também assumi que você desejava essa alteração zGapenas para alguns arquivos específicos.
— MMontu

@ mMontu Oh, não, eu não quis dizer um spellfilepara tipos de arquivos específicos , mas um spellfilepara cada arquivo . Para adicionar palavras, e quando eu abrir esse arquivo novamente, elas ainda serão adicionadas, mas apenas para esse arquivo específico e não para outros. Também é uma ideia interessante. Infelizmente, parece que não é uma maneira de obter mais de um arquivo ortográfico; caso contrário, eu poderia fazer os dois e ter um comando para adicionar palavras ao arquivo atual e outro para adicionar palavras ao tipo de arquivo atual.
— dbmrq

Eu estava falando exatamente sobre isso one spellfile for each file. Talvez eu tenha esquecido alguma coisa, mas se você adicionou o código ao seu, .vimrcnão poderia ter mais de um arquivo ortográfico, a menos que explicitamente :sourcenovamente para reavaliar o arquivo %.
— MMontu

Respostas:


2

Idéia legal!

Você não menciona o que acha que está errado com o seu código. Parece muito bom para mim!

Eu provavelmente faria o contrário: é apenas o comportamento local que você deseja alterar; portanto, idealmente, removeríamos a GlobalSpellfunção e todos os mapeamentos globais e apenas alteraríamos a funcionalidade de ortografia local.

Infelizmente, essa abordagem só funciona se 'spellfile'não estiver vazia antes da execução do comando automático. (Como com um vazio 'spellfile', o Vim descobre um local no 'runtimepath'momento em que você adiciona uma ortografia, mas você não tem como acessar esse caminho.) Também não funcionará se 'spellfile'já houver uma lista: para ser mais robusto, deve realmente conte as entradas e altere a zgcontagem de acordo.

Portanto, a abordagem a seguir é adequada para uso pessoal em um .vimrc, mas você realmente não pode usá-lo em seu plugin.

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>

No exemplo acima Eu também rodeado seu autocommandem um augroup, que é sempre uma boa idéia.

Você também pode considerar o uso de mapeamentos de expressão. Você removeria o ifbloco da função e escreveria mapeamentos como:

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

Porém, não tenho certeza se vale a pena: neste caso, você está apenas movendo a complexidade da função para o mapeamento.

A única outra coisa que se destaca é a longa série de comandos de mapa muito semelhantes. Você pode reduzir isso um pouco com um loop (e ao contrário do acima, você pode usar esta abordagem no seu plugin):

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

Se você estiver se sentindo super seco , poderá criar todos os mapeamentos com uma única :executelinha, mas acho que é uma péssima idéia: você acabaria com um código muito mais complicado, quase tão longo quanto o original! Tentei de qualquer maneira, por diversão:

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

Finalmente, notei que nenhuma das opções acima funciona se o arquivo que você está editando tiver um sublinhado no nome, porque você não pode usar sublinhados nos nomes dos arquivos de ortografia! Você precisará alterar seu comando automático para removê-los / transformá-los.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.