diff --git a/.config/emacs/init.org b/.config/emacs/init.org index 3097a52..6017928 100644 --- a/.config/emacs/init.org +++ b/.config/emacs/init.org @@ -34,7 +34,6 @@ enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes. (add-hook 'focus-out-hook 'garbage-collect)))) (setq native-comp-async-report-warnings-errors nil) -(setq native-comp-deferred-compilation t) #+end_src Disabling these classic visual options during early-init seems to net a 0.04 ms boost in init time @@ -57,8 +56,8 @@ documentation; (setq package-enable-at-startup nil) #+END_SRC -Prioritize old byte-compiled source files over newer sources. It saves us a little IO time to skip -all the mtime checks on each lookup. +Prioritize old byte-compiled source files over newer sources. It saves us a +little IO time to skip all the mtime checks on each lookup. #+begin_src emacs-lisp :tangle ./early-init.el (setq load-prefer-newer nil) @@ -70,8 +69,8 @@ all the mtime checks on each lookup. (org-babel-tangle)) nil t))) -(setq server-name (format "Emacs-%d" (emacs-pid))) -(add-hook 'after-init-hook #'server-start) +;; (setq server-name (format "Emacs-%d" (emacs-pid))) +;; (add-hook 'after-init-hook #'server-start) #+end_src Prevent instructions on how to close an emacsclient frame. @@ -80,8 +79,8 @@ Prevent instructions on how to close an emacsclient frame. (setq server-client-instructions nil) #+end_src -Implicitly resizing the Emacs frame adds to init time. Fonts larger than the system default can -cause frame resizing, which adds to startup time. +Implicitly resizing the Emacs frame adds to init time. Fonts larger than the +system default can cause frame resizing, which adds to startup time. #+begin_src emacs-lisp (setq frame-inhibit-implied-resize t) @@ -92,7 +91,6 @@ Ignore X resources. #+begin_src emacs-lisp (advice-add #'x-apply-session-resources :override #'ignore) #+end_src - *** UTF-8 Support #+begin_src emacs-lisp :tangle ./early-init.el (setq default-input-method nil) @@ -111,8 +109,8 @@ Finish up (provide 'early-init) ;;; early-init.el ends here #+end_src -** Elpaca -#+BEGIN_SRC emacs-lisp :tangle no +** COMMENT Elpaca +#+BEGIN_SRC emacs-lisp ;; -*- lexical-binding: t -*- (defvar elpaca-installer-version 0.3) (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) @@ -264,6 +262,7 @@ need to benchmark slow init times later. (setq recentf-auto-cleanup 10) (setq recentf-keep '(file-remote-p file-readable-p)) (setq recentf-max-saved-items 1000) +(setq package-native-compile t) #+end_src This avoids those annoying *#backup#* files that get added and eventually slow down loading the file again. @@ -292,40 +291,6 @@ I don't even know how you resume from GUI mode, we'll find a use for this keybin (global-unset-key (kbd "C-z"))) #+end_src ** Visuals -*** Initial Buffer - -#+begin_src emacs-lisp -(defun load-projects () - (with-temp-buffer - (insert-file-contents project-list-file) - (goto-char (point-min)) - (apply #'append (read (current-buffer))))) - -(defun my-dashboard () - "Show Welcome buffer" - (with-current-buffer (get-buffer-create "*Welcome*") - - (erase-buffer) - (goto-char (point-min)) - (insert-image (create-image "~/Documents/emacs-alt.png")) - (insert "\n\n\n") - (insert "Welcome to Emacs!\n\n") - (let* ((time-str (emacs-init-time)) - (time (string-to-number (car (split-string time-str))))) - (insert (format "It took %.3f seconds to start up\n\n" time))) - (insert "Happy hacking!\n\n") - (insert "Projects:\n") - (dolist (proj (load-projects)) - (insert (format "\t%s\n" proj))) - (setq cursor-type nil) - (switch-to-buffer (current-buffer)) - (goto-char (point-min)) - (display-line-numbers-mode 0) - (read-only-mode +1))) - -(setq initial-buffer-choice #'my-dashboard) - -#+end_src *** COMMENT Dashboard Use Dashboard.el. First load `all-the-icons` for nicer rendering @@ -404,7 +369,9 @@ Setup other stuff #+begin_src emacs-lisp (setq ring-bell-function 'ignore) -(setq default-frame-alist '((undecorated . t) (fullscreen . maximized))) +(add-to-list 'default-frame-alist '(undecorated . t)) +(add-to-list 'default-frame-alist '(fullscreen . maximized)) +(add-to-list 'default-frame-alist '(vertical-scroll-bars . nil)) (add-hook 'text-mode-hook (lambda () (setq fill-column 100) (turn-on-auto-fill))) @@ -416,7 +383,7 @@ Setup other stuff (dolist (mode '( dashboard-mode-hook org-mode-hook term-mode-hook eww-mode-hook vterm-mode-hook dirvish-directory-view-mode-hook eshell-mode-hook dired-mode-hook shell-mode-hook magit-mode-hook compilation-mode-hook - mu4e-main-mode-hook)) + mu4e-headers-mode-hook mu4e-main-mode-hook)) (add-hook mode #'joe/disable-line-numbers)) (set-window-margins nil 0) @@ -447,9 +414,10 @@ Setup other stuff (require 'doom-modeline) (doom-modeline-mode) (doom-modeline-def-modeline 'main - '(workspace-name bar modals bar window-number matches buffer-info remote-host buffer-position word-count selection-info) + '(bar modals bar window-number matches buffer-info remote-host buffer-position word-count selection-info) '(parrot objed-state misc-info battery grip irc mu4e gnus github debug repl lsp bar input-method indent-info buffer-encoding bar major-mode process)) - +;; Show the tab names, just put this at the car of the previous list +;; workspace-name ;; Set default mode-line (add-hook 'doom-modeline-mode-hook (lambda () @@ -538,8 +506,8 @@ weren't working, until I randomly saw this in someone's init.el #+end_src #+end_src -*** Hydra -#+begin_src emacs-lisp :tangle no +*** COMMENT Hydra +#+begin_src emacs-lisp (require 'hydra) (defhydra hydra-navigate (global-map "") @@ -553,13 +521,13 @@ weren't working, until I randomly saw this in someone's init.el ("p" previous-line "line up") ("M-r" move-to-window-line-top-bottom "Reposition cursor")) #+end_src -*** Multiple Cursors +*** COMMENT Multiple Cursors -#+begin_src emacs-lisp :tangle no +#+begin_src emacs-lisp (require 'multiple-cursors) #+end_src -*** Meow -#+begin_src emacs-lisp :tangle no +*** COMMENT Meow +#+begin_src emacs-lisp (elpaca 'meow) (defun meow-setup () (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) @@ -651,8 +619,8 @@ weren't working, until I randomly saw this in someone's init.el (meow-global-mode t) (setq scroll-preserve-screen-position nil) #+end_src -*** Boon -#+begin_src emacs-lisp :tangle no +*** COMMENT Boon +#+begin_src emacs-lisp (defun joe/psp-scroll-down-half-page () (interactive) (pixel-scroll-precision-scroll-down-page (/ (window-pixel-height) 2))) @@ -757,8 +725,8 @@ weren't working, until I randomly saw this in someone's init.el (kbd "SPC fa") '(lambda () (interactive) (project-find-file t)) (kbd "SPC fi") 'joe/edit-init (kbd "SPC bl") 'mode-line-other-buffer - (kbd "SPC ba") 'consult-buffer - (kbd "SPC bb") 'consult-project-buffer + (kbd "SPC ba") 'switch-to-buffer + (kbd "SPC bb") 'consult-buffer (kbd "SPC bi") 'ibuffer (kbd "SPC bm") 'joe/toggle-buffer-mode (kbd "SPC br") 'joe/revert-buffer-no-confirm @@ -781,6 +749,16 @@ weren't working, until I randomly saw this in someone's init.el (define-key evil-window-map "u" #'winner-undo) (define-key evil-window-map "U" #'winner-redo) + (defvar joe-mode-map + (let ((map (make-sparse-keymap))) + ;; (define-key map (kbd "C-'") #'embark-act) + map) + "my-keys-minor-mode keymap.") + +(define-key joe/evil-space-mode-map (kbd "M-'") #'embark-dwim) +(define-key joe/evil-space-mode-map (kbd "C-'") #'embark-act) +(define-key joe/evil-space-mode-map (kbd "C-/") #'comment-line) + (defun joe/scroll-up-line () (interactive) (scroll-up-line 2)) (defun joe/scroll-down-line () (interactive) (scroll-down-line 2)) (evil-global-set-key 'normal (kbd "C-e") #'joe/scroll-up-line) @@ -805,6 +783,76 @@ weren't working, until I randomly saw this in someone's init.el (setq evil-goggles-pulse t) (setq evil-goggles-async-duration 0.55) +#+end_src +** Initial Buffer + +#+begin_src emacs-lisp +;; (require 'dashboard) +;; (defun dashboard-center-text (start end) +;; "Center the text between START and END." +;; (save-excursion +;; (goto-char start) +;; (let ((width 0)) +;; (while (< (point) end) +;; (let* ((line-str (buffer-substring (line-beginning-position) (line-end-position))) +;; (line-length (dashboard-str-len line-str))) +;; (setq width (max width line-length))) +;; (forward-line 1)) +;; (let ((prefix (propertize " " 'display `(space . (:align-to (- center ,(/ width 2))))))) +;; (add-text-properties start end `(line-prefix ,prefix indent-prefix ,prefix)))))) + +;; (defun dashboard-insert-center (&rest strings) +;; "Insert STRINGS in the center of the buffer." +;; (let ((start (point))) +;; (apply #'insert strings) +;; (dashboard-center-text start (point)))) + +(defvar joe/welcome-load-project-map (make-sparse-keymap) + "High precedence keymap.") + +(defun joe/welcome-open-project () + "Open the directory at point in dired." + (interactive) + (let ((path (file-truename (substring-no-properties + (thing-at-point 'filename))))) + (project-switch-project path))) + +;; (evil-define-key 'normal 'joe/welcome-load-project-map (kbd "RET") #'joe/welcome-open-project) + +(defun load-projects () + (with-temp-buffer + (insert-file-contents project-list-file) + (goto-char (point-min)) + (apply #'append (read (current-buffer))))) + +(defun my-dashboard () + "Show Welcome buffer" + (with-current-buffer (get-buffer-create "*Welcome*") + + (erase-buffer) + (goto-char (point-min)) + (insert-image (create-image "~/Documents/emacs-alt.png")) + (insert "\n\n\n") + (insert "Welcome to Emacs!\n\n") + ;; (dashboard-insert-center "testing this thing out\n\n") + (let* ((time-str (emacs-init-time)) + (time (string-to-number (car (split-string time-str))))) + (insert (format "It took %.3f seconds to start up\n\n" time))) + (insert "Happy hacking!\n\n") + (insert "Projects:\n") + (dolist (proj (load-projects)) + (insert (format "\t%s\n" proj))) + ;; (insert (propertize (format "\t%s\n" proj) :keymap joe/welcome-load-project-map))) + (setq cursor-type nil) + (switch-to-buffer (current-buffer)) + (goto-char 86) + (display-line-numbers-mode 0) + (olivetti-mode) + (read-only-mode +1) + (current-buffer))) + + (setq initial-buffer-choice #'my-dashboard) + #+end_src ** Buffers #+begin_src emacs-lisp @@ -879,7 +927,33 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really (global-set-key (kbd "C-x C-o") #'ace-swap-window) #+end_src -*** COMMENT Beframe + +#+begin_src emacs-lisp +(global-set-key (kbd "C-`") #'window-toggle-side-windows) + +(defvar joe/side-window-buffers '("^\\*Flycheck errors\\*$" + "^\\*Completions\\*$" + "^\\*Help\\*$" + "^\\*Embark.*" + "^\\*helpful.*" + "^\\*Compilation\\*$" + "^\\*SQL.*" + "^\\*HTTP Response\\*$" + "^\\*grep\\*$" + "^\\*Colors\\*$" + "^\\*Async Shell Command\\*$")) +(dolist (bufname joe/side-window-buffers) + (add-to-list 'display-buffer-alist + `(,bufname + display-buffer-in-side-window + (side . right) + (window-width . 0.43) + (slot . 0) + (window-parameters + (no-delete-other-windows . t))))) + +#+end_src +*** Beframe #+begin_src emacs-lisp (defvar consult-buffer-sources) (declare-function consult--buffer-state "consult") @@ -901,9 +975,12 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really (add-to-list 'consult-buffer-sources 'beframe-consult-source)) -(require 'beframe) +(beframe-mode +1) + +(global-set-key (kbd "s-n") #'joe/consult-buffer-vertico) +(global-set-key (kbd "s-p") #'joe/consult-buffer-vertico) #+end_src -*** Popper +*** COMMENT Popper #+begin_src emacs-lisp (require 'popper) @@ -988,8 +1065,8 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really (global-set-key (kbd "s-p") #'tab-line-switch-to-prev-tab) #+end_src -*** Scrolling -#+begin_src emacs-lisp :tangle no +*** COMMENT Scrolling +#+begin_src emacs-lisp (require 'pixel-scroll) (setq pixel-scroll-precision-large-scroll-height 10.0) (setq pixel-scroll-precision-interpolation-factor 30) @@ -1044,9 +1121,9 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really #+end_src ** Tabs/Workspaces -*** Centaur Tabs +*** COMMENT Centaur Tabs #+begin_src emacs-lisp -(require 'centaur-tabs) +;; (require 'centaur-tabs) (setq centaur-tabs-set-bar 'under) (setq x-underline-at-descent-line t) (setq centaur-tabs-set-close-button nil) @@ -1057,8 +1134,23 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really (setq centaur-tabs-show-new-tab-button nil) (setq centaur-tabs-label-fixed-length 16) -(global-set-key (kbd "s-n") #'centaur-tabs-forward-tab) -(global-set-key (kbd "s-p") #'centaur-tabs-backward-tab) +(defun joe/forward-tab-or-popup () + (interactive) + (if (popper-popup-p (current-buffer)) + (popper-cycle) + (centaur-tabs-forward-tab))) +(defun joe/backward-tab-or-popup () + (interactive) + (if (popper-popup-p (current-buffer)) + (popper-cycle) + (centaur-tabs-backward-tab))) + +;; (global-set-key (kbd "s-n") #'centaur-tabs-forward-tab) +;; (global-set-key (kbd "s-p") #'centaur-tabs-backward-tab) + +(global-set-key (kbd "s-n") #'joe/forward-tab-or-popup) +(global-set-key (kbd "s-p") #'joe/backward-tab-or-popup) + (global-set-key (kbd "s-N") #'centaur-tabs-forward-group) (global-set-key (kbd "s-P") #'centaur-tabs-backward-group) (global-set-key (kbd "C-s-p") #'centaur-tabs-move-current-tab-to-left) @@ -1101,8 +1193,42 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really (centaur-tabs-mode +1) #+end_src -*** Tabs -#+begin_src emacs-lisp :tangle no +*** COMMENT iflipb +#+begin_src emacs-lisp +(global-set-key (kbd "s-n") #'iflipb-next-buffer) +(global-set-key (kbd "s-p") #'iflipb-previous-buffer) +(setq iflipb-permissive-flip-back t) +(setq iflipb-other-buffer-template " %s ") +(setq iflipb-current-buffer-template "<[%s]>") +(setq iflipb-buffer-list-function #'tabspaces--buffer-list) +#+end_src +*** COMMENT Tabspaces +#+begin_src emacs-lisp +(tabspaces-mode +1) + +;; Filter Buffers for Consult-Buffer +(with-eval-after-load 'consult + ;; hide full buffer list (still available with "b" prefix) + (consult-customize consult--source-buffer :hidden t :default nil) + ;; set consult-workspace buffer list + (defvar consult--source-workspace + (list :name "Workspace Buffers" + :narrow ?w + :history 'buffer-name-history + :category 'buffer + :state #'consult--buffer-state + :default t + :items (lambda () (consult--buffer-query + :predicate #'tabspaces--local-buffer-p + :sort 'visibility + :as #'buffer-name))) + + "Set workspace buffer list for consult-buffer.") + (add-to-list 'consult-buffer-sources 'consult--source-workspace)) + +#+end_src +*** COMMENT Tabs +#+begin_src emacs-lisp ;; (setq tab-bar-mode t) ;; (setq tab-bar-show nil) @@ -1159,9 +1285,7 @@ Ace Window will show a hint if there are more than 2 windows, but I don't really #+end_src ** VEMCO - -Vertico Embark Marginalia Consult Orderless - +*** Vertico #+begin_src emacs-lisp (require 'all-the-icons-completion) ;; (require '(vertico :files (:defaults "extensions/*") @@ -1191,9 +1315,22 @@ Vertico Embark Marginalia Consult Orderless ;; 150)) ;; (setq vertico-posframe-poshandler #'posframe-poshandler-slightly-below-top) - (setq vertico-count 17 +(defun joe/consult-buffer-vertico () + (interactive) + (let ((vertico-count 12) + (vertico-posframe-width 110) + (vertico-posframe-height 20)) + (consult-buffer))) + + (setq vertico-count 20 vertico-resize nil vertico-cycle t) +(setq vertico-posframe-width 130) +(setq vertico-posframe-height 30) +(setq vertico-posframe-parameters + '((child-frame-border-width . 5) + (left-fringe . 30) + (right-fringe . 30))) (require 'savehist) (savehist-mode) @@ -1201,6 +1338,8 @@ Vertico Embark Marginalia Consult Orderless (add-to-list 'savehist-additional-variables 'vertico-repeat-history) (define-key vertico-map (kbd "C-M-n") #'vertico-next-group) + (define-key vertico-map (kbd "s-p") #'vertico-previous) + (define-key vertico-map (kbd "s-n") #'vertico-next) ;; #' "C-M-p" #'vertico-previous-group) @@ -1211,25 +1350,13 @@ Vertico Embark Marginalia Consult Orderless ;; ("M-DEL" . vertico-directory-delete-word)) ;; :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)) +#+end_src +*** Embark +#+begin_src emacs-lisp (require 'embark) (setq embark-quit-after-action '((kill-buffer . nil))) - (defvar joe-mode-map - (let ((map (make-sparse-keymap))) - ;; (define-key map (kbd "C-'") #'embark-act) - (define-key map (kbd "M-'") #'embark-dwim) - (define-key map (kbd "C-/") #'comment-line) - map) - "my-keys-minor-mode keymap.") - - (define-minor-mode joe-mode - "A minor mode so that my key settings override annoying major modes." - :init-value t - :lighter " joe-keys") - - (joe-mode t) - (defun embark-which-key-indicator () "An embark indicator that displays keymaps using which-key. The which-key help message will show the type and value of the @@ -1268,10 +1395,9 @@ Vertico Embark Marginalia Consult Orderless (advice-add #'embark-completing-read-prompter :around #'embark-hide-which-key-indicator) - (global-set-key (kbd "C-'") #'embark-act) - - (require 'embark-consult) - +#+end_src +*** Marginalia +#+begin_src emacs-lisp (require 'marginalia) (setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) (setq marginalia-align 'right) @@ -1284,31 +1410,30 @@ Vertico Embark Marginalia Consult Orderless (add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup) +#+end_src +*** Consult +#+begin_src emacs-lisp +(require 'embark-consult) + +(require 'consult) + +;; (require 'consult-lsp) + +(global-set-key (kbd "C-. C-l") 'consult-line) +(global-set-key (kbd "C-. C-i") 'consult-imenu) +(global-set-key (kbd "C-. C-t") 'consult-theme) +(global-set-key (kbd "C-. C-r") 'consult-recent-file) +(global-set-key (kbd "C-. C-y") 'consult-yank-from-kill-ring) + +#+end_src +*** Orderless + +#+begin_src emacs-lisp + (require 'orderless) (setq completion-styles '(orderless basic) completion-category-overrides '((file (styles basic partial-completion)))) #+end_src - -*** Consult -#+begin_src emacs-lisp - (require 'consult) - ;; (require 'consult-lsp) - - ;; (defun joe/consult-line () - ;; (interactive) - ;; (let ((vertico-posframe-mode -1)) - ;; (consult-line))) - - (global-set-key (kbd "C-. C-l") 'consult-line) - ;; (global-set-key (kbd "C-. C-l") 'joe/consult-line) - (global-set-key (kbd "C-. C-i") 'consult-imenu) - (global-set-key (kbd "C-. C-t") 'consult-theme) - (global-set-key (kbd "C-. C-r") 'consult-recent-file) - (global-set-key (kbd "C-. C-y") 'consult-yank-from-kill-ring) - - ;; (global-set-key (kbd "C-s") 'swiper-thing-at-point) - -#+end_src ** Dirvish/Dired #+begin_src emacs-lisp (require 'dirvish) @@ -1318,7 +1443,7 @@ Vertico Embark Marginalia Consult Orderless (setq dired-dwim-target t) (setq dirvish-reuse-session nil) - (add-hook 'dired-mode-hook 'centaur-tabs-local-mode) + ;; (add-hook 'dired-mode-hook 'centaur-tabs-local-mode) (dirvish-define-preview exa (file) "Use `exa' to generate directory preview." @@ -1740,10 +1865,12 @@ startup. Reason we have to call this is so the vterm fucntion can call `vterm--i (evil-visual-line)) ;; This is required so that .dir-locals that read env files for credentials works (require 'dotenv) -(with-eval-after-load 'sql-mode +(defun joe/sql-mode-hook () (define-key sql-mode-map (kbd "C-M-h") #'joe/mark-sql-defun) (define-key sql-mode-map (kbd "") #'sql-connect)) +(add-hook 'sql-mode-hook #'joe/sql-mode-hook) + (defun joe/sql-save-history-hook () (let ((lval 'sql-input-ring-file-name) (rval 'sql-product)) @@ -1758,6 +1885,18 @@ startup. Reason we have to call this is so the vterm fucntion can call `vterm--i (symbol-name rval)))))) (add-hook 'sql-interactive-mode-hook 'joe/sql-save-history-hook) + +(defun joe/sql-login-hook () + "Custom SQL log-in behaviours. See `sql-login-hook'." + ;; n.b. If you are looking for a response and need to parse the + ;; response, use `sql-redirect-value' instead of `comint-send-string'. + (when (eq sql-product 'postgres) + (let ((proc (get-buffer-process (current-buffer)))) + ;; Output each query before executing it. (n.b. this also avoids + ;; the psql prompt breaking the alignment of query results.) + (comint-send-string proc "\\set ECHO queries\n")))) + +(add-hook 'sql-login-hook 'joe/sql-login-hook) #+end_src *** C @@ -1775,7 +1914,7 @@ it doesn't close it. (c-toggle-comment-style -1)) (add-hook 'c-mode-hook #'joe/c-mode-hook) #+end_src -*** Haskell +*** COMMENT Haskell #+begin_src emacs-lisp (require 'haskell-mode) (setq haskell-interactive-popup-errors nil) @@ -1785,14 +1924,14 @@ it doesn't close it. (evil-define-key 'insert haskell-interactive-mode-map (kbd "C-p") #'haskell-interactive-mode-history-previous)) #+end_src -*** Clojure +*** COMMENT Clojure #+begin_src emacs-lisp (require 'clojure-mode) (require 'cider) (setq cider-show-error-buffer 'only-in-repl) #+end_src -*** OCaml -#+begin_src emacs-lisp :tangle no +*** COMMENT OCaml +#+begin_src emacs-lisp (require 'tuareg) (require 'dune) (require 'utop) @@ -1819,7 +1958,7 @@ it doesn't close it. We won't use the LSP server but rather directly talk to Merlin, since I guess LSP just wraps Merlin and there's no need for a middle-man when it's already been implemented. -#+begin_src emacs-lisp :tangle no +#+begin_src emacs-lisp ;; (require 'utop) ;; Use the opam installed utop @@ -1836,13 +1975,13 @@ and there's no need for a middle-man when it's already been implemented. ;; Use opam switch to lookup ocamlmerlin binary (setq merlin-command 'opam))) #+end_src -*** FSharp +*** COMMENT FSharp #+begin_src emacs-lisp (require 'fsharp-mode) ;; (elpaca 'eglot-fsharp) #+end_src -*** Go +*** COMMENT Go #+begin_src emacs-lisp (require 'go-mode) @@ -1936,7 +2075,9 @@ The best git porcelain/client I've ever used. Also kill stray magit buffers left #+end_src + * COMMENT Local variables ;; Local Variables: +;; eval: (olivetti-mode t) ;; eval: (add-hook 'after-save-hook '(lambda () (org-babel-tangle)) nil t) ;; End: