dotfiles/guix/init.org

1005 lines
36 KiB
Org Mode

#+title Ian's Emacs Config
#+PROPERTY: header-args:emacs-lisp :tangle ~/.config/emacs/init.el
* First things first
** Literate Config Setup
To get started, run =C-c C-v t=
#+begin_src emacs-lisp
(defun dotfiles/org-babel-tangle-config ()
(when (string-equal (buffer-file-name)
(expand-file-name "~/dotfiles/guix/init.org"))
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle))))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'dotfiles/org-babel-tangle-config)))
#+end_src
** Package initialization
#+begin_src emacs-lisp
;; Initialize Package Sources
(require 'package)
(setq package-archives
'(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
;; Initialize use-package on non-linux platforms
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
:init
(savehist-mode))
#+end_src
** Secrets
#+begin_src emacs-lisp
(use-package pinentry)
(use-package pass)
(use-package password-store)
(pinentry-start)
(setq gptel-api-key (password-store-get "openai-alt")) ;; TODO if-macos
#+end_src
** Global variables
** Handle config file
#+begin_src emacs-lisp
(setq user-init-file (expand-file-name "~/.config/emacs/init.el"))
(defun reload-config ()
"Reload the Emacs configuration."
(interactive)
(load-file user-init-file))
#+end_src
** Required directories for emacs setup
#+begin_src emacs-lisp
(defun ensure-directory (dir)
"Ceate a dir if it doesn't exist."
(unless (file-directory-p dir)
(make-directory dir t)))
(ensure-directory "~/.config/emacs/backups/")
(ensure-directory "~/.config/emacs/autosaves")
(ensure-directory "~/notes/roam")
(ensure-directory "~/notes/deft")
(ensure-directory "~/notes/code")
(ensure-directory "~/.config/emacs/video")
(ensure-directory "~/.config/emacs/audio")
(setq deft-directory "~/notes/deft"
org-roam-directory "~/notes/roam"
projectile-project-search-path '("~/code/")
empv-video-dir "~/.config/emacs/video"
empv-audio-dir "~/.config/emacs/audio"
backup-directory-alist `(("." . "~/.config/emacs/backups/"))
auto-save-file-name-transforms `((".*" "~/.config/emacs/autosaves/" t)))
#+end_src
** Helper Functions
#+begin_src emacs-lisp
(defun custom/eval-region-or-buffer ()
"Eval the region if anything is selected, otherwise eval the whole buffer."
(interactive)
(if mark-active
(eval-region (region-beginning) (region-end))
(eval-buffer)))
(defun custom/conditional-imenu ()
"Call `consult-org-heading` in Org mode, otherwise `consult-imenu`."
(interactive)
(if (eq major-mode 'org-mode)
(consult-org-heading)
(consult-imenu)))
#+end_src
* One-Line Includes
#+begin_src emacs-lisp
(use-package treemacs)
#+end_src
* Notes
#+begin_src emacs-lisp
(use-package deft)
(setq deft-recursive t
deft-extensions '("org" "txt"))
#+end_src
* AI
#+begin_src emacs-lisp
(use-package gptel)
(setq gptl-default-mode 'org-mode)
#+end_src
* Org Mode
#+begin_src emacs-lisp
(use-package org)
; (add-hook 'org-mode-hook 'yas-minor-mode)
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)))
(setq org-confirm-babel-evaluate nil)
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(use-package org-make-toc
:hook (org-mode . org-make-toc-mode))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(setq org-hide-emphasis-markers t)
(use-package org-appear
:hook (org-mode . org-appear-mode))
#+end_src
* Basic Appearance and Behaviors
#+begin_src emacs-lisp
(setq inhibit-startup-message t)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(recentf-mode 1)
(savehist-mode 1) ; remember previous commands in minibuffer
(save-place-mode 1) ; put cursor in last place when opening a file
;; Avoid customization UI auto-variables in init.el
(setq custom-file (locate-user-emacs-file "custom-vars.el"))
(load custom-file 'noerror 'nomessage)
;; Don't show popup UI when prompting
(setq use-dialog-box nil)
;; Update files when changed on disk
(global-auto-revert-mode 1)
(set-frame-font "DejaVu Sans Mono 14")
(use-package simple-modeline
:hook (after-init . simple-modeline-mode))
(use-package base16-theme)
(load-theme 'base16-oceanicnext t)
(global-display-line-numbers-mode t)
(dolist (mode
'(org-mode-hook
term-mode-hook
eshell-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
(column-number-mode)
(use-package default-text-scale
:defer 1
:config
(default-text-scale-mode))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package helpful) ; Slightly more helpful help
(setq tab-always-indent 'complete)
(setq tab-first-completion 'word)
;; Generate buffers in last window
(setq display-buffer-base-action
'(display-buffer-reuse-mode-window
display-buffer-reuse-window
display-buffer-same-window))
;; If a popup does happen, don't resize windows to be equal-sized
(setq even-window-sizes nil)
#+end_src
* Navigation
** Helper Functions
#+begin_src emacs-lisp
(defun split-and-follow-horizontally ()
(interactive)
(split-window-below)
(balance-windows)
(other-window 1))
(defun split-and-follow-vertically ()
(interactive)
(split-window-right)
(balance-windows)
(other-window 1))
#+end_src
** Direct keymaps
#+begin_src emacs-lisp
(global-set-key (kbd "s-c") 'delete-window)
(global-set-key (kbd "s-h") 'windmove-left)
(global-set-key (kbd "s-j") 'windmove-down)
(global-set-key (kbd "s-k") 'windmove-up)
(global-set-key (kbd "s-l") 'windmove-right)
; (define-key evil-normal-state-map (kbd "s-d") 'kill-this-buffer)
; (define-key evil-normal-state-map (kbd "s-n") 'projectile-next-project-buffer)
; (define-key evil-normal-state-map (kbd "s-p") 'projectile-previous-project-buffer)
; (define-key evil-normal-state-map (kbd "s-J") 'split-and-follow-horizontally)
; (define-key evil-normal-state-map (kbd "s-L") 'split-and-follow-vertically)
; (define-key evil-normal-state-map (kbd "s-b") 'buffer-menu)
; (define-key evil-normal-state-map (kbd "s-x") 'execute-extended-command)
(global-set-key (kbd "s-SPC") 'tab-next)
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
(use-package winner
:after evil
:config
(winner-mode))
#+end_src
** Workspaces
#+begin_src emacs-lisp
(use-package perspective)
(unless (equal persp-mode t)
(persp-mode))
#+end_src
** Dired
#+begin_src emacs-lisp
(setq ring-bell-function 'ignore)
(setq dired-listing-switches "-al")
(setq dired-dwim-target t) ; opening 'other window' on a subdir enters 2 window dired mode for copy/paste
(use-package dired-single)
(defun my-dired-init ()
"Bunch of stuff to run for dired, either immediately or when it's
loaded."
;; <add other stuff here>
(define-key dired-mode-map [remap dired-find-file]
'dired-single-buffer)
(define-key dired-mode-map [remap dired-mouse-find-file-other-window]
'dired-single-buffer-mouse)
(define-key dired-mode-map [remap dired-up-directory]
'dired-single-up-directory))
;; if dired's already loaded, then the keymap will be bound
(if (boundp 'dired-mode-map)
;; we're good to go; just add our bindings
(my-dired-init)
;; it's not loaded yet, so add our bindings to the load-hook
(add-hook 'dired-load-hook 'my-dired-init))
(use-package dired-open
:config
(setq dired-open-extensions '(("png" . "sxiv")
("mkv" . "mpv")
("avi" . "mpv"))))
(use-package all-the-icons-dired
:hook (dired-mode . all-the-icons-dired-mode))
#+end_src
** Treemacs
#+begin_src emacs-lisp
(use-package treemacs-all-the-icons)
#+end_src
** Which-key
#+begin_src emacs-lisp
(use-package which-key
:init (which-key-mode)
:diminish which-key-mode
:config
(setq which-key-idle-delay 0.3))
#+end_src
** General
#+begin_src emacs-lisp
(use-package general
:ensure t
:config
(general-create-definer general-definition
:keymaps '(normal insert visual emacs)
:prefix "SPC"
:global-prefix "C-SPC")
(general-definition
;; Top level bindings
"SPC" '(projectile-find-file :which-key "Find project file")
"<backspace>" '(treemacs-find-file :which-key "Find current file in sidebar")
"," '(+ivy/switch-workspace-buffer :which-key "Buffers (workspace)")
"/" '(consult-ripgrep :which-key "Search project")
":" '(execute-extended-command :which-key "M-x")
";" '(eval-expression :which-key "Eval")
"<" '(consult-buffer :which-key "Buffers (all)")
"x" '(scratch-buffer :which-key "Scratch popup")
"-" '(dired :which-key "Find Directory")
"*" '(counsel-locate :which-key "Fuzzy find file") ;; find-file? consult-locate?
"d" '(docker :which-key "Docker")
"i" '(custom/conditional-imenu :which-key "Imenu") ;; consult-outline?
;; Agenda
"a" '(:ignore t :which-key "Agenda")
"aa" '(org-agenda :which-key "Open Agenda")
"a/" '(consult-org-agenda :which-key "Search agenda headlines")
"ac" '(:ignore t :which-key "Clock")
"acc" '(org-clock-goto :which-key "Active clock")
"ack" '(org-clock-cancel :which-key "Cancel current clock")
"act" '(+org/toggle-last-clock :which-key "Toggle last clock")
;; Buffers / bookmarks
"b" '(:ignore t :which-key "Buffers")
"bb" '(counsel-bookmark :which-key "Goto Bookmark") ;; consult-bookmark
"bk" '(kill-current-buffer :which-key "Kill buffer")
"bm" '(bookmark-set :which-key "Set bookmark")
"bM" '(bookmark-delete :which-key "Delete bookmark")
;; "bo" '(NEEDS CUSTOM FUNCTION :which-key "Kill other buffers")
"br" '(revert-buffer :which-key "Revert buffer")
"bR" '(rename-buffer :which-key "Rename buffer")
"bz" '(bury-buffer :which-key "Bury buffer")
;; "bZ" '(NEEDS CUSTOM FUNCTION :which-key "Kill buried buffers")
"bj" '(+ivy/jump-list :which-key "Jump list")
"bu" '(vundo :which-key "Undo history")
;; Code
"c" '(:ignore t :which-key "Code")
"cc" '(compile :which-key "Compile")
"cC" '(recompile :which-key "Recompile")
"cd" '(+lookup/definition :which-key "Goto definition")
"cr" '(+lookup/references :which-key "Goto references")
"ce" '(custom/eval-region-or-buffer :which-key "Eval buffer/region")
;; "cf" '(NOT A COMMAND (re-do) :which-key "Format buffer/region")
"ci" '(+lookup/implementations :which-key "Find implementations")
"cj" '(lsp-ivy-workspace-symbol :which-key "Goto symbol (curr. workspace)")
"cJ" '(lsp-ivy-global-workspace-symbol :which-key "Goto symbol (any workspace)")
"ck" '(+lookup/documentation :which-key "Jump to documentation")
"cl" '(+default/lsp-command-map :which-key "LSP")
"co" '(lsp-organize-imports :which-key "LSP organize imports")
"cR" '(lsp-rename :which-key "LSP rename")
"cs" '(+eval/send-region-to-repl :which-key "Send to repl")
"ct" '(+lookup/type-definition :which-key "Find type definition")
"cw" '(delete-trailing-whitespace :which-key "Delete trailing whitespace")
;; "cn" '(doom/delete-trailing-newlines :which-key "Delete trailing newlines")
"cx" '(+default/diagnostics :which-key "List errors")
;; File
"f" '(:ignore t :which-key "File")
;; "fp" '(doom/open-private-config :which-key "Browse private config")
"fr" '(counsel-recentf :which-key "Recent files")
"fR" '(reload-config :which-key "Reload config")
;; "fm" '(doom/move-this-file :which-key "Move/rename file")
;; "fS" '(doom/sudo-find-file :which-key "Sudo find file")
;; "fs" '(doom/sudo-this-file :which-key "Sudo this file")
"fy" '(+default/yank-buffer-path :which-key "yank file path")
"fY" '(+default/yank-buffer-path-relative-to-project :which-key "Yank file path from project")
;; Git
"g" '(:ignore t :which-key "git")
"gb" '(magit-branch-checkout :which-key "magit switch branch")
"gB" '(magit-blame-addition :which-key "magit blame")
"gF" '(magit-fetch :which-key "magit fetch")
"gg" '(magit-status :which-key "magit status")
"gG" '(magit-status-here :which-key "magit status here")
"gL" '(magit-log-buffer-file :which-key "magit buffer log")
"gt" '(git-timemachine-toggle :which-key "git time machine")
"gd" '(:ignore t :which-key "dispatch")
"gdF" '(forge-dispatch :which-key "Forge dispatch")
"gdd" '(magit-dispatch :which-key "Magit dispatch")
"gdf" '(magit-file-dispatch :which-key "Magit file dispatch")
"gf" '(:ignore t :which-key "find")
"gfc" '(magit-show-commit :which-key "find commit")
"gff" '(magit-find-file :which-key "find file")
"gfg" '(magit-find-git-config-file :which-key "find gitconfig file")
"gfi" '(forge-visit-issue :which-key "find issue")
"gfp" '(forge-visit-pullreq :which-key "find pull request")
"gh" '(:ignore t :which-key "hunk")
"ghn" '(+vc-gutter/previous-hunk :which-key "jump to previous hunk")
"ghp" '(+vc-gutter/next-hunk :which-key "jump to next hunk")
"ghr" '(+vc-gutter/revert-hunk :which-key "revert hunk at point")
"ghs" '(+vc-gutter/stage-hunk :which-key "stage hunk at point")
"gl" '(:ignore t :which-key "list")
"gli" '(forge-list-issues :which-key "list issues")
"gln" '(forge-list-notifications :which-key "list notifications")
"glp" '(forge-list-pullreqs :which-key "list pull requests")
"glr" '(forge-list-issues :which-key "list repositories")
"gls" '(magit-list-submodules :which-key "list submodules")
"go" '(:ignore t :which-key "open")
"goI" '(forge-browse-issues :which-key "Browse issues")
"goP" '(forge-browse-pullreqs :which-key "Browse pull requests")
"goc" '(forge-browse-commit :which-key "Browse commit")
"goh" '(+vc/browse-at-remote-homepage :which-key "Browse homepage")
"goi" '(forge-browse-issue :which-key "Browse an issue")
"goo" '(+vc/browse-at-remote :which-key "Browse file or region")
"gop" '(forge-browse-pullreq :which-key "Browse a pull request")
"gor" '(forge-browse-remote :which-key "Browse remote")
;; Help
"h" '(:ignore t :which-key "help")
"h<return>" '(info-emacs-manual :which-key "Emacs manual")
"h'" '(describe-char :which-key "Describe character")
"ha" '(counsel-apropos :which-key "Apropos")
"hb" '(embark-bindings :which-key "Describe bindings")
"he" '(view-echo-area-messages :which-key "View echo area messages")
"hf" '(helpful-function :which-key "Describe function")
"hi" '(info :which-key "Info")
"hk" '(helpful-key :which-key "Describe key")
"hl" '(view-lossage :which-key "View actions log")
"hm" '(describe-mode :which-key "Describe mode")
"ho" '(counsel-describe-symbol :which-key "Describe symbol")
"hv" '(helpful-variable :which-key "Describe variable")
"hx" '(helpful-command :which-key "Describe command")
"hA" '(apropos-documentation :which-key "Apropos(documentation)")
"hF" '(counsel-faces :which-key "Describe Face")
"hM" '(popwin:messages :which-key "View system messages")
"hw" '(:ignore t :which-key "which-key")
"hwf" '(which-key-show-full-keymap :which-key "Full keymap")
"hwi" '(which-key-show-minor-mode-keymap :which-key "Minor mode keymap")
"hwk" '(which-key-show-keymap :which-key "Show keymap")
"hwm" '(which-key-show-major-mode :which-key "Show major mode")
"hwt" '(which-key-show-top-level :which-key "Show top-level")
;; Notes
"nd" '(deft :which-key "Deft")
"nt" '(org-todo-list :which-key "Todo list")
"nf" '(org-roam-node-find :which-key "Find node")
"ng" '(org-roam-graph :which-key "Show graph")
"nr" '(org-roam-buffer-toggle :which-key "Toggle roam buffer")
"nb" '(org-roam-buffer-display-dedicated :which-key "Launch roam buffer")
"ns" '(org-roam-db-sync :which-key "Sync database")
"nc" '(org-roam-capture :which-key "Capture to node")
;; Org mode
"o" '(:ignore t :which-key "org")
"ol" '(org-store-link :which-key "Org store link")
"oc" '(org-capture :which-key "Org Capture")
"oC" '(org-capture-goto-target :which-key "Goto Capture")
"ot" '(org-babel-tangle-file :which-key "Org Tangle")
"oy" '(+org/export-to-clipboard :which-key "Org export to clipboard")
"oY" '(+org/export-to-clipboard-as-rich-text :which-key "Org export to clipboard (rich)")
"oe" '(:ignore t :which-key "export")
"oeh" '(org-html-export-to-html :which-key "Export Org to HTML")
"oa" '(:ignore t :which-key "attach")
"oaa" '(org-attach :which-key "Attach")
"oac" '(org-download-clipboard :which-key "Org download clipboard")
"oad" '(org-attach-delete-one :which-key "Delete one attachment")
"oaD" '(org-attach-delete-all :which-key "Delete all attachments")
"oas" '(org-attach-sync :which-key "Sync attachments")
"oay" '(org-download-yank :which-key "Org download yank")
;; Project
"p" '(:ignore t :which-key "project")
"ps" '(+neotree/open :which-key "Open project sidebar")
"pa" '(projectile-add-known-project :which-key "Add new project")
"pc" '(+ivy/project-compile :which-key "Compile in project")
"pd" '(projectile-remove-known-project :which-key "Remove known project")
"ps" '(counsel-projectile-switch-project :which-key "Switch projects")
"pC" '(projectile-configure-project :which-key "Configure project")
"pr" '(projectile-run-project :which-key "Run project")
"pt" '(magit-todos-list :which-key "List project todos")
"pT" '(projectile-test-project :which-key "Test project")
"pz" '(+taskrunner/project-tasks :which-key "List project tasks")
;; Shell
"s" '(:ignore t :which-key "shell")
"se" '(+eshell/toggle :which-key "Toggle eshell popup")
"sE" '(+eshell/here :which-key "Open eshell here")
"sr" '(+eval/open-repl-other-window :which-key "Repl")
"st" '(+vterm/toggle :which-key "Toggle vterm popup")
"sT" '(+vterm/here :which-key "Open vterm here")
;; Toggle
"t" '(:ignore t :which-key "toggle")
"tc" '(global-display-fill-column-indicator-mode :which-key "Fill Column Indicator")
"tf" '(flycheck-mode :which-key "Flycheck")
"tm" '(consult-minor-mode-menu :which-key "Minor modes")
"tp" '(org-tree-slide-mode :which-key "Org-tree-slide-mode")
"tw" '(+word-wrap-mode :which-key "Soft line wrapping")
"tz" '(+zen/toggle :which-key "Zen mode")
;; "tl" '(doom/toggle-line-numbers :which-key "Line numbers")
;; Visual / appearance
"v" '(:ignore t :which-key "visual/appearance")
"vt" '(counsel-load-theme :which-key "load theme")
;; Workspaces
"TAB TAB" '(+workspace/display :which-key "Display tab bar")
"TAB d" '(+workspace/delete :which-key "Delete this workspace")
"TAB l" '(+workspace/load :which-key "Load workspace from file")
"TAB n" '(+workspace/new :which-key "New workspace")
"TAB N" '(+workspace/new-named :which-key "New named workspace")
"TAB r" '(+workspace/rename :which-key "Rename workspace")
"TAB R" '(+workspace/restore-last-session :which-key "Restore last session")
"TAB s" '(+workspace/save :which-key "Save workspace")
"TAB x" '(+workspace/kill-session :which-key "Delete session")
))
#+end_src
* Project management
#+begin_src emacs-lisp
(use-package projectile) ; todo config inside use-package
(use-package treemacs-projectile)
#+end_src
* Autocomplete
** Vertico
#+begin_src emacs-lisp
(use-package vertico
:init
(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)
)
#+end_src
** Consult
#+begin_src emacs-lisp
(use-package consult
:bind (:map minibuffer-local-map ("C-r" . consult-history)))
#+end_src
** Generic completion
Idk I think this came from the vertico readme
#+begin_src emacs-lisp
(use-package emacs
:init
;; Add prompt indicator to `completing-read-multiple'.
;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
;; (setq read-extended-command-predicate
;; #'command-completion-default-include-p)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t))
(setq completion-styles '(basic substring partial-completion flex))
#+end_src
** Orderless
#+begin_src emacs-lisp
(use-package orderless
:init
;; Configure a custom style dispatcher (see the Consult wiki)
;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)
;; orderless-component-separator #'orderless-escapable-split-on-space)
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion)))))
#+end_src
** Marginalia
#+begin_src emacs-lisp
(use-package marginalia
;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding
;; available in the *Completions* buffer, add it to the
;; `completion-list-mode-map'.
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
;; The :init section is always executed.
:init
;; Marginalia must be activated in the :init section of use-package such that
;; the mode gets enabled right away. Note that this forces loading the
;; package.
(marginalia-mode))
#+end_src
** Company-mode
#+begin_src emacs-lisp
(use-package company
:ensure t
:hook (prog-mode . company-mode)
:diminish
:bind (:map company-active-map
("<tab>" . company-select-next)
("TAB" . company-select-next)
("<backtab>" . company-select-previous)
("<S-tab>" . company-select-previous))
(:map lsp-mode-map ; more general mode than this?
("<tab>" . company-indent-or-complete-common))
:config
(global-company-mode 1)
:init
(setq company-idle-delay nil))
#+end_src
** Embark
#+begin_src emacs-lisp
(use-package embark
:ensure t
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Show the Embark target at point via Eldoc. You may adjust the Eldoc
;; strategy, if you want to see the documentation from multiple providers.
(add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
: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)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:ensure t ; only need to install it, embark loads it after consult if found
:hook
(embark-collect-mode . consult-preview-at-point-mode))
#+end_src
** Snippets
#+begin_src emacs-lisp
(use-package yasnippet)
(use-package yasnippet-snippets)
(yas-global-mode)
#+end_src
<el
* Languages
** LSP
#+begin_src emacs-lisp
(use-package lsp-mode
:commands (lsp lsp-deferred)
:init
(setq lsp-keymap-prefix "C-c l")
:config
(lsp-enable-which-key-integration t)
:hook (terraform-mode . lsp-deferred)
:hook (rust-mode . lsp-deferred))
(use-package lsp-ui)
(use-package lsp-treemacs)
(use-package flycheck
:ensure t
:init (global-flycheck-mode))
#+end_src
** Rust
#+begin_src emacs-lisp
(use-package rust-mode
:ensure t
:mode "\\.rs\\'"
:config
(setq rust-format-on-save t)) ; Automatically format rust files on save
(use-package cargo
:ensure t
:hook (rust-mode . cargo-minor-mode))
#+end_src
** Terraform
#+begin_src emacs-lisp
(use-package terraform-mode
:ensure t)
#+end_src
** Lisp
All lisp-family languages
#+begin_src emacs-lisp
(use-package lispy)
(use-package lispyville
:init
(general-add-hook '(emacs-lisp-mode-hook lisp-mode-hook) #'lispyville-mode)
:config
(lispyville-set-key-theme '(operators c-w additional)))
#+end_src
* Shells
** Enable fish completions
Uses the external fish program to provide fish-style completions to eshell etc
#+begin_src emacs-lisp
(use-package fish-completion)
(when (and (executable-find "fish")
(require 'fish-completion nil t))
(global-fish-completion-mode))
#+end_src
* Git
#+begin_src emacs-lisp
(use-package git-gutter+)
(global-git-gutter+-mode t)
(use-package magit)
(use-package magit-todos)
(setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1)
#+end_src
* Meow
#+begin_src emacs-lisp
; (use-package 'meow)
; (defun meow-setup ()
; (setq meow-cheatsheet-layout meow-cheatsheet-layout-colemak)
; (meow-motion-overwrite-define-key
; ;; Use e to move up, n to move down.
; ;; Since special modes usually use n to move down, we only overwrite e here.
; '("e" . meow-prev)
; '("<escape>" . ignore))
; (meow-leader-define-key
; '("?" . meow-cheatsheet)
; ;; To execute the originally e in MOTION state, use SPC e.
; '("e" . "H-e")
; '("1" . meow-digit-argument)
; '("2" . meow-digit-argument)
; '("3" . meow-digit-argument)
; '("4" . meow-digit-argument)
; '("5" . meow-digit-argument)
; '("6" . meow-digit-argument)
; '("7" . meow-digit-argument)
; '("8" . meow-digit-argument)
; '("9" . meow-digit-argument)
; '("0" . meow-digit-argument))
; (meow-normal-define-key
; '("0" . meow-expand-0)
; '("1" . meow-expand-1)
; '("2" . meow-expand-2)
; '("3" . meow-expand-3)
; '("4" . meow-expand-4)
; '("5" . meow-expand-5)
; '("6" . meow-expand-6)
; '("7" . meow-expand-7)
; '("8" . meow-expand-8)
; '("9" . meow-expand-9)
; '("-" . negative-argument)
; '(";" . meow-reverse)
; '("," . meow-inner-of-thing)
; '("." . meow-bounds-of-thing)
; '("[" . meow-beginning-of-thing)
; '("]" . meow-end-of-thing)
; '("/" . meow-visit)
; '("a" . meow-append)
; '("A" . meow-open-below)
; '("b" . meow-back-word)
; '("B" . meow-back-symbol)
; '("c" . meow-change)
; '("d" . meow-delete)
; '("e" . meow-prev)
; '("E" . meow-prev-expand)
; '("f" . meow-find)
; '("g" . meow-cancel-selection)
; '("G" . meow-grab)
; '("m" . meow-left)
; '("M" . meow-left-expand)
; '("i" . meow-right)
; '("I" . meow-right-expand)
; '("j" . meow-join)
; '("k" . meow-kill)
; '("l" . meow-line)
; '("L" . meow-goto-line)
; '("h" . meow-mark-word)
; '("H" . meow-mark-symbol)
; '("n" . meow-next)
; '("N" . meow-next-expand)
; '("o" . meow-block)
; '("O" . meow-to-block)
; '("p" . meow-yank)
; '("q" . meow-quit)
; '("r" . meow-replace)
; '("s" . meow-insert)
; '("S" . meow-open-above)
; '("t" . meow-till)
; '("u" . meow-undo)
; '("U" . meow-undo-in-selection)
; '("v" . meow-search)
; '("w" . meow-next-word)
; '("W" . meow-next-symbol)
; '("x" . meow-delete)
; '("X" . meow-backward-delete)
; '("y" . meow-save)
; '("z" . meow-pop-selection)
; '("'" . repeat)
; '("<escape>" . ignore)))
;
; (require 'meow)
; (meow-setup)
; (meow-global-mode 1)
#+end_src
* Evil
#+begin_src emacs-lisp
(use-package evil
:ensure t
:config
(evil-mode 1))
(use-package undo-tree
:ensure t
:after evil
:diminish
:config
(evil-set-undo-system 'undo-tree)
(global-undo-tree-mode 1))
(use-package evil-org
:ensure t
:after org
:hook (org-mode . (lambda () evil-org-mode))
; :config
; (require 'evil-org-agenda)
; (evil-org-agenda-set-keys)
)
(use-package evil-collection
:after evil
:ensure t
:config
(evil-collection-init))
(setq evil-want-C-u-scroll t)
(setq evil-want-C-i-jump nil)
(setq evil-respect-visual-line-mode t)
#+end_src
* Web browsing and youtube
#+begin_src emacs-lisp
;; Using straight:
;;(use-package empv
;; :straight (:host github :repo "isamert/empv.el"))
(use-package empv)
(setq empv-radio-channels
'(("SomaFM - Groove Salad" . "http://www.somafm.com/groovesalad.pls")
("SomaFM - Drone Zone" . "http://www.somafm.com/dronezone.pls")
("SomaFM - Sonic Universe" . "https://somafm.com/sonicuniverse.pls")
("SomaFM - Metal" . "https://somafm.com/metal.pls")
("SomaFM - Vaporwaves" . "https://somafm.com/vaporwaves.pls")
("ADHD 1" . "https://www.youtube.com/watch?v=CmMrm4BpQHU")
("WREK FM" . "http://streaming.wrek.org:8000/wrek_live-128kb.m3u")
))
;; Todo: lainchan? adhd music stream from youtube? wuog? wrekFM? does freeside have streaming radio?
(with-eval-after-load 'embark (empv-embark-initialize-extra-actions))
(add-to-list 'empv-mpv-args "--ytdl-format=best")
(add-to-list 'empv-mpv-args "--save-position-on-quit")
(add-hook 'empv-init-hook #'empv-override-quit-key)
(setq empv-invidious-instance "https://invidious.projectsegfau.lt/api/v1")
#+end_src
* Todo
** General
- Refactor to use use-package more effectively
** Terminals
- More terminals
- emacs-fish-completions
- setup terminals to complete to vertico
- starship prompts
** New functions
- Git-time-machine-or-vc-region-history
** Note taking
- deft
- org : roam2, hugo, pretty, dragndrop, bullet
** Lisp stuff
- paredit
- lispy
** One-offs
- hl-todo
- persistent undo
- commentary
- highlight tabs and newlines
- [[https://youtu.be/UtqE-lR2HCA?t=5027][Vertico backwards delete]]
- alphabetical keybindings
- brighter modeline
- surpress global minor modes
- Undo-Tree, company, flycheck, which-key
- ignore case in imenu
- improve which-key visibility
** LSP stuff
- look into treemacs integrations
- consider eglot
- dap-mode
** Completion
- dabbrev-expand or company on c-n c-p
- c-N c-P for expand full line
- yasnippet
- company-mode to corfu (or vertico completions? or cofu-in-vertico?)
- get vertico as completion box
** Keybindings
- put general bindings in separate keymaps in separate sections
- map hyper bindings for buffer nav and jumping
- bind persp-mode
- bind lispy for colemak-dh
- bind lispy doc features and ide-like features
- bind embark
- evil-org
- map alignment functions in 'code'section
- define global meow-left and vim-left, swich contextually
- fix c-u in evil mode
- fix tab key
- window size functions, winner undo/redo
- map default-text-scale operations
- empv
- map
- empv-play-radio
- empv-play-random-channel
- empv-log-current-radio-song-name
- empv-youtube
- empv-play
- empv-play-{file,audio,video,directory,radio,random-channel}
- empv-playlist-{select,next,prev,clear,shuffle}
- empv-display-current
- empv-toggle
- empv-toggle-video
- empv-youtube
- empv-volume-{down,up}
- empv-chapter-{prev,next,select}
- empv-exit
- configure
- empv-radio-log-file
- empv-radio-log-format
- spc m y(outube)
- spc m l(ocal)
- spc m r(adio)
- empv-video-dir empv-audio-dir?
- empv-play-file
selected radio (See empv-radio-log-file and empv-radio-log-format
variables and their documentations).
** New plugins
- tramp
- k8s
- docker
- terraform
- straight?
- embark?
- emms, emms-play-url binding (youtube view)
- [[https://youtu.be/UtqE-lR2HCA?t=5134][consult-lsp]] (better for errors than treemacs integrations probably)
- srht.el
- affe
- gnus
** Appearance switches
- fonts
- random theme
- org mode bullets / pretty / etc
** Research
- What does C-d do when in a minibuffer for vertico?
- embark
** System crafters videos
- [[https://www.youtube.com/watch?v=CUkuyW6hr18][5 Hacks to improve org roam]]
- [[https://www.youtube.com/watch?v=C1kwStlEick][Improving the IRC experience]]
- [[https://www.youtube.com/watch?v=J0OaRy85MOo][Streamlined completions with vertico]]
- [[https://www.youtube.com/watch?v=XZjyJG-sFZI][Keeping your folders clean while using emacs]]
- [[https://www.youtube.com/watch?v=zMzkorlfqLA][Static site generator from org mode]]
- [[https://www.youtube.com/watch?v=za99DwdZEyg][Automated website publishing w/ org and sourcehut]]
- [[https://www.youtube.com/watch?v=SCPoF1PTZpI][Emacs presentations]]
- [[https://www.youtube.com/watch?v=0C16LLHGYzk&t=1882s][Converting a literate config to guix home]]
- [[https://www.youtube.com/watch?v=zWIByv8JOrg][Do we really need use-package]]
- [[https://www.youtube.com/playlist?list=PLEoMzSkcN8oM-kA19xOQc8s0gr0PpFGJQ][Emacs mail playlist]]
- [[https://www.youtube.com/watch?v=qk2Is_sC8Lk][Embark]]
** Clean up Org Roam
- Major mode notes master node
** Create yasnippets repo as per [[https://github.com/joaotavora/yasnippet#where-are-the-snippets][The docs]]