How can I improve this solution for the "create index entries" of Emacs Lisp Intro?

I programmed this solution for the exercise from section 11.4 (Looping Exercise):

(defun texinfo-index-dfns-in-par () "Create an index entry at the beginning of the paragraph for every '@dfn'." (interactive) (save-excursion (forward-paragraph) (let ((bound (point))) (backward-paragraph) (let ((insert-here (point))) (while (search-forward "@dfn{" bound t) (let* ((start (point)) (end (1- (search-forward "}" bound))) (dfn (buffer-substring start end))) (save-excursion (goto-char insert-here) (newline) (setq insert-here (point)) (insert "@cindex " dfn) (while (< insert-here (line-beginning-position)) (join-line)) (end-of-line) (setq insert-here (point)) (forward-paragraph) (setq bound (point))))))))) 

Despite the fact that it works, it seems to me that it is too confused. I would like to know how this code can be simplified. I am also interested in other possible improvements.

Edit:

Tyler's answer was wonderful. With narrowing, I could write a much shorter and cleaner version:

 (defun texinfo-index-dfns-in-par () "Create an index entry at the beginning of the paragraph for every '@dfn'." (interactive) (save-excursion (mark-paragraph) (save-restriction (narrow-to-region (point) (mark)) (while (search-forward "@dfn{" nil t) (let ((start (point)) (end (1- (search-forward "}")))) (save-excursion (goto-char (point-min)) (insert "\ n@cindex " (buffer-substring start end)) (while (> (line-number-at-pos) 2) (join-line)) (narrow-to-region (line-end-position) (point-max)))))))) 
+4
source share
2 answers

One thing to look at is narrowing. You can use narrowing to get around the many back and forth jumpers you do.

 (mark-paragraph) (narrow-to-region) 

Limits the scope of your function to the current paragraph and moves the point to the beginning. Then you can start your direct search without worrying about moving past the current paragraph. When you are done

 (widen) 

restores the rest of the buffer for viewing.

+3
source

You can replace search-forward and buffer-substring with re-search-forward and match-string (note: untested):

 (while (re-search-forward "@dfn{\\([^}]+\\)}" nil t) (save-excursion (goto-char (point-min)) (insert "\ n@cindex " (match-string 1)) (while (> (line-number-at-pos) 2) (join-line)) (narrow-to-region (line-end-position) (point-max)))) 
+2
source

Source: https://habr.com/ru/post/1338786/


All Articles