~thecatster/.emacs.d

8c56cb64fa60fcc217bcbaa5feeae47c60628d7d — Daniil Rose 1 year, 11 months ago 0577c30
Large cleanup, remove largely unused programs
2 files changed, 9 insertions(+), 734 deletions(-)

M emacs.org
M init.el
M emacs.org => emacs.org +7 -433
@@ 884,19 884,6 @@ package as well. Great, because it's one of my most used!
  (global-set-key [remap kill-whole-line] #'crux-kill-whole-line))
#+END_SRC

** Windmove
   Quickly switch between buffers and windows instead of ~C-x o~.

   #+BEGIN_SRC emacs-lisp
   (use-package windmove
     :bind (:prefix "M-o"
            :prefix-map my-helper-map
            ("h" . windmove-left)
            ("j" . windmove-down)
            ("k" . windmove-up)
            ("l" . windmove-right)))
   #+END_SRC

** No Littering
This is nice to have, so why not add it.



@@ 912,7 899,7 @@ This is nice to have, so why not add it.
#+END_SRC

** Shackle
What the hell are those default buffer popup locations?
What in the world are those default buffer popup locations?

#+BEGIN_SRC emacs-lisp
(defun rk/open-compilation-buffer (&optional buffer-or-name shackle-alist shackle-plist)


@@ 966,14 953,6 @@ What the hell are those default buffer popup locations?

(shackle-mode)
#+END_SRC
** Selection
I've heard good about expand-region, so I've decided to give it a whirl.

#+BEGIN_SRC emacs-lisp
(use-package expand-region
  :bind (("M-[" . er/expand-region)
         ("C-(" . er/mark-outside-pairs)))
#+END_SRC
** Yasnippet
Still trying to get use to this one, my ultisnips in Neovim are just
unstoppable. Porting my snippets over is also a pain, so once that is


@@ 1031,193 1010,13 @@ The one, the only. I used CLI git only (still do often) but now I've learned to 
        (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
        :bind ("C-x g" . magit-status))

      (use-package magit-todos
        :defer t)

      ;; Hell yeah I want git gutter
      ;; well yeah I want git gutter
      (use-package git-gutter
        :diminish
        :hook ((prog-mode) . git-gutter-mode)
        :config
        (setq git-gutter:update-interval 2))
#+END_SRC
** Vterm
Vterm is the best Emacs terminal, however I use Alacritty when
developing TUI applications, and eshell when I want to work with elisp
in the terminal.

#+BEGIN_SRC emacs-lisp
(use-package vterm
   :commands vterm
   :hook ((vterm-mode . (lambda ()
                          (display-line-numbers-mode -1)
                          (setq-local global-hl-line-mode nil))))
   :config
   (setq vterm-max-scrollback 10000))
#+END_SRC
** Eshell
Eshell is really quite a fascinating concept, and this adds syntax
highlighting to it!
*** Configuration

#+BEGIN_SRC emacs-lisp
  (defun read-file (file-path)
    (with-temp-buffer
      (insert-file-contents file-path)
      (buffer-string)))

  (defun dw/get-current-package-version ()
    (interactive)
    (let ((package-json-file (concat (eshell/pwd) "/package.json")))
      (when (file-exists-p package-json-file)
        (let* ((package-json-contents (read-file package-json-file))
               (package-json (ignore-errors (json-parse-string package-json-contents))))
          (when package-json
            (ignore-errors (gethash "version" package-json)))))))

  (defun dw/map-line-to-status-char (line)
    (cond ((string-match "^?\\? " line) "?")))

  (defun dw/get-git-status-prompt ()
    (let ((status-lines (cdr (process-lines "git" "status" "--porcelain" "-b"))))
      (seq-uniq (seq-filter 'identity (mapcar 'dw/map-line-to-status-char status-lines)))))

  (defun dw/get-prompt-path ()
    (let* ((current-path (eshell/pwd))
           (git-output (shell-command-to-string "git rev-parse --show-toplevel"))
           (has-path (not (string-match "^fatal" git-output))))
      (if (not has-path)
        (abbreviate-file-name current-path)
        (string-remove-prefix (file-name-directory git-output) current-path))))

  ;; This prompt function mostly replicates my custom zsh prompt setup
  ;; that is powered by github.com/denysdovhan/spaceship-prompt.
  (defun dw/eshell-prompt ()
    (let ((current-branch (magit-get-current-branch))
          (package-version (dw/get-current-package-version)))
      (concat
       "\n"
       (propertize (system-name) 'face `(:foreground "#62aeed"))
       (propertize " ॐ " 'face `(:foreground "white"))
       (propertize (dw/get-prompt-path) 'face `(:foreground "#82cfd3"))
       (when current-branch
         (concat
          (propertize " • " 'face `(:foreground "white"))
          (propertize (concat " " current-branch) 'face `(:foreground "#c475f0"))))
       (when package-version
         (concat
          (propertize " @ " 'face `(:foreground "white"))
          (propertize package-version 'face `(:foreground "#e8a206"))))
       (propertize " • " 'face `(:foreground "white"))
       (propertize (format-time-string "%I:%M:%S %p") 'face `(:foreground "#5a5b7f"))
       (if (= (user-uid) 0)
           (propertize "\n#" 'face `(:foreground "red2"))
         (propertize "\nλ" 'face `(:foreground "#aece4a")))
       (propertize " " 'face `(:foreground "white")))))

  (defun dw/eshell-configure ()
    (use-package xterm-color)

    (push 'eshell-tramp eshell-modules-list)
    (push 'xterm-color-filter eshell-preoutput-filter-functions)
    (delq 'eshell-handle-ansi-color eshell-output-filter-functions)

    ;; Save command history when commands are entered
    (add-hook 'eshell-pre-command-hook 'eshell-save-some-history)

    (add-hook 'eshell-before-prompt-hook
              (lambda ()
                (setq xterm-color-preserve-properties t)))

    ;; Truncate buffer for performance
    (add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer)

    ;; We want to use xterm-256color when running interactive commands
    ;; in eshell but not during other times when we might be launching
    ;; a shell command to gather its output.
    (add-hook 'eshell-pre-command-hook
              (lambda () (setenv "TERM" "xterm-256color")))
    (add-hook 'eshell-post-command-hook
              (lambda () (setenv "TERM" "dumb")))

    ;; Use completion-at-point to provide completions in eshell
    (define-key eshell-mode-map (kbd "<tab>") 'completion-at-point)

    ;; Initialize the shell history
    (eshell-hist-initialize)

    (setenv "PAGER" "cat")

    (setq
          eshell-prompt-regexp        "^λ "
          eshell-history-size         10000
          eshell-buffer-maximum-lines 10000
          eshell-hist-ignoredups t
          eshell-highlight-prompt t
          eshell-scroll-to-bottom-on-input t
          eshell-prefer-lisp-functions nil))

  (use-package eshell
    :hook (eshell-first-time-mode . dw/eshell-configure)
    :init
    (setq eshell-directory-name "~/.emacs.d/eshell/"
          eshell-aliases-file (expand-file-name "~/.emacs.d/eshell/alias")))

  (use-package eshell-z
    :hook ((eshell-mode . (lambda () (require 'eshell-z)))
           (eshell-z-change-dir .  (lambda () (eshell/pushd (eshell/pwd))))))
#+END_SRC
*** Shell Commands
Custom eshell commands will go here.

Clearing the eshell is annoying. I always try to do ~C-l~ which
results in the screen shifting just like Emacs. Let's fix that
behaviour:

#+BEGIN_SRC emacs-lisp
(defun run-this-in-eshell (cmd)
    "Runs the command 'cmd' in eshell."
    (end-of-buffer)
    (eshell-kill-input)
    (message (concat "Running in Eshell: " cmd))
    (insert cmd)
    (eshell-send-input)
    (end-of-buffer)
    (eshell-bol)
    (yank))

(add-hook 'eshell-mode-hook (lambda ()
    (interactive)
    (local-set-key (kbd "C-l")
    (run-this-in-eshell "clear 1"))))
#+END_SRC
*** Visual Commands

#+BEGIN_SRC emacs-lisp
  (with-eval-after-load 'esh-opt
    (setq eshell-destroy-buffer-when-process-dies t)
    (setq eshell-visual-commands '("htop" "zsh" "vim")))
#+END_SRC
*** Command Highlighting

#+BEGIN_SRC emacs-lisp
  (use-package eshell-syntax-highlighting
    :after esh-mode
    :config
    (eshell-syntax-highlighting-global-mode 1))
#+END_SRC
*** Toggling Eshell
=eshell-toggle= allows me to toggle an Eshell window below the current buffer for the path (or project path) of the buffer.

#+BEGIN_SRC emacs-lisp
  (use-package eshell-toggle
    :after eshell
    :bind ("C-M-'" . eshell-toggle)
    :custom
    (eshell-toggle-size-fraction 3)
    (eshell-toggle-use-projectile-root t)
    (eshell-toggle-run-command nil))
#+END_SRC
** Ediff
It's nice to see differences when debugging two things.



@@ 1267,39 1066,6 @@ modify) PDFs in Emacs.
    (advice-add 'pdf-annot-edit-contents-commit :after 'bjm/save-buffer-no-args)))
#+END_SRC
* Programs and Extensions
** XKCD
Comics are fun, why not add them to Emacs as well?

#+BEGIN_SRC emacs-lisp
(use-package xkcd)
#+END_SRC

** SX
Alright, I got my XKCD, what's the other most popular site for
hackers? Right, Stack Overflow!

#+BEGIN_SRC emacs-lisp
(use-package sx
  :config
  (bind-keys :prefix "C-c s"
             :prefix-map my-sx-map
             :prefix-docstring "Global keymap for SX."
             ("q" . sx-tab-all-questions)
             ("i" . sx-inbox)
             ("o" . sx-open-link)
             ("u" . sx-tab-unanswered-my-tags)
             ("a" . sx-ask)
             ("s" . sx-search)))
#+END_SRC

** Ledger
So, if I have my work, comics, answers, and math in Emacs, might as
well have my finance as well (encrypted of course.)

#+BEGIN_SRC emacs-lisp
(use-package ledger-mode)
#+END_SRC

** Docker
I often want to write and/or edit Dockerfiles and docker-compose.yml's
for my server or development. Having the ability to seamlessly do this


@@ 1453,42 1219,6 @@ Sharing pictures of code is useful, why not build that into Emacs.
;;   :straight (:host github :repo "tecosaur/screenshot"))
#+END_SRC

** System Packages
Although Guix has a really cool emacs package to manage packages, I'm
not always on Guix. This is the next best thing for every other
distro.

#+BEGIN_SRC emacs-lisp
(use-package system-packages
  :custom
  (system-packages-package-manager 'paru) ;; For Arch
  ;; (system-packages-package-manager 'xbps) ;; For Void
  ;; (system-packages-package-manager 'nix) ;; For Nix/LFS
  :config
  (add-to-list 'system-packages-supported-package-managers
               '(paru .
                        ((default-sudo . nil)
                         (install . "paru -S")
                         (search . "paru -Ss")
                         (uninstall . "paru -Rs")
                         (update . "paru -Syu")
                         (clean-cache . "paru -Sc")
                         (log . "cat /var/log/pacman.log")
                         (change-log . "paru -Qc")
                         (get-info . "paru -Qi")
                         (get-info-remote . "paru -Si")
                         (list-files-provided-by . "paru -Ql")
                         (owning-file . "paru -Qo")
                         (owning-file-remote . "paru -F")
                         (verify-all-packages . "paru -Qkk")
                         (verify-all-dependencies . "paru -Dk")
                         (remove-orphaned . "paru -Rns $(pacman -Qtdq)")
                         (list-installed-packages . "paru -Qe")
                         (list-installed-packages-all . "paru -Q")
                         (list-dependencies-of . "paru -Qi")
                         (noconfirm . "--noconfirm")))))
#+END_SRC

** Ledger
By keeping my finances in (encrypted) plain text, I can ensure they
are always accessible, even offline (as opposed to my previous


@@ 1501,19 1231,6 @@ self-hosted solution, SilverStrike).
  :after ledger-mode)
#+END_SRC

** LilyPond
LilyPond is quite interesting, and adding it to Emacs is great as
well! Writing my music in text is a different way to approach it, and
an especially unique approach when rearranging music.

#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path "/usr/share/emacs/site-lisp/") ; Arch Linux path
(require 'lilypond-mode)
(add-to-list 'auto-mode-alist '("\\.ly$" . LilyPond-mode))

(add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))
#+END_SRC

** Elfeed
I use miniflux as a self-hosted RSS reader/aggregator, and use elfeed
as a client.


@@ 1551,67 1268,6 @@ as a client.
  (elfeed-autotag))
#+END_SRC

** Wttr.el
wttr.in Emacs!

#+BEGIN_SRC emacs-lisp
(use-package wttrin
  :custom
  (wttrin-default-cities '("Lancaster")))
#+END_SRC

** Pulseaudio Control
Why not control pulseaudio/pipewire in Emacs as well? Especially
useful when using EXWM, as always having to use pamixer is a bit
annoying.

#+BEGIN_SRC emacs-lisp
(use-package pulseaudio-control
  :init
  (pulseaudio-control-default-keybindings))
#+END_SRC

** Ytel
Ytel is an Emacs "frontend" for Invidious/YouTube, which plays using
mpv. Pretty cool!

Sadly I haven't been able to get this to work yet, constantly having
JSON errors (unrelated to shutdown instances!)

#+BEGIN_SRC emacs-lisp
;; (use-package ytel
;;   :custom
;;   (ytel-invidious-api-url "https://invidious.exonip.de")
;;   :config
;;   (defun ytel-watch ()
;;     "Stream video at point in mpv."
;;     (interactive)
;;     (let* ((video (ytel-get-current-video))
;;      	     (id    (ytel-video-id video)))
;;       (start-process "ytel mpv" nil
;; 		                 "mpv"
;; 		                 (concat "https://www.youtube.com/watch?v=" id))
;; 		  "--ytdl-format=bestvideo[height<=?720]+bestaudio/best")
;;     (message "Starting streaming..."))

;;   (define-key ytel-mode-map "y" #'ytel-watch))

;; (use-package ytel-show
;;   :after ytel
;;   :bind (:map ytel-mode-map ("RET" . ytel-show)))

#+END_SRC

** Nov
I usually use my iPad or eReader for books, but sometimes having them
open at the same time in Emacs is convenient!

#+BEGIN_SRC emacs-lisp
(use-package nov
  :config
  (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))
#+END_SRC

** OpenSCAD
OpenSCAD has modes for files and previews in Emacs!



@@ 1632,44 1288,6 @@ just copy it,) I can now do that.
(use-package simple-httpd)
#+END_SRC

** EMMS
EMMS is quite cool, and since I usually sync my music library through
Nextcloud or *Sonic, it's super convenient.

#+BEGIN_SRC emacs-lisp
(use-package emms
  :custom
  (emms-source-file-default-directory "~/Nextcloud/Music/")
  (emms-info-functions '(emms-info-tinytag))
  (emms-browser-covers 'emms-browser-cache-thumbnail-async)
  :config
  (emms-all)
  (emms-default-players))
#+END_SRC
** *Sonic API
I use Gonic for a lot of my music (which is based on the Subsonic
API), and recently came across a great player in Emacs!

#+BEGIN_SRC emacs-lisp
(use-package subsonic
  :commands subsonic
  :bind (("C-c m" . subsonic))
  :custom
  (subsonic-url "music.danielr.xyz")
  (subsonic-enable-art nil)
  (subsonic-host "music.danielr.xyz"))
#+END_SRC

** Elpher
The best browser for Gopher and Gemini protocols.

#+BEGIN_SRC emacs-lisp
(use-package elpher)
;; Fixes gemini timeout
(setq gnutls-verify-error t)
(setq elpher-use-tls t)
#+END_SRC

** Email
Now, let's add mu4e. I keep this account file in a different location,
but you can easily learn to do this with the great Reddit post "mu4e


@@ 1837,9 1455,9 @@ DAP is causing issues again, so I'm commenting it out temporarily.
** Languages
The meat and potatoes of this section. Includes all the above
mentioned languages! Technically, my "four" most used are Rust,
Python, C/C++, and Lisp (which mostly includes Hy, Elisp, and
Clojure). The rest of the things here are either for fun, or just
convenient to have. I've been spending more time improving my Computer
Python, C/C++, and Lisp (which mostly includes Hy and Elisp). The rest
of the things here are either for fun, or just convenient to
have. I've been spending more time improving my Computer
Science/Critical Thinking skills instead of focusing on languages.

Now that language list isn't particularly true. I have recently been


@@ 1852,9 1470,6 @@ Sadly IntelliJ and Android Studio are just too good for
Java/Kotlin. I'll stick with the proper tools for those languages, but
with Emacs keybindings of course :D

Languages are marked ~:disabled~ in ~use-package~ when I am not
currently doing a project in them (but would like to keep my setup).

*** Rust
Crustacean for life! Rust is a great language, but is taking it's time
to completely be accepted. Most of my work nowadays is done in Rust.


@@ 2028,15 1643,6 @@ Arduinos is fun, but the Arduino IDE sucks. Let's use Emacs instead!
(use-package arduino-mode)
#+END_SRC

*** Clojure
I don't do JVM work often, but when I need to I prefer Clojure or
Kotlin.

#+BEGIN_SRC emacs-lisp
(use-package clojure-mode)
(use-package cider)
#+END_SRC

*** Web Languages
Despite my usual hate for these languages (and web languages in
general), I've recently been learning more about them and


@@ 2176,13 1782,6 @@ Change the fonts and colours of headings.

#+END_SRC

Use ~tectonic~ instead of ~pdflatex~ in when exporting to PDF.

#+BEGIN_SRC emacs-lisp
(setq org-latex-pdf-process
      '("tectonic %f"))
#+END_SRC

Hide emphasis markers and make stars UTF-8 bullets!

#+BEGIN_SRC emacs-lisp


@@ 2233,7 1832,7 @@ Some more good options.
F**K YEAH Radians over Degrees.

#+BEGIN_SRC emacs-lisp
  (setq calc-angle-mode 'rad  ; radians are rad, fuck degrees
  (setq calc-angle-mode 'rad  ; radians are rad, screw degrees
        calc-symbolic-mode t) ; keeps expressions like \sqrt{2} irrational for as long as possible
#+END_SRC



@@ 2244,36 1843,17 @@ Properly indent headings in org mode.
#+END_SRC

** Blog, Agenda, and Capture
Various things here that make working with [[https://www.regressions.xyz/][my blog]] easier from Emacs,
Various things here that make working with [[https://www.danielr.xyz/blog][my blog]] easier from Emacs,
and working on my gemini capsule. Settings here also make organizing
my Org agenda and capture more pleasant.

#+BEGIN_SRC emacs-lisp
(use-package ox-gemini)

;; I used to use aspell, but I find proselint to be more accurate for English
;; Install using `pip install proselint` or through your package manager
(flycheck-define-checker proselint
  "A linter for prose."
  :command ("proselint" source-inplace)
  :error-patterns
  ((warning line-start (file-name) ":" line ":" column ": "
            (id (one-or-more (not (any " "))))
            (message (one-or-more not-newline)
                     (zero-or-more "\n" (any " ") (one-or-more not-newline)))
            line-end))
  :modes (text-mode markdown-mode gfm-mode org-mode))

;; Word choice and such
(use-package writegood-mode
  :bind ("C-c g" . writegood-mode)
  :config
  (add-to-list 'writegood-weasel-words "actionable"))

;; Export to GitHub flavored markdown
(use-package ox-gfm
  :after org)

;; Various good settings
(setq org-agenda-window-setup (quote current-window)) ;; open agenda in current window
(setq org-deadline-warning-days 7) ;; warn me of any deadlines in next 7 days


@@ 2316,22 1896,16 @@ Enabling necessary languages.
#+BEGIN_SRC emacs-lisp
(use-package ob-hy)
(use-package ob-rust)
(use-package ob-clojurescript)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((arduino . t)
   (C . t)
   (clojure . t)
   (clojurescript . t)
   (emacs-lisp . t)
   (gnuplot . t)
   (haskell . t)
   (hy . t)
   (js . t)
   (latex . t)
   (ledger . t)
   (lilypond . t)
   (lisp . t)
   (python . t)
   (rust . t)

M init.el => init.el +2 -301
@@ 565,14 565,6 @@
  (global-set-key (kbd "C-<backspace>") #'crux-kill-line-backwards)
  (global-set-key [remap kill-whole-line] #'crux-kill-whole-line))

(use-package windmove
  :bind (:prefix "M-o"
         :prefix-map my-helper-map
         ("h" . windmove-left)
         ("j" . windmove-down)
         ("k" . windmove-up)
         ("l" . windmove-right)))

(use-package no-littering
  :config
  (require 'recentf)


@@ 633,10 625,6 @@

(shackle-mode)

(use-package expand-region
  :bind (("M-[" . er/expand-region)
         ("C-(" . er/mark-outside-pairs)))

(use-package yasnippet-snippets)

(use-package yasnippet


@@ 679,163 667,13 @@
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
  :bind ("C-x g" . magit-status))

(use-package magit-todos
  :defer t)

;; Hell yeah I want git gutter
;; well yeah I want git gutter
(use-package git-gutter
  :diminish
  :hook ((prog-mode) . git-gutter-mode)
  :config
  (setq git-gutter:update-interval 2))

(use-package vterm
   :commands vterm
   :hook ((vterm-mode . (lambda ()
                          (display-line-numbers-mode -1)
                          (setq-local global-hl-line-mode nil))))
   :config
   (setq vterm-max-scrollback 10000))

(defun read-file (file-path)
  (with-temp-buffer
    (insert-file-contents file-path)
    (buffer-string)))

(defun dw/get-current-package-version ()
  (interactive)
  (let ((package-json-file (concat (eshell/pwd) "/package.json")))
    (when (file-exists-p package-json-file)
      (let* ((package-json-contents (read-file package-json-file))
             (package-json (ignore-errors (json-parse-string package-json-contents))))
        (when package-json
          (ignore-errors (gethash "version" package-json)))))))

(defun dw/map-line-to-status-char (line)
  (cond ((string-match "^?\\? " line) "?")))

(defun dw/get-git-status-prompt ()
  (let ((status-lines (cdr (process-lines "git" "status" "--porcelain" "-b"))))
    (seq-uniq (seq-filter 'identity (mapcar 'dw/map-line-to-status-char status-lines)))))

(defun dw/get-prompt-path ()
  (let* ((current-path (eshell/pwd))
         (git-output (shell-command-to-string "git rev-parse --show-toplevel"))
         (has-path (not (string-match "^fatal" git-output))))
    (if (not has-path)
      (abbreviate-file-name current-path)
      (string-remove-prefix (file-name-directory git-output) current-path))))

;; This prompt function mostly replicates my custom zsh prompt setup
;; that is powered by github.com/denysdovhan/spaceship-prompt.
(defun dw/eshell-prompt ()
  (let ((current-branch (magit-get-current-branch))
        (package-version (dw/get-current-package-version)))
    (concat
     "\n"
     (propertize (system-name) 'face `(:foreground "#62aeed"))
     (propertize " ॐ " 'face `(:foreground "white"))
     (propertize (dw/get-prompt-path) 'face `(:foreground "#82cfd3"))
     (when current-branch
       (concat
        (propertize " • " 'face `(:foreground "white"))
        (propertize (concat " " current-branch) 'face `(:foreground "#c475f0"))))
     (when package-version
       (concat
        (propertize " @ " 'face `(:foreground "white"))
        (propertize package-version 'face `(:foreground "#e8a206"))))
     (propertize " • " 'face `(:foreground "white"))
     (propertize (format-time-string "%I:%M:%S %p") 'face `(:foreground "#5a5b7f"))
     (if (= (user-uid) 0)
         (propertize "\n#" 'face `(:foreground "red2"))
       (propertize "\nλ" 'face `(:foreground "#aece4a")))
     (propertize " " 'face `(:foreground "white")))))

(defun dw/eshell-configure ()
  (use-package xterm-color)

  (push 'eshell-tramp eshell-modules-list)
  (push 'xterm-color-filter eshell-preoutput-filter-functions)
  (delq 'eshell-handle-ansi-color eshell-output-filter-functions)

  ;; Save command history when commands are entered
  (add-hook 'eshell-pre-command-hook 'eshell-save-some-history)

  (add-hook 'eshell-before-prompt-hook
            (lambda ()
              (setq xterm-color-preserve-properties t)))

  ;; Truncate buffer for performance
  (add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer)

  ;; We want to use xterm-256color when running interactive commands
  ;; in eshell but not during other times when we might be launching
  ;; a shell command to gather its output.
  (add-hook 'eshell-pre-command-hook
            (lambda () (setenv "TERM" "xterm-256color")))
  (add-hook 'eshell-post-command-hook
            (lambda () (setenv "TERM" "dumb")))

  ;; Use completion-at-point to provide completions in eshell
  (define-key eshell-mode-map (kbd "<tab>") 'completion-at-point)

  ;; Initialize the shell history
  (eshell-hist-initialize)

  (setenv "PAGER" "cat")

  (setq
        eshell-prompt-regexp        "^λ "
        eshell-history-size         10000
        eshell-buffer-maximum-lines 10000
        eshell-hist-ignoredups t
        eshell-highlight-prompt t
        eshell-scroll-to-bottom-on-input t
        eshell-prefer-lisp-functions nil))

(use-package eshell
  :hook (eshell-first-time-mode . dw/eshell-configure)
  :init
  (setq eshell-directory-name "~/.emacs.d/eshell/"
        eshell-aliases-file (expand-file-name "~/.emacs.d/eshell/alias")))

(use-package eshell-z
  :hook ((eshell-mode . (lambda () (require 'eshell-z)))
         (eshell-z-change-dir .  (lambda () (eshell/pushd (eshell/pwd))))))

(defun run-this-in-eshell (cmd)
    "Runs the command 'cmd' in eshell."
    (end-of-buffer)
    (eshell-kill-input)
    (message (concat "Running in Eshell: " cmd))
    (insert cmd)
    (eshell-send-input)
    (end-of-buffer)
    (eshell-bol)
    (yank))

(add-hook 'eshell-mode-hook (lambda ()
    (interactive)
    (local-set-key (kbd "C-l")
    (run-this-in-eshell "clear 1"))))

(with-eval-after-load 'esh-opt
  (setq eshell-destroy-buffer-when-process-dies t)
  (setq eshell-visual-commands '("htop" "zsh" "vim")))

(use-package eshell-syntax-highlighting
  :after esh-mode
  :config
  (eshell-syntax-highlighting-global-mode 1))

(use-package eshell-toggle
  :after eshell
  :bind ("C-M-'" . eshell-toggle)
  :custom
  (eshell-toggle-size-fraction 3)
  (eshell-toggle-use-projectile-root t)
  (eshell-toggle-run-command nil))

(use-package ediff)
;; don't start another frame
;; this is done by default in prelude


@@ 875,22 713,6 @@
    ;; save after adding comment
    (advice-add 'pdf-annot-edit-contents-commit :after 'bjm/save-buffer-no-args)))

(use-package xkcd)

(use-package sx
  :config
  (bind-keys :prefix "C-c s"
             :prefix-map my-sx-map
             :prefix-docstring "Global keymap for SX."
             ("q" . sx-tab-all-questions)
             ("i" . sx-inbox)
             ("o" . sx-open-link)
             ("u" . sx-tab-unanswered-my-tags)
             ("a" . sx-ask)
             ("s" . sx-search)))

(use-package ledger-mode)

(use-package dockerfile-mode
  :mode "Dockerfile\\'")



@@ 1015,46 837,11 @@
;; (use-package screenshot
;;   :straight (:host github :repo "tecosaur/screenshot"))

(use-package system-packages
  :custom
  (system-packages-package-manager 'paru) ;; For Arch
  ;; (system-packages-package-manager 'xbps) ;; For Void
  ;; (system-packages-package-manager 'nix) ;; For Nix/LFS
  :config
  (add-to-list 'system-packages-supported-package-managers
               '(paru .
                        ((default-sudo . nil)
                         (install . "paru -S")
                         (search . "paru -Ss")
                         (uninstall . "paru -Rs")
                         (update . "paru -Syu")
                         (clean-cache . "paru -Sc")
                         (log . "cat /var/log/pacman.log")
                         (change-log . "paru -Qc")
                         (get-info . "paru -Qi")
                         (get-info-remote . "paru -Si")
                         (list-files-provided-by . "paru -Ql")
                         (owning-file . "paru -Qo")
                         (owning-file-remote . "paru -F")
                         (verify-all-packages . "paru -Qkk")
                         (verify-all-dependencies . "paru -Dk")
                         (remove-orphaned . "paru -Rns $(pacman -Qtdq)")
                         (list-installed-packages . "paru -Qe")
                         (list-installed-packages-all . "paru -Q")
                         (list-dependencies-of . "paru -Qi")
                         (noconfirm . "--noconfirm")))))

(use-package ledger-mode)

(use-package flycheck-ledger
  :after ledger-mode)

(add-to-list 'load-path "/usr/share/emacs/site-lisp/") ; Arch Linux path
(require 'lilypond-mode)
(add-to-list 'auto-mode-alist '("\\.ly$" . LilyPond-mode))

(add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock)))

(use-package elfeed
  :config
  (setq elfeed-use-curl t))


@@ 1086,66 873,11 @@
  (setq elfeed-autotag-files '("~/Nextcloud/org/elfeed.org"))
  (elfeed-autotag))

(use-package wttrin
  :custom
  (wttrin-default-cities '("Lancaster")))

(use-package pulseaudio-control
  :init
  (pulseaudio-control-default-keybindings))

;; (use-package ytel
;;   :custom
;;   (ytel-invidious-api-url "https://invidious.exonip.de")
;;   :config
;;   (defun ytel-watch ()
;;     "Stream video at point in mpv."
;;     (interactive)
;;     (let* ((video (ytel-get-current-video))
;;      	     (id    (ytel-video-id video)))
;;       (start-process "ytel mpv" nil
;; 		                 "mpv"
;; 		                 (concat "https://www.youtube.com/watch?v=" id))
;; 		  "--ytdl-format=bestvideo[height<=?720]+bestaudio/best")
;;     (message "Starting streaming..."))

;;   (define-key ytel-mode-map "y" #'ytel-watch))

;; (use-package ytel-show
;;   :after ytel
;;   :bind (:map ytel-mode-map ("RET" . ytel-show)))

(use-package nov
  :config
  (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)))

(use-package scad-mode)
(use-package scad-preview)

(use-package simple-httpd)

(use-package emms
  :custom
  (emms-source-file-default-directory "~/Nextcloud/Music/")
  (emms-info-functions '(emms-info-tinytag))
  (emms-browser-covers 'emms-browser-cache-thumbnail-async)
  :config
  (emms-all)
  (emms-default-players))

(use-package subsonic
  :commands subsonic
  :bind (("C-c m" . subsonic))
  :custom
  (subsonic-url "music.danielr.xyz")
  (subsonic-enable-art nil)
  (subsonic-host "music.danielr.xyz"))

(use-package elpher)
;; Fixes gemini timeout
(setq gnutls-verify-error t)
(setq elpher-use-tls t)

(setq catster/use-mail t)

(when catster/use-mail


@@ 1378,9 1110,6 @@

(use-package arduino-mode)

(use-package clojure-mode)
(use-package cider)

(use-package typescript-mode
  :hook (typescript-mode . (lambda () (electric-indent-local-mode -1) (setq-local create-lockfiles nil)))
  :init


@@ 1492,9 1221,6 @@
 '(org-level-4 ((t (:foreground "#0ABDA0"))))
 '(org-level-5 ((t (:foreground "#80ADD7")))))

(setq org-latex-pdf-process
      '("tectonic %f"))

(use-package org-superstar
  :diminish org-superstar-mode
  :hook (org-mode . org-superstar-mode))


@@ 1534,36 1260,17 @@
         "DONE(d)"           ; Task has been completed
         "CANCELLED(c)"))) ; Task has been cancelled

(setq calc-angle-mode 'rad  ; radians are rad, fuck degrees
(setq calc-angle-mode 'rad  ; radians are rad, screw degrees
      calc-symbolic-mode t) ; keeps expressions like \sqrt{2} irrational for as long as possible

(org-indent-mode 1)

(use-package ox-gemini)

;; I used to use aspell, but I find proselint to be more accurate for English
;; Install using `pip install proselint` or through your package manager
(flycheck-define-checker proselint
  "A linter for prose."
  :command ("proselint" source-inplace)
  :error-patterns
  ((warning line-start (file-name) ":" line ":" column ": "
            (id (one-or-more (not (any " "))))
            (message (one-or-more not-newline)
                     (zero-or-more "\n" (any " ") (one-or-more not-newline)))
            line-end))
  :modes (text-mode markdown-mode gfm-mode org-mode))

;; Word choice and such
(use-package writegood-mode
  :bind ("C-c g" . writegood-mode)
  :config
  (add-to-list 'writegood-weasel-words "actionable"))

;; Export to GitHub flavored markdown
(use-package ox-gfm
  :after org)

;; Various good settings
(setq org-agenda-window-setup (quote current-window)) ;; open agenda in current window
(setq org-deadline-warning-days 7) ;; warn me of any deadlines in next 7 days


@@ 1588,22 1295,16 @@

(use-package ob-hy)
(use-package ob-rust)
(use-package ob-clojurescript)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((arduino . t)
   (C . t)
   (clojure . t)
   (clojurescript . t)
   (emacs-lisp . t)
   (gnuplot . t)
   (haskell . t)
   (hy . t)
   (js . t)
   (latex . t)
   (ledger . t)
   (lilypond . t)
   (lisp . t)
   (python . t)
   (rust . t)