Skip to content

Latest commit

 

History

History
244 lines (215 loc) · 9.01 KB

jaszhe-hacks.org

File metadata and controls

244 lines (215 loc) · 9.01 KB

Jaszhe Hacks

header comments

;;; jaszhe-hacks.el --- Description -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2024 Jason Zhen
;;
;; Author: Jason Zhen <[email protected]>
;; Maintainer: Jason Zhen <[email protected]>
;; Created: July 05, 2024
;; Modified: July 05, 2024
;; Version: 0.0.1
;; Keywords: Symbol’s value as variable is void: finder-known-keywords
;; Homepage: https://github.com/jasonzhen/jaszhe-hacks
;; Package-Requires: ((emacs "24.3"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;;  Description
;;
;;; Code:

Ace-window window prefix

Similar to how other-window-prefix or same-window-prefix works we can use ace-window to choose the window we want to display a buffer in.

(defvar ace-choose-window-prefix-window nil)
(defun ace-choose-window-prefix ()
  "Interactively pick which window to show the next command's buffer in."
  (interactive)
  (setq ace-choose-window-prefix-window nil)
  (let ((aw-dispatch-always t))
    (aw-select "Choose window" (lambda (window) (setq ace-choose-window-prefix-window window)))
    )
  (when ace-choose-window-prefix-window
    (display-buffer-override-next-command
     (lambda (buffer alist)
       (select-window ace-choose-window-prefix-window)
       (setq alist (append '((inhibit-same-window . nil)) alist))
       (cons (or
              (display-buffer-same-window buffer alist)
              (display-buffer-use-some-window buffer alist))
             'reuse))
     nil "[same-window]")
    (message "Display next command buffer in the chosen window...")
    )
  )

Transient other window prefix common command

Sometimes I want to use other-window-prefix or the above ace-window-choose-window-prefix in transient commands that open a buffer.

Turns out transient has a “common-commands” prefix that we can use, that all transients inherit. https://github.com/magit/transient/blob/main/lisp/transient.el#L1734

We’re going to abuse this somewhat

(transient-define-suffix transient-other-window-prefix ()
  "Common transient to be used to open next transient command in other window."
  :transient t
  (interactive)
  (other-window-prefix))

(transient-define-suffix transient-ace-choose-window-prefix ()
  "Common transient to be used to open next transient command in other chosen window."
  :transient t
  (interactive)
  (ace-choose-window-prefix))

(transient-append-suffix 'transient-common-commands '(0 -1)
  (vector "Window"
          (list "M-o" "other-window" #'transient-other-window-prefix)
          (list "M-O" "choose-window" #'transient-ace-choose-window-prefix)
          ))

Hacky two page scrolling for pdfs

Requires use to open two or more pdf buffers in the current frame, with an offset of 1 page between each buffer. These functions just synchronize scrolling so we can emulate a two page pdf view.

This could probably be improved to have a command to set up the frame/window configuration accordingly. Possibly its own major mode..

(defun pdf-next-page-all-windows-for-doc ()
  "Next page for all pdf buffers in the current frame."
  (interactive)
  (let ((buf (current-buffer))
        (cur-win (selected-window)))
    (dolist (win (get-buffer-window-list buf))
      (save-window-excursion
        (select-window win)
        (pdf-view-next-page-command)))))

(defun pdf-prev-page-all-windows-for-doc ()
  "Prev page for all pdf buffers in the current frame."
  (interactive)
  (let ((buf (current-buffer))
        (cur-win (selected-window)))
    (dolist (win (get-buffer-window-list buf))
      (save-window-excursion
        (select-window win)
        (pdf-view-previous-page-command)))))

ripgrep wrapper using the default grep utility

This basically allows us to use the built-in *grep commands but with rg as the underlying command to run instead of gnu grep

(defun ripgrep ()
  (interactive)
  (call-interactively 'grep))

(defun rripgrep ()
  (interactive)
  (call-interactively 'rgrep))

(defun rripgrep-multiline ()
  (interactive)
  (call-interactively 'rgrep))

(defun rgrep-multiline ()
  (interactive)
  (grep-apply-setting 'grep-command "grep -Pazo --color=auto -nH --null -e ")
  (call-interactively 'rgrep))

(defun grep-options-advice ()
  "A convenient way for us to put different options depending on the grep command being run.
See notes:emacs-notes-and-tips for more details."
  (cond ((or (eq this-command 'ripgrep) (eq this-command 'rripgrep))
         (progn
           (grep-apply-setting 'grep-command "rg -nS --no-heading ") ;; for normal single file grep
           (grep-apply-setting 'grep-find-template "find <D> <X> -type f <F> -exec rg <C> -nS --no-heading -H  <R> /dev/null {} +"))) ;; for rgrep; uses grep-find-template
        ((eq this-command 'rripgrep-multiline)
         (progn
           (grep-apply-setting 'grep-find-template "find <D> <X> -type f <F> -exec rg <C> -nSU --no-heading -H  <R> /dev/null {} +")))
        ((eq this-command 'rgrep-multiline)
         (progn
           (grep-apply-setting 'grep-find-template "find -H <D> <X> -type f <F> -exec grep -zo <C> -nH --null -e <R> \\{\\} +")))
        (t (progn ;; defaults in case I want to change them later to do something different, otherwise don't really need this last case
             (grep-apply-setting 'grep-find-template "find -H <D> <X> -type f <F> -exec grep <C> -nH --null -e <R> \\{\\} +")
             (grep-apply-setting 'grep-command "grep --color=auto -nH --null -e ")))
        )
  )

(advice-add #'grep-compute-defaults :before #'grep-options-advice)

get shell environment variables and add them to emacs

Various commands to spawn a login shell and get related environment variables and set them in emacs using setenv.

(defun copy-env-vars-from-shell ()
  (interactive)
  (mapc (lambda (env-var-string)
          (let* ((split (split-string env-var-string "="))
                 (name (cl-first split))
                 (val (cl-second split)))
            (when (and name val)
              (setq val (string-replace " " "\\ " val))
              (setenv name val)
              (when (string-equal "PATH" name)

                ;; eshell path
                (setq-default eshell-path-env val)
                (when (fboundp 'eshell-set-path) (eshell-set-path val))))))
        (split-string (shell-command-to-string "bash --login -i -c printenv") "\n")))

(defun copy-env-vars-from-envrc ()
  (interactive)
  (mapc (lambda (env-var-string)
          (let* ((split (split-string env-var-string "="))
                 (name (cl-first split))
                 (val (cl-second split)))
            (when (and name val)
              (setq val (string-replace " " "\\ " val))
              (setenv name val))))
        (-filter (lambda (line) (not (string-empty-p (string-trim line))))
                 (-filter (lambda (line) (not (string-prefix-p "#" line)))
                          (split-string
                           (with-temp-buffer
                             (insert-file-contents-literally (concat (project-root (project-current)) ".envrc"))
                             (buffer-string)
                             )
                           "\n"))
                 )
        )
  )

(defun unset-env-vars-from-envrc ()
  (interactive)
  (mapc (lambda (env-var-string)
          (let* ((split (split-string env-var-string "="))
                 (name (cl-first split))
                 (val (cl-second split)))
            (when (and name val)
              (setq val (string-replace " " "\\ " val))
              (setenv name nil))))
        (-filter (lambda (line) (not (string-empty-p (string-trim line))))
                 (-filter (lambda (line) (not (string-prefix-p "#" line)))
                          (split-string
                           (with-temp-buffer
                             (insert-file-contents-literally (concat (project-root (project-current)) ".envrc"))
                             (buffer-string)
                             )
                           "\n"))
                 )
        )
  )

vc, diff, ediff goodies

In a diff buffer (usually via vc), this command will call ediff on the file at point, in case we want side-by-side viewing.

(defvar my-ediff-prior-window-configuration nil)
(defun vc-ediff-file-at-point ()
  (interactive)
  (when (eq major-mode 'diff-mode)
    (setq my-ediff-prior-window-configuration (current-window-configuration))
    (let ((old-revision (first diff-vc-revisions))
          (new-revision (second diff-vc-revisions))
          (file-to-diff (save-window-excursion
                          (diff-goto-source)
                          (buffer-file-name))))
      (vc-version-ediff `(,file-to-diff) old-revision new-revision))))

(add-hook 'ediff-quit-hook
          (lambda () (when (window-configuration-p my-ediff-prior-window-configuration)
                       (set-window-configuration my-ediff-prior-window-configuration)))
          100)

*