Simplify workspace/window/buffer management. Init structure improvements

This commit is contained in:
Joseph Ferano 2023-04-20 12:29:39 +07:00
parent bf25734059
commit c2f091634e

View File

@ -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 "<f2>")
@ -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 "<f8>") #'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: