3

I am trying to match a Perl identifier at the point, like My::Module::dummy_func. I'd like to start simple and require a valid identifier as follows:

  • restricted to a single line
  • starts with a space
  • ends with a (

So if point is at a colon in this line:

my $a = My::Module::dummy_func(3)

I should get a match equal to My::Module::dummy_func.

Here is what I have

(defun get-perl-id-at-point ()
  (interactive)
  (let ((beg nil) (end nil))
    (save-excursion
      (if (re-search-forward "[A-Za-z0-9:_]*?(" (line-end-position) t)
          (setq end (- (point) 1))))
    (save-excursion
      (if (re-search-backward " [A-Za-z0-9:_]*?" (line-beginning-position) t)
          (setq beg (+ (point) 1))))
    (if (and beg end)
        (message (buffer-substring beg end)))))

This works for example if point is at a :, but if point is at the $ in $a I get $a = My::Module::dummy_func whereas I would like to get a no match..

How can this be done?

Malabarba
  • 22,878
  • 6
  • 78
  • 163
Håkon Hægland
  • 3,608
  • 1
  • 20
  • 51
  • 1
    I recommend using [`match-string`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Simple-Match-Data.html) to extract the string you matched. You can also use `match-beginning` and `match-end` to get positions of the start and end of the match. If you want to check if there is a match at point, use [`looking-at`](http://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Search.html#Regexp-Search). – Constantine Dec 16 '14 at 19:54
  • @Constantine Thanks! I followed your recommendation, see my answer below. – Håkon Hægland Dec 17 '14 at 07:32

1 Answers1

3

Using the recommendations of @Constantine, here is an improved version of the function:

(defun get-perl-id-at-point ()
  (interactive)
  (let ((beg nil) (end nil))
    (if (looking-at "[A-Za-z0-9:_]*?(")
        (setq end (- (match-end 0) 1)))
    (if (looking-back "[-+=*/;[:space:]][A-Za-z0-9:_]*?" (- (line-beginning-position) 1))
        (setq beg (+ (match-beginning 0) 1)))
    (if (and beg end)
        (message (buffer-substring beg end))
      (message "No match"))))

This seems to work well.

Håkon Hægland
  • 3,608
  • 1
  • 20
  • 51