emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: jinx


From: Gustavo Barros
Subject: Re: jinx
Date: Wed, 19 Apr 2023 19:09:50 -0300

Hi Arash,
Hi All,

Arash Esbati <arash@gnu.org> writes:

> Somewhat off-topic, but it would be great if ispell and flyspell could
> use the same logic for skipping portions of buffer text.  Take for
> example (La)TeX mode: ispell uses `ispell-tex-skip-alists' and flyspell
> uses `flyspell-tex-command-regexp' (which is not very powerful) and then
> a function added to `flyspell-generic-check-word-predicate' (AFAIU).  I
> once wrote an addition for AUCTeX (tex-ispell.el) which extends
> `ispell-tex-skip-alists' for many LaTeX packages but had hard times
> making it work with flyspell as well, skipping multi-line text portions
> was something I couldn't solve for flyspell, e.g.:

I've been trying pretty hard to make `jinx` work with AUCTeX this
week, and perhaps I can chime in. And I also come from a background of
heavily customizing `flyspell` for LaTeX.

Jinx relies heavily on font-lock to be able to ignore certain parts of
the buffer according to their faces. This is a powerful and fast
approach, but comes with some challenges.

I tried to summarize the main ones I found at an issue there
(https://github.com/minad/jinx/issues/25#issuecomment-1512876646, see
also https://github.com/minad/jinx/issues/40), and I shared there the
following summary:

  ;; The way font-lock works in AUCTeX, as done by 'font-latex.el', poses some
  ;; challenges to the face based predicate for ignoring (or not) certain
  ;; parts of the buffer used by Jinx.
  ;;
  ;; 1. All optional arguments are fontified with a single face,
  ;; 'font-lock-variable-name-face', for all classes and all commands, and
  ;; that's hard-coded inside 'font-latex-match-command-with-arguments' with
  ;; no viable way to selectively control it.  Even if arguably most optional
  ;; arguments are meant to be ignored, not all of them are, and there is no
  ;; way to distinguish the cases based on faces alone.
  ;;
  ;; 2. For each keyword class, and hence for every command in the class, a
  ;; single face is applied to all mandatory arguments.  Therefore, if a macro
  ;; has one argument which should be spell checked and another that should
  ;; not, there is no way to distinguish them based on faces alone.
  ;;
  ;; 3. Since the keyword classes are populated with criteria other than spell
  ;; checking in mind it is not always easy to decide if a class of commands
  ;; should have its arguments ignored or not.  Take the "reference" class,
  ;; for example, which includes most cross-referencing commands, whose
  ;; arguments are labels, but also "\footnote", "\footnotetext" and
  ;; "\marginpar".  Besides, some keyword classes share the same face.
  ;;
  ;; 4. Given that (currently) the face predicate is called first by Jinx, at
  ;; the time the regexp predicate is called, point is already inside the
  ;; argument, meaning a regexp for the whole macro won't match, and which
  ;; macro that argument comes from can only be found out by expensive
  ;; backwards searching.
  ;;
  ;; To some extend, number 3 can be dealt with by tweaking font-lock with
  ;; regular tools ('font-latex-add-keywords' etc.), possibly requiring
  ;; personal style files in many cases.  How much this is a meaningful way to
  ;; deal with the problem, I'm not sure.
  ;;
  ;; A reordering of the ignore predicates may help with 4, but it doesn't
  ;; fully solve the problem either.  Because it is easy to use a regexp to
  ;; ignore a command which the faces predicate would not, but not the other
  ;; way around.  So, if you have a command using a face which is part of
  ;; 'jinx-exclude-faces' but should be spell checked, the only way to deal
  ;; with it would be to remove the face altogether from 'jinx-exclude-faces',
  ;; and then handling all the other commands which use that face be ignored
  ;; by regexps.  Not an appealing route.
  ;;
  ;; But numbers 1 and 2 remain impossible to tackle with current machinery
  ;; since there's no way to distinguish the parts of a regexp what should be
  ;; spell checked from those that shouldn't.

It is quite possible though to complement font-lock to cover these
gaps though. My attempt at it ran in the following lines:
https://github.com/minad/jinx/issues/25#issuecomment-1511954696

By now I've generalized this a little, and can reach outstanding
results solely based on font-locking, faces, plus some extra added
command/argument specific properties. Better than what I had on a
heavily customized `flyspell` for the same purpose. I don't add a
single TeX specific regexp to my config.

It must be said though that `flyspell` already supports custom
predicates through `flyspell-generic-check-word-predicate`. So using
the same approach with `flyspell` is a matter of "plugging it in"
there. With faces (and some little extra properties to guide spell
checking) in hand, the predicate itself is trivial.

Best,
Gustavo.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]