Search code examples
elispregex-negation

match the first character of WORD in elisp


I want to find an elisp regex that only finds the first character of a word (a set of non-whitespace characters).

This is what I have:

\\(^\\|\\(:?\[[:space:]\]\\)\\)\[^\n[:space:]\]

It's close but not exactly right. It captures any non-whitespace character that has either whitespace or is at the beginning of the line. But it captures the whitespace and the beginning of line as well.

I'd I'm writing this for specific emacs method that takes in an elisp regex as a parameter, specifically avy--generic-jump.

This is what avy-generic-jump looks like:

'(avy--generic-jump REGEX WINDOW-FLIP STYLE &optional BEG END)'

And this is what I have now:

(avy--generic-jump "\\(?:^\\|\\(:?[[:space:]]\\)\\)[^\n[:space:]]" nil 'at))

Main Question: What can I do to match the first character of a word in elisp?

More general question: what's the proper way to deal with cases in elisp where you don't want to capture the whole match?


Solution

  • Trying to create a new zero-width assertion in emacs is not possible. You basically need look-around support. You can try out this patch, or less instrusively, advising the avy--generic-jump function to adjusting the result position candidates off by one.

    Here is an example to make avy jump off by one.

    (defun avy--regex-candidates (regex &optional beg end pred group)
      "Return all elements that match REGEX.
    Each element of the list is ((BEG . END) . WND)
    When PRED is non-nil, it's a filter for matching point positions.
    When GROUP is non-nil, (BEG . END) should delimit that regex group."
      (setq group (or group 0))
      (let ((case-fold-search (or avy-case-fold-search
                                  (string= regex (downcase regex))))
            candidates)
        (avy-dowindows current-prefix-arg
          (dolist (pair (avy--find-visible-regions
                         (or beg (window-start))
                         (or end (window-end (selected-window) t))))
            (save-excursion
              (goto-char (car pair))
              (while (re-search-forward regex (cdr pair) t)
                (unless (get-char-property (1- (point)) 'invisible)
                  (when (or (null pred)
                            (funcall pred))
                    (push (cons (cons (1+ (match-beginning group))
                                      (1+ (match-end group)))
                                wnd) candidates)))))))
        (nreverse candidates)))