5

I've defined the \ character to behave as a word constituent in latex-mode, and I'm pretty happy with the results. The only thing bothering me is that a sequence like \alpha\beta gets treated as a single word (which is the expected behavior, of course).

Is there a way to make emacs interpret a specific character as a word "starter"? This way it would always be considered part of the word following it, but never part of the word preceding it.

For clarity, here's an example:

\alpha\beta
^          ^
1          2

If the point is at 1 and I press M-d, the string "\alpha" should be killed. If the point is at 2 and I press M-<backspace>, the string "\beta" should be killed.

How can I achieve this?

Malabarba
  • 4,473
  • 2
  • 30
  • 49

2 Answers2

3

Another thought:
Your requirement is very like what subword-mode provides for camelCase.

You can't customize subword-mode's behaviour -- the regexps are hard-coded -- but you could certainly copy that library and modify it for your purposes.

M-x find-library RET subword RET

That would presumably be a pretty robust solution.

Edit: updated from the comments, as suggested:

For the record, changing every instance of [[:upper:]] to [\\\\[:upper:]] in the functions subword-forward-internal and subword-backward-internal inside subword.el works great =) (as long as "\" is defined as "w" syntax).

Personally I would be more inclined to make a copy of the library than edit it directly, unless for the purpose of making the existing library a little more general-purpose, for which the simplest solution would seem to be to move those regexps into variables -- after which it would be trivial to have buffer-local modified versions for this kind of purpose.

Edit 2: As of Emacs 24.3 (currently a release candidate), subword-mode facilitates this with the new subword-forward-regexp and subword-backward-regexp variables (for simple modifications), and the subword-forward-function and subword-backward-function variables (for more complex modifications).

By making those regexp variables buffer-local in latex-mode with the desired values, you can just use subword-mode directly.

phils
  • 71,335
  • 11
  • 153
  • 198
  • Yeah, I've been wondering if subword mode might be of any help. I'll check out the regexps. – Malabarba May 04 '12 at 14:19
  • Actually, if manage to get `\\` to be treated as uppercase, _subword-mode_ would do the rest for me. I think that's configured in *Syntax Properties*, but I'm not sure yet. – Malabarba May 04 '12 at 14:35
  • Nice idea, but it rather looks to me as if you can't have an upper-case character without specifying its lower-case variant? (I'm looking at `Case Tables` and `Case Conversion` under `(elisp) Strings and Characters`, as well as the `[:upper:]` and `[:lower:]` definitions in `(elisp) Char Classes`.) – phils May 04 '12 at 14:53
  • For the record, changing every instance of `[[:upper:]]` to `[\\\\[:upper:]]` in the functions `subword-forward-internal` and `subword-backward-internal` inside *subword.el* works great =) (as long as "\" is defined as "w" syntax). I'd still rather find a way of using _syntax properties_ (so I won't have to repeat it every time I update _subword.el_), but for now I'll accept your answer if you update it. – Malabarba May 04 '12 at 15:14
2

You should be able to implement this using syntax text properties:

M-: (info "(elisp) Syntax Properties") RET

Edit: Actually, I'm not sure if you can do precisely this?

The following (which is just experimentation) is close, but M-<backspace> at 2 will only delete "beta" and not the preceding "\".

I suppose you could remap backward-kill-word to a function which checked for that preceding "\" and killed that as well. Fairly hacky, but it would probably do the trick if there's not a cleaner solution.

I haven't played with this functionality before; perhaps someone else can clarify.

(modify-syntax-entry ?\\ "w")
(setq parse-sexp-lookup-properties t)
(setq syntax-propertize-function 'my-propertize-syntax)
(defun my-propertize-syntax (start end)
  "Set custom syntax properties."
  (save-excursion
    (goto-char start)
    (while (re-search-forward "\\w\\\\" end t)
      (put-text-property
       (1- (point)) (point) 'syntax-table (cons "." ?\\)))))
phils
  • 71,335
  • 11
  • 153
  • 198