2
votes

I am starting to learn Emacs Lisp, and as a first project I would like to improve the fortran mode in Emacs. I would like to mark the name of a sub routine in the buffer, and then press a shortcut key. To bring up a buffer with all lines in the given source where the name of the subroutine is mentioned.

I found that I can get the marked text using:

(defun get-selected-text (beg end)
  (interactive
   (if (use-region-p)
       (list (region-beginning) (region-end))
     (list nil nil)))
  (message "%s" (if (and beg end)
                    (buffer-substring-no-properties beg end) "")))

and can store the line numbers of the subroutines using:

(defun get-line-numbers (str)
  (interactive "sEnter string: ")
  (save-excursion
    (goto-char 0)
    (let (( sok 1) (list nil) pp)
      (while sok
        (setq pp (search-forward str nil t))
        (if pp (push (line-number-at-pos pp) list)
          (setq sok nil)))
      (message "%s" list))))

I would now like to open a new buffer similar to when I use Ctrl-x Ctrl-b to execute list-buffers and then display each line number, together with the text on the line, and the user can select a given line, and press Enter to goto the given line in the original buffer..

2
So you're re-implementing occur? - abo-abo
Thanks for letting me know. I will check out the info on the Emacs occur mode.. It looks very promising, maybe I will abandon my project if I get the occur mode to work.. - Håkon Hægland
Emacs is an old lisp-interpreter that is used by many programmers as an editor. So, it is very difficult to find a general useful feature that is not already implemented. With that in mind my answer below has to be understood as a programming exercise -- and only as such. Nevertheless, becoming a lisper has its big advantages if you need your very special features that do not exist in emacs and of course in no other editor. - Tobias

2 Answers

4
votes

Just wanted to show you my version of occur-dwim. I remember spending some time to find out about the regexp-history variable. The first function is similar to your get-selected-text.

(defun region-str-or-symbol ()
  "Return the contents of region or current symbol."
  (if (region-active-p)
      (buffer-substring-no-properties
       (region-beginning)
       (region-end))
    (thing-at-point 'symbol)))

(defun occur-dwim ()
  "Call `occur' with a sane default."
  (interactive)
  (push (region-str-or-symbol) regexp-history)
  (call-interactively 'occur)) 
2
votes

To display the list-buffer you use get-buffer-create and clear it with erase-buffer (it might be that it already extisted).

To output the lines you search in the current buffer save the line in a string and put it into the list buffer via with-current-buffer and insert.

To make return special on the text or to make it clickable put a text-property with a local keymap on it.

With this guide you should be able to find everything you need in the elisp-manual.

Regarding your code, you get the beginning and end of the current region with (interactive "r"). Therewith you also get the error message if there is no active region.