emacs-config/config-emacs.org

13 KiB

buffer-window management

  (defun switch-to-buffer-force-same-window (buffer)
    (interactive
     (list (read-buffer-to-switch "Switch to buffer: ")))
    (let ((switch-to-buffer-obey-display-actions nil))
      (switch-to-buffer buffer nil t)))

  (global-set-key (kbd "C-x B") #'switch-to-buffer-force-same-window)

  (setq switch-to-buffer-obey-display-actions t)

  (add-to-list 'display-buffer-alist
               `("COMMIT_EDITMSG"
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 0)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 80)))

  (add-to-list 'display-buffer-alist
               `("*Async Shell Command*"
                 display-buffer-in-side-window
                 (side . left)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 80)))

  (add-to-list 'display-buffer-alist
               `((major-mode . magit-status-mode)
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 1)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 80)))

  (add-to-list 'display-buffer-alist
               `((major-mode . magit-log-mode)
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 2)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 100)))

  ;; TODO: This should be fixed in future versions of emacs
  (defun my/is-compilation-buffer (buffer &optional _rest)
    (with-current-buffer buffer
      (or compilation-minor-mode
          (eq major-mode 'compilation-mode))))

  ;; TODO: Show multiple deadgrep buffers in side-window
  (add-to-list 'display-buffer-alist
               `((major-mode . deadgrep-mode)
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 3)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 100)))

  (add-to-list 'display-buffer-alist
               `(my/is-compilation-buffer
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 4)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 80)))

  (add-to-list 'display-buffer-alist
               `((major-mode . helpful-mode)
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 5)
                 (window-width . 80)))

  (add-to-list 'display-buffer-alist
               `((major-mode . Info-mode)
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 6)
                 (window-width . 80)))

  (require 'org-capture)

  (defun my/is-org-capture-buffer (buffer &optional _rest)
    (with-current-buffer buffer
      org-capture-mode))

  (add-to-list 'display-buffer-alist
               `(my/is-org-capture-buffer
                 display-buffer-in-side-window
                 (side . left)
                 (select . t)
                 (window-width . 85)
                 (window-parameters
                  . ((no-delete-other-windows . t)
                     (dedicated . t)))))

  ;; (pop display-buffer-alist)

Tramp configuration

  ;; This is sort the default in tramp, but I wanted to keep this here
  ;; as a reminder that THIS is the way to communicate to a shell that
  ;; we want a plain vanilla experience.

  ;; The way to check this is in shell is as follows:
  ;; if [[ "$TERM" != "dumb" ]]; then
  ;;    # vterm configuration, etc.
  ;; fi

  ;; OR, the new way I've been doing this:
  ;; [[ "$TERM" = "dumb" ]] && return
  (setq tramp-terminal-type "dumb")

  ;; To debug tramp, set the following variable (max value 11).

  ;; (setq tramp-verbose 3)
  ;; (setq tramp-verbose 9)

set-default-directory

  (defun set-default-directory (dir)
    (interactive "f")
    (setq default-directory dir))

Profiler Keymap

  (define-prefix-command '*profiler-map*)

  (define-key *profiler-map* (kbd "s") #'profiler-start)
  (define-key *profiler-map* (kbd "r") #'profiler-report)
  (define-key *profiler-map* (kbd "S") #'profiler-stop)

  (define-key *root-map* (kbd "p") '*profiler-map*)

colorful compilation buffer

  (require 'ansi-color)
  (defun colorize-compilation-buffer ()
    (let ((buffer-read-only nil))
      (ansi-color-apply-on-region (point-min) (point-max))))
  (add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

World time

    (setq world-clock-list
          '(("America/Chicago" "Houston")
            ("Asia/Taipei" "Taiwan")
            ("Turkey" "Turkey")
            ("Asia/Shanghai" "China")
            ("Asia/Jakarta" "Indonesia")))

auto-save files in same directory

  (setq backup-directory-alist `(("." . ,(ef "backups/"))))

  (setq make-backup-files t               ; backup of a file the first time it is saved.
        backup-by-copying t               ; don't clobber symlinks
        version-control t                 ; version numbers for backup files
        kept-old-versions 6               ; oldest versions to keep when a new numbered backup is made (default: 2)
        kept-new-versions 9               ; newest versions to keep when a new numbered backup is made (default: 2)
        auto-save-default t               ; auto-save every buffer that visits a file
        auto-save-timeout 20              ; number of seconds idle time before auto-save (default: 30)
        auto-save-interval 200            ; number of keystrokes between auto-saves (default: 300)
        )

freezing time

  (defvar my/frozen-time nil)

  (defvar my/format-time-string-function nil)

  (defun my/org-today ()
    (time-to-days my/frozen-time))

  (defun my/current-time ()
    my/frozen-time)

  (defun my/format-time-string (original format-string &optional time zone)
    (apply original
           format-string
           (if time
               time
             my/frozen-time)
           zone))

  (defun my/decode-time (original &optional time zone form)
    (apply original
           (if time
               time
             my/frozen-time)
           zone
           form))

  ;; Change and freeze time
  (defun za-warudo ()
    "Freeze `current-time' at the current active or inactive timestamp. If point
  is not on a timestamp, the function prompts for one. If time is not specified,
  either by the timstamp under point or prompt, the time defaults to the
  current HH:MM of today at the selected date."
    (interactive)
    (let* ((org-read-date-prefer-future nil)
           (time (org-read-date t 'totime nil "Input freeze time: ")))
      (setq my/frozen-time (append time '(0 0)))
      (advice-add #'current-time :override #'my/current-time)
      (advice-add #'format-time-string :around #'my/format-time-string)
      (advice-add #'decode-time :around #'my/decode-time)
      (advice-add #'org-today :override #'my/org-today)
      (set-face-background 'fringe "firebrick2")
      (message "Toki yo tomare")))

  (define-key *root-map* (kbd "C-z") 'za-warudo)

  ;; Release changed / frozen time
  (defun un-za-warudo ()
    "Release the time frozen by `freeze-time'."
    (interactive)
    (advice-remove #'current-time #'my/current-time)
    (advice-remove #'format-time-string #'my/format-time-string)
    (advice-remove #'decode-time #'my/decode-time)
    (advice-remove #'org-today #'my/org-today)
    (setq my/frozen-time nil)
    (set-face-background 'fringe nil)
    (message "Soshite, toki wa ugoki dasu"))

  (define-key *root-map* (kbd "C-r") 'un-za-warudo)

encryption

  (let ((authinfo-file
         (if my-ec/at-ti
             (ef "secrets/.authinfo.gpg")
           (expand-file-name "~/.authinfo"))))
    (if (not (setq my-ec/authinfo-exists
                   (file-exists-p authinfo-file)))
        (warn ".authinfo file missing, remember to setup seafile. Mail config is also prevented from loading")
      (require 'epa-file)
      (epa-file-enable)
      (setq epa-pinentry-mode 'loopback)
      (setq epa-file-cache-passphrase-for-symmetric-encryption t)
      (setenv "GPG_AGENT_INFO" nil)

      (setq epg-gpg-program "gpg2")
      ;; (setq auth-source-debug t)
      (setq auth-sources `((:source ,authinfo-file)))

      (when-let* ((gpg (executable-find "gpg2"))
                  (version (shell-command-to-string (format "%s --version" gpg)))
                  ((string-match (rx "gpg (GnuPG) "
                                     (group (+ digit)
                                            (+ "."
                                               (+ digit))))
                                 version))
                  (version (match-string 1 version))
                  (number (string-to-number
                           (string-replace "." "" version)))
                  ((>= 243 number 241)))
        (fset 'epg-wait-for-status 'ignore))))

delete-other-side-windows

  (defun my/delete-other-windows (arg)
    (interactive "p")
    (let* ((win (selected-window))
           (side-win (window-parameter win 'window-side)))
      (if (= arg 1)
          (if (not side-win)
              (delete-other-windows)
            (delete-other-windows-vertically))
        (set-window-dedicated-p win nil)
        (when side-win
          (set-window-parameter win 'window-side nil)
          (set-window-parameter win 'no-delete-other-windows nil))
        (let ((ignore-window-parameters t)
              (window--sides-inhibit-check t))
          (delete-other-windows)))))

  (define-key pestctrl-minor-mode-map (kbd "C-x 1") #'my/delete-other-windows)

find-file-view

  (defun view-mode-file ()
    (interactive)
    (call-interactively #'ido-find-file)
    (view-mode))

  (global-set-key (kbd "C-c C-v") #'view-mode-file)

man select window

  (setq Man-notify-method 'aggressive)

Scroll interval

  (setq scroll-margin 1
        hscroll-margin 2
        hscroll-step 1
        scroll-conservatively 101
        scroll-preserve-screen-position t
        mouse-wheel-scroll-amount '(3)
        mouse-wheel-progressive-speed nil)

Window splitting function

  (defun split-window-sensibly-prefer-horizontal (&optional window)
    "Based on split-window-sensibly, but designed to prefer a horizontal split,
  i.e. windows tiled side-by-side."
    (let ((window (or window (selected-window))))
      (or (and (window-splittable-p window t)
               ;; Split window horizontally
               (with-selected-window window
                 (split-window-right)))
          (and (window-splittable-p window)
               ;; Split window vertically
               (with-selected-window window
                 (split-window-below)))
          (and
           ;; If WINDOW is the only usable window on its frame (it is
           ;; the only one or, not being the only one, all the other
           ;; ones are dedicated) and is not the minibuffer window, try
           ;; to split it horizontally disregarding the value of
           ;; `split-height-threshold'.
           (let ((frame (window-frame window)))
             (or
              (eq window (frame-root-window frame))
              (catch 'done
                (walk-window-tree (lambda (w)
                                    (unless (or (eq w window)
                                                (window-dedicated-p w))
                                      (throw 'done nil)))
                                  frame)
                t)))
           (not (window-minibuffer-p window))
           (let ((split-width-threshold 0))
             (when (window-splittable-p window t)
               (with-selected-window window
                 (split-window-right))))))))

  (defun split-window-really-sensibly (&optional window)
    (let ((window (or window (selected-window))))
      (if (> (window-total-width window) (* 2 (window-total-height window)))
          (with-selected-window window (split-window-sensibly-prefer-horizontal window))
        (with-selected-window window (split-window-sensibly window)))))

  (setq
     split-height-threshold 4
     split-width-threshold (if my/puppet-p 100 160)
     split-window-preferred-function 'split-window-really-sensibly)

Splitting functions

  (defun mp-split-below (arg)
    "Split window below from the parent or from root with ARG."
    (interactive "P")
    (split-window (if arg (frame-root-window)
                    (window-parent (selected-window)))
                  nil 'below nil))

  (defun mp-split-left (arg)
    "Split window below from the parent or from root with ARG."
    (interactive "P")
    (split-window (if arg (frame-root-window)
                    (window-parent (selected-window)))
                  nil 'left nil))

Gimme that process

  (require 'rgrep-patch)