2015-10-31 1 views
6

Я прошу прощения за хорошее решение для тезауруса vim. Очевидно, что эта возможность встроена, но файл, который, по-видимому, используется, - это файл mthesaur.txt. Хотя он «работает» в том смысле, что команды в режиме вставки отображают список, мне кажется, что результаты являются программно правильными, но не очень полезными. Плагин vim online thesaurus работает очень хорошо, но латентность по проводу и необходимость использования разделения для возвращаемого буфера менее идеальны. У кого-нибудь есть мнение об этом?VIM thesaurus file

ответ

4

Я написал плагин, который может адресовать два вопроса, которые вы здесь задали.

Multi-language Thesaurus Query plugin for Vim

Это улучшает используя опыт в двух отношениях: более разумный синоним выборе механизма; и лучший и более гибкий источник синонимов.

Thesaurus_query.vim screen cast

По умолчанию плагин использует MessageBox Vim, для кандидата дисплея, с каждым синонима, помеченной номером. И он позволяет пользователю выбрать подходящий для замены слова под курсором, набрав его номер. Он работает аналогично подсказке по исправлению заклинаний по умолчанию vim's . И резко сократил время работы для , выбирая правильный синоним из длинного списка кандидатов.

Чтобы улучшить качество кандидатов-синонимов, использовалось множество запросов для запросов: . Для английского пользователя два примечания заслуживают внимания.

  • thesaurus_com Backend с использованием в качестве источника Thesaurus.com синонимов
  • mthesaur_txt Backend с использованием в качестве источника mthesaur.txt синонима

thesaurus_com Backend будет работать сразу. Для работы Local Query Backend для работы вам необходимо загрузить mthesaur.txt и сообщить плагину, где находится , либо устанавливая переменную thesaurus, либо указав переменную g:tq_mthesaur_file. Или иначе только Online Backend будет функциональным.

По умолчанию будет использоваться онлайн-запрос Backend. Но если интернет не является доступным или слишком медленным, будущий запрос в текущем сеансе vim будет обрабатываться с помощью Local Query Backend, чтобы уменьшить время ожидания. Приоритет этих двух базовых компонентов также может быть изменен вручную (см. documentation).

Чтобы решить проблему с задержкой (которая обычно выделяется, когда слово не найдено), я ввел механизм тайм-аута. Вы можете установить

let g:tq_online_backends_timeout = 0.6 

если ваш интернет достаточно быстр. Чтобы латентность могла быть уменьшена до менее 0,6 секунды.

Плагин написан на Python. Поэтому вы можете использовать его с Vim, скомпилированным с поддержкой Python и/или Python3.

+0

Вау, это потрясающе. Очень круто, и очень впечатляет. –

+0

@ThadBrown Дайте ему пойти ~ И обратная связь приветствуется. : D – Chong

+0

Трудная вещь для меня (как с точки зрения латентности, так и общего плагина) - это отсутствие действительно хорошего файла тезауруса. Например, вы хотите автоматическое завершение для огромной базы данных, вы можете просто запросить имена столбцов/таблиц, выполнить другой запрос для хранимых процедур и т. Д., А также привести результаты в файл словаря. Это может быть базовый источник автозаполнения. Есть ли там файл тезауруса, который лицензируется таким образом, что его можно перераспределять и изменять? Я мог бы очистить веб-сайт для меня, но это никому не помогло бы, если бы его нельзя было перераспределить. Мысли? –

1

Если ваша система Unix-подобный, и если вы AWK установлены, то у меня есть простого решения проблемы, которая дает вам доступ к тезаурусам в нескольких языков без подключения к Интернету и без окна сплита либо.

Первая загрузка LibreOffice тезаурусов из:

https://cgit.freedesktop.org/libreoffice/dictionaries/tree/

, например.

(Позаботьтесь е _ *. Даты файлов, это те, которые вам нужно, а не .aff и .DIC файлов, которые работают только для проверки орфографии с Hunspell.) Скачать * .dat тезаурусов понравившегося и скопировать их в подкаталог папки , где вы разместите свой плагин; этот подкаталог должен быть указан , «thes.».

Теперь создайте новый файл в папку плагинов (папку, в которой вы должны иметь «Thes» подкаталог с * .dat тезаурусов внутри) и поставить следующий в этом файле:

" 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() 

Это позволит вам выбрать тезаурус по вашему выбору, набрав :Thesaurus в командном режиме Vim.

(На самом деле, если вы планируете использовать только один тезауруса, то вам не нужны никакие этого, просто присвоить полное имя файла тезауруса в буфер локальной переменной, b:thesaurus).

Наконец, добавьте следующие строки в ваш файл плагина:

" 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 

Это позволит вам получить синонимы любого слова, которое вы печатаете в режиме вставки . Еще находясь в режиме вставки, нажмите Ctrl-X Ctrl-O (или любую комбинацию клавиш , которую вы отобразили на omnicompletion), и всплывающее меню отобразит с перечнем синонимов.

Это решение очень грубо по сравнению с мощным плагином Чонга (см. Выше), но оно легкое и работает достаточно хорошо для меня. Я использую его с тезаурусами на четырех разных языках.

+0

Интересно, интересно, на каком этапе действует функция тезауруса LibreOffice. Официальные выпуски пакета не содержат источника тезауруса; и источник, который вы указали, выглядит очень похоже на источник тезауруса OpenOffice, за исключением того, что он не имеет файлов idx, что на самом деле весьма полезно для быстрого поиска слова в этих огромных файлах данных ... – Chong

+0

Это последние версии для разработки, и я подумайте, что португальский тезаурус (например) более совершенен, чем тот, который я загрузил с официальной страницы расширения LibreOffice. –

1

Сценарий для ~/.vimrc, ему нужен файл thesaurii.txt (объединенные словари от https://github.com/moshahmed/vim/blob/master/thesaurus/thesaurii.txt) и perl.exe в пути для поиска синонимов. Скрипт проверен на win7 и cygwin perl.

Вызывает aspell для исправления заклинаний, если синонимы не найдены.

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 
+0

Пожалуйста, не просто отправляйте какой-либо инструмент или библиотеку в качестве ответа. По крайней мере, продемонстрируйте [как он решает проблему] (http://meta.stackoverflow.com/a/251605) в самом ответе. –

+1

@BaummitAugen, Ok включил сам скрипт, я предоставил ссылку, потому что словарь thesaurii.txt огромен (12M), это была самая трудная часть для этого ответа. – mosh

 Смежные вопросы

  • Нет связанных вопросов^_^