A little bit of Scheme
A question came through this morning on how to do something in Scheme. I don't
usually have time to answer individual Scheme questions unfortunately however
this one caught my eye and I gave it a go.
The user wanted to define a Scheme function to select a line in the text editor
based on the position of the cursor. This could then be attached to an editor
toolbar button.
The problem can be broken down as follows:
- Get the start of the line the cursor is currently on.
- Find the end of the line.
- Select the line.
A clue on how to get the start of the current line can be found in the beorg
library.org (the file that defines a bunch of Scheme code used internally by
beorg):
(define (line-start)
  (+ (string-search-backward "\n" (buffer-substring (point-min) (point))) 2))
More difficult is to get the end of the line. Once you know the start of the
line the trick is to either find the next newline, or failing that the end of
the current buffer. The following solution does highlight a few inefficiencies in
the available integration with the text editor, but it should work well enough
on files which aren't huge:
(define (line-end)
  (let* ((start-of-line (line-start))
         (rest-of-buffer (buffer-substring start-of-line (point-max)))
         (next-newline (string-search-forward "\n" rest-of-buffer)))
    (if next-newline
        (+ start-of-line next-newline)
        (point-max))))
You can now use these to create a new toolbar button. Here is
the text editor toolbar with a new button "Line" to select the current line:
(set! editor-toolbar-items '(("icon-left" (backward-char))
                             ("icon-right" (forward-char))
                             ("icon-list" (insert "+ "))
                             ("icon-todolist" (insert "+ [ ] "))
                             ("icon-change" (show-transform-commands))
                             ("icon-tools" (show-tools-commands))
                             ("icon-settings" (insert-code-snippet))
                             ("Line" (region-set (line-start) (line-end)))))