Sto cercando una buona soluzione per un thesaurus vim. La funzionalità è integrata, ovviamente, ma il file che tutti sembrano utilizzare è il mthesaur.txt. Mentre "funziona" nel senso che i comandi in modalità inserimento fanno apparire una lista, mi sembra che i risultati siano programmaticamente corretti ma non super utili. Il plugin per thesaurus online di Vim funziona molto bene, ma la latenza sul filo e la necessità di utilizzare una divisione per il buffer restituito non è l'ideale. Qualcuno ha un'opinione su questo?Vim thesaurus file
risposta
Ho scritto un plug-in che può risolvere i due problemi sollevati qui.
Multi-language Thesaurus Query plugin for Vim
Migliora l'esperienza con sotto due aspetti: sinonimo più sensato scegliere meccanismo; e fonti di sinonimi migliori e più flessibili.
Thesaurus_query.vim screen cast
Per impostazione predefinita, il plug-in utilizza messagebox di vim per la visualizzazione candidato, con ogni sinonimo etichettato da un numero. E permette all'utente di scegliere quello adatto per sostituire la parola sotto il cursore digitando il suo numero. Funziona in modo simile al prompt di correzione ortografica predefinito di di vim di vim. E drasticamente ridotto il tempo di operazione per scegliendo il sinonimo appropriato da una lunga lista di candidati.
Per migliorare la qualità dei candidati dei sinonimi, più backend di query sono stati utilizzati . Per l'utente inglese, due sono degni di nota.
thesaurus_com
backend utilizzando Thesaurus.com come fonte sinonimomthesaur_txt
backend utilizzando mthesaur.txt come fonte sinonimo
thesaurus_com
backend funzionerà subito. Per eseguire il backend di Query locale, devi scaricare mthesaur.txt
e indicare al plug-in dove si trova o impostando la variabile thesaurus
o specificando variabile g:tq_mthesaur_file
. Oppure solo il back-end online sarà funzionale.
Per impostazione predefinita, verrà utilizzato prima il backend della query online. Tuttavia, se Internet non è disponibile a o troppo lento, la query futura nella sessione vim corrente verrà gestita dal backend Query locale prima per ridurre il tempo di latenza. Anche la priorità di questi due backend può essere modificata manualmente (vedere documentation).
Per risolvere il problema della latenza (che di solito risalta quando la parola non viene trovata), ho introdotto un meccanismo di timeout. È possibile impostare
let g:tq_online_backends_timeout = 0.6
se la vostra connessione internet è abbastanza veloce. In modo che la latenza potrebbe essere ridotta a meno di 0,6 secondi.
Il plugin è scritto in Python, però. Quindi potresti volerlo usare con Vim compilato con il supporto Python e/o Python3.
Se il sistema è unix-like e se avete installato awk, poi ho una soluzione semplice al vostro problema che consente di accedere a thesauri in più lingue senza connessione internet e senza una finestra divisa neanche.
Prima scaricare LibreOffice thesauri da:
https://cgit.freedesktop.org/libreoffice/dictionaries/tree/
per esempio.
(Prenditi cura ° _ *. Dat file, questi sono quelli che avete bisogno, non il .aff e file .dic che funzionano solo per il controllo ortografico con Hunspell.) Scarica il * .dat thesauri di vostro gradimento e copia in una sottodirectory della cartella in cui verrà inserito il plug-in; questa sottodirectory dovrebbe essere chiamata "thes".
Ora creare un nuovo file nella cartella Plugin (la cartella in cui si dovrebbe avere sottodirectory "thes" con il * .dat thesauri all'interno) e mettere il seguente in questo file:
" offer choice among installed thesauri
" ==================================================
let s:thesaurusPath = expand("<sfile>:p:h") . "/thes"
function! s:PickThesaurus()
" 1, 1: glob does not ignore any pattern, returns a list
let thesaurusList = glob(s:thesaurusPath . "/*", 1, 1)
if len(thesaurusList) == 0
echo "Nothing found in " . s:thesaurusPath
return
endif
let index = 0
let optionList = []
for name in thesaurusList
let index = index + 1
let shortName = fnamemodify(name, ":t:r")
let optionList += [index . ". " . shortName]
endfor
let choice = inputlist(["Select thesaurus:"] + optionList)
let indexFromZero = choice - 1
if (indexFromZero >= 0) && (indexFromZero < len(thesaurusList))
let b:thesaurus = thesaurusList[indexFromZero]
endif
endfunction
command! Thesaurus call s:PickThesaurus()
Ciò ti consentirà di scegliere il thesaurus di tua scelta digitando :Thesaurus
in modalità comando di Vim.
(In realtà, se si prevede di utilizzare un solo thesaurus allora non è necessario alcun di questo, basta assegnare il nome completo del file thesaurus alla variabile buffer locale, b:thesaurus
).
Infine, aggiungere il seguente al file plugin:
" run awk on external thesaurus to find synonyms
" ==================================================
function! OmniComplete(findstart, base)
if ! exists("b:thesaurus")
return
endif
if a:findstart
" first, must find word
let line = getline('.')
let wordStart = col('.') - 1
" check backward, accepting only non-white space
while wordStart > 0 && line[wordStart - 1] =~ '\S'
let wordStart -= 1
endwhile
return wordStart
else
" a word with single quotes would produce a shell error
if match(a:base, "'") >= 0
return
endif
let searchPattern = '/^' . tolower(a:base) . '\|/'
" search pattern is single-quoted
let thesaurusMatch = system('awk'
\ . " '" . searchPattern . ' {printf "%s", NR ":" $0}' . "'"
\ . " '" . b:thesaurus . "'"
\)
if thesaurusMatch == ''
return
endif
" line info was returned by awk
let matchingLine = substitute(thesaurusMatch, ':.*$', '', '')
" entry count was in the thesaurus itself, right of |
let entryCount = substitute(thesaurusMatch, '^.*|', '', '')
let firstEntry = matchingLine + 1
let lastEntry = matchingLine + entryCount
let rawOutput = system('awk'
\ . " '" . ' NR == ' . firstEntry . ', NR == ' . lastEntry
\ . ' {printf "%s", $0}' . "'"
\ . " '" . b:thesaurus . "'"
\)
" remove dash tags if any
let rawOutput = substitute(rawOutput, '^-|', '', '')
let rawOutput = substitute(rawOutput, '-|', '|', 'g')
" remove grammatical tags if any
let rawOutput = substitute(rawOutput, '(.\{-})', '', 'g')
" clean spaces left by tag removal
let rawOutput = substitute(rawOutput, '^ *|', '', '')
let rawOutput = substitute(rawOutput, '| *|', '|', 'g')
let listing = split(rawOutput, '|')
return listing
endif
endfunction
" configure completion
" ==================================================
set omnifunc=OmniComplete
set completeopt=menuone
Questo vi permetterà di ottenere i sinonimi qualsiasi parola durante la digitazione in modalità di inserimento . Mentre sei ancora in modalità di inserimento, premi Ctrl-X Ctrl-O (o qualsiasi combinazione di tasti mappata in modo omnicompleto) e un menu a comparsa visualizza con l'elenco dei sinonimi.
Questa soluzione è molto grezza rispetto al potente plug-in di Chong (vedere sopra), ma è leggero e funziona abbastanza bene per me. Lo uso con thesauri in quattro lingue diverse.
Interessante, mi chiedo in quale fase sia attiva la funzione di thesaurus di LibreOffice. Le versioni ufficiali del pacchetto non contengono la fonte del thesaurus; e la sorgente che hai indicato sembra molto simile alla sorgente del thesaurus di OpenOffice, tranne che non ha i file idx, che è in realtà abbastanza utile per localizzare rapidamente la parola in questi enormi file dat ... – Chong
Queste sono le versioni recenti per lo sviluppo, e io penso che il thesaurus portoghese (per esempio) sia più completo di uno che ho scaricato dalla pagina di estensione ufficiale di LibreOffice. –
Script per ~/.vimrc, richiede il file thesaurii.txt (dizionari uniti da https://github.com/moshahmed/vim/blob/master/thesaurus/thesaurii.txt) e perl.exe nel percorso per la ricerca di sinonimi. Script testato su win7 e cygwin perl.
Le chiamate devono eseguire la correzione ortografica, se non vengono trovati sinonimi.
set thesaurus=thesaurii.txt
let s:thesaurus_pat = "thesaurii.txt"
set completeopt+=menuone
set omnifunc=MoshThesaurusOmniCompleter
function! MoshThesaurusOmniCompleter(findstart, base)
" == First call: find-space-backwards, see :help omnifunc
if a:findstart
let s:line = getline('.')
let s:wordStart = col('.') - 1
" Check backward, accepting only non-white space
while s:wordStart > 0 && s:line[s:wordStart - 1] =~ '\S'
let s:wordStart -= 1
endwhile
return s:wordStart
else
" == Second call: perl grep thesaurus for word_before_cursor, output: comma separated wordlist
" == Test: so % and altitude[press <C-x><C-o>]
let a:word_before_cursor = substitute(a:base,'\W','.','g')
let s:cmd='perl -ne ''chomp; '
\.'next if m/^[;#]/;'
\.'print qq/$_,/ if '
\.'/\b'.a:word_before_cursor.'\b/io; '' '
\.s:thesaurus_pat
" == To: Debug perl grep cmd, redir to file and echom till redir END.
" redir >> c:/tmp/vim.log
" echom s:cmd
let s:rawOutput = substitute(system(s:cmd), '\n\+$', '', '')
" echom s:rawOutput
let s:listing = split(s:rawOutput, ',')
" echom join(s:listing,',')
" redir END
if len(s:listing) > 0
return s:listing
endif
" Try spell correction with aspell: echo mispeltword | aspell -a
let s:cmd2 ='echo '.a:word_before_cursor
\.'|aspell -a'
\.'|perl -lne ''chomp; next unless s/^[&]\s.*?:\s*//; print '' '
let s:rawOutput2 = substitute(system(s:cmd2), '\n\+$', '', '')
let s:listing2 = split(s:rawOutput2, ',\s*')
if len(s:listing2) > 0
return s:listing2
endif
" Search dictionary without word delimiters.
let s:cmd3='perl -ne ''chomp; '
\.'next if m/^[;#]/;'
\.'print qq/$_,/ if '
\.'/'.a:word_before_cursor.'/io; '' '
\.&dictionary
let s:rawOutput3 = substitute(system(s:cmd3), '\n\+$', '', '')
let s:listing3 = split(s:rawOutput3, ',\s*')
if len(s:listing3) > 0
return s:listing3
endif
" Don't return empty list
return [a:word_before_cursor, '(no synonyms or spell correction)']
endif
endfunction
Si prega di non inserire solo alcuni strumenti o librerie come risposta. Dimostrare almeno [come risolve il problema] (http://meta.stackoverflow.com/a/251605) nella risposta stessa. –
@BaummitAugen, Ok ha incluso lo script stesso, avevo fornito il collegamento perché il dizionario thesaurii.txt è enorme (12M) era la parte più difficile per questa risposta. – mosh
Wow, è incredibile. Molto bello e molto impressionante. –
@ThadBrown Fai un salto ~ E il feedback è ben accetto. : D – Chong
La cosa complicata per me (sia in termini di latenza che di plug-in complessivo) è la mancanza di un file del thesaurus veramente buono. Ad esempio, si desidera il completamento automatico per un enorme database, è sufficiente eseguire una query per i nomi di colonna/tabella, eseguire un'altra query per le stored procedure e così via e inserire i risultati in un file di dizionario. Questa può essere una fonte di completamento automatico di base. Esiste un file del thesaurus che è concesso in licenza in modo tale che possa essere ridistribuito e modificato? Potrei racimolare un sito Web per me, ma questo non aiuterebbe nessuno se non potesse essere ridistribuito. Pensieri? –