Làm cho zG và zW bền bỉ


7

Chỉnh sửa : Tôi đã biến nó thành một plugin nhỏ. Đây là nỗ lực đầu tiên của tôi khi viết một bài và tôi không biết mình đang làm gì, vì vậy mọi sự giúp đỡ đều được đánh giá cao. :)

Đây là: https://github.com/danielbmarques/vim-dialect

----------

Tôi muốn tiếp tục sử dụng zgzwthêm từ vào vim toàn cầu spellfile, nhưng tôi muốn sử dụng zGzWthêm từ vào một spellfile cụ thể cho tệp tôi đang chỉnh sửa . Nói cách khác, tôi muốn zGzWkiên trì cho từng tệp.

Đặt các spellfilethay đổi zgzwcác lệnh, trong khi điều tôi muốn là chỉ thay đổi các lệnh zGzW.

Vì vậy, tôi đã làm điều này:

: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

Và nó hoạt động rất tốt nhưng nó không giống như một giải pháp tốt cho tôi (chỉnh sửa: nó đã trở nên tốt hơn rồi :)). Vì vậy, tôi nghĩ rằng tôi sẽ đăng nó ở đây trong trường hợp bất cứ ai có ý tưởng hoặc cải tiến tốt hơn để đề xuất. Bạn nghĩ sao?


Bạn đã bao gồm các mã ở trên? Một plugin filetype? Làm thế nào nó được kích hoạt / đọc?
mMontu

@mMontu Chà, bây giờ tôi mới thêm nó vào vimrc của mình. Tôi đã nghĩ đến việc viết một plugin nhỏ chỉ để đưa nó ra khỏi đó. Tôi không thấy lý do tại sao làm cho kiểu tệp này cụ thể, tôi không bao giờ muốn các từ tôi thêm vào bị loại bỏ và spellfilechỉ được tạo khi lần đầu tiên zGđược chạy.
dbmrq

Như bạn đã đề cập, a spellfile specific to the file I'm editingtôi nghĩ rằng bạn đang sử dụng nhiều chính tả cho zG; vì tên chính tả được lấy từ tên tệp ( let &l:spellfile = expand('%:p:h')...), bạn có thể đạt được điều này cho một kiểu tệp cụ thể bằng cách xác định tên tệp và ánh xạ khi mở tệp đó (bạn sẽ cần đưa <buffer>vào ánh xạ). Tôi cũng cho rằng bạn muốn thay đổi này zGchỉ trong một số tệp cụ thể.
mMontu

@mMontu Ồ, không, tôi không có ý nghĩa spellfilecho các kiểu tệp cụ thể , nhưng một spellfilecho mỗi tệp . Vì vậy, tôi có thể thêm từ và khi tôi mở lại tệp đó, chúng sẽ vẫn được thêm, nhưng chỉ với tệp cụ thể đó chứ không phải bất kỳ tệp nào khác. Đó cũng là một ý tưởng thú vị. Thật không may, có vẻ như đó không phải là một cách để tạo nhiều nguồn chính tả, nếu không tôi có thể thực hiện cả hai và có một lệnh để thêm từ cho tệp hiện tại và một cách khác để thêm từ cho kiểu tệp hiện tại.
dbmrq

Tôi đã nói chính xác về one spellfile for each file. Có thể tôi đã bỏ lỡ điều gì đó, nhưng nếu bạn đã thêm mã vào thì .vimrcbạn không thể có nhiều hơn một lỗi chính tả, trừ khi bạn rõ ràng :sourcelại đánh giá nó một lần nữa để đánh giá lại %.
mMontu

Câu trả lời:


2

Ý tưởng tuyệt vời!

Bạn không đề cập đến những gì bạn nghĩ là sai với mã của bạn. Nó trông khá tốt với tôi!

Có lẽ tôi sẽ làm theo cách khác: đó chỉ là hành vi cục bộ mà bạn muốn thay đổi, vì vậy, lý tưởng nhất là chúng tôi sẽ xóa GlobalSpellchức năng và tất cả các ánh xạ toàn cầu và chỉ thay đổi chức năng chính tả cục bộ.

Thật không may, cách tiếp cận này chỉ hoạt động nếu 'spellfile'không trống trước khi autocommand chạy. (Vì với một khoảng trống 'spellfile', Vim tìm ra một vị trí 'runtimepath'tại thời điểm bạn thêm chính tả, nhưng bạn không có cách nào để truy cập vào đường dẫn đó.) Nó cũng sẽ không hoạt động nếu 'spellfile'đã là một danh sách: để mạnh mẽ hơn thực sự đếm các mục và thay đổi zgsố lượng cho phù hợp.

Do đó, cách tiếp cận sau đây là ổn khi sử dụng cá nhân trong .vimrc, nhưng bạn thực sự không thể sử dụng nó trong plugin của mình.

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>

Ở trên tôi cũng bao quanh bạn autocommandtrong một augroup, đó luôn là một ý tưởng tốt.

Bạn cũng có thể xem xét sử dụng ánh xạ biểu thức. Sau đó, bạn sẽ xóa ifkhối khỏi hàm và thay vào đó hãy viết ánh xạ như:

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

Tôi không chắc liệu nó có thực sự đáng giá trong trường hợp này hay không: bạn chỉ đang chuyển sự phức tạp từ chức năng sang ánh xạ.

Điều khác duy nhất xuất hiện là một chuỗi dài các lệnh bản đồ rất giống nhau. Bạn có thể cắt giảm một chút với một vòng lặp (và không giống như ở trên, bạn có thể sử dụng phương pháp này trong plugin của mình):

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

Nếu bạn cảm thấy siêu DRY thì bạn có thể tạo tất cả các ánh xạ với một :executedòng duy nhất , nhưng tôi nghĩ đây thực sự là một ý tưởng tồi: bạn sẽ kết thúc với mã phức tạp hơn nhiều so với bản gốc! Dù sao tôi cũng đã thử nó, cho vui:

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

Cuối cùng tôi lưu ý rằng không có cách nào ở trên hoạt động nếu tệp bạn đang chỉnh sửa có dấu gạch dưới trong tên của nó, bởi vì bạn không thể sử dụng dấu gạch dưới trong tên tệp chính tả! Bạn sẽ cần phải thay đổi chế độ tự động của mình để loại bỏ chúng / biến đổi chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.