tmalsburg / guess-language.el

Emacs minor mode that detects the language you're typing in. Automatically switches spell checker. Supports multiple languages per document.
115 stars 14 forks source link

Add guess-language-after-autoset-hook #11

Closed peterwvj closed 7 years ago

peterwvj commented 7 years ago

I started using this package, and I'm very happy with it. The language detection mechanisms works very well. Thanks!

One feature that I'm missing though is to perform additional actions after the language detection mechanism has finished executing. Usually when I switch from English to Danish dictionary I also set the input method to danish-postfix, which allows me to use the English (US) keyboard layout, while still being able to write Danish letters that are not available on the English keyboard layout. Setting the input method can be done like this:

M-x set-input-method RET danish-postfix RET

Now when I type "oe", Emacs changes it to "ø", "aa" becomes "å" and so on. The important thing, however, is that the keyboard layout remains the same.

Right now I have to change the input method manually every time guess-language switches dictionary. It would be better if guess-language could help me change the input method too. I tried to look for a hook that would allow me to run additional code when the dictionary changes (some ispell hook), but I couldn't really find a clever way to do this. Since other users of guess-language might want to perform a similar task I thought that adding a guess-language-after-autoset-hook would be a good idea (perhaps you can think of a better name)? The hook is intended to be run immediately before guess-language-autoset exits. What do you think?

tmalsburg commented 7 years ago

Yes, I agree. We need a more flexible way to configure what happens when a new language is detected. I suppose we should add a hook for when the language changes (guess-language-change-hook). Each function on this hook will then receive the new language as an argument and can do with it whatever it wants. This would also partly solve #8 because you could also add functions to this hook which operate other spell-checkers than Flyspell.

peterwvj commented 7 years ago

I like your idea of passing the newly detected language. It's generic and it would support almost any kind of extension, I suppose.

tmalsburg commented 7 years ago

I have an implementation with the necessary hooks. There is a bug that I haven't tracked down yet but otherwise it's looking good.

peterwvj commented 7 years ago

Sounds great, thanks! I'm happy to help you try it out, if you prefer.

tmalsburg commented 7 years ago

There is a new branch which includes the new hooks: https://github.com/tmalsburg/guess-language.el/tree/hooks

Unfortunately, this code breaks Flyspell in my setup: after language detection, Flyspell stops marking incorrect words. I have no idea what's going on there. Perhaps you see something?

peterwvj commented 7 years ago

Thanks for looking into this! Does #13 help?

tmalsburg commented 7 years ago

Unfortunately, your PR doesn't solve the problem. The language is actually switched in ispell (see mode line indicator) but Flyspell stops checking. Even if I switch Flyspell off and on again it still not working.

tmalsburg commented 7 years ago

Found the problem. When a function on flyspell-incorrect-hook returns non-nil, the word is not highlighted as incorrect. This allows us to write functions that override Flyspell's judgment of whether a word is correct or not. Could actually be pretty useful in other contexts. So the solution is simply to make sure that guess-language-function returns nil.

tmalsburg commented 7 years ago

Merged: ac991ce410c7724506e3b3891c6507d7774af0a4

Happy hacking.

peterwvj commented 7 years ago

Good catch :) Sorry that the PR didn't help. I'll give the hook extension a try. Again, thank you for working on this.

tmalsburg commented 7 years ago

No problem, let me know how it goes.

peterwvj commented 7 years ago

Currently I'm not receiving notifications (call-backs) when the dictionary is switched back to English (from Danish). My configuration is this:

(use-package guess-language
  :init

  (defun my-custom-function (lang beginning end)
    (progn
      (print lang)))

  (add-hook 'guess-language-after-detection-functions #'my-custom-function)

  (add-hook 'text-mode-hook
            (lambda ()
              (guess-language-mode 1)))
  :config
  (setq guess-language-languages '(en da))
  (setq guess-language-min-paragraph-length 35))

When I change from English to Danish, "da" is printed (as expected). By intuition I would also expect "en" to be printed, when I change from Danish to English. Are you experiencing the same?

tmalsburg commented 7 years ago

It works ok on my machine. Not sure what's happening. Perhaps guess-language doesn't recognize that your text is English? What does the modeline say?

tmalsburg commented 7 years ago

Perhaps, this should also be a new issue.

tmalsburg commented 7 years ago

Could you please test with test_data.org?

peterwvj commented 7 years ago

Sure, I will test it some more, and try to see if I can produce this problem using a minimum example/Emacs configuration. I'll create a separate issue, if necessary.

peterwvj commented 7 years ago

I have it working now :) The problem was in my own configuration. Sorry about the confusion.

tmalsburg commented 7 years ago

Fantastic, glad to hear.