tvl-depot/users/grfn/emacs.d/utils.el
Griffin Smith 6266c5d32f refactor(users/glittershark): Rename to grfn
Rename my //users directory and all places that refer to glittershark to
grfn, including nix references and documentation.

This may require some extra attention inside of gerrit's database after
it lands to allow me to actually push things.

Change-Id: I4728b7ec2c60024392c1c1fa6e0d4a59b3e266fa
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2933
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Reviewed-by: lukegb <lukegb@tvl.fyi>
Reviewed-by: glittershark <grfn@gws.fyi>
2021-04-12 14:45:51 +00:00

114 lines
3.3 KiB
EmacsLisp

;;; -*- lexical-binding: t; -*-
;; Elisp Extras
(defmacro comment (&rest _body)
"Comment out one or more s-expressions"
nil)
(defun inc (x) "Returns x + 1" (+ 1 x))
(defun dec (x) "Returns x - 1" (- x 1))
(defun average (ns)
"Arithmetic mean of xs"
(if (null ns) nil
(/ (apply #'+ ns)
(length ns))))
(comment
(average (list 1 2 3 4))
)
;;
;; Text editing utils
;;
;; Reading strings
(defun get-char (&optional point)
"Get the character at the given `point' (defaulting to the current point),
without properties"
(let ((point (or point (point))))
(buffer-substring-no-properties point (+ 1 point))))
(defun get-line (&optional lineno)
"Read the line number `lineno', or the current line if `lineno' is nil, and
return it as a string stripped of all text properties"
(let ((current-line (line-number-at-pos)))
(if (or (not lineno)
(= current-line lineno))
(thing-at-point 'line t)
(save-mark-and-excursion
(line-move (- lineno (line-number-at-pos)))
(thing-at-point 'line t)))))
(defun get-line-point ()
"Get the position in the current line of the point"
(- (point) (line-beginning-position)))
;; Moving in the file
(defun goto-line-char (pt)
"Moves the point to the given position expressed as an offset from the start
of the line"
(goto-char (+ (line-beginning-position) pt)))
(defun goto-eol ()
"Moves to the end of the current line"
(goto-char (line-end-position)))
(defun goto-regex-on-line (regex)
"Moves the point to the first occurrence of `regex' on the current line.
Returns nil if the regex did not match, non-nil otherwise"
(when-let ((current-line (get-line))
(line-char (string-match regex current-line)))
(goto-line-char line-char)))
(defun goto-regex-on-line-r (regex)
"Moves the point to the *last* occurrence of `regex' on the current line.
Returns nil if the regex did not match, non-nil otherwise"
(when-let ((current-line (get-line))
(modified-regex (concat ".*\\(" regex "\\)"))
(_ (string-match modified-regex current-line))
(match-start (match-beginning 1)))
(goto-line-char match-start)))
(comment
(progn
(string-match (rx (and (zero-or-more anything)
(group "foo" "foo")))
"foofoofoo")
(match-beginning 1)))
;; Changing file contents
(defun delete-line ()
"Remove the line at the current point"
(delete-region (line-beginning-position)
(inc (line-end-position))))
(defmacro modify-then-indent (&rest body)
"Modify text in the buffer according to body, then re-indent from where the
cursor started to where the cursor ended up, then return the cursor to where
it started."
`(let ((beg (line-beginning-position))
(orig-line-char (- (point) (line-beginning-position))))
(atomic-change-group
(save-mark-and-excursion
,@body
(evil-indent beg (+ (line-end-position) 1))))
(goto-line-char orig-line-char)))
(pcase-defmacro s-starts-with (prefix)
`(pred (s-starts-with-p ,prefix)))
(pcase-defmacro s-contains (needle &optional ignore-case)
`(pred (s-contains-p ,needle
,@(when ignore-case (list ignore-case)))))
(comment
(pcase "foo"
((s-contains "bar") 1)
((s-contains "o") 2))
)