Проверка грамматики в emacs.
13.02.2022
Поддержка spell checking функциональности внутри emacs для мультиязычных файлов и camelCase
Для тех кто хочет просто что-нибудь скопировать.
Проблема.
В мире emacs присутствует достаточно много решений позволяющих проверять грамматику. Однако, большинство из них имеет ряд проблем, а оставшиеся не реализуют основные требования. Мои требования к спелчекеру (на мой взгляд весьма скромные):
- Работает с несколькими языками
- Не лагает, в идеале проверяет только видимую часть текста (буфера)
- Поддержка своих словарей
- Имеет поддержку для camelCase, PascalCase, snake_case нотаций.
Единственным вариантом, который реализует все вышеперечисленные потребности - spell-fu
Spell-fu. Установка и настройка.
Внимание! Устанавливать spell fu нужно с gitlab! и только напрямую! т.к. в melpa и github устаревшие версии в которых нет поддержки функционала для нескольких языков.
Установка
Для примера возьму straight + use package
(use-package spell-fu
:straight (:host gitlab :repo "ideasman42/emacs-spell-fu")
:config
(setq ispell-program-name "aspell")
(setq spell-fu-directory "~/.doom.d/dictionary") ;; Путь до вашего dictionary
(setq spell-fu-ignore-modes '(org-mode dired-mode vterm-mode)) ;; Моды в которых мне не нужна проверка грамматики
(add-hook 'spell-fu-mode-hook
(lambda ()
(spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "en"))
(spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "ru"))
(spell-fu-dictionary-add
(spell-fu-get-personal-dictionary "en-personal" "/Users/darkawower/.doom.d/dictionary/.pws"))
(spell-fu-dictionary-add
(spell-fu-get-personal-dictionary "ru-personal" "/Users/darkawower/.doom.d/dictionary/ru.pws"))))
(defun cs/spell-fu-check-range (pos-beg pos-end)
(let (case-fold-search)
(spell-fu-check-range-default pos-beg pos-end)))
(setq-default spell-fu-check-range #'cs/spell-fu-check-range)
(global-spell-fu-mode))
Поддержка подсветки для tree-sitter
(setq spell-fu-faces-include '(tree-sitter-hl-face:comment
tree-sitter-hl-face:doc
tree-sitter-hl-face:string
tree-sitter-hl-face:function
tree-sitter-hl-face:variable
tree-sitter-hl-face:type
tree-sitter-hl-face:method
tree-sitter-hl-face:function.method
tree-sitter-hl-face:function.special
tree-sitter-hl-face:attribute
font-lock-comment-face
font-lock-doc-face
font-lock-string-face
lsp-face-highlight-textual
default))
Поддержка camelCase и PascalCase нотаций
Данная поддержка взята отсюда
(setq-default spell-fu-word-regexp
(rx
(or
;; lowercase
(seq
(one-or-more lower)
(opt
(any "'’")
(one-or-more lower)
word-end))
;; capitalized
(seq
upper
(zero-or-more lower)
(opt
(any "'’")
(one-or-more lower)
word-end))
;; uppercase
(seq
(one-or-more upper)
(opt
(any "'’")
(one-or-more upper)
word-end)))))
Альтернативные варианты проверки грамматики в emacs
- Flyspell - околонативное решение (под капотом оперирует с ispell), работает достаточно быстро, с hunspell поддерживает мультияз, c aspell - camelCase, но не все сразу :(
- Guess language - расширение для flyspell которое позволяет применять его к 2 языкам (автору не удалось заставить это работать нормально c camelCase)
- Wucuo - поддерживает camel case (мне завести не удалось) и либо мультиязычность, либо camelCase. Медленный. Очень медленный
- wcheck-mode - еще 1 расширение для проверки нескольких языков. Не работает с camel case.