Как я могу улучшить это решение в упражнении Emacs Lisp Intro «создание записей индекса»? - PullRequest
4 голосов
/ 08 февраля 2011

Я запрограммировал это решение для упражнения из раздела 11.4 (Упражнение с циклом):

(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)))))))))

Несмотря на то, что оно работает, мне кажется, что оно очень запутанно.Я хотел бы знать, как этот код может быть упрощен.Меня также интересуют другие возможные улучшения.

Редактировать:

Ответ Тайлера был великолепным.При сужении я мог бы написать гораздо более короткую и чистую версию:

(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))))))))

Ответы [ 2 ]

3 голосов
/ 08 февраля 2011

Одна вещь, на которую нужно смотреть - это сужение. Вы можете использовать сужение, чтобы обойти большую часть подпрыгивания вперед и назад.

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

Ограничит область действия вашей функции текущим абзацем и переместит точку в начало. Затем вы можете начать поиск вперед, не беспокоясь о том, чтобы пройти текущий абзац. Когда вы закончите,

(widen)

восстанавливает оставшуюся часть буфера для просмотра.

2 голосов
/ 10 февраля 2011

Вы можете заменить свои search-forward s и buffer-substring на re-search-forward и match-string (примечание: не проверено):

(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))))
...