2015-10-31 15 views
6

Tôi đã tìm kiếm một giải pháp tốt cho một từ điển đồng nghĩa. Khả năng được tích hợp, rõ ràng, nhưng tất cả mọi người dường như đều sử dụng tập tin là mthesaur.txt. Trong khi nó 'hoạt động' theo nghĩa là các lệnh trong chế độ chèn đưa ra một danh sách, có vẻ như với tôi các kết quả có lập trình chính xác nhưng không siêu hữu ích. Plugin vạn năng trực tuyến vim hoạt động rất tốt, nhưng độ trễ trên dây và sự cần thiết của việc sử dụng phân chia cho bộ đệm được trả về ít hơn lý tưởng. Bất cứ ai cũng có một ý kiến ​​về điều này?Tệp từ điển VIM

Trả lời

4

Tôi đã viết một plugin có thể giải quyết hai vấn đề bạn nêu tại đây.

Multi-language Thesaurus Query plugin for Vim

Nó cải thiện kinh nghiệm sử dụng trong hai liên quan: từ đồng nghĩa hợp lý hơn việc lựa chọn cơ chế; và các nguồn đồng nghĩa tốt hơn và linh hoạt hơn.

Thesaurus_query.vim screen cast

Theo mặc định, các plugin sử dụng MessageBox vim cho hiển thị ứng cử viên, với mỗi đồng nghĩa dán nhãn bởi một số. Và nó cho phép người dùng chọn một cái phù hợp để thay thế từ dưới con trỏ bằng cách nhập số của nó. Nó hoạt động tương tự như lời nhắc sửa lỗi chính tả mặc định của vim . Và giảm đáng kể thời gian hoạt động cho chọn từ đồng nghĩa chính xác từ một danh sách dài các ứng cử viên.

Để cải thiện chất lượng của các ứng viên đồng nghĩa, nhiều phụ trợ truy vấn được sử dụng . Đối với người dùng tiếng Anh, hai là đáng lưu ý.

  • thesaurus_com Backend sử dụng Thesaurus.com như nguồn từ đồng nghĩa
  • mthesaur_txt Backend sử dụng mthesaur.txt như nguồn từ đồng nghĩa

thesaurus_com Backend sẽ làm việc ngay lập tức. Đối với Backend truy vấn cục bộ hoạt động, bạn sẽ cần tải xuống mthesaur.txt và cho plugin biết vị trí của nó là bằng cách đặt biến số thesaurus hoặc chỉ định biến g:tq_mthesaur_file. Hoặc nếu không, Chương trình phụ trợ trực tuyến sẽ là chức năng .

Theo mặc định, Chương trình phụ trợ truy vấn trực tuyến sẽ được sử dụng trước tiên. Nhưng nếu Internet không phải là khả dụng hoặc quá chậm, truy vấn trong tương lai trong phiên vim hiện tại sẽ được xử lý bởi Chương trình phụ trợ truy vấn cục bộ trước tiên để giảm thời gian chờ. Ưu tiên của hai phần phụ trợ này là cũng có thể được thay đổi theo cách thủ công (xem documentation).

Để giải quyết vấn đề độ trễ (thường xuất hiện khi không tìm thấy từ), tôi đã giới thiệu một cơ chế thời gian chờ. Bạn có thể đặt

let g:tq_online_backends_timeout = 0.6 

nếu internet của bạn là hợp lý nhanh. Vì vậy, độ trễ có thể được giảm xuống còn dưới 0,6 giây.

Plugin được viết bằng Python. Vì vậy, bạn có thể muốn sử dụng nó với Vim được biên dịch với hỗ trợ Python và/hoặc Python3.

+0

Thật tuyệt vời. Rất mát mẻ, và rất ấn tượng. –

+0

@ThadBrown Cho nó đi ~ Và phản hồi được hoan nghênh. : D – Chong

+0

Điều khó khăn đối với tôi (cả về độ trễ và plugin tổng thể) là thiếu tệp từ điển thực sự tốt. Ví dụ, bạn muốn tự động hoàn thành cho một cơ sở dữ liệu khổng lồ, bạn chỉ có thể truy vấn tên cột/bảng, thực hiện truy vấn khác cho các thủ tục được lưu trữ, vv .. và đưa kết quả vào tệp từ điển. Đó có thể là nguồn tự động hoàn thành cơ bản. Có một tệp từ điển ngoài kia được cấp phép theo cách mà nó có thể được phân phối lại và sửa đổi không? Tôi có thể cạo một trang web cho tôi, nhưng điều đó sẽ không giúp đỡ bất cứ ai khác nếu nó không thể được phân phối lại. Suy nghĩ? –

1

Nếu hệ thống của bạn là unix-like và nếu bạn đã cài đặt awk, sau đó tôi có một giải pháp đơn giản cho vấn đề của bạn cung cấp cho bạn truy cập vào từ điển lớn trong nhiều ngôn ngữ mà không cần kết nối internet và không có một cửa sổ chia một trong hai.

Đầu tiên tải LibreOffice bộ từ từ:

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

ví dụ.

(Hãy chăm sóc thứ _ *. Dat file, đây là những cái bạn cần, không phải là .aff và file .dic mà chỉ làm việc cho kiểm tra chính tả với Hunspell.) Tải các * .dat từ chuẩn của ý thích của bạn và sao chép chúng vào thư mục con của thư mục nơi bạn sẽ đặt plugin của mình; thư mục con này phải là được gọi là "thes".

Bây giờ tạo một file mới trong thư mục plugin của bạn (thư mục mà bạn nên có "thes" thư mục con với * .dat từ chuẩn bên trong) và đặt sau trong tập tin này:

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

Điều này sẽ cho phép bạn chọn từ điển bạn chọn bằng cách gõ :Thesaurus trong chế độ lệnh của Vim.

(Thực tế, nếu bạn dự định chỉ sử dụng một từ điển thì bạn không cần bất kỳ nào trong số này; chỉ cần gán tên đầy đủ của tệp từ điển vào số biến bộ đệm cục bộ, b:thesaurus).

Cuối cùng, thêm dòng sau vào file plugin của bạn:

" 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 

này sẽ cho phép bạn để có được những từ đồng nghĩa của bất cứ từ mà bạn gõ vào insert mode . Trong khi vẫn ở chế độ chèn, nhấn Ctrl-X Ctrl-O (hoặc bất kỳ phím nào kết hợp mà bạn đã ánh xạ trên omnicompletion) và menu bật lên sẽ hiển thị với danh sách từ đồng nghĩa.

Giải pháp này rất thô so với plugin mạnh mẽ của Chong (xem ở trên), nhưng nó nhẹ và hoạt động đủ tốt cho tôi. Tôi sử dụng nó với thesauri trong bốn ngôn ngữ khác nhau.

+0

Thú vị, tôi tự hỏi về chức năng từ điển của LibreOffice vào lúc này. Các bản phát hành chính thức của gói không chứa nguồn từ điển đồng nghĩa; và nguồn bạn chỉ trông khá giống với nguồn từ điển của OpenOffice, ngoại trừ nó không có tệp idx, thực sự khá hữu ích trong việc định vị nhanh từ trong các tệp dữ liệu khổng lồ này ... – Chong

+0

Đây là các phiên bản gần đây để phát triển và tôi nghĩ rằng từ điển tiếng Bồ Đào Nha (ví dụ) hoàn chỉnh hơn so với cái tôi đã tải xuống từ trang mở rộng chính thức của LibreOffice. –

1

Tập lệnh cho ~/.vimrc, nó cần tệp thesaurii.txt (từ điển được hợp nhất từ ​​https://github.com/moshahmed/vim/blob/master/thesaurus/thesaurii.txt) và perl.exe trong đường dẫn để tìm kiếm từ đồng nghĩa. Kịch bản thử nghiệm trên win7 và cygwin perl.

Cuộc gọi khao khát thực hiện chỉnh sửa chính tả, nếu không tìm thấy từ đồng nghĩa nào.

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

Vui lòng không chỉ đăng một số công cụ hoặc thư viện làm câu trả lời. Ít nhất là chứng minh [cách giải quyết vấn đề] (http://meta.stackoverflow.com/a/251605) trong chính câu trả lời. –

+1

@BaummitAugen, Ok kèm theo bản thân tập lệnh, tôi đã cung cấp liên kết vì từ điển thesaurii.txt rất lớn (12M) đó là phần khó nhất cho câu trả lời này. – mosh

Các vấn đề liên quan