Giter Club home page Giter Club logo

emacs.d's Introduction

Emacs configuration

early-init.el and init.el

early-init.el

;;; early-init.el --- Early Init File -*- lexical-binding: t; no-byte-compile: t -*-

;; Defer garbage collection further back in the startup process
(setq gc-cons-threshold most-positive-fixnum
			  gc-cons-percentage 0.6)

;; In Emacs 27+, package initialization occurs before `user-init-file' is
;; loaded, but after `early-init-file'. Doom handles package initialization, so
;; we must prevent Emacs from doing it early!
(setq package-enable-at-startup nil)
;; Do not allow loading from the package cache (same reason).
(setq package-quickstart nil)

;; Prevent the glimpse of un-styled Emacs by disabling these UI elements early.
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)

;; Resizing the Emacs frame can be a terribly expensive part of changing the
;; font. By inhibiting this, we easily halve startup times with fonts that are
;; larger than the system default.
(setq frame-inhibit-implied-resize t)

;; Disable GUI elements
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t)
(setq use-file-dialog nil)

;; Prevent unwanted runtime builds in gccemacs (native-comp); packages are
;; compiled ahead-of-time when they are installed and site files are compiled
;; when gccemacs is installed.
(setq comp-deferred-compilation nil)

;; Mitigate https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57849
(when (eq system-type 'darwin)
	  (setq native-comp-driver-options '("-Wl,-w")))

init.el: startup optimization

 ;;; init.el --- Personal configuration file -*- lexical-binding: t; no-byte-compile: t; -*-

 ;; `file-name-handler-alist' is consulted on every `require', `load' and various
 ;; path/io functions. You get a minor speed up by nooping this. However, this
 ;; may cause problems on builds of Emacs where its site lisp files aren't
 ;; byte-compiled and we're forced to load the *.el.gz files (e.g. on Alpine)
 (unless (daemonp)
   (defvar doom--initial-file-name-handler-alist file-name-handler-alist)
   (setq file-name-handler-alist nil)
   ;; Restore `file-name-handler-alist' later, because it is needed for handling
   ;; encrypted or compressed files, among other things.
   (defun doom-reset-file-handler-alist-h ()
     ;; Re-add rather than `setq', because changes to `file-name-handler-alist'
     ;; since startup ought to be preserved.
     (dolist (handler file-name-handler-alist)
	(add-to-list 'doom--initial-file-name-handler-alist handler))
     (setq file-name-handler-alist doom--initial-file-name-handler-alist))
   (add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h)
   (add-hook 'after-init-hook (lambda ()
				 ;; restore after startup
				 (setq gc-cons-threshold 16777216
				       gc-cons-percentage 0.1))))

 ;; Ensure Doom is running out of this file's directory
 (setq user-emacs-directory (file-truename (file-name-directory load-file-name)))

init.el: load modules

 (add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))

 (let ((file-name-handler-alist nil)
	(gc-cons-threshold 100000000))
   (load "init-core")
   (load "init-keybindings")
   (load "init-evil")
   (load "init-ui")
   (load "init-window")
   (load "init-navigation")
   (load "init-completion")
   (load "init-search")
   (load "init-org")
   (load "init-writing")
   (load "init-prog")
   (load "init-apps")
   )

init.el: measure startup

(add-hook 'emacs-startup-hook
	    (lambda ()
	      (message "Emacs started in %s with %d garbage collections."
		       (format "%.3f seconds"
			       (float-time
				(time-subtract after-init-time before-init-time)))
		       gcs-done)))

Package manager

bootstrap straight and straight-use-package

 (setq straight-use-package-by-default t)
 (setq straight-vc-git-default-clone-depth 1)
 (setq straight-recipes-gnu-elpa-use-mirror t)
 (setq straight-check-for-modifications nil)

 (defvar bootstrap-version)
 (let ((bootstrap-file
	 (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
	(bootstrap-version 6))
   (unless (file-exists-p bootstrap-file)
     (with-current-buffer
	  (url-retrieve-synchronously
	   "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
	   'silent 'inhibit-cookies)
	(goto-char (point-max))
	(eval-print-last-sexp)))
   (load bootstrap-file nil 'nomessage))

 (straight-use-package 'use-package)

 (setq comp-deferred-compilation-black-list nil)

Enable use-package statistics

(setq use-package-compute-statistics t)

Core

Sane defaults

(use-package emacs
  :custom
  (user-full-name "John Downey")
  (user-mail-address "[email protected]")

  (inhibit-startup-screen t)
  (initial-scratch-message nil)
  (initial-major-mode 'text-mode)

  (sentence-end-double-space nil)
  (ring-bell-function 'ignore)
  (ad-redefinition-action 'accept)
  (frame-resize-pixelwise t)
  (vc-follow-symlinks t)

  (custom-file (make-temp-file ""))
  (make-backup-files nil)
  (auto-save-default nil)
  (create-lockfiles nil)

  (byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
  (native-comp-async-report-warnings-errors nil)

  (column-number-mode t)
  (tab-always-indent 'complete)
  :init
  (defalias 'yes-or-no-p 'y-or-n-p)

  ;; default to utf-8 for all the things
  (set-charset-priority 'unicode)
  (setq locale-coding-system 'utf-8
	  coding-system-for-read 'utf-8
	  coding-system-for-write 'utf-8)
  (set-terminal-coding-system 'utf-8)
  (set-keyboard-coding-system 'utf-8)
  (set-selection-coding-system 'utf-8)
  (prefer-coding-system 'utf-8)
  (setq default-process-coding-system '(utf-8-unix . utf-8-unix))

  (delete-selection-mode 1)
  (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
  (winner-mode 1)
  (show-paren-mode 1)
  (display-time-mode -1)

  (setq-default indent-tabs-mode nil))

On hooks

(use-package on
  :demand
  :straight (:host github :repo "ajgrf/on.el"))

Private configuration

(add-hook
 'after-init-hook
 (lambda ()
   (let ((private-file (concat user-emacs-directory "private.el")))
     (when (file-exists-p private-file)
	 (load-file private-file)))))

Zoom

(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

macOS

(use-package emacs
  :init
  (when (eq system-type 'darwin)
    (setq mac-command-modifier 'super)     ; command as super
    (setq mac-option-modifier 'meta)     ; alt as meta
    (setq mac-control-modifier 'control))

  ;; when on emacs-mac
  (when (fboundp 'mac-auto-operator-composition-mode)
    (mac-auto-operator-composition-mode)   ;; enables font ligatures
    (global-set-key [(s c)] 'kill-ring-save)
    (global-set-key [(s v)] 'yank)
    (global-set-key [(s x)] 'kill-region)
    (global-set-key [(s q)] 'kill-emacs)))

Garbage collector magic hack

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

Helpful

(use-package helpful
  :bind
  ([remap describe-function] . helpful-function)
  ([remap describe-command] . helpful-command)
  ([remap describe-variable] . helpful-variable)
  ([remap describe-key] . helpful-key))

Save recent files

(use-package recentf
  :straight (:type built-in)
  :hook
  (after-init . recentf-mode)
  :custom
  (recentf-exclude `(,(expand-file-name "straight/build/" user-emacs-directory)
		       ,(expand-file-name "eln-cache/" user-emacs-directory)
		       ,(expand-file-name "etc/" user-emacs-directory)
		       ,(expand-file-name "var/" user-emacs-directory))))

Highlight trailing whitespace

(dolist (hook '(prog-mode-hook text-mode-hook))
  (add-hook hook (lambda ())
	      (setq-local show-trailing-whitespace t)))

Undo

(use-package undo-fu)

Tramp

(use-package tramp
  :defer 1 
  :straight (:type built-in)
  :config
  (setq vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)"
				       vc-ignore-dir-regexp
				       tramp-file-name-regexp)
	  tramp-default-method "ssh"
	  tramp-auto-save-directory (expand-file-name "tramp-auto-save" user-emacs-directory)
	  tramp-persistency-file-name (expand-file-name "tramp-connection-history" user-emacs-directory)
	  tramp-use-ssh-controlmaster-options nil
	  remote-file-name-inhibit-cache nil
	  tramp-ssh-controlmaster-options (concat
					   "-o ControlPath=/tmp/ssh-tramp-%%r@%%h:%%p "
					   "-o ControlMaster=auto -o ControlPersist=yes")))

(use-package tramp-container
  :defer 2
  :straight (:type built-in))

Keybindings

General

 (defun jtd/find-file-in-emacs ()
   "Find files in the emacs configuration directory"
   (interactive)
   (ido-find-file-in-dir user-emacs-directory))

 (defun jtd/switch-to-scratch-buffer ()
   "Switch to the scratch buffer"
   (interactive)
   (switch-to-buffer "*scratch*"))

 (defun jtd/copy-buffer ()
   "Copy the entire buffer"
   (interactive)
   (mark-whole-buffer)
   (kill-ring-save 0 0 t))

 (defun jtd/kill-other-buffers ()
   "Kill all buffers but the current one. Don't mess with special buffers."
   (interactive)
   (dolist (buffer (buffer-list))
     (unless (or (eql buffer (current-buffer)) (not (buffer-file-name buffer)))
	(kill-buffer buffer))))

 (use-package general
   :config
   (general-evil-setup)

   (general-create-definer jtd/leader-key
     :keymaps 'override
     :states '(normal visual)
     :prefix "SPC"
     :global-prefix "C-SPC")
   (general-create-definer jtd/local-leader-key
     :states '(normal visual motion)
     :prefix ","
     :global-prefix "C-,")

   (general-def '(normal insert visual emacs) "C-@" (general-simulate-key "C-SPC"))

   (jtd/leader-key
     ":" 'execute-extended-command
     "a" '(:ignore t :wk "apps")
     "b" '(:ignore t :wk "buffer")
     "bk" 'kill-buffer-and-window
     "bK" 'jtd/kill-other-buffers
     "bs" 'jtd/switch-to-scratch-buffer
     "bY" 'jtd/copy-buffer
     "f" '(:ignore t :wk "file")
     "ff" '(find-file :wk "find file")
     "fe" '(jtd/find-file-in-emacs :wk "find file in emacs.d")
     "g" '(:ignore t :wk "git")
     "h" '(:ignore t :wk "help")
     "ha" 'apropos-command
     "hf" 'helpful-function
     "hk" 'helpful-key
     "hm" 'helpful-macro
     "ho" 'helpful-symbol
     "hv" 'helpful-variable
     "hx" 'helpful-command
     "s" '(:ignore t :wk "search")
     "sj" '(imenu :wk "jump")
     "t" '(:ignore t :wk "tabs")
     "T" '(:ignore t :wk "toggle")
     "w" '(:ignore t :wk "window"))

   (general-define-key
    :definer 'minor-mode
    :states '(normal motion)
    :keymaps 'outline-minor-mode
    "]h" 'outline-next-visible-heading
    "[h" 'outline-prev-visible-heading))

Which key

(use-package which-key
  :hook (on-first-input . which-key-mode)
  :custom
  (which-key-idle-delay 1))

Hydra

(use-package hydra)

Evil

evil mode

(use-package evil
  :general
  (jtd/leader-key
    "wv" 'evil-window-vsplit
    "ws" 'evil-window-split)
  (general-imap "C-g" 'evil-normal-state)
  :custom
  ((evil-want-integration t)
   (evil-want-keybinding nil)
   (evil-want-abbrev-expand-on-insert-exit nil)
   (evil-respect-visual-line-mode t)
   (evil-want-C-i-jump nil)
   (evil-want-C-d-scroll t)
   (evil-want-C-u-scroll t)
   (evil-want-C-w-delete nil)
   (evil-want-Y-yank-to-eol t)
   (evil-undo-system 'undo-fu)
   (evil-search-module 'evil-search-module 'evil-search)  ;; enables gn
   (evil-split-window-below t)
   (evil-vsplit-window-right t)
   (evil-auto-indent t)
   (evil-want-C-w-in-emacs-state t))
  :init
  (evil-mode 1)
  (evil-set-initial-state 'messages-buffer-mode 'normal)
  (evil-set-initial-state 'dashboard-mode 'normal))

evil-collection

(use-package evil-collection
  :after evil
  :config
  (evil-collection-init))

Surround

(use-package evil-surround
  :after evil
  :hook
  (on-first-input . global-evil-surround-mode))

Preview registers

(use-package evil-owl
  :hook
  (on-first-input . evil-owl-mode)
  :custom
  (evil-owl-max-string-length 500)
  (evil-owl-display-method 'window))

UI

Theme

(load-theme 'modus-vivendi t)

Font

(set-face-attribute 'default nil :font "Berkeley Mono" :height 160)
(set-face-attribute 'variable-pitch nil :font "Fira Sans" :height 160)

Highlight current line

(global-hl-line-mode 1)

Highlight indentation guides

(use-package highlight-indent-guides
  :hook (prog-mode . highlight-indent-guides-mode)
  :custom
  (highlight-indent-guides-method 'character)
  (highlight-indent-guides-responsive 'top))

Doom modeline

(use-package doom-modeline
  :hook
  (on-init-ui . doom-modeline-mode)
  :custom
  (doom-modeline-buffer-encoding nil)
  (doom-modeline-env-enable-python nil)
  (doom-modeline-height 15))

All the icons

(use-package all-the-icons)

Icons in the terminal

(use-package icons-in-terminal
  :straight (:host github :repo "seagle0128/icons-in-terminal.el")
  :if (not (display-graphic-p))
  :config
  (defalias #'all-the-icons-insert #'icons-in-terminal-insert)
  (defalias #'all-the-icons-insert-faicon #'icons-in-terminal-insert-faicon)
  (defalias #'all-the-icons-insert-fileicon #'icons-in-terminal-insert-fileicon)
  (defalias #'all-the-icons-insert-material #'icons-in-terminal-insert-material)
  (defalias #'all-the-icons-insert-octicon #'icons-in-terminal-insert-octicon)
  (defalias #'all-the-icons-insert-wicon #'icons-in-terminal-insert-wicon)
  (defalias #'all-the-icons-icon-for-dir #'icons-in-terminal-icon-for-dir)
  (defalias #'all-the-icons-icon-for-file #'icons-in-terminal-icon-for-file)
  (defalias #'all-the-icons-icon-for-mode #'icons-in-terminal-icon-for-mode)
  (defalias #'all-the-icons-icon-for-url #'icons-in-terminal-icon-for-url)
  (defalias #'all-the-icons-icon-family #'icons-in-terminal-icon-family)
  (defalias #'all-the-icons-icon-family-for-buffer #'icons-in-terminal-icon-family-for-buffer)
  (defalias #'all-the-icons-icon-family-for-file #'icons-in-terminal-icon-family-for-file)
  (defalias #'all-the-icons-icon-family-for-mode #'icons-in-terminal-icon-family-for-mode)
  (defalias #'all-the-icons-icon-for-buffer #'icons-in-terminal-icon-for-buffer)
  (defalias #'all-the-icons-faicon #'icons-in-terminal-faicon)
  (defalias #'all-the-icons-octicon #'icons-in-terminal-octicon)
  (defalias #'all-the-icons-fileicon #'icons-in-terminal-fileicon)
  (defalias #'all-the-icons-material #'icons-in-terminal-material)
  (defalias #'all-the-icons-wicon #'icons-in-terminal-wicon)
  (defalias 'all-the-icons-default-adjust 'icons-in-terminal-default-adjust)
  (defalias 'all-the-icons-color-icons 'icons-in-terminal-color-icons)
  (defalias 'all-the-icons-scale-factor 'icons-in-terminal-scale-factor)
  (defalias 'all-the-icons-icon-alist 'icons-in-terminal-icon-alist)
  (defalias 'all-the-icons-dir-icon-alist 'icons-in-terminal-dir-icon-alist)
  (defalias 'all-the-icons-weather-icon-alist 'icons-in-terminal-weather-icon-alist))

Ligatures

(use-package ligature
  :straight (:host github :repo "mickeynp/ligature.el")
  :hook (prog-mode . ligature-mode)
  :config
  (ligature-set-ligatures 't '("www" "ff" "fi" "ffi"))
  (ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
					 ":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
					 "!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
					 "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
					 "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
					 "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
					 "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
					 "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
					 ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
					 "<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
					 "##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
					 "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
					 "\\\\" "://")))

Pretty symbols

(global-prettify-symbols-mode 1)

Hide modeline

(use-package hide-mode-line
  :commands hide-mode-line)

Show end of file

(use-package vi-tilde-fringe
  :if (display-graphic-p)
  :hook (prog-mode . vi-tilde-fringe-mode))

Emoji

(use-package emojify
  :hook
  (on-init-ui . global-emojify-mode)
  :config
  (delete 'mu4e-headers-mode emojify-inhibit-major-modes))

Fill column indicator

(use-package display-fill-column-indicator
  :straight (:type built-in)
  :hook
  (prog-mode . display-fill-column-indicator-mode)
  :custom
  (fill-column 120))

Dashboard

(use-package dashboard
  :demand t
  :custom
  (dashboard-projects-backend 'project-el)
  (dashboard-set-heading-icons t)
  (dashboard-set-file-icons t)
  (dashboard-banner-logo-title nil)
  (dashboard-set-footer nil)
  (dashboard-items '((recents . 5)
		       (projects . 5)))
  :config
  (dashboard-setup-startup-hook))

Window management

Disable built in

(tab-bar-mode -1)
(tab-line-mode -1)

(global-unset-key (kbd "C-<tab>"))

Golden ratio

(use-package golden-ratio
  :hook
  (on-first-buffer . golden-ratio-mode)
  :custom
  (golden-ratio-exclude-modes '(treemacs-mode imenu-list-major-mode))
  (golden-ratio-extra-commands
   '(windmove-left
     windmove-right
     windmove-down
     windmove-up
     evil-window-left
     evil-window-right
     evil-window-up
     evil-window-down
     buf-move-left
     buf-move-right
     buf-move-up
     buf-move-down
     window-number-select
     select-window
     select-window-1
     select-window-2
     select-window-3
     select-window-4
     select-window-5
     select-window-6
     select-window-7
     select-window-8
     select-window-9)))

Transpose frame

(use-package transpose-frame
  :general
  (jtd/leader-key
    "wt" '(transpose-frame :wk "transpose")
    "wf" '(rotate-frame :wk "flip")))

Perspective

(use-package perspective
  :demand
  :after consult
  :custom
  (persp-state-default-file (expand-file-name ".persp" user-emacs-directory))
  (persp-mode-prefix-key (kbd "C-c M-p"))
  :general
  (jtd/leader-key
    "TAB" '(:ignore true :wk "tab")
    "TAB TAB" 'persp-switch
    "TAB `" 'persp-switch-last
    "TAB d" 'persp-kill
    "TAB h" 'persp-prev
    "TAB l" 'persp-next
    "TAB x" '((lambda () (interactive) (persp-kill (persp-current-name))) :wk "kill current")
    "TAB X" '((lambda () (interactive) (persp-kill (persp-names))) :wk "kill all"))
  :init
  :config
  (persp-mode)
  (consult-customize consult--source-buffer :hidden t :default nil)
  (add-to-list 'consult-buffer-sources persp-consult-source)
  (add-hook 'kill-emacs-hook #'persp-state-save))

Navigation

Ranger

(use-package ranger
  :custom
  (ranger-key "zp")
  :general
  (jtd/leader-key
    "ar" 'ranger))

dired

(use-package dired
  :straight (:type built-in)
  :general
  (jtd/leader-key
    "ad" 'dired)
  (general-nmap
    "-" 'dired-jump)
  (general-nmap dired-mode-map
    "c" 'find-file)
  :config
  (require 'dired-x))

Treemacs

(use-package treemacs
  :custom
  ((treemacs-project-follow-mode t)
   (treemacs-follow-mode t)
   (treemacs-filewatch-mode t))
  :general
  (jtd/leader-key
    "fd" 'treemacs-find-file
    "ft" 'treemacs))

(use-package treemacs-evil
  :after (treemacs evil))

(use-package treemacs-icons-dired
  :hook (dired-mode . treemacs-icons-dired-enable-once))

(use-package treemacs-magit
  :after (treemacs magit))

Completion

Ignore case

 (setq read-buffer-completion-ignore-case t
	read-file-name-completion-ignore-case t
	completion-ignore-case t)

Vertico

(use-package vertico
  :demand t
  :straight (:files (:defaults "extensions/*"))
  :bind (:map vertico-map
		("C-j" . vertico-next)
		("C-k" . vertico-previous)
		("C-l" . vertico-insert)
		:map minibuffer-local-map
		("M-h" . backward-kill-word))
  :custom
  (vertico-cycle t)
  :config
  (vertico-mode 1)
  (advice-add #'vertico--format-candidate :around
		(lambda (orig cand prefix suffix index _start)
		  (setq cand (funcall orig cand prefix suffix index _start))
		  (concat
		   (if (= vertico--index index)
		       (propertize "ยป " 'face 'vertico-current)
		     "  ")
		   cand))))

(use-package vertico-directory
  :demand t
  :after vertico
  :straight nil
  :bind (:map vertico-map
		("RET" . vertico-directory-enter)
		("DEL" . vertico-directory-delete-char)
		("M-DEL" . vertico-directory-delete-word))
  :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))

Save history

(use-package savehist
  :demand t
  :after vertico
  :hook
  (on-first-input . savehist-mode))

Consult

(use-package consult
  :general
  (jtd/leader-key
    "bb" 'consult-buffer
    "fr" 'consult-recent-file
    "pb" 'consult-project-buffer
    "so" 'consult-outline
    "si" 'consult-isearch
    "sr" 'consult-ripgrep
    "ss" 'consult-line)
  :init
  (setq xref-show-xrefs-function #'consult-xref
	  xref-show-definitions-function #'consult-xref)
  :config
  (setq consult-project-root-function #'project-root))

Embark

(use-package embark
  :bind
  (("C-." . embark-act)
   ("C-;" . embark-dwim)
   ("C-h B" . embark-bindings))
  :init
  (setq prefix-help-command #'embark-prefix-help-command)
  :config
  (add-to-list 'display-buffer-alist
		 '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
		   nil
		   (window-parameters (mode-line-format . none)))))

(use-package embark-consult
  :after (embark consult)
  :demand t
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Marginalia

(use-package marginalia
  :after vertico
  :hook
  (on-first-input . marginalia-mode))

Better search matching

(use-package fussy
  :demand t
  :after vertico
  :config
  (push 'fussy completion-styles)
  (setq completion-category-defaults nil
	  completion-category-overrides nil))

(use-package orderless
  :demand t
  :after fussy
  :commands orderless-filter
  :init
  (setq fussy-filter-fn 'fussy-filter-orderless))

Corfu

(use-package corfu
  :hook ((prog-mode . corfu-mode)
         (org-mode . corfu-mode))
  :bind
  (:map corfu-map
        ("C-j" . corfu-next)
        ("C-k" . corfu-previous))
  :general
  (evil-insert-state-map "C-k" nil)
  :custom
  (corfu-auto nil)
  (corfu-cycle t)
  (corfu-min-width 80)
  (corfu-max-width corfu-min-width)
  (corfu-preselect-first t)
  :init
  (defun corfu-enable-always-in-minibuffer ()
    "Enable Corfu in the minibuffer if Vertico/Mct are not active."
    (unless (or (bound-and-true-p mct--active) ; Useful if I ever use MCT
                (bound-and-true-p vertico--input))
      (setq-local corfu-auto nil)       ; Ensure auto completion is disabled
      (corfu-mode 1)))
  (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1))

(use-package corfu-terminal
  :if (not (display-graphic-p))
  :config
  (corfu-terminal-mode +1))

(use-package cape
  :init
  ;; Add `completion-at-point-functions', used by `completion-at-point'.
  ;; (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-file)
  ;;(add-to-list 'completion-at-point-functions #'cape-history)
  ;;(add-to-list 'completion-at-point-functions #'cape-keyword)
  ;;(add-to-list 'completion-at-point-functions #'cape-tex)
  ;;(add-to-list 'completion-at-point-functions #'cape-sgml)
  ;;(add-to-list 'completion-at-point-functions #'cape-rfc1345)
  ;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
  ;;(add-to-list 'completion-at-point-functions #'cape-ispell)
  ;;(add-to-list 'completion-at-point-functions #'cape-dict)
  ;;(add-to-list 'completion-at-point-functions #'cape-symbol)
  ;;(add-to-list 'completion-at-point-functions #'cape-line)
)

Kind icon

(use-package kind-icon
  :demand t
  :after corfu
  :custom
  (kind-icon-default-face 'corfu-default)
  :config
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

Search

Avy

(use-package avy
  :general
  (jtd/leader-key
    "SPC" 'evil-avy-goto-subword-1
    "j" '(:ignore t :wk "jump")
    "jJ" 'evil-avy-goto-char-2
    "jj" 'evil-avy-goto-char
    "jl" 'evil-avy-goto-line
    "jw" 'evil-avy-goto-subword-1))

Org

Org mode

(use-package org
  :defer t
  :hook
  (org-mode . variable-pitch-mode)
  (org-mode . visual-line-mode)
  :general
  (jtd/leader-key
    "o" '(:ignore t :wk "org")
    "oa" 'org-agenda-list
    "oc" 'org-capture
    "om" 'org-tags-view
    "oo" 'org-agenda
    "ot" 'org-todo-list)
  :custom
  (org-startup-indented t)
  (org-agenda-files '("~/org/inbox.org"
			"~/org/projects.org"
			"~/org/tickler.org"))
  (org-refile-targets '(("~/org/projects.org" :maxlevel . 3)
			  ("~/org/someday.org" :level . 1)
			  ("~/org/tickler.org" :maxlevel . 2)))
  (org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)")))
  :config
  (jtd/local-leader-key :keymaps 'org-mode-map
    "!" 'org-time-stamp-inactive
    "'" 'org-edit-special
    "*" 'org-ctrl-c-star
    "," 'org-ctrl-c-ctrl-c
    "-" 'org-ctrl-c-minus
    "." 'org-time-stamp
    "/" 'org-sparse-tree
    ":" 'org-set-tags
    "A" 'org-archive-subtree
    "D" 'org-insert-drawer
    "H" 'org-shiftleft
    "I" 'org-clock-in
    "J" 'org-shiftdown
    "K" 'org-shiftup
    "L" 'org-shiftright
    "N" 'widen
    "O" 'org-clock-out
    "P" 'org-set-property
    "R" 'org-refile
    "Sh" 'org-promote-subtree
    "Sj" 'org-move-subtree-down
    "Sk" 'org-move-subtree-up
    "Sl" 'org-demote-subtree
    "T" 'org-show-todo-tree
    "^" 'org-sort
    "a" 'org-agenda
    "b" 'org-tree-to-indirect-buffer
    "c" 'org-capture
    "d" 'org-deadline
    "e" 'org-export-dispatch
    "f" 'org-set-effort
    "hI" 'org-insert-heading
    "hi" 'org-insert-heading-after-current
    "hs" 'org-insert-subheading
    "ia" 'org-attach
    "if" 'org-footnote-new
    "il" 'org-insert-link
    "l" 'org-open-at-point
    "n" 'org-narrow-to-subtree
    "q" 'org-clock-cancel
    "s" 'org-schedule
    "tE" 'org-table-export
    "tH" 'org-table-move-column-left
    "tI" 'org-table-import
    "tJ" 'org-table-move-row-down
    "tK" 'org-table-move-row-up
    "tL" 'org-table-move-column-right
    "tN" 'org-table-create-with-table.el
    "ta" 'org-table-align
    "tb" 'org-table-blank-field
    "tc" 'org-table-convert
    "tdc" 'org-table-delete-column
    "tdr" 'org-table-kill-row
    "te" 'org-table-eval-formula
    "th" 'org-table-previous-field
    "tiH" 'org-table-hline-and-move
    "tic" 'org-table-insert-column
    "tih" 'org-table-insert-hline
    "tir" 'org-table-insert-row
    "tj" 'org-table-next-row
    "tl" 'org-table-next-field
    "tn" 'org-table-create
    "tr" 'org-table-recalculate
    "ts" 'org-table-sort-lines
    "ttf" 'org-table-toggle-formula-debugger
    "tto" 'org-table-toggle-coordinate-overlays
    "tw" 'org-table-wrap-region
    "RET" 'org-ctrl-c-ret)
  (jtd/local-leader-key
    :definer 'minor-mode
    :keymaps 'org-src-mode
    "c" 'org-edit-src-exit
    "a" 'org-edit-src-abort
    "k" 'org-edit-src-abort)
  (setq org-capture-templates
	  `(("b" "Books")
	    ("bf" "Finished book" table-line
	     (file+headline ,(concat org-directory "/books.org") "Finished")
	     "| %^{Title} | %^{Author} | %u |")
	    ("br" "Book to read" entry
	     (file+headline ,(concat org-directory "/books.org") "To Read")
	     "* %i%?\n")
	    ("g" "GTD")
	    ("gt" "Todo [inbox]" entry
	     (file+headline ,(concat org-directory "/inbox.org") "Tasks")
	     "* TODO %i%?")
	    ("gT" "Tickler" entry
	     (file+headline ,(concat org-directory "/tickler.org") "Tickler")
	     "* %i%? \n %U")
	    ("i" "Ideas")
	    ("ib" "Blog idea" entry
	     (file ,(concat org-directory "/blog-ideas.org"))
	     "* %?\n")
	    )))

Evil integration

(use-package evil-org
  :hook (org-mode . evil-org-mode)
  :config
  (require 'evil-org-agenda)
  (evil-org-agenda-set-keys)
  (evil-org-set-key-theme '(textobjects
			      insert
			      navigation
			      additional
			      shift
			      todo
			      heading)))

Structure templates

(use-package org-tempo
  :after org
  :straight nil
  :config
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("py" . "src python"))
  (add-to-list 'org-structure-template-alist '("sh" . "src shell")))

Modern

(use-package org-modern
  :hook
  (org-mode . org-modern-mode))

Writing

Writeroom

(use-package writeroom-mode
  :general
  (jtd/leader-key "Tw" 'writeroom-mode))

Darkroom

(use-package darkroom
  :general
  (jtd/leader-key "Td" 'darkroom-tentative-mode))

Spelling

(use-package flyspell
  :hook
  (text-mode . flyspell-mode)
  (prog-mode . flyspell-prog-mode)
  :custom
  (ispell-program-name "aspell"))

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map
		("C-;" . flyspell-correct-wrapper)))

Programming

Line numbers

(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'conf-mode-hook #'display-line-numbers-mode)

Version control

magit

(use-package magit
  :general
  (jtd/leader-key
    "gb" 'magit-blame
    "gl" 'magit-log
    "gg" 'magit-status
    "gG" 'magit-status-here))

Time machine

(use-package git-timemachine
  :straight (:package "git-timemachine"
			:type git
			:host nil
			:repo "https://codeberg.org/pidu/git-timemachine.git")
  :hook
  (git-time-machine-mode . evil-normalize-keymaps)
  :custom
  (git-timemachine-show-minibuffer-details t)
  :general
  (jtd/leader-key
    "gt" 'git-timemachine)
  (git-timemachine-mode-map
   "C-k" 'git-timemachine-show-previous-revision
   "C-j" 'git-timemachine-show-next-revision
   "q" 'git-timemachine-quit))

Highlight uncommitted changes

(use-package diff-hl
  :hook
  ((prog-mode text-mode vc-dir-mode) . diff-hl-mode)
  (magit-pre-refresh . diff-hl-magit-pre-refresh)
  (magit-post-refresh . diff-hl-magit-post-refresh))

smerge

(use-package smerge-mode
  :straight (:type built-in)
  :after hydra
  :general
  (jtd/leader-key "gm" 'smerge-hydra/body)
  :hook
  (magit-diff-visit-file . (lambda ()
			       (when smerge-mode
				 (smerge-hydra/body))))
  :init
  (defhydra smerge-hydra (:hint nil
				  :pre (smerge-mode 1)
				  :post (smerge-auto-leave))
    "
																										  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
	  Movement   Keep           Diff              Other โ”‚ smerge โ”‚
	  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
		   ^_g_^       [_b_] base       [_<_] upper/base    [_C_] Combine
		   ^_C-k_^     [_u_] upper      [_=_] upper/lower   [_r_] resolve
		   ^_k_ โ†‘^     [_l_] lower      [_>_] base/lower    [_R_] remove
		   ^_j_ โ†“^     [_a_] all        [_H_] hightlight
		   ^_C-j_^     [_RET_] current  [_E_] ediff             โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
		   ^_G_^                                            โ”‚ [_q_] quit"
    ("g" (progn (goto-char (point-min)) (smerge-next)))
    ("G" (progn (goto-char (point-max)) (smerge-prev)))
    ("C-j" smerge-next)
    ("C-k" smerge-prev)
    ("j" next-line)
    ("k" previous-line)
    ("b" smerge-keep-base)
    ("u" smerge-keep-upper)
    ("l" smerge-keep-lower)
    ("a" smerge-keep-all)
    ("RET" smerge-keep-current)
    ("\C-m" smerge-keep-current)
    ("<" smerge-diff-base-upper)
    ("=" smerge-diff-upper-lower)
    (">" smerge-diff-base-lower)
    ("H" smerge-refine)
    ("E" smerge-ediff)
    ("C" smerge-combine-with-next)
    ("r" smerge-resolve)
    ("R" smerge-kill-current)
    ("q" nil :color blue)))

Project management

(use-package project
  :straight (:type built-in)
  :general
  (jtd/leader-key
    "p" '(:ignore t :wk "project")
    "pD" 'project-dired
    "pf" 'project-find-file
    "pk" 'project-kill-buffers
    "pp" 'project-switch-project))

Comments

(use-package evil-commentary
  :hook (prog-mode . evil-commentary-mode))

Treat _ as part of a word like vim

(add-hook 'prog-mode-hook (lambda () (modify-syntax-entry ?_ "w")))

Delete trailing white space

(add-hook 'before-save-hook
	    (lambda ()
	      (when (derived-mode-p 'prog-mode)
		(whitespace-cleanup))))

Terminal emulation

(use-package vterm
  :general
  (jtd/leader-key
    "'" 'vterm))

(use-package vterm-toggle
  :general
  (jtd/leader-key
    "`" 'vterm-toggle-cd))

Completion

(use-package company
  :hook (prog-mode . company-mode)
  :custom
  (company-minimum-prefix-length 1))

Snippets

(use-package yasnippet
  :config
  (yas-global-mode 1))

(use-package yasnippet-snippets
  :after yasnippet)

(use-package company-yasnippet
  :straight (:type built-in))

Formatting

(use-package apheleia
  :commands apheleia-mode)

Tree sitter

(use-package tree-sitter
  :hook
  (on-first-buffer . global-tree-sitter-mode)
  (tree-sitter-after-on . tree-sitter-hl-mode))

(use-package tree-sitter-langs
  :defer 1)

Rainbow Delimiters

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

Smartparens

(use-package smartparens
  :hook (prog-mode . smartparens-mode))

Copilot

(use-package copilot
  :straight (:host github :repo "zerolfx/copilot.el"
                   :files ("dist" "*.el"))
  :general
  (jtd/leader-key
    "c" '(:ignore t :wk "copilot")
    "cx" 'copilot-clear-overlay
    "cc" 'copilot-complete)
  (copilot-completion-map
   "TAB" 'copilot-accept-completion)
  :init
  (with-eval-after-load 'company
    ;; disable inline previews
    (delq 'company-preview-if-just-one-frontend company-frontends)))

Docker

(use-package dockerfile-mode
  :defer t)

Lisps

Lispy

(use-package lispy
  :hook (emacs-lisp-mode . lispy-mode))

Lispyville

(use-package lispyville
  :hook (lispy-mode . lispyville-mode)
  :config
  (lispyville-set-key-theme '((operators normal)
				c-w
				(prettify insert)
				(atom-movement t)
				slurp/barf-lispy
				additional
				additional-insert)))

Eglot

(defun jtd/eglot-cap-config ()
  (setq-local completion-at-point-functions
              (list (cape-super-capf
                     #'eglot-completion-at-point
                     (cape-company-to-capf #'company-yasnippet)))))

(use-package eglot
  :defer 2
  :hook
  (before-save . eglot-format-buffer)
  (eglot-managed-mode . jtd/eglot-cap-config)
  :custom
  (eglot-confirm-server-initiated-edits nil)
  :general
  (jtd/local-leader-key eglot-mode-map
    "l" '(:ignore t :wk "lsp")
    "la" 'eglot-code-actions
    "lf" 'eglot-format
    "lh" 'eldoc
    "lr" 'eglot-rename))

Breadcrumb

(cl-defgeneric project-name (project)
  "A human-readable name for the project.
Nominally unique, but not enforced."
  (file-name-base (directory-file-name (project-root project))))

(use-package breadcrumb
  :straight (:repo "joaotavora/breadcrumb"
             :host github))

Rust

(use-package rustic
  :hook
  (rustic-mode . eglot-ensure)
  :custom
  (rustic-lsp-client 'eglot)
  :general
  (jtd/local-leader-key
    :keymaps 'rustic-mode-map
    "=" 'rustic-cargo-fmt
    "c" '(:ignore t :wk "cargo")
    "cC" 'rustic-cargo-clippy
    "ca" 'rustic-cargo-add
    "cb" 'rustic-cargo-build
    "cc" 'rustic-cargo-check
    "cd" 'rustic-cargo-doc
    "cf" 'rustic-cargo-clippy-fix
    "co" 'rustic-cargo-outdated
    "cu" 'rustic-cargo-upgrade
    "cx" 'rustic-cargo-run
    "t" '(:ignore t :wk "test")
    "ta" 'rustic-cargo-test
    "tt" 'rustic-cargo-current-test))

Elixir

(use-package elixir-mode
  :after eglot
  :hook
  (elixir-mode . eglot-ensure)
  :config
  (add-to-list 'eglot-server-programs '(elixir-mode "~/.emacs.d/elixir-ls/release/language_server.sh")))

(defun jtd/elixir-format-on-save ()
  (add-hook 'before-save-hook 'elixir-format nil t))

(use-package elixir-format
  :after elixir-mode
  :straight nil
  :hook
  (elixir-mode . jtd/elixir-format-on-save))

YAML

(use-package yaml-mode
  :hook
  (yaml-mode . display-line-numbers-mode)
  :commands yaml-mode)

Apps

Notes

(use-package deft
  :general
  (jtd/leader-key
    "n" '(:ignore t :wk "notes")
    "nf" 'deft-find-file
    "nv" 'deft)
  (jtd/local-leader-key :keymaps 'deft-mode-map
    "c" 'deft-filter-clear
    "d" 'deft-delete-file
    "i" 'deft-toggle-incremental-search
    "n" 'deft-new-file
    "r" 'deft-rename-file)
  :config
  (evil-set-initial-state 'deft-mode 'insert)

  (setq deft-default-extension "org"
	  deft-directory "~/notes"
	  deft-use-filename-as-title nil
	  deft-use-filter-string-for-filename t))

Email

mu4e

(use-package mu4e
  :straight nil
  :custom
  (mu4e-attachment-dir (expand-file-name "~/Downloads"))
  (mu4e-headers-fields '((:human-date . 12)
			   (:flags . 6)
			   (:from . 22)
			   (:subject)))
  :general
  (jtd/leader-key
    "am" 'mu4e))

org-msg

(use-package org-msg
  :after mu4e)

RSS

(use-package elfeed
  :custom
  (elfeed-sort-order 'ascending)
  :general
  (jtd/leader-key
    "af" 'elfeed))

(use-package elfeed-protocol
  :after elfeed
  :config
  (elfeed-protocol-enable))

IRC

(use-package circe
  :custom
  (circe-reduce-lurker-spam t)
  :general
  (jtd/leader-key
    "ac" 'circe)
  :config
  (enable-circe-color-nicks))

OpenAI

ChatGPT

(use-package chatgpt-shell
  :straight (:host github :repo "xenodium/chatgpt-shell")
  :custom
  (chatgpt-shell-openai-key
   (lambda ()
     (auth-source-pick-first-password :host "api.openai.com")))
  :commands chatgpt-shell)

Dall-E

(use-package dall-e-shell
  :straight (:host github :repo "xenodium/chatgpt-shell")
  :custom
  (dall-e-shell-openai-key
   (lambda ()
     (auth-source-pick-first-password :host "api.openai.com")))
  :commands dall-e-shell)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.