>>> + (re-search-forward >>> + (concat "^\\(?:" outline-regexp "\\)") >>> + nil 'move))) >> >> These two loops cons a new string each iteration. (So did the >> original code, but if we are touching this, might as well fix that.) > > This is optimized as well: Here is a more tested patch that works in apropos and shortdoc. Also tested for group outlines in the Completions buffer with: ``` (setq-local outline-search-function (lambda (&optional bound move backward looking-at) (outline-search-text-property 'face 'completions-group-separator bound move backward looking-at)) outline-level (lambda () 1)) ``` It even works when using the search function that searches for outline-regexp. This better shows the meaning of its arguments: ``` (setq-default outline-search-function (lambda (&optional bound move backward looking-at) (cond (looking-at (looking-at outline-regexp)) (backward (re-search-backward (concat "^\\(?:" outline-regexp "\\).*") bound (if move 'move t))) (t (re-search-forward (concat "^\\(?:" outline-regexp "\\).*") bound (if move 'move t))))) outline-level (lambda () (looking-at outline-regexp) (outline-level))) ``` As can be seen, the default outline-level function can't be used, because the search function is expected to match to the end of the heading line, but the default outline-level expects to match only beginning of the outline heading.