Table of Contents

Various useful things from my .emacs file.

1. General text-processing functions

1.1. Do anything to each line in the buffer or region

(E.g., number some lines)

(defun btv/replace-lines (f)
  (let ((begin (point-min))
        (end (point-max)))
    (when (use-region-p)
      (setq begin (region-beginning))
      (setq end (region-end))
      )
    (save-excursion
      (goto-char begin)
      (let* ((s (filter-buffer-substring (point) end 'delete))
             (r (string-join (mapcar f (split-string s "\n")) "\n")))
        (insert r)
        ))
    ))

;; Assuming lexical binding is on.
(defun btv/numberize ()
  (interactive)
  (let ((n 0))
    (btv/replace-lines
     (lambda (l) (setq n (+ 1 n)) (format "%d. %s" n l))))
  )

2. GitHub functions

2.1. Go to the current file in GitHub

(Or copy the link to it, with prefix arg)

;; Taken (with modifications) from https://github.com/magit/forge/issues/91#issuecomment-736613816
(defun btv/get-buffer-file-url ()
  (let
      ((rev (magit-rev-abbrev "HEAD"))
       (repo (forge-get-repository 'stub))
       (file (magit-file-relative-name buffer-file-name))
       (highlight
        (if
            (use-region-p)
            (let ((l1 (line-number-at-pos (region-beginning)))
                  (l2 (line-number-at-pos (- (region-end) 1))))
              (format "#L%d-L%d" l1 l2))
          ""
          )))
    (forge--format repo "https://%h/%o/%n/blob/%r/%f%L"
                   `((?r . ,rev) (?f . ,file) (?L . ,highlight)))))

(defun btv/forge-browse-buffer-file (prefix)
  (interactive "P")
  (let ((f (if prefix 'kill-new 'browse-url)))
    (funcall f (btv/get-buffer-file-url))))

3. Comment processing

3.1. Mark a block of consecutive comments

(defun btv/find-comments-region () 
  (save-excursion
    (let* ((syn (syntax-ppss))
           (cur-com-begin (and (nth 4 syn) (nth 8 syn))))
      (if cur-com-begin (goto-char cur-com-begin)))
    (let ((begin (point)))
      (while (forward-comment -1)
        (setq begin (point)))
      (let ((result))
        (while (forward-comment 1)
          (setq result `(,begin . ,(point))))
        result))))

(defun btv/mark-comments ()
  (interactive)
  (let ((region (btv/find-comments-region)))
    (when region
      (goto-char (car region))
      (set-mark (cdr region))
      t)))

3.2. Auto-fill them (i.e., intelligently linebreak)

(defun btv/fill-comments ()
   (interactive)
   (save-mark-and-excursion
     (if (btv/mark-comments)
         (fill-paragraph nil t))))

4. Projectile functions

4.1. Visit all files matching a regex

(defun btv/projectile-open-files-by-regex (r)
  (interactive "M")
  (let* ((project-root (projectile-acquire-root))
         (files (projectile-project-files project-root))
         (match (--filter (string-match r it) files)))
    (dolist (elt match)
      (find-file (expand-file-name elt project-root)))))

5. xref functions

5.1. Set up M-[ to find references to the defun at point in various modes

(defun btv/lispy-goto-defun-identifier ()
  (and (beginning-of-defun)
       (sp-down-sexp)
       (sp-next-sexp)))

(defun btv/ts-goto-defun-identifier ()  
  (let ((dfn (treesit-defun-at-point)))
    (let ((id (and dfn
                   (--first
                    (equal (treesit-node-type it) "identifier")
                    (treesit-node-children dfn)))))
      (and id
           (goto-char (treesit-node-start id))))))

(setq btv/goto-defun-identifier-function
      `((go-mode .
                 ,(lambda ()
                    (and (go-beginning-of-defun)
                         (goto-char (match-beginning 2)))))
        (emacs-lisp-mode . ,#'btv/lispy-goto-defun-identifier)
        (clojure-mode . ,#'btv/lispy-goto-defun-identifier)
        (rust-ts-mode . ,#'btv/ts-goto-defun-identifier)))

(defun btv/find-defun-references ()
  (interactive)
  (let ((f (alist-get major-mode btv/goto-defun-identifier-function)))
    (if f
        (save-excursion
          (if (funcall f)
              (xref-find-references (substring-no-properties (thing-at-point 'symbol)))
            (error "not in defun")))
      (error "no goto defun identifier function found for this major mode"))))

(dolist (it btv/goto-defun-identifier-function)
  (let* ((mode-name (symbol-name (car it)))
         (mode-hook (intern (concat mode-name "-hook")))
         (mode-map (intern (concat mode-name "-map"))))
    (add-hook mode-hook (lambda ()
                          (define-key (symbol-value mode-map) (kbd "M-[") 'btv/find-defun-references)))))

6. Miscellaneous functions

6.1. Look up a word in Wiktionary

(defun btv/wiktionary-at-point (arg)
  (interactive "P")
  (let* ((wap (word-at-point))
         (word (if (or arg (not wap))
                   (read-no-blanks-input "Word to look up: " wap)
                 wap)))
    (when word
      (eww (format "https://en.wiktionary.org/wiki/%s" word)))))

Author: User Ec2-user

Created: 2024-12-09 Mon 18:35

Validate