;;; spell-settings.el --- Spell settings  -*- lexical-binding: t -*-

;;; Commentary:
;;  https://melpa.org/#/flyspell-correct
;;  https://melpa.org/#/flyspell-correct-ivy
;;  https://melpa.org/#/langtool
;;  https://github.com/mhayashi1120/Emacs-langtool

;; Requirements:
;;   Linux package: languagetool
;;   Emacs package: langtool.el

;;; Code:
(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-ivy
  :after flyspell-correct)

(use-package langtool
  :commands (langtool-check langtool-check-buffer)
  :init 
  ;; classpath where LanguageTool's jars reside
  (setq langtool-java-classpath
        "/usr/share/languagetool:/usr/share/java/languagetool/*")
  ;; LanguageTool launcher (not working with )
  ;;(setq langtool-bin "/usr/bin/languagetool")
  :config
  ;;(setq langtool-default-language "en-US")
  (setq langtool-mother-tongue "de")
  ;;(setq langtool-java-user-arguments '("-Dfile.encoding=UTF-8"))
  ;;(setq langtool-user-arguments ...)

  ;; Show LanguageTool report automatically by popup
  ;;(defun langtool-autoshow-detail-popup (overlays)
  ;;  (when (require 'popup nil t)
  ;;    ;; Do not interrupt current popup
  ;;    (unless (or popup-instances
  ;;                ;; suppress popup after type `C-g` .
  ;;                (memq last-command '(keyboard-quit)))
  ;;      (let ((msg (langtool-details-error-message overlays)))
  ;;        (popup-tip msg)))))
  ;;(setq langtool-autoshow-message-function
  ;;      'langtool-autoshow-detail-popup)

  ;;https://github.com/redguardtoo/Emacs-langtool
  (eval-after-load 'org-mode
    '(progn
       (setq langtool-generic-check-predicate
             '(lambda (start end)
                ;; set up for `org-mode'
                (let* ((begin-regexp "^[ \t]*#\\+begin_\\(src\\|html\\|latex\\|example\\|quote\\)")
                       (end-regexp "^[ \t]*#\\+end_\\(src\\|html\\|latex\\|example\\|quote\\)")
                       (case-fold-search t)
                       (ignored-font-faces '(org-verbatim
                                             org-block-begin-line
                                             org-meta-line
                                             org-tag
                                             org-link
                                             org-level-1
                                             org-document-info))
                       (rlt t)
                       ff
                       th
                       b e)
                  (save-excursion
                    (goto-char start)

                    ;; get current font face
                    (setq ff (get-text-property start 'face))
                    (if (listp ff) (setq ff (car ff)))

                    ;; ignore certain errors by set rlt to nil
                    (cond
                     ((memq ff ignored-font-faces)
                      ;; check current font face
                      (setq rlt nil))
                     ((string-match "^ *- $" (buffer-substring (line-beginning-position) (+ start 2)))
                      ;; dash character of " - list item 1"
                      (setq rlt nil))
                     ((and (setq th (thing-at-point 'evil-WORD))
                           (or (string-match "^=[^=]*=[,.]?$" th)
                               (string-match "^\\[\\[" th)))
                      ;; embedded cde like =w3m= or org-link [[http://google.com][google]] or [[www.google.com]]
                      ;; langtool could finish checking before major mode prepare font face for all texts
                      (setq rlt nil))
                     (t
                      ;; inside source block?
                      (setq b (re-search-backward begin-regexp nil t))
                      (if b (setq e (re-search-forward end-regexp nil t)))
                      (if (and b e (< start e)) (setq rlt nil)))))
                  ;; (if rlt (message "start=%s end=%s ff=%s" start end ff))
                  rlt)))))

  (eval-after-load 'prog-mode
    '(progn
       (unless (featurep 'flyspell) (require 'flyspell))
       (setq langtool-generic-check-predicate
             '(lambda (start end)
                (let* ((f (get-text-property start 'face)))
                  (memq f flyspell-prog-text-faces))))))
  )

(provide 'spell-settings)
;;; spell-settings.el ends here
