Skip to content

My literate emacs config

Notifications You must be signed in to change notification settings

sidmitra/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 

Repository files navigation

Emacs Configuration

This is my emacs config written as a literate program via org-babel.

Initialize

Enable built-in package upgrades

Magit requires ‘transient’ >= 0.5.0, but due to bad defaults, Emacs’ package manager, refuses to upgrade this and other built-in packages to higher releases from GNU Elpa.

(setq package-install-upgrade-built-in t)
(use-package transient)

Perf config

Adjust gc-cons-threshold. The default setting is too low for lsp-mode’s needs due to the fact that client/server communication generates a lot of memory/garbage.

  ;; Set garbage collection threshold to 1GB
(setq gc-cons-threshold #x40000000)

;;  See when GC is running
(setq garbage-collection-messages t)

(run-with-idle-timer 300 t 'garbage-collect)

;; https://news.ycombinator.com/item?id=39190110
;; Following worked on MacOSx, but on archlinux+gnome it does gc on every
;; click!
;; (add-function :after
;;             after-focus-change-function
;;             (lambda ()
;;               (unless (frame-focus-state)
;;                 ;; Check if the frame state changed from focused to unfocused
;;                 (if (not (frame-focus-state))
;;                     (garbage-collect)))))

;; (add-function :after after-focus-change-function
;;             (lambda ()
;;               (when (not (frame-focus-state))
;;                 (garbage-collect))))

https://github.com/hlissner/doom-emacs/wiki/FAQ#how-is-dooms-startup-so-fast

(setq-default lexical-binding t
            load-prefer-newer t)

Increase the amount of data which Emacs reads from the process. Again the emacs default is too low 4k considering that the some of the language server responses are in 800k - 3M range.

(setq read-process-output-max (* 1024 1024)) ;; 1mb

Post Init

Disable Command/Super Key on Mac systems

Do this early, before any mappings are added. This is a problem on Macbook where option and command is weirdly placed.

(defun global-unset-all-super-key ()
  "Will unset any single key in global keymap that has the super modifier."
  (let ((km (current-global-map)))
    (while km
      (let ((maybe-event (and (listp (car km))
                              (caar km))))
        (if (and (eventp maybe-event) ; Also filters maybe-event when
                                        ; nil because (car km) was not a list.
                 (memq 'super (event-modifiers maybe-event)))
            (global-unset-key (vector maybe-event))))
      (setq km (cdr km)))))

(provide 'global-unset-all-super-key)

(when (string-equal system-type "darwin")
  (require 'global-unset-all-super-key)
  (global-unset-all-super-key))

Inhibit compacting font Cache

(setq inhibit-compacting-font-caches t)

Turn off ad-handle-definition: `tramp-read-passwd’ got redefined

(setq ad-redefinition-action 'accept)

Change “yes or no” to “y or n”

Not working anymore???

(setopt use-short-answers t)

Shell/exec-path-from-shell

https://github.com/wyuenho/emacs-pet

(use-package exec-path-from-shell
  :if (memq (window-system) '(mac ns))
  :config (exec-path-from-shell-initialize))

Character Encodings

(set-default-coding-systems 'utf-8)
;; (set-keyboard-coding-system 'utf-8)
;; (set-language-environment 'utf-8)
;; (setq locale-coding-system 'utf-8)
;; (set-selection-coding-system 'utf-8)
;; (set-terminal-coding-system 'utf-8)
;; (prefer-coding-system 'utf-8)
;; (when (display-graphic-p)
;;   (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))

;; Set default coding system for new files to UTF-8 with Unix EOL
(prefer-coding-system 'utf-8-unix)
(setq default-buffer-file-coding-system 'utf-8-unix)

;; Automatically convert EOL style to Unix when opening existing files
(add-hook 'find-file-hook
          (lambda ()
            (when (eq buffer-file-coding-system 'undecided)
              (set-buffer-file-coding-system 'utf-8-unix))))

Config Helpers

Enable minor mode

(defun enable-minor-mode (my-pair)
  "Enable minor mode if filename match the regexp.  MY-PAIR is a cons cell (regexp . minor-mode)."
  (if (buffer-file-name)
      (if (string-match (car my-pair) buffer-file-name)
          (funcall (cdr my-pair)))))

Appearance/Visual

Icons

all-the-icons

https://github.com/domtronn/all-the-icons.el

Run M-x all-the-icons-install-fonts

(defun install-all-the-icons-fonts-if-missing ()
  "Install all-the-icons fonts if they are not already installed."
  (unless (file-exists-p (expand-file-name "~/.local/share/fonts/all-the-icons.ttf"))
    (all-the-icons-install-fonts t)))

(use-package all-the-icons
  :if (display-graphic-p)
  :config
  (install-all-the-icons-fonts-if-missing)
  )

nerd-icons

(use-package nerd-icons)

Load colour theme

ef-themes

(use-package ef-themes
  :config
  (setq ef-themes-to-toggle '(ef-maris-light ef-maris-dark))
  (setq ef-themes-mixed-fonts t
    ef-themes-variable-pitch-ui t)
  (mapc #'disable-theme custom-enabled-themes)
  (load-theme 'ef-maris-dark :no-confirm)
  )

Fonts

(use-package unicode-fonts
  :config
  (unicode-fonts-setup))

Enable emoji font https://old.reddit.com/r/emacs/comments/mvlid5/native_emojis_in_emacs_just_some_pure_fun/

;; Emoji: 😄, 🤦, 🏴󠁧󠁢󠁳󠁣󠁴󠁿
(set-fontset-font t 'symbol "Apple Color Emoji")
(set-fontset-font t 'symbol "Noto Color Emoji" nil 'append)
(set-fontset-font t 'symbol "Segoe UI Emoji" nil 'append)
(set-fontset-font t 'symbol "Symbola" nil 'append)

Set font, size

Set font and size

;; (set-frame-font "Hack 14")
;; (set-frame-font "CommitMono 14")
(set-frame-font "JetBrains Mono 16")

Change font-size with ctrl + mouse wheel

(global-set-key (vector (list 'control mouse-wheel-down-event)) 'text-scale-increase)
(global-set-key (vector (list 'control mouse-wheel-up-event))   'text-scale-decrease)

Hide welcome message

(setq inhibit-startup-message t)

Hide initial scratch buffer message

(setq initial-scratch-message nil)

Hide toolbar

(if window-system
    (tool-bar-mode -1))
(if window-system
    (menu-bar-mode -1))
;; Remove the GNOME title bars
;; (add-to-list 'default-frame-alist '(undecorated . t))

Hide scrollbar

(scroll-bar-mode -1)

Update Titlebar appearance

Is this working? Worked once, but not now.

(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))

Switch window to fullscreen

(add-to-list 'default-frame-alist '(fullscreen . maximized))

Disable emacs window disappearing on Ctrl-z

(global-unset-key (kbd "C-z"))

Simplify whitespace style

(setq-default whitespace-style (quote (spaces tabs newline space-mark tab-mark newline-mark)))

Enable soft-wrap lines

(global-visual-line-mode t)

Enable smooth scrolling

;;(use-package smooth-scrolling)
;;(setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling

(setq scroll-conservatively 101) ;; move minimum when cursor exits view, instead of recentering
(setq mouse-wheel-scroll-amount '(5)) ;; mouse scroll moves 1 line at a time, instead of 5 lines
(setq mouse-wheel-progressive-speed nil) ;; on a long mouse scroll keep scrolling by 1 line

Change cursor from box to bar

(setq-default cursor-type 'bar)

Highlight syntax

Apply syntax highlighting to all buffers

(global-font-lock-mode t)

Highlight current line

(global-hl-line-mode +1)

Highlight indentation

(use-package highlight-indent-guides
  :config
  ;; values are fill, column, character, and bitmap
  (setq highlight-indent-guides-method 'column)
  (set-face-background 'highlight-indent-guides-odd-face "darkgray")
  (set-face-background 'highlight-indent-guides-even-face "dimgray")
  (set-face-foreground 'highlight-indent-guides-character-face "dimgray")
  (add-hook 'prog-mode-hook 'highlight-indent-guides-mode))

Highlight delimiters

Show matching parentheses with 0 delay

(show-paren-mode 1)
(setq-default show-paren-delay 0)

rainbow-mode

Highlight matching delimiters parens, brackets, and braces with different colors https://www.emacswiki.org/emacs/RainbowDelimiters

(use-package rainbow-delimiters
  :config
  (progn
    (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)))

Highlight hex color strings

This minor mode sets background color to strings that match color. https://elpa.gnu.org/packages/rainbow-mode.html

(use-package rainbow-mode
  :hook (css-mode sass-mode scss-mode web-mode html-mode))

Manage layout

Save window layout history.

(winner-mode 1)

Show line/col Numbers

Show Line col numbers

(use-package nlinum
  :config
  (add-hook 'prog-mode-hook 'nlinum-mode))

nlinum-hl [tries to] remedy an issue in nlinum where line numbers disappear, due to a combination of bugs internal to nlinum and the fontification processes of certain major-modes and commands. Load this after nlinum

(use-package nlinum-hl)

Update line numbers format to avoid graphics glitches in fringe

(setq-default linum-format " %4d ")

Show column numbers

;; show column number
(setq-default column-number-mode t)

Style the modeline

Minion

(use-package minions
  :config
  (minions-mode 1))

Mode Icons

(use-package mode-icons
  :config
  (mode-icons-mode))

Dim other buffers

https://github.com/mina86/auto-dim-other-buffers.el The auto-dim-other-buffers-mode is a global minor mode which makes windows without focus less prominent. With many windows in a frame, the idea is that this mode helps recognise which is the selected window by providing a non-intrusive but still noticeable visual indicator.

(use-package auto-dim-other-buffers
  :config
  (auto-dim-other-buffers-mode t)
  )

Screensaver

Zone mode

https://www.emacswiki.org/emacs/ZoneMode

(defun zone-choose (pgm)
 "Choose a PGM to run for `zone'."
 (interactive
  (list
   (completing-read
    "Program: "
    (mapcar 'symbol-name zone-programs))))
 (let ((zone-programs (list (intern pgm))))
   (zone)))

zone-words

https://xenodium.com/emacs-zones-to-lift-you-up/

brew install wordnet

(use-package zone-words
  :ensure (zone-words :type git :host github :repo "xenodium/dotsies" :files ("emacs/ar/zone-words*"))
  )

zone-nyan

(use-package zone-nyan
  :after zone
  :ensure t
  :commands zone-mode)

zone-rainbow

(use-package zone-rainbow :ensure t
:after zone
:config
(setq zone-programs (vconcat [zone-rainbow] zone-programs)))

Editing

Set default tab char’s display width to 4 spaces

(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)
;; make tab key always call a indent command.
;; (setq-default tab-always-indent t)
;; make tab key call indent command or insert tab character, depending on cursor position
;; (setq-default tab-always-indent nil)
;; make tab key do indent first then completion.
(setq-default tab-always-indent 'complete)

Set fill-column

(setq-default fill-column 88)

Delete trailing whitespace before saving

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Copy/paste

Enable clipboard

(setq select-enable-clipboard t)

Save Interprogram paste

https://www.reddit.com/r/emacs/comments/30g5wo/the_kill_ring_and_the_clipboard/

(setq save-interprogram-paste-before-kill t)

browse-kill-ring

Look through everything you’ve killed recently https://github.com/browse-kill-ring/browse-kill-ring

(use-package browse-kill-ring)

Overwrite active region

(delete-selection-mode t)

Indent new line automatically on ENTER

(global-set-key (kbd "RET") 'newline-and-indent)

Duplicate current line

(defun duplicate-line()
  (interactive)
  (move-beginning-of-line 1)
  (kill-line)
  (yank)
  (open-line 1)
  (next-line 1)
  (yank)
  )

(global-set-key (kbd "C-c d") 'duplicate-line)

Insert pair of chars

(global-set-key (kbd "M-[") 'insert-pair)
(global-set-key (kbd "M-{") 'insert-pair)
(global-set-key (kbd "M-\"") 'insert-pair)

Multiple Cursors

(use-package multiple-cursors
  :config
  (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines))

Sorting lines

(global-set-key (kbd "C-c M-s") 'sort-lines)

Region

Operate on whole line or region

https://github.com/purcell/whole-line-or-region/

This minor mode allows functions to operate on the current line if they would normally operate on a region and region is currently undefined.

(use-package whole-line-or-region)

Enable moving line or region, up or down

(use-package move-text
  :config
  (move-text-default-bindings))

Expand region

(use-package expand-region
  :config
  (global-set-key (kbd "C-=") 'er/expand-region))

Commenting

https://github.com/remyferre/comment-dwim-2 comment-dwim-2 is a replacement for the Emacs’ built-in command comment-dwim

(use-package comment-dwim-2
  :config
  (global-set-key (kbd "M-;") 'comment-dwim-2))

Key Bindings

Utilities/helpers for key-bindings.

Which Key

Main

(use-package which-key
  :defer 0.2
  :diminish
  :config (which-key-mode))

which-key-posframe

This package is a emacs-which-key extension, which use posframe to show which-key popup.

(use-package which-key-posframe
  :config
  (which-key-posframe-mode))

Buffers

Backup

Force emacs to save backups to a specific directory.

(setq make-backup-files nil) ; stop creating backup~ files
(setq auto-save-default nil) ; stop creating #autosave# files
(setq create-lockfiles nil)  ; stop creating .#lock file links

(setq backup-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*" ,temporary-file-directory t)))

(setq backup-by-copying t    ; Don't delink hardlinks
      version-control t      ; Use version numbers on backups
      delete-old-versions t  ; Automatically delete excess backups
      kept-new-versions 20   ; how many of the newest versions to keep
      kept-old-versions 5    ; and how many of the old
      )

(defun force-backup-of-buffer ()
  "Make a special 'per session' backup at the first save of each Emacs session."
  (when (not buffer-backed-up)
    ;; Override the default parameters for per-session backups.
    (let ((backup-directory-alist '(("" . temporary-file-directory)))
          (kept-new-versions 3))
      (backup-buffer)))
  ;; Make a "per save" backup on each save.  The first save results in
  ;; both a per-session and a per-save backup, to keep the numbering
  ;; of per-save backups consistent.
  (let ((buffer-backed-up nil))
    (backup-buffer)))

Force backup of buffer before saving.

(add-hook 'before-save-hook  'force-backup-of-buffer)

Kill buffer without confirmation

(defun volatile-kill-buffer ()
  "Kill current buffer unconditionally."
  (interactive)
  (let ((buffer-modified-p nil))
    (kill-buffer (current-buffer))))
(global-set-key (kbd "C-x k") 'volatile-kill-buffer)

Refresh buffer from filesystem periodically

(global-auto-revert-mode t)

Show current file path

(defun show-file-name ()
  "Show the full path file name in the minibuffer."
  (interactive)
  (message (buffer-file-name)))
(global-set-key [C-f1] 'show-file-name)

Tools

Offline docs

https://github.com/astoff/devdocs.el devdocs.el is a documentation viewer for Emacs similar to the built-in Info browser, but geared towards documentation distributed by the https://devdocs.io/ website. Currently, this covers over 500 versions of 188 different software components.

M-x devdocs-install

;; Define the installation function outside of the use-package block
(defun my-devdocs-install ()
  "Install documentation sets defined in `my-devdocs-docs-list` if not already installed."
  (interactive)
  (require 'devdocs) ;; Ensure devdocs is loaded
  (dolist (doc my-devdocs-docs-list)
    (unless (member doc (devdocs--installed-docs))
      (devdocs-install doc))))

;; Ensure my-devdocs-docs-list is defined before use
(defvar my-devdocs-docs-list
  '("django~5.0" "rust" "django_rest_framework")
  "List of documentation sets to install in devdocs.")

(use-package devdocs
  :ensure t
  :commands (devdocs-install devdocs-peruse devdocs-lookup)
  :config
  ;; Automatically call the installation function on startup
  (my-devdocs-install)

  (global-set-key (kbd "C-h D") 'devdocs-lookup)
  )

Spell check

https://github.com/minad/jinx

brew install enchant pkgconf
(use-package jinx
  ;; :hook (emacs-startup . global-jinx-mode)
  ;; :bind (("M-$" . jinx-correct)
  ;;        ("C-M-$" . jinx-languages))
  )

Auth

(add-to-list 'auth-sources "~/.authinfo" t)
(require 'auth-source)

Project Navigation

Bookmarks

https://github.com/joodland/bm

(use-package bm
  :demand t

  :init
  ;; restore on load (even before you require bm)
  (setq bm-restore-repository-on-load t)


  :config
  ;; Allow cross-buffer 'next'
  (setq bm-cycle-all-buffers t)

  ;; where to store persistant files
  (setq bm-repository-file "~/.emacs.d/bm-repository")

  ;; save bookmarks
  (setq-default bm-buffer-persistence t)

  ;; Loading the repository from file when on start up.
  (add-hook' after-init-hook 'bm-repository-load)

  ;; Restoring bookmarks when on file find.
  (add-hook 'find-file-hooks 'bm-buffer-restore)

  ;; Saving bookmarks
  (add-hook 'kill-buffer-hook #'bm-buffer-save)

  ;; Saving the repository to file when on exit.
  ;; kill-buffer-hook is not called when Emacs is killed, so we
  ;; must save all bookmarks first.
  (add-hook 'kill-emacs-hook #'(lambda nil
                                 (bm-buffer-save-all)
                                 (bm-repository-save)))

  ;; The `after-save-hook' is not necessary to use to achieve persistence,
  ;; but it makes the bookmark data in repository more in sync with the file
  ;; state.
  (add-hook 'after-save-hook #'bm-buffer-save)

  ;; Restoring bookmarks
  (add-hook 'find-file-hooks   #'bm-buffer-restore)
  (add-hook 'after-revert-hook #'bm-buffer-restore)

  ;; The `after-revert-hook' is not necessary to use to achieve persistence,
  ;; but it makes the bookmark data in repository more in sync with the file
  ;; state. This hook might cause trouble when using packages
  ;; that automatically reverts the buffer (like vc after a check-in).
  ;; This can easily be avoided if the package provides a hook that is
  ;; called before the buffer is reverted (like `vc-before-checkin-hook').
  ;; Then new bookmarks can be saved before the buffer is reverted.
  ;; Make sure bookmarks is saved before check-in (and revert-buffer)
  (add-hook 'vc-before-checkin-hook #'bm-buffer-save)

  ;; Use mouse + left fring to handle bookmarks
  (global-set-key (kbd "<left-fringe> <mouse-1>") 'bm-toggle-mouse)
  (global-set-key (kbd "C-<mouse-4>") 'bm-next-mouse)
  ;; (global-set-key (kbd "C-<mouse-3>") 'bm-previous-mouse)

  ;; fix Lisp nesting exceeds ‘max-lisp-eval-depth’ in bm-count
  (setq max-lisp-eval-depth 10000)

  :bind (("C-x p n" . bm-next)
         ("C-x p p" . bm-previous)
         ("C-x p t" . bm-toggle))
  )

;; HACK: To make bm work in emacs-29
;; https://github.com/joodland/bm/issues/45
;; (defun bm-lists (&optional direction predicate)
;;   "Return a pair of lists giving all the bookmarks of the current buffer.
;; The car has all the bookmarks before the overlay center;
;; the cdr has all the bookmarks after the overlay center.
;; A bookmark implementation of `overlay-lists'.

;; If optional argument DIRECTION is provided, only return bookmarks
;; in the specified direction.

;; If optional argument PREDICATE is provided, it is used as a
;; selection criteria for filtering the lists."
;;   (if (null predicate)
;;       (setq predicate 'bm-bookmarkp))

;;   (overlay-recenter (point))
;;   (cond ((equal 'forward direction)
;;          (cons nil (remq nil (mapcar predicate (overlays-in (point) (point-max))))))
;;         ((equal 'backward direction)
;;          (cons (remq nil (mapcar predicate (overlays-in (point-min) (point)))) nil))
;;         (t
;;          (cons
;;           (remq nil (mapcar predicate (overlays-in (point-min) (point))))
;;           (remq nil (mapcar predicate (overlays-in (point) (point-max))))))))

;; https://github.com/elbeno/dotemacs/blob/94208542da779372fd44fd693204089601dcf824/.emacs.d/hacks.el#L114
(defun sm/bm-lists (&optional direction predicate)
  "Return a pair of lists giving all the bookmarks of the current buffer.
The car has all the bookmarks before the overlay center;
the cdr has all the bookmarks after the overlay center.
A bookmark implementation of `overlay-lists'.

If optional argument DIRECTION is provided, only return bookmarks
in the specified direction.

If optional argument PREDICATE is provided, it is used as a
selection criteria for filtering the lists."
  (if (null predicate)
      (setq predicate 'bm-bookmarkp))

  (overlay-recenter (point))
  (cond ((equal 'forward direction)
         (cons nil (remq nil (mapcar predicate (overlays-in (point) (point-max))))))
        ((equal 'backward direction)
         (cons (remq nil (mapcar predicate (overlays-in (point-min) (point)))) nil))
        (t
         (cons
          (remq nil (mapcar predicate (overlays-in (point-min) (point))))
          (remq nil (mapcar predicate (overlays-in (point) (point-max))))))))

(advice-add #'bm-lists
            :override #'sm/bm-lists)

projectile

(use-package projectile
  :diminish projectile-mode
  :init
  (setq projectile-keymap-prefix (kbd "C-c p"))
  :config
  (projectile-global-mode)
  (setq projectile-completion-system 'default)
  (setq projectile-enable-caching t)
  (setq projectile-indexing-method 'alien)
  )

dump-jump

(use-package dumb-jump
  :config
  ;; enable the xref backend, evaluate
  (add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
  ;; Use completing-read to select a target. That way a completion framework of your choice (Icomplete, Helm, Ivy, ...) will be used instead of the default pop-up buffer. To do this, evaluate
  (setq xref-show-definitions-function #'xref-show-definitions-completing-read)
  )

neotree

(use-package neotree
  :config
  (global-set-key [f8] 'neotree-toggle)
  (setq neo-smart-open t)
  (setq-default neo-show-hidden-files t)
  ;; (setq neo-theme 'icons)
  ;; (setq projectile-switch-project-action 'neotree-projectile-action)
  )

(defun text-scale-twice ()(interactive)(progn(text-scale-adjust 0)(text-scale-decrease 2)))
(add-hook 'neo-after-create-hook (lambda (_)(call-interactively 'text-scale-twice)))

recentf

https://www.emacswiki.org/emacs/RecentFiles Recentf is a minor mode that builds a list of recently opened files. This list is is automatically saved across sessions on exiting Emacs - you can then access this list through a command or the menu.

(recentf-mode 1)
(setq recentf-max-menu-items 25)
(setq recentf-max-saved-items 25)
;;(global-set-key "\C-x\ \C-r" 'recentf-open-files)

Incremental narrowing, completion

Some of the packages are confusing. This thread helps https://www.reddit.com/r/emacs/comments/1bz0ekn/company_vertico_corfu_corfusion/

corfu

https://github.com/minad/corfu

(use-package corfu
  ;; Optional customizations
  ;; :custom
  ;; (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  ;; (corfu-auto t)                 ;; Enable auto completion
  ;; (corfu-separator ?\s)          ;; Orderless field separator
  ;; (corfu-quit-at-boundary nil)   ;; Never quit at completion boundary
  ;; (corfu-quit-no-match nil)      ;; Never quit, even if there is no match
  ;; (corfu-preview-current nil)    ;; Disable current candidate preview
  ;; (corfu-preselect 'prompt)      ;; Preselect the prompt
  ;; (corfu-on-exact-match nil)     ;; Configure handling of exact matches
  ;; (corfu-scroll-margin 5)        ;; Use scroll margin

  ;; Enable Corfu only for certain modes. See also `global-corfu-modes'.
  ;; :hook ((prog-mode . corfu-mode)
  ;;        (shell-mode . corfu-mode)
  ;;        (eshell-mode . corfu-mode))

  ;; Recommended: Enable Corfu globally.  This is recommended since Dabbrev can
  ;; be used globally (M-/).  See also the customization variable
  ;; `global-corfu-modes' to exclude certain modes.
  :init
  (global-corfu-mode)
  :config
  (setq-default corfu-auto t
                corfu-quit-no-match 'separator) ;; or t
  )

vertico

(use-package vertico
  :config
  (vertico-mode)
  ;; Different scroll margin
  (setq vertico-scroll-margin 0)

  ;; Show more candidates
  (setq vertico-count 20)

  ;; Grow and shrink the Vertico minibuffer
  (setq vertico-resize t)

  ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
  (setq vertico-cycle t)
  )

orderless

https://github.com/oantolin/orderless This package provides an orderless completion style that divides the pattern into space-separated components, and matches candidates that match all of the components in any order. Each component can match in any one of several ways: literally, as a regexp, as an initialism, in the flex style, or as multiple word prefixes. By default, regexp and literal matches are enabled.

(use-package orderless
  :config
  ;; :init (icomplete-mode) ; optional but recommended!

  ;; Configure a custom style dispatcher (see the Consult wiki)
  ;; (setq orderless-style-dispatchers '(+orderless-dispatch)
  ;;       orderless-component-separator #'orderless-escapable-split-on-space)
  (setq completion-styles '(orderless)
        completion-category-defaults nil
        completion-category-overrides '((file (styles . (partial-completion))))))

prescient

Simple but effective sorting and filtering for Emacs. https://github.com/raxod502/prescient.el

prescient.el is a library which sorts and filters lists of candidates, such as appear when you use a package like Ivy or Company. Extension packages such as ivy-prescient.el and company-prescient.el adapt the library for usage with various frameworks.

prescient.el also provides a completion style (prescient) for filtering candidates via Emacs’s generic completion, such as in Icomplete, Vertico, and Corfu. These last two have extension packages to correctly set up filtering and sorting.

(use-package prescient)
(use-package vertico-prescient
  :config
  ;; cause Vertico to use prescient.el
  (vertico-prescient-mode t)

  ;; usage statistics to be saved between Emacs sessions
  (prescient-persist-mode t)
  )

(use-package company-prescient
  :after company
  :config
  (company-prescient-mode t))

marginalia

Marginalia are marks or annotations placed at the margin of the page of a book or in this case helpful colorful annotations placed at the margin of the minibuffer for your completion candidates. Marginalia can only add annotations to be displayed with the completion candidates. It cannot modify the appearance of the candidates themselves, which are shown as supplied by the original commands.

https://github.com/minad/marginalia

(use-package marginalia
  :bind (:map minibuffer-local-map
              ("C-M-a" . marginalia-cycle)
              ;; When using the Embark package, you can bind `marginalia-cycle' as an Embark action!
              ;;:map embark-general-map
              ;;     ("A" . marginalia-cycle)
              )

  ;; The :init configuration is always executed (Not lazy!)
  :config

  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode)

  ;; Prefer richer, more heavy, annotations over the lighter default variant.
  ;; E.g. M-x will show the documentation string additional to the keybinding.
  ;; By default only the keybinding is shown as annotation.
  ;; Note that there is the command `marginalia-cycle' to
  ;; switch between the annotators.
  ;; (setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
  )

embark

https://github.com/oantolin/embark/

(use-package embark
  :bind
  (("C-." . embark-act)
   ("C-;" . embark-dwim)
   ("C-h B;" . embark-bindings))
  :init
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  :config


  ;; Hide the mode line of the Embark live/completions buffers
  ;; (add-to-list 'display-buffer-alist
  ;;              '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
  ;;                nil
  ;;                (window-parameters (mode-line-format . none))))
  )

embark-consult

(use-package embark-consult
  :after (embark consult)
  :demand t ; only necessary if you have the hook below
  ;; if you want to have consult previews as you move around an
  ;; auto-updating embark collect buffer
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

consult

https://github.com/minad/consult Consult provides practical commands based on the Emacs completion function completing-read. Completion allows you to quickly select an item from a list of candidates. Consult offers in particular an advanced buffer switching command consult-buffer to switch between buffers and recently opened files.

(use-package consult
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (("C-x M-:" . consult-complex-command)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-x b" . consult-buffer)
         ("C-x 4 b" . consult-buffer-other-window)
         ("C-x 5 b" . consult-buffer-other-frame)
         ("C-x r x" . consult-register)
         ("C-x r b" . consult-bookmark)
         ("M-g g" . consult-goto-line)
         ("M-g M-g" . consult-goto-line)
         ("M-g o" . consult-outline)       ;; "M-s o" is a good alternative.
         ("M-g l" . consult-line)          ;; "M-s l" is a good alternative.
         ("M-g m" . consult-mark)          ;; I recommend to bind Consult navigation
         ("M-g k" . consult-global-mark)   ;; commands under the "M-g" prefix.
         ("M-g r" . consult-ripgrep)      ;; or consult-grep, consult-ripgrep
         ("M-g f" . consult-find)          ;; or consult-locate, my-fdfind
         ("M-g i" . consult-project-imenu) ;; or consult-imenu
         ("M-g e" . consult-error)
         ("M-s m" . consult-multi-occur)
         ("M-y" . consult-yank-pop)
         ("<help> a" . consult-apropos))

  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI.
  :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy!)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Not sure where this was used? Maybe an old experiment?
  ;; ;; Custom command wrappers. It is generally encouraged to write your own
  ;; ;; commands based on the Consult commands. Some commands have arguments which
  ;; ;; allow tweaking. Furthermore global configuration variables can be set
  ;; ;; locally in a let-binding.
  ;; (defun my-fdfind (&optional dir)
  ;;   (interactive "P")
  ;;   (let ((consult-find-command '("fdfind" "--color=never" "--full-path")))
  ;;     (consult-find dir)))

  ;; ;; Replace `multi-occur' with `consult-multi-occur', which is a drop-in replacement.
  (fset 'multi-occur #'consult-multi-occur)

  ;; Configure other variables and modes in the :config section, after lazily loading the package
  :config
  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key "M-.")
  ;; (setq consult-preview-key '("S-<down>" "S-<up>"))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme :preview-key '(:debounce 0.2 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-file-register
   consult--source-recent-file consult--source-project-recent-file
   ;; :preview-key "M-."
   :preview-key '(:debounce 0.4 any))

  ;; Optionally configure narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  ;; Optionally configure a function which returns the project root directory
  (autoload 'projectile-project-root "projectile")
  (setq consult-project-root-function #'projectile-project-root)
  )

;; TODO Install and figure out consult-vertico

;; Optionally add the `consult-flycheck' command.
(use-package consult-flycheck
  :bind (:map flycheck-command-map
              ("!" . consult-flycheck)))

helpful

https://github.com/Wilfred/helpful Helpful is an alternative to the built-in Emacs help that provides much more contextual information.

(use-package helpful
  )

misc

(setq completion-cycle-threshold 3)

Search

ctrlf

CTRLF (pronounced “control F”) is an intuitive and efficient solution for single-buffer text search in Emacs. https://github.com/raxod502/ctrlf

(use-package ctrlf
  :config
  (ctrlf-mode +1))

thesilversearcher - ag

(use-package ag
  :config
  ;; (setq-default ag-reuse-window 't)
  (setq-default ag-reuse-buffers 't)
  (setq ag-highlight-search t)

  ;; (setq ag-ignore-list (quote (
  ;;                              "*migrations/*"
  ;;                              "*node_modules/*"
  ;;                              "*elpa/*"
  ;;                              "*lib/*"
  ;;                              "*build/*"
  ;;                              "*static/*"
  ;;                              )))
  (setq-default ag-arguments '(
                               "--smart-case"
                               "--stats"
                               "--ignore-dir" "migrations"
                               "--ignore-dir" "node_modules"
                               "--ignore-dir" "elpa"
                               "--ignore-dir" "lib"
                               "--ignore-dir" "build"
                               "--ignore" "*?.min.js"
                               "--ignore" "*?.map"
                               "--ignore" "*?.min.js"
                               "--ignore" "*?.min.css"
                               "--ignore" "*.csv"
                               "--ignore" "*.svg"
                               "--ignore" "*.json"
                               "--ignore" "*.yaml"
                               "--ignore" "*.yml"
                               ))
  (global-set-key "\C-c\C-g" 'ag-project))

deadgrep

https://github.com/Wilfred/deadgrep

(use-package deadgrep
  :config
  (global-set-key (kbd "<f5>") #'deadgrep))

fzf

(use-package fzf
  :bind
  ;; Don't forget to set keybinds!
  :config
  (setq fzf/args "-x --color bw --print-query --margin=1,0 --no-hscroll"
        fzf/executable "fzf"
        fzf/git-grep-args "-i --line-number %s"
        ;; command used for `fzf-grep-*` functions
        ;; example usage for ripgrep:
        fzf/grep-command "rg --no-heading -nH"
        ; fzf/grep-command "grep -nrH"
        ;; If nil, the fzf buffer will appear at the top of the window
        fzf/position-bottom t
        fzf/window-height 15))

Completion

(use-package company
  :config
  (add-hook 'after-init-hook 'global-company-mode)
  (setq company-idle-delay 0.2
        company-minimum-prefix-length 1
        company-selection-wrap-around t
        company-tooltip-align-annotations t
        company-tooltip-flip-when-above nil
        company-tooltip-limit 10
        company-tooltip-minimum 3
        company-tooltip-margin 1
        company-transformers '(company-sort-by-occurrence)
        company-dabbrev-downcase nil)

  ;; Add yasnippet support for all company backends
  ;; https://github.com/syl20bnr/spacemacs/pull/179
  (defvar company-mode/enable-yas t "Enable yasnippet for all backends.")
  (defun company-mode/backend-with-yas (backend)
    (if (or (not company-mode/enable-yas) (and (listp backend) (member 'company-yasnippet backend)))
        backend
      (append (if (consp backend) backend (list backend))
              '(:with company-yasnippet))))
  )
company-statistics

Company-statistics is a global minor mode built on top of the in-buffer completion system company-mode. The idea is to keep a log of a certain number of completions you choose, along with some context information, and use that to rank candidates the next time you have to choose — hopefully showing you likelier candidates at the top of the list.

(use-package company-statistics
  :config
  (company-statistics-mode))

undo-tree

;; Prevent undo tree files from polluting your git repo
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
(use-package undo-tree
  :config
  (global-undo-tree-mode 1))

Terminal

vterm

(use-package vterm
  :init
  (setq vterm-always-compile-module t)
  :config
  (setq vterm-buffer-name-string "%s"
        vterm-max-scrollback 100000
        vterm-kill-buffer-on-exit t)

  ;; Change the font in vterm buffers to a mono-spaced font (the fixed-pitch face)
  ;; if the default font in Emacs is a proportional font.
  (add-hook 'vterm-mode-hook
            (lambda ()
              (set (make-local-variable 'buffer-face-mode-face) 'fixed-pitch)
              (buffer-face-mode t)))

  ;; You can use another font for vterm buffer
  ;; (add-hook 'vterm-mode-hook
  ;;       (lambda ()
  ;;            (set (make-local-variable 'buffer-face-mode-face) '(:family "IosevkaTerm Nerd Font"))
  ;;            (buffer-face-mode t))
  )

vterm-eshell

An Emacs global minor mode allowing eshell to use vterm for visual commands. https://github.com/iostapyshyn/eshell-vterm

(use-package eshell-vterm
  :after eshell
  :config
  (eshell-vterm-mode))

better-shell

This package simplifies shell management and sudo access by providing the following commands. better-shell-for-current-dir better-shell-for-projectile-root - Like better-shell-for-current-dir, except you are taken to the projectile root of the current directory, provided you have projectile installed. better-shell-shell - cycle through existing shell buffers https://github.com/killdash9/better-shell

(use-package better-shell
  :bind (("C-'" . better-shell-shell)
         ;;("C-;" . better-shell-remote-open)
         ))

keyfreq

(use-package keyfreq
  :config
  (keyfreq-mode 1)
  (keyfreq-autosave-mode 1))

Programming

Snippets

(use-package yasnippet
  :config
  (yas-global-mode 1)
  (add-hook 'term-mode-hook (lambda()
                              (setq yas-dont-activate-functions t))))
(use-package yasnippet-snippets)

Formatting

Auto-format source code in many languages using the same command for all languages. https://github.com/lassik/emacs-format-all-the-code

(use-package format-all)

Version Control (git)

magit

(use-package magit
  :config
  (setq magit-auto-revert-mode nil)
  ;; (setq magit-last-seen-setup-instructions "1.4.0")
  )
(add-hook 'magit-log-edit-mode-hook
          '(lambda ()
             (shell-command "./.git/hooks/pre-commit")))

magit-delta

Use magit + delta to show diffs. https://github.com/dandavison/magit-delta

Install delta via instructions here: https://github.com/dandavison/delta

(use-package magit-delta
  :config
  (magit-delta-mode))

forge

Forge allows you to work with Git forges, such as Github and Gitlab

(use-package forge
  :after magit)

vc-msg

(use-package vc-msg)

browse-at-remote

(use-package browse-at-remote
  :bind ("C-c g g" . browse-at-remote)
  )

git-timemachine

(use-package git-timemachine
:ensure (git-timemachine :type git :host codeberg :repo "pidu/git-timemachine")
)

diff-hl

Highlights uncommitted changes on the left side of the window, allows you to jump between and revert them selectively.

(use-package diff-hl
  :config
  (global-diff-hl-mode)
  )

blamer

https://github.com/Artawower/blamer.el A git blame plugin for emacs inspired by VS Code’s GitLens plugin and Vim plugin

(use-package blamer
  :ensure (:host github :repo "artawower/blamer.el")
  :bind (("s-i" . blamer-show-posframe-commit-info))
  :custom
  (blamer-idle-time 0.3)
  (blamer-min-offset 70)
  :custom-face
  (blamer-face ((t :foreground "#7a88cf"
                   :background nil
                   :height 140
                   :italic t)))
  :config
  (setq blamer-show-avatar-p t)
  (global-blamer-mode 1))

Enviroment

mise

(use-package mise
  ;; enable globally
  ;; (add-hook 'after-init-hook #'global-mise-mode)

  ;; or turn on in some buffer
  ;; (add-hook 'emacs-lisp-mode-hook #'mise-mode)

  ;(global-mise-mode)
  )

dot-env

(use-package dotenv-mode
  :mode (("\\.env$" . dotenv-mode)))

flycheck

(use-package let-alist)
(use-package flycheck
  :init (global-flycheck-mode)
  :config
  (setq-default flycheck-checker-error-threshold 500)
  (setq-default flycheck-highlighting-mode 'lines)
  (setq-default flycheck-idle-change-delay 3)
  (setq-default flycheck-display-errors-delay 0))

SQL

Trying to figure if i need this for calibredb

(use-package emacsql)

Language Server Protocol (LSP)

lsp-bridge

https://github.com/manateelazycat/lsp-bridge

pip install epc orjson sexpdata six setuptools paramiko rapidfuzz pip install python-lsp-server[all]

(use-package lsp-bridge
  :ensure (
           :type git
           :host github
           :repo "manateelazycat/lsp-bridge"
           :files (:defaults "*.el" "*.py" "acm/*" "core/*" "langserver/*" "multiserver" "resources")
           :build (:not compile)
           )
  :defer t
  :init
  (setq lsp-bridge-python-lsp-server "pylsp")
  (setq lsp-bridge-enable-hover-diagnostic t)
  (setq lsp-bridge-enable-log t)
  (setq acm-backend-lsp-show-progress t)
  ; (global-lsp-bridge-mode)
  )

lsp-booster

https://github.com/blahgeek/emacs-lsp-booster

Python

Base

(use-package python
  :ensure nil ; because python is built-in, no need to install
  :bind
  (:map python-mode-map
        ("C-c C-p" . nil))) ; Unset C-c C-p in python-mode-map

emacs-pet

https://github.com/wyuenho/emacs-pet

(use-package pet
  :config
  (add-hook 'python-base-mode-hook 'pet-mode -10)
  )

pyvenv

(use-package pyvenv
  :config
  (pyvenv-mode 1))

;; (if (getenv "WORKON_HOME")
;;   (setq virtualenv-workon-home (getenv "WORKON_HOME"))
;; (setq virtualenv-workon-home "~/Library/Caches/pypoetry/virtualenvs/"))

poetry

https://github.com/galaunay/poetry.el

(use-package poetry
  ;; :hook (python-mode . poetry-tracking-mode)
  ;; :config
  ;; (setq poetry-tracking-strategy 'switch-buffer)
  )

JSON

(use-package json-mode)
;;(use-package json-navigator)
;;(use-package tree-mode)  ;; Does this work in the json-navigator hierarcy window??

YAML

(use-package yaml-mode
  :mode (("\\.yaml$" . yaml-mode)))

TOML

(use-package toml-mode)

HTML/Javascript

lsp-mode

npm install -g typescript-language-server typescript vue-language-server

Typescript

(use-package tide
  :after (typescript-mode company flycheck)
  :hook (
         (typescript-mode . tide-setup)
         (typescript-mode . tide-hl-identifier-mode)
         (before-save . tide-format-before-save))
  :config
  (flycheck-add-mode 'typescript-tslint)
  )

Javascript

Prettier

(use-package prettier-js
  :config
  ;;(add-hook 'web-mode-hook 'prettier-js-mode)
  (add-hook 'web-mode-hook #'(lambda ()
                               (enable-minor-mode
                                '("\\.jsx?\\'" . prettier-js-mode))))
  )

web-mode

(use-package web-mode
  :mode (
         ("\\.css$" . web-mode)
         ("\\.html$" . web-mode)
         ("\\.js$" . web-mode)
         ("\\.ts$" . web-mode)
         ("\\.json$" . web-mode)
         ("\\.jsx$" . web-mode)
         ("\\.tsx$" . web-mode)
         ("\\.vue$" . web-mode)
         ("\\.scss$" . web-mode)
         ("\\.less$" . web-mode))
  :config
  (setq-default indent-tabs-mode nil) ;; no TABS
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-enable-auto-closing t)
  (setq web-mode-enable-auto-expanding t)
  (setq web-mode-enable-auto-opening t)
  (setq web-mode-enable-auto-pairing t)
  (setq web-mode-enable-auto-pairing t)
  (setq web-mode-enable-auto-quoting nil)
  (setq web-mode-enable-css-colorization t)
  (setq web-mode-enable-current-column-highlight t)
  (setq web-mode-enable-current-element-highlight t)
  (setq web-mode-js-indent-offset 2)
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-content-types-alist
        '(("jsx" . "\\.js[x]?\\'")
          ;;("tsx" . "\\.ts[x]?\\'")
          )
        )
  ;; Default comment to //
  (setq-default web-mode-comment-formats (remove '("javascript" . "/*") web-mode-comment-formats))
  (add-to-list 'web-mode-comment-formats '("javascript" . "//"))
  )

(use-package company-web);

Emmet(Zencoding)

(use-package emmet-mode)

Rust

(use-package rust-mode
  :hook (rust-mode . lsp)
  :config
  (setq rust-format-on-save t)
  (define-key rust-mode-map (kbd "C-c C-c") 'rust-run)
  )

;; Add keybindings for interacting with Cargo
(use-package cargo
  :hook (rust-mode . cargo-minor-mode))

(use-package flycheck-rust
  :config (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))

Go

(use-package go-mode
  :bind (
         ;; If you want to switch existing go-mode bindings to use lsp-mode/gopls instead
         ;; uncomment the following lines
         ;; ("C-c C-j" . lsp-find-definition)
         ;; ("C-c C-d" . lsp-describe-thing-at-point)
         )
  ;; :hook ((go-mode . lsp-deferred)
  ;;        (before-save . lsp-format-buffer)
  ;;        (before-save . lsp-organize-imports))
  )

Markdown

Install CLI markdown first

brew install markdown
# apt-get install pandoc
(use-package markdown-mode)
(add-hook 'markdown-mode-hook
          (lambda ()
            (when buffer-file-name
              (add-hook 'after-save-hook
                        'check-parens
                        nil t))))

(use-package flymd)
(defun my-flymd-browser-function (url)
  (let ((browse-url-browser-function 'browse-url-firefox))
    (browse-url url)))
(setq flymd-browser-open-function 'my-flymd-browser-function)

dockerfile-mode

(use-package dockerfile-mode
  :mode "Dockerfile$")

sql

Activate babel languages

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (shell . t)
   (screen . t)
   (R . t)
   (C . t)
   (css . t)
   (python . t)
   (js . t)
   (haskell . t)
   (clojure . t)
   (lisp . t)
   (org . t)
   (sql . t)
   ))

Elixir

(use-package elixir-mode
  :init
  (add-hook 'elixir-mode-hook
            (lambda ()
              (push '(">=" . ?\u2265) prettify-symbols-alist)
              (push '("<=" . ?\u2264) prettify-symbols-alist)
              (push '("!=" . ?\u2260) prettify-symbols-alist)
              (push '("==" . ?\u2A75) prettify-symbols-alist)
              (push '("=~" . ?\u2245) prettify-symbols-alist)
              (push '("<-" . ?\u2190) prettify-symbols-alist)
              (push '("->" . ?\u2192) prettify-symbols-alist)
              (push '("<-" . ?\u2190) prettify-symbols-alist)
              (push '("|>" . ?\u25B7) prettify-symbols-alist))))

Justfile

https://github.com/leon-barrett/just-mode.el

(use-package just-mode)

Notes

org

Main config

Note that org mode actually is installed first via init.el, to ensure org-babel can process this literate config property with the right version loaded. Otherwise the built-in org gets mixed up with the one via straight. I’m still leaving the org section and any custom config here.

;; Change ... to downward arrow when there's stuff under a header.
(setq org-hide-leading-stars t)

;; Use syntax highlighting in source blocks while editing.
(setq org-src-fontify-natively t)
(font-lock-flush)

;; Make TAB act as if it were issued in a buffer of the language's major mode.
(setq org-src-tab-acts-natively t)

(setq org-support-shift-select 'always)

;; Highlight some keywords
;; (setq org-todo-keyword-faces
;;       '(("TODO" . (:foreground "yellow" :weight bold))
;;         ("DONE" . "green")
;;         ))

;; (setq org-catch-invisible-edits 'smart)
;; (setq org-ctrl-k-protect-subtree t)

;; Save archive file after something is archived.
(setq org-archive-subtree-save-file-p t)

;; Hide emphasis markers */~=+
(setq org-hide-emphasis-markers t)

;; Ensure org section expands on search
;; TODO: not working with ctrl+f still
(setq-default org-fold-core-style 'overlays)

org-modern

https://github.com/minad/org-modern

(use-package org-modern
  :custom
  ;; (add-hook 'org-mode-hook #'org-modern-mode)
  ;; (add-hook 'org-agenda-finalize-hook #'org-modern-agenda)
  ;; :
  config
  (global-org-modern-mode)
  )

org-contrib

(use-package org-contrib)

DOCT: Declarative Org Capture Templates

(use-package doct
  :defer t
  ;;recommended: defer until calling doct
  :commands (doct))

org-babel

(setq org-babel-python-command "python3")
(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)))

org-journal

https://github.com/bastibe/org-journal

(use-package org-journal
  :config

  (defun org-journal-file-header-func (time)
    "Custom function to create journal header."
    (concat
     (pcase org-journal-file-type
       (`daily "#+TITLE: Daily Journal\n#+STARTUP: showeverything")
       (`weekly "#+TITLE: Weekly Journal\n#+STARTUP: folded")
       (`monthly "#+TITLE: Monthly Journal\n#+STARTUP: folded")
       (`yearly "#+TITLE: Yearly Journal\n#+STARTUP: folded"))))

  (setq org-journal-file-header 'org-journal-file-header-func)

  (setq org-journal-dir "~/Projects/Notes/journal/")
  (setq org-journal-file-type 'daily)
  (setq org-journal-file-format "%Y%m%d.org")
  )

Links

deft

Searching/Filtering notes

(use-package deft
  :custom
  (deft-extensions '("org" "txt" "md"))
  (deft-directory "~/Projects/Notes/")
  (deft-recursive t)
  (deft-use-filename-as-title t)
  :config
  (global-set-key [f9] 'deft)
  )

mermaid

Emacs major mode for working with mermaid graphs

brew install mermaid-cli

(use-package mermaid-mode)

d2lang

What is D2?

D2 is a diagram scripting language that turns text to diagrams. It stands for Declarative Diagramming. Declarative, as in, you describe what you want diagrammed, it generates the image.

https://d2lang.com/tour/intro/

First install CLI tool brew install d2

https://github.com/andorsk/d2-mode https://github.com/dmacvicar/ob-d2

(use-package d2-mode)

(use-package ob-d2
  :ensure (:type git :host github :repo "dmacvicar/ob-d2")
  :defer t)

External Services/Apps

browser

(defun eww-default () (interactive)
       (setq browse-url-browser-function 'eww-browse-url))

eradio

eradio is a simple internet radio player for Emacs. https://github.com/olav35/eradio

(use-package eradio
  :config
  ;; (setq eradio-player '("mpv" "--no-video" "--no-terminal"))
  (setq eradio-player '("/Applications/VLC.app/Contents/MacOS/VLC" "--no-video" "-I" "rc"))
  ;;(global-set-key (kbd "C-c r p") 'eradio-play)
  ;;(global-set-key (kbd "C-c r s") 'eradio-stop)
  )


(setq eradio-channels
      '(
        ("secretagent - somafm" . "https://somafm.com/secretagent130.pls")
        ("groovesalad - somafm"   . "https://somafm.com/groovesalad130.pls")
        ("defcon - somafm"   . "https://somafm.com/defcon130.pls")
        ("cafe - lainon"     . "https://lainon.life/radio/cafe.ogg.m3u")
        ))

calibre

Ebook manager https://github.com/chenyanming/calibredb.el

(use-package calibredb
  :config
  ;; TODO: Move to file-path section?
  ;; TODO: Also make dependent on OS.
  (setq calibredb-root-dir "~/Library/CloudStorage/[email protected]/My Drive/Media/Calibre")
  (setq calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir))
  (setq sql-sqlite-program "/usr/bin/sqlite3")
  (setq calibredb-program "/Applications/calibre.app/Contents/MacOS/calibredb")
  )

pdf

(use-package pdf-tools
  :ensure (pdf-tools :type git :host github
                       :repo "vedang/pdf-tools")
  :mode ("\\.pdf\\'" . pdf-view-mode)
  :config
  (pdf-tools-install)
  (setq auto-revert-interval 0.5)

  ;; Fix blurry PDFs on MacOS.
  ;; From https://github.com/politza/pdf-tools/issues/51
  (setq pdf-view-use-scaling t)
  )

AI

Copilot

https://github.com/copilot-emacs/copilot.el Copilot.el is an Emacs plugin for GitHub Copilot. Note: You need access to GitHub Copilot to use this plugin.

Run M-x copilot-install-server and then M-x copilot-login

TODO: Note the hardcoded path.Anyway to make that configurable? Using which node

(use-package copilot
  :ensure (:host github :repo "copilot-emacs/copilot.el" :files ("*.el"))
  :custom (
           (copilot-node-executable "~/.local/share/mise/installs/node/22/bin/node" "Set node executable.")
           (copilot-indent-warning-suppress t))
  ;; :hook (prog-mode . copilot-mode)
  :config
  (define-key copilot-completion-map (kbd "C-<tab>") 'copilot-accept-completion)
  )
;; you can utilize :map :hook and :config to customize copilot

gptel

https://github.com/karthink/gptel

The key currently is stored in ~~/.authinfo~ as shown below. By default, api.openai.com is used as HOST and “apikey” as USER.

machine api.openai.com login apikey password TOKEN

(use-package gptel
  :config
  (setq gptel-model "gpt-4o")
  )

Starcoder

https://huggingface.co/bigcode/starcoder https://gitlab.com/daanturo/starhugger.el

;; (setq starhugger-api-token
;;       (auth-source-pick-first-password :host "huggingface"))
;; For inference endpoints
(setq starhugger-hugging-face-api-token
      (auth-source-pick-first-password :host "huggingface"))

;; Use https://huggingface.co/codellama/CodeLlama-13b-hf, best to be set before loading this package
(setq-default starhugger-model-id "bigcode/starcoder2-15b")

(global-set-key (kbd "M-\\") #'starhugger-trigger-suggestion)

(elpaca (starhugger :repo "https://gitlab.com/daanturo/starhugger.el" :files (:defaults "*.py")))

(with-eval-after-load 'starhugger
  ;; `starhugger-inline-menu-item' makes a conditional binding that is only active at the inline suggestion start
  (define-key starhugger-inlining-mode-map (kbd "TAB") (starhugger-inline-menu-item #'starhugger-accept-suggestion))
  (define-key starhugger-inlining-mode-map (kbd "M-[") (starhugger-inline-menu-item #'starhugger-show-prev-suggestion))
  (define-key starhugger-inlining-mode-map (kbd "M-]") (starhugger-inline-menu-item #'starhugger-show-next-suggestion))
  (define-key starhugger-inlining-mode-map (kbd "M-f") (starhugger-inline-menu-item #'starhugger-accept-suggestion-by-word)))

My Helpers

Revert all buffers and ignore errors

(defun sm/revert-all-file-buffers ()
  "Refresh all open file buffers without confirmation.
Buffers in modified (not yet saved) state in emacs will not be reverted. They
will be reverted though if they were modified outside emacs.
Buffers visiting files which do not exist any more or are no longer readable
will be killed."
  (interactive)
  (dolist (buf (buffer-list))
    (let ((filename (buffer-file-name buf)))
      ;; Revert only buffers containing files, which are not modified;
      ;; do not try to revert non-file buffers like *Messages*.
      (when (and filename
                 (not (buffer-modified-p buf)))
        (if (file-readable-p filename)
            ;; If the file exists and is readable, revert the buffer.
            (with-current-buffer buf
              (revert-buffer :ignore-auto :noconfirm :preserve-modes))
          ;; Otherwise, kill the buffer.
          (let (kill-buffer-query-functions) ; No query done when killing buffer
            (kill-buffer buf)
            (message "Killed non-existing/unreadable file buffer: %s" filename))))))
  (message "Finished reverting buffers containing unmodified files."))

Quote lines

Source

(defun sm-quote-lines ()
  "Change current text block's lines to quoted lines with comma or other separator char.
When there is a text selection, act on the selection, else, act on a text block separated by blank lines.

For example,

 cat
 dog
 cow

becomes

 \"cat\",
 \"dog\",
 \"cow\",

or

 (cat)
 (dog)
 (cow)

If the delimiter is any left bracket, the end delimiter is automatically the matching bracket.

URL `http://ergoemacs.org/emacs/emacs_quote_lines.html'
Version 2020-06-26"
  (interactive)
  (let* (
         $p1
         $p2
         ($quoteToUse
          (read-string
           "Quote to use:" "\"" nil
           '(
             ""
             "\""
             "'"
             "("
             "{"
             "["
             )))
         ($separator
          (read-string
           "line separator:" "," nil
           '(
             ""
             ","
             ";"
             )))
         ($beginQuote $quoteToUse)
         ($endQuote
          ;; if begin quote is a bracket, set end quote to the matching one. else, same as begin quote
          (let (($syntableValue (aref (syntax-table) (string-to-char $beginQuote))))
            (if (eq (car $syntableValue ) 4) ; ; syntax table, code 4 is open paren
                (char-to-string (cdr $syntableValue))
              $quoteToUse
              ))))
    (if (use-region-p)
        (setq $p1 (region-beginning) $p2 (region-end))
      (progn
        (if (re-search-backward "\n[ \t]*\n" nil "move")
            (progn (re-search-forward "\n[ \t]*\n")
                   (setq $p1 (point)))
          (setq $p1 (point)))
        (re-search-forward "\n[ \t]*\n" nil "move")
        (skip-chars-backward " \t\n" )
        (setq $p2 (point))))
    (save-excursion
      (save-restriction
        (narrow-to-region $p1 $p2)
        (goto-char (point-min))
        (catch 'EndReached
          (while t
            (skip-chars-forward "\t ")
            (insert $beginQuote)
            (end-of-line )
            (insert $endQuote $separator)
            (if (eq (point) (point-max))
                (throw 'EndReached t)
              (forward-char 1))))))))

Open file with line number

Opens file with line number for eg. service/models/vendor.py:1481:25

Source

(defun sm-find-file-at-point-with-line()
  "if file has an attached line num goto that line, ie boom.rb:12"
  (interactive)
  (setq line-num 0)
  (save-excursion
    (search-forward-regexp "[^ ]:" (point-max) t)
    (if (looking-at "[0-9]+")
        (setq line-num (string-to-number (buffer-substring (match-beginning 0) (match-end 0))))))
  (find-file-at-point)
  (if (not (equal line-num 0))
      (goto-line line-num)))

My Workflow

Registers

(set-register ?t (cons 'file "~/Projects/Notes/todo.org"))
(set-register ?i (cons 'file "~/.emacs.d/README.org"))
(set-register ?s (cons 'file "~/Projects/Notes/scratch.org"))

File Paths

;; (add-to-list 'auth-sources "~/.authinfo" t) ;; pinboard, magit-forge
(setq-default org-directory "~/Projects/Notes")
(setq-default org-roam-directory "~/Projects/Notes/")
(setq-default org-roam-index-file "index.org")
(setq-default org-agenda-files '("~/Projects/Notes/todo.org"))
;; (setq-default rmh-elfeed-org-files '("~/Projects/Notes/elfeed.org"))

Shortcuts

;; unset run-python shortcut, interferes with projectile open file and i never use this.
;; (global-unset-key (kbd "C-c C-p"))

Airbase

;; Forcing django mode on all html
;; TODO: Better way to do this?
;; (setq-default web-mode-engines-alist
;;               '(("django"    . "\\.html\\'")))

(defun airbase-enable () (interactive)
       ;; JS
       ;; (setq web-mode-code-indent-offset 2)
       ;; (setq web-mode-markup-indent-offset 2)
       ;; (setq web-mode-css-indent-offset 2)
       ;; (setq web-mode-js-indent-offset 2)
       ;; ;;(prettier-js-mode 1)
       ;; (setq prettier-args '())

       ;; Python
       (pyvenv-activate "/Users/sidmitra/Library/Caches/pypoetry/virtualenvs/airbase-backend-csyzUOJz-py3.11")
       (setq flycheck-pylintrc "~/Projects/Airbase/airbase-backend/pyproject.toml")
       (setq flycheck-flake8rc "~/Projects/Airbase/airbase-backend/ci_scripts/.flake8")
       (setq flycheck-python-mypy-config "~/Projects/Airbase/airbase-backend/pyproject.toml")
       ;; (lsp-deferred)
       )

(defun airbase-disable () (interactive))

(defun custom-ag-args () (interactive)
       (set
        q-default ag-arguments '(
                                    "--smart-case"
                                    "--stats"
                                    "--ignore-dir" "migrations"
                                    "--ignore-dir" "node_modules"
                                    "--ignore-dir" "elpa"
                                    "--ignore-dir" "lib"
                                    "--ignore-dir" "build"
                                    "--ignore" "\pdf_purchase_order.html"
                                    "--ignore" "\*.min.js"
                                    "--ignore" "\*.min.css"
                                    "--ignore" "\*.csv"
                                    "--ignore" "\*.svg"
                                    "--ignore" "\*.json"
                                    "--ignore" "\*.yaml"
                                    "--ignore" "\*.yml"
                                    ))
       )


;; https://erick.navarro.io/blog/using-compilation-mode-to-run-all-the-things/
(defun sm/run-pytest ()
  "Run  pytest over the current project."
  (interactive)
  (let ((default-directory (projectile-project-root)))
    (compile "poetry run pytest tests/")))