diff --git a/guix/init.org b/guix/init.org index 9083bc4..328a078 100644 --- a/guix/init.org +++ b/guix/init.org @@ -1,5 +1,20 @@ #+title Ian's Emacs Config #+PROPERTY: header-args:emacs-lisp :tangle (if (eq system-type 'darwin) "~/dotfiles/guix/init.el" "~/.config/emacs/init.el") +#+EXPORT_FILE_NAME: ~/code/website/src/content/dotfiles/emacs.md + +#+begin_src ++++ +title = "Emacs Configuration" +author = ["Ian Keane"] +date = 2023-02-09 +tags = ["Config", "Text editing"] +description = 'My emacs configuration.' ++++ +#+end_src + + +* Preamble +My emacs configuration. It tangles to =.emacs.d/init.el= and exports to this markdown file on save. If you're viewing this in a repo, it's better to visit the website at . If you are viewing this on the website and want the repo, you can find it at . To see the hugo front-matter configuration, you'll have to view the raw code. * First things first ** Literate Config Setup @@ -10,7 +25,7 @@ To get started, run =C-c C-v t= (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 @@ -20,8 +35,8 @@ To get started, run =C-c C-v t= (setq package-archives '(("melpa" . "https://melpa.org/packages/") - ("org" . "https://orgmode.org/elpa/") - ("elpa" . "https://elpa.gnu.org/packages/"))) + ("org" . "https://orgmode.org/elpa/") + ("elpa" . "https://elpa.gnu.org/packages/"))) (package-initialize) ;; Initialize use-package on non-linux platforms @@ -37,6 +52,26 @@ To get started, run =C-c C-v t= :init (savehist-mode)) #+end_src +** Straight +#+begin_src emacs-lisp + (defvar bootstrap-version) + (let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (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)) + + (setq package-enable-at-startup nil) +#+end_src ** Environment-specific setup #+begin_src emacs-lisp (setq IS-MACOS (eq system-type 'darwin)) @@ -79,26 +114,24 @@ To get started, run =C-c C-v t= (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/") + (setq 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))) + 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 () + (defun ian/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-region (region-beginning) (region-end)) (eval-buffer))) - (defun custom/conditional-imenu () + (defun ian/conditional-imenu () "Call `consult-org-heading` in Org mode, otherwise `consult-imenu`." (interactive) (if (eq major-mode 'org-mode) @@ -107,15 +140,27 @@ To get started, run =C-c C-v t= #+end_src * One-Line Includes +TODO: rename this section #+begin_src emacs-lisp (use-package treemacs) + ;; Enable follow mode + ;; Use treemacs-current-visibility function to expand backspace functionality + (setq treemacs--project-follow-delay 0) + (defun ian/treemacs-open-current-or-jump () + "Find the current file and open treemacs if it's not open, otherwise jump + to the treemacs window" + (interactive) + (if + (not(eq (treemacs-current-visibility) 'visible)) + (treemacs-find-file)) + (treemacs-select-window)) #+end_src * Notes #+begin_src emacs-lisp (use-package deft) (setq deft-recursive t - deft-extensions '("org" "txt")) + deft-extensions '("org" "txt")) #+end_src * AI #+begin_src emacs-lisp @@ -125,7 +170,7 @@ To get started, run =C-c C-v t= * Org Mode #+begin_src emacs-lisp (use-package org) - ;; (add-hook 'org-mode-hook 'yas-minor-mode) + ;; (add-hook 'org-mode-hook 'yas-minor-mode) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) @@ -137,8 +182,6 @@ To get started, run =C-c C-v t= (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) @@ -146,6 +189,34 @@ To get started, run =C-c C-v t= (use-package org-appear :hook (org-mode . org-appear-mode)) + (use-package org-roam + :ensure t + :custom + (org-roam-directory "~/notes/roam") + :config + ;; If you're using a vertical completion framework, you might want a more informative completion interface + ;; (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) + (org-roam-db-autosync-mode)) + + (use-package deft + :commands (deft) + :config + (setq deft-directory "~/notes/deft" + deft-extensions '("org" "txt") + deft-recursive t)) + + (use-package ox-hugo + :after ox) + + (use-package org-roam-ui + :after org-roam + :config + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start t)) + + (use-package ox-gfm) #+end_src * Basic Appearance and Behaviors #+begin_src emacs-lisp @@ -171,20 +242,20 @@ To get started, run =C-c C-v t= :config (solaire-global-mode +1)) (use-package doom-themes - :ensure t - :config - ;; Global settings (defaults) - (setq doom-themes-enable-bold t ; if nil, bold is universally disabled - doom-themes-enable-italic t) ; if nil, italics is universally disabled - ;; (load-theme 'doom-one t) + :ensure t + :config + ;; Global settings (defaults) + (setq doom-themes-enable-bold t ; if nil, bold is universally disabled + doom-themes-enable-italic t) ; if nil, italics is universally disabled + ;; (load-theme 'doom-one t) - ;; Enable flashing mode-line on errors - (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme - (doom-themes-treemacs-config) - ;; Corrects (and improves) org-mode's native fontification. - (doom-themes-org-config)) + ;; Enable flashing mode-line on errors + (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme + (doom-themes-treemacs-config) + ;; Corrects (and improves) org-mode's native fontification. + (doom-themes-org-config)) - (set-frame-font "DejaVu Sans Mono 14") + (set-frame-font "DejaVu Sans Mono 17") (use-package simple-modeline :hook (after-init . simple-modeline-mode)) @@ -193,9 +264,9 @@ To get started, run =C-c C-v t= (global-display-line-numbers-mode t) (dolist (mode - '(org-mode-hook - term-mode-hook - eshell-mode-hook)) + '(org-mode-hook + term-mode-hook + eshell-mode-hook)) (add-hook mode (lambda () (display-line-numbers-mode 0)))) (column-number-mode) @@ -215,12 +286,23 @@ To get started, run =C-c C-v t= ;; Generate buffers in last window (setq display-buffer-base-action - '(display-buffer-reuse-mode-window - display-buffer-reuse-window - display-buffer-same-window)) + '(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) + (setq whitespace-style '(trailing tabs newline tab-mark )) ; show tab characters + (setq indent-tabs-mode nil) ; tabs not spaces + (visual-line-mode) +#+end_src +** Tab bar +#+begin_src emacs-lisp + (use-package tab-bar-echo-area + :ensure + :config + (tab-bar-echo-area-mode 1) + (setq tab-bar-show nil)) #+end_src * Navigation ** Helper Functions @@ -262,31 +344,36 @@ To get started, run =C-c C-v t= #+end_src ** Windows and Workspaces +[[https://github.com/abo-abo/ace-window/issues/216][Credit]] for manual dispatch function #+begin_src emacs-lisp - (use-package persp-mode - :diminish persp-mode) - (unless (equal persp-mode t) - (persp-mode)) + (defun ace-window-manual-dispatch (arg) + "Calls `ace-window' with ARG asking for the dispatch, even if `aw-dispatch-always' is nil. + This could be useful to use the advanced commands" + (interactive "p") + (let ((aw-dispatch-always t)) + (ace-window arg) + )) (use-package ace-window) (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) - (defvar aw-dispatch-alist - '((?x aw-delete-window "Delete Window") - (?m aw-swap-window "Swap Windows") - (?M aw-move-window "Move Window") - (?c aw-copy-window "Copy Window") - (?j aw-switch-buffer-in-window "Select Buffer") - (?n aw-flip-window) - ;;(?u aw-switch-buffer-other-window "Switch Buffer Other Window") - (?u aw-switch-buffer-other-window 'winner-undo) - (?U aw-switch-buffer-other-window 'winner-redo) - (?c aw-split-window-fair "Split Fair Window") - (?v aw-split-window-vert "Split Vert Window") - (?b aw-split-window-horz "Split Horz Window") - (?o delete-other-windows "Delete Other Windows") - (?? aw-show-dispatch-help)) - "List of actions for `aw-dispatch-default'.") - ;; TODO: maybe put workspace controls in aw-dispatch? - + (setq aw-dispatch-alist + '( + (?x aw-delete-window "Delete Window") + (?m aw-swap-window "Swap Windows") + (?M aw-move-window "Move Window") + ;; (?c aw-copy-window "Copy Window") + ;; (?j aw-switch-buffer-in-window "Select Buffer") + ;; (?n aw-flip-window) + ;; ;; + (?b aw-switch-buffer-other-window "Switch Buffer Other Window") + (?u winner-undo) + (?U winner-redo) + (?c aw-split-window-fair "Split Fair Window") + (?v aw-split-window-vert "Split Vert Window") + (?H aw-split-window-horz "Split Horz Window") + (?o delete-other-windows "Delete Other Windows") + (?? aw-show-dispatch-help))) + (setq aw-scope 'frame) + ;; TODO: Window width controls #+end_src ** Dired #+begin_src emacs-lisp @@ -302,11 +389,11 @@ To get started, run =C-c C-v t= loaded." ;; (define-key dired-mode-map [remap dired-find-file] - 'dired-single-buffer) + 'dired-single-buffer) (define-key dired-mode-map [remap dired-mouse-find-file-other-window] - 'dired-single-buffer-mouse) + 'dired-single-buffer-mouse) (define-key dired-mode-map [remap dired-up-directory] - 'dired-single-up-directory)) + 'dired-single-up-directory)) ;; if dired's already loaded, then the keymap will be bound (if (boundp 'dired-mode-map) @@ -318,8 +405,8 @@ To get started, run =C-c C-v t= (use-package dired-open :config (setq dired-open-extensions '(("png" . "sxiv") - ("mkv" . "mpv") - ("avi" . "mpv")))) + ("mkv" . "mpv") + ("avi" . "mpv")))) (use-package all-the-icons-dired :hook (dired-mode . all-the-icons-dired-mode)) @@ -357,19 +444,20 @@ To get started, run =C-c C-v t= (general-definition ;; Top level bindings - "SPC" '(projectile-find-file :which-key "Find project file") - "" '(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? - "w" '(ace-window :which-key "Window") + "SPC" '(projectile-find-file :which-key "Find project file") + "" '(ian/treemacs-open-current-or-jump :which-key "Find current file in sidebar") ; TODO or treemacs-select-window + "," '(+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" '(ian/conditional-imenu :which-key "Imenu") ;; consult-outline? + "w" '(ace-window :which-key "Window") + "W" '(ace-window-manual-dispatch :which-key "Window (dispatch)") ;; Agenda "a" '(:ignore t :which-key "Agenda") @@ -402,7 +490,7 @@ To get started, run =C-c C-v t= "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") + "ce" '(ian/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)") @@ -500,44 +588,44 @@ To get started, run =C-c C-v t= "hwm" '(which-key-show-major-mode :which-key "Show major mode") "hwt" '(which-key-show-top-level :which-key "Show top-level") - "m" '(:ignore t :which-key "media") - "my" '(empv-youtube :which-key "youtube") - "mt" '(empv-toggle :which-key "toggle") - "mT" '(empv-toggle-video :which-key "toggle-video") - "mq" '(empv-exit :which-key "quit") - "ms" '(empv-display-current :which-key "show currently playing") + "m" '(:ignore t :which-key "media") + "my" '(empv-youtube :which-key "youtube") + "mt" '(empv-toggle :which-key "toggle") + "mT" '(empv-toggle-video :which-key "toggle-video") + "mq" '(empv-exit :which-key "quit") + "ms" '(empv-display-current :which-key "show currently playing") - "mr" '(:ignore t :which-key "radio") - "mrr" '(empv-play-radio :which-key "play") - "mrR" '(empv-play-random-channel :which-key "play random") - "mrl" '(empv-log-current-radio-song-name :which-key "log song name") + "mr" '(:ignore t :which-key "radio") + "mrr" '(empv-play-radio :which-key "play") + "mrR" '(empv-play-random-channel :which-key "play random") + "mrl" '(empv-log-current-radio-song-name :which-key "log song name") - "mp" '(:ignore t :which-key "playlist") - "mpP" '(empv-playlist :which-key "playlist") - "mps" '(empv-playlist-select :which-key "select") - "mpn" '(empv-playlist-next :which-key "next") - "mpp" '(empv-playlist-prev :which-key "prev") - "mpc" '(empv-playlist-clear :which-key "clear") - "mpS" '(empv-playlist-shuffle :which-key "shuffle") + "mp" '(:ignore t :which-key "playlist") + "mpP" '(empv-playlist :which-key "playlist") + "mps" '(empv-playlist-select :which-key "select") + "mpn" '(empv-playlist-next :which-key "next") + "mpp" '(empv-playlist-prev :which-key "prev") + "mpc" '(empv-playlist-clear :which-key "clear") + "mpS" '(empv-playlist-shuffle :which-key "shuffle") - "mf" '(:ignore t :which-key "file") - "mff" '(empv-play-file :which-key "play file") - "mfd" '(empv-play-directory :which-key "play directory") + "mf" '(:ignore t :which-key "file") + "mff" '(empv-play-file :which-key "play file") + "mfd" '(empv-play-directory :which-key "play directory") - "mv" '(:ignore t :which-key "volume") - "mvd" '(empv-volume-down :which-key "down") - "mvu" '(empv-volume-up :which-key "up") + "mv" '(:ignore t :which-key "volume") + "mvd" '(empv-volume-down :which-key "down") + "mvu" '(empv-volume-up :which-key "up") - "mc" '(:ignore t :which-key "chapter") - "mcp" '(empv-chapter-prev :which-key "prev") - "mcn" '(empv-chapter-next :which-key "next") - "mcs" '(empv-chapter-select :which-key "select") + "mc" '(:ignore t :which-key "chapter") + "mcp" '(empv-chapter-prev :which-key "prev") + "mcn" '(empv-chapter-next :which-key "next") + "mcs" '(empv-chapter-select :which-key "select") ;; 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") + "ng" '(org-roam-ui-open :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") @@ -607,7 +695,6 @@ To get started, run =C-c C-v t= "TAB s" '(+workspace/save :which-key "Save workspace") "TAB x" '(+workspace/kill-session :which-key "Delete session") )) - #+end_src * Project management @@ -649,16 +736,16 @@ Idk I think this came from the vertico readme ;; We display [CRM], 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))) + (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)) + '(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. @@ -678,8 +765,8 @@ Idk I think this came from the vertico readme ;; (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))))) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) #+end_src ** Marginalia #+begin_src emacs-lisp @@ -688,7 +775,7 @@ Idk I think this came from the vertico readme ;; available in the *Completions* buffer, add it to the ;; `completion-list-mode-map'. :bind (:map minibuffer-local-map - ("M-A" . marginalia-cycle)) + ("M-A" . marginalia-cycle)) ;; The :init section is always executed. :init @@ -705,12 +792,12 @@ Idk I think this came from the vertico readme :hook (prog-mode . company-mode) :diminish :bind (:map company-active-map - ("" . company-select-next) - ("TAB" . company-select-next) - ("" . company-select-previous) - ("" . company-select-previous)) + ("" . company-select-next) + ("TAB" . company-select-next) + ("" . company-select-previous) + ("" . company-select-previous)) (:map lsp-mode-map ; more general mode than this? - ("" . company-indent-or-complete-common)) + ("" . company-indent-or-complete-common)) :config (global-company-mode 1) :init @@ -799,6 +886,7 @@ All lisp-family languages (lispyville-set-key-theme '(operators c-w additional))) #+end_src * Markups +** Markdown #+begin_src emacs-lisp (use-package markdown-mode :mode ("\\.md\\'" . markdown-mode)) @@ -807,13 +895,32 @@ All lisp-family languages (use-package json-mode) (use-package yaml-mode) #+end_src +** Beancount +#+begin_src emacs-lisp +(defun beancount-tab-function () + "Improved beancount tab ripped off from doom emacs" + (interactive) + (if (and outline-minor-mode (outline-on-heading-p)) + (beancount-outline-cycle) + (indent-according-to-mode))) + +(use-package beancount + :straight (beancount :type git :host github :repo "beancount/beancount-mode") + :mode ("\\.beancount\\'" . beancount-mode) + :hook (beancount-mode . outline-minor-mode) + :config + (evil-define-key 'normal 'beancount-mode-map (kbd "TAB") 'beancount-tab-function) + ) ;; Bind the TAB key + +(add-hook 'beancount-mode-hook #'flymake-bean-check-enable) +#+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)) + (require 'fish-completion nil t)) (global-fish-completion-mode)) #+end_src * Git @@ -935,16 +1042,22 @@ Uses the external fish program to provide fish-style completions to eshell etc ;; (require 'evil-org-agenda) ;; (evil-org-agenda-set-keys) ) + (use-package evil-collection :after evil :ensure t :diminish evil-collection-unimpaired-mode + :init + (setq evil-want-C-u-scroll t) :config (evil-collection-init) - (setq evil-want-C-i-jump t - evil-respect-visual-line-mode t)) - #+end_src + evil-respect-visual-line-mode t)) + + (use-package evil-commentary + :config + (evil-commentary-mode)) +#+end_src * Web browsing and youtube #+begin_src emacs-lisp ;; Using straight: @@ -954,14 +1067,14 @@ Uses the external fish program to provide fish-style completions to eshell etc (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") - )) + '(("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")