tecosaur / LaTeX-auto-activating-snippets

Mirror of https://git.tecosaur.net/tec/LaTeX-auto-activating-snippets
GNU General Public License v3.0
100 stars 24 forks source link

Only trigger if the string is a proper word #39

Closed ThibautVerron closed 2 years ago

ThibautVerron commented 2 years ago

Hello,

The snippets are activated whenever the key is seen, even in the middle of a longer word. Admittedly, there shouldn't be long words in math mode, but there may however be long commands, and they trigger just as well.

For example, if one has, say, a command \dmax, it gets inserted as \d\max.

Is it sometimes the wanted behavior? If not, I didn't look in much detail, but it seems fairly easy to fix: the package already checks if the key is preceded by a backslash, it should just be expanded to also exclude any character with the "w" syntax.

Cheers!

ymarco commented 2 years ago

Seems annoying, yeah, but only expanding at word boundries would break things like ann → a_n and asr → a^2 that I use a ton.

When I implement snippet properties in aas I guess we could tag snippet groups to indicate that they need a word boundry to expand. I'm not sure where's the boundry between usefulness and annoying is though. rcos expanding to r\cos is quite useful IMO...

ThibautVerron commented 2 years ago

Oh I see. I would usually write "r cos" in such a case.

And checking that we are not in a macro (not just a word) is also not safe, because you'd also want to expand \rhocos to \rho\cos.

It's true that snippets which "act behind" would also need to be handled differently, so the check would have to handle those cases.

For the other snippets, the ones which behave like math abbrevs, maybe a uniform setting could work? That way, users who routinely place word boundaries where they matter would not have any surprise, and users who don't would enjoy the extra expansions they have gotten used to.

ymarco commented 2 years ago

maybe a uniform setting could work?

I don't know if the added complexity is worth it. The package has a lot of options already that I don't use and can't dogfood.

And users can code the setting by themselves. You can add a global snippet condition similar to the backslash-before-point? one we have right now and that would solve your problem.

ThibautVerron commented 2 years ago

Hm, I understand how I could add a global hook, but how would one go about adding one which applies only for a set of snippets?

If I'm right and it's not possible, how about wrapping the existing conditions into another function variable, allowing the users to change or expand that wrapper if they want?

e.g.

(defvar laas-basic-snippets
  '(:cond laas-basic-snippet-cond ;; was: laas-mathp
   ...))

and by default

(defun laas-basic-snippet-cond ()
  (laas-mathp))

which the user could change into e.g.

(defun laas-basic-snippet-cond ()
  (and 
    (laas-mathp)
    (not (looking-back "[\\\w]"))) ;; untested, that's probably not the right amount of escaping
ymarco commented 2 years ago

Hm, I understand how I could add a global hook, but how would one go about adding one which applies only for a set of snippets?

Check the aas-transient-* variables and return t for snippets you don't want to restrict. For example to filter only snippets in laas-basic-snippets, yau can do

(member aas-transient-snippet-key laas-basic-snippets)

And the condition for each snippet has to be a function, not a hook, so we change it while preserving the existing tests.

How about wrapping the existing conditions into another function variable, allowing the users to change or expand that wrapper if they want?

I guess if you only wanted to restrict one snippet, it wouldn't be ideal with global conds. But then it'd be possible to just redefine it. I had an idea where the condition for each snippet would actually be a list of functions that you can add to, but I don't think its necessary.

ThibautVerron commented 2 years ago

Ooh great, thanks!

For future reference, here is my setting now:

(defun tv/laas-not-in-word ()
  (not
   (and
    (member aas-transient-snippet-key laas-basic-snippets)
    (looking-back "\\w\\|\\\\" (- (point) 1)))))

(use-package laas
  :hook (LaTeX-mode . laas-mode)
  :hook (LaTeX-mode . (lambda ()
            (add-hook 'aas-global-condition-hook
                  #'tv/laas-not-in-word
                  nil 'local))))