Search code examples
performancesearchemacsbufferelisp

Most efficient way of collecting numbers in the first n columns of a buffer


If I have a buffer containing

         |    inout(Ix)[] prefix() inout
         |    {
     2037|        assert(!keys.empty);
     2037|        final switch (keys.length)
         |        {
000000000|        case 1:
000000000|            return keys.at!0[];
     2037|        case 2:
         |            import std.algorithm.searching : commonPrefix;
     2037|            return commonPrefix(keys.at!0[], keys.at!1[]);
         |        }
         |    }

what's the most efficient way of iterating over all lines that have a number to the left of the pipe-character?

Is re-search-forward together with match-string the most efficient way to go?


Solution

  • I chose to add line-numbers to the result because there is another related thread -- Showing D Coverage Results as Overlays in Source Buffer -- that indicates the original poster would like to place overlays and so forth using the result. [The original poster may wish to add a little bit more stuff to the result (e.g., such as point locations in the buffer), and then take the result and mapc down that list -- placing overlays with the before-string property inside the left margin (before the left fringe) if so desired. The text of each line from the far-left to the pipe can also be deleted (or hidden), so that the overlays take the place of what has been deleted (or hidden).]

    (let (result)
      (save-excursion
        (goto-char (point-max))
        (while (re-search-backward "^\s?+\\([0-9]?+\\)|" nil t)
          (push (cons (format-mode-line "%l") (match-string 1)) result))
        result))
    

    The result looks like this:

    (("1" . "") ("2" . "") ("3" . "2037") ("4" . "2037") ("5" . "") ("6" . "000000000") ("7" . "000000000") ("8" . "2037") ("9" . "") ("10" . "2037") ("11" . "") ("12" . ""))