Machen Sie zG und zW dauerhaft

7

Edit : Ich habe daraus ein kleines Plugin gemacht. Dies ist mein erster Versuch, einen zu schreiben, und ich habe keine Ahnung, was ich tue. Daher wird jede Hilfe sehr geschätzt. :) :)

Hier ist es: https://github.com/danielbmarques/vim-dialect

----------

Ich möchte weiterhin verwenden zgund zwWörter zu den globalen vim hinzuzufügen spellfiles, aber ich möchte verwenden zGund zWWörter hinzuzufügen spellfile spezifisch auf die Datei , die ich bin der Bearbeitung . Mit anderen Worten, ich möchte zGund zWmuss für jede Datei persistent sein.

Festlegen der spellfileÄnderungen der Befehle zgund zw, während ich nur die Befehle zGund ändern möchte zW.

Also habe ich das einfach gemacht:

: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

Und es funktioniert ... aber es sieht für mich nicht nach einer guten Lösung aus (edit: es wird schon besser :)). Also dachte ich, ich würde es hier posten, falls jemand bessere Ideen oder Verbesserungen vorschlägt. Was denken Sie?

dbmrq
quelle
Wo haben Sie den obigen Code eingefügt? Ein Dateityp-Plugin? Wie wird es ausgelöst / gelesen?
mMontu
@mMontu Nun, für den Moment habe ich es einfach zu meinem vimrc hinzugefügt. Ich dachte daran, ein winziges Plugin zu schreiben, um es dort herauszunehmen. Ich verstehe nicht, warum ich diesen Dateityp spezifisch machen soll. Ich möchte nie, dass die von mir hinzugefügten Wörter entsorgt werden, und das spellfilewird nur erstellt, wenn der erste zGtrotzdem ausgeführt wird.
dbmrq
Wie Sie bereits erwähnt haben, a spellfile specific to the file I'm editingdachte ich, Sie verwenden mehrere Zauberdateien für zG; Da der Rechtschreibdateiname vom Dateinamen ( let &l:spellfile = expand('%:p:h')...) abgeleitet ist, können Sie dies für einen bestimmten Dateityp erreichen, indem Sie den Dateinamen und die Zuordnungen beim Öffnen dieser Datei definieren (Sie müssten <buffer>sie den Zuordnungen hinzufügen). Ich ging auch davon aus, dass Sie diese Änderung zGnur für bestimmte Dateien wünschen.
mMontu
@mMontu Oh nein, ich meinte nicht einen spellfilefür bestimmte Dateitypen , sondern einen spellfilefür jede Datei . Ich kann also Wörter hinzufügen, und wenn ich diese Datei erneut öffne, werden sie weiterhin hinzugefügt, jedoch nur für diese bestimmte Datei und nicht für andere. Das ist aber auch eine interessante Idee. Leider scheint es nicht möglich zu sein, mehr als eine Zauberdatei zu beschaffen, andernfalls könnte ich beides tun und einen Befehl zum Hinzufügen von Wörtern für die aktuelle Datei und einen anderen zum Hinzufügen von Wörtern für den aktuellen Dateityp haben.
dbmrq
Ich habe genau darüber gesprochen one spellfile for each file. Vielleicht habe ich etwas verpasst, aber wenn Sie den Code zu Ihrem hinzugefügt .vimrchaben, konnten Sie nicht mehr als eine Zauberdatei haben, es sei denn, Sie haben es ausdrücklich noch :sourceeinmal wiederholt, um die neu zu bewerten %.
mMontu

Antworten:

2

Tolle Idee!

Sie erwähnen nicht, was Ihrer Meinung nach mit Ihrem Code falsch ist. Es sieht ziemlich gut für mich aus!

Ich würde es wahrscheinlich umgekehrt machen: Es ist nur das lokale Verhalten, das Sie ändern möchten. Im Idealfall entfernen wir die GlobalSpellFunktion und alle globalen Zuordnungen und ändern einfach die lokale Rechtschreibfunktion.

Leider funktioniert dieser Ansatz nur, wenn er 'spellfile'nicht leer ist, bevor der automatische Befehl ausgeführt wird. (Denn mit einem leeren 'spellfile'Wert ermittelt Vim 'runtimepath'zum Zeitpunkt des Hinzufügens einer Schreibweise einen Ort in der , aber Sie haben keine Möglichkeit, auf diesen Pfad zuzugreifen.) Es funktioniert auch nicht, wenn 'spellfile'bereits eine Liste vorhanden ist: Um robuster zu sein, sollte dies der Fall sein Zählen Sie die Einträge wirklich und ändern Sie die zgAnzahl entsprechend.

Daher ist der folgende Ansatz für den persönlichen Gebrauch in einer .vimrc-Datei in Ordnung, aber Sie können ihn in Ihrem Plugin nicht wirklich verwenden.

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>

Oben habe ich dich auch autocommandin einem umgeben augroup, was immer eine gute Idee ist.

Sie können auch Ausdruckszuordnungen verwenden. Sie würden dann den ifBlock aus der Funktion entfernen und stattdessen Zuordnungen schreiben wie:

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

Ich bin mir jedoch nicht sicher, ob es sich in diesem Fall tatsächlich lohnt: Sie verlagern nur die Komplexität von der Funktion auf das Mapping.

Das einzige andere, was auffällt, ist die lange Reihe sehr ähnlicher Kartenbefehle. Sie könnten trimmen diese ein wenig nach unten mit einer Schleife (und im Gegensatz zu dem oben Sie können diesen Ansatz in Ihrem 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

Wenn Sie sich super trocken fühlen, können Sie alle Zuordnungen mit einer einzigen :executeZeile erstellen , aber ich denke, das ist eigentlich eine schlechte Idee: Sie würden viel komplizierteren Code erhalten, der fast so lang ist wie das Original! Ich habe es trotzdem versucht, zum Spaß:

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

Schließlich stelle ich fest, dass keines der oben genannten Verfahren funktioniert, wenn die Datei, die Sie bearbeiten, einen Unterstrich im Namen hat, da Sie in Buchstabendateinamen keine Unterstriche verwenden können! Sie müssen Ihren automatischen Befehl ändern, um diese zu entfernen / zu transformieren.

Reich
quelle