├── .emacs ├── .gitignore ├── .gitmodules ├── README.md ├── canggu-theme ├── README.md └── canggu-theme.el ├── dependencies.el ├── init.el └── miso ├── anzu.el ├── colors.el ├── completion.elc ├── consult.el ├── copilot.el ├── debugging.el ├── elixir.el ├── emacs.el ├── git.el ├── go.el ├── javascript.el ├── lsp.el ├── mac.el ├── markdown.el ├── minibuffer.el ├── modeline.el ├── programming.el ├── project.el ├── rabbit-mode.el ├── rename-current-buffer.el ├── scratch.el ├── straight.el ├── tabs.el ├── trailing-whitespace.el ├── typescript.el ├── warnings.el ├── windows.el ├── writing-mode.el └── yasnippet.el /.emacs: -------------------------------------------------------------------------------- 1 | (defconst +home-dir+ "~") 2 | (defconst +emacs-dir+ (concat +home-dir+ "/.miso-emacs")) 3 | 4 | (defun add-load-path (p) 5 | (add-to-list 'load-path (concat +emacs-dir+ "/" p))) 6 | 7 | (defun load-local-file (f) 8 | (load-file (concat +emacs-dir+ "/" f ".el"))) 9 | 10 | (defun private (name) 11 | (let ((file (concat +emacs-dir+ "/private/" name ".el"))) 12 | (when (file-exists-p file) 13 | (load-file file)) 14 | ) 15 | ) 16 | 17 | (defun include (f) 18 | (load-file (concat +emacs-dir+ "/" f ".el"))) 19 | 20 | (defun enable (f) 21 | (message (concat "Enable" f)) 22 | (load-file (concat +emacs-dir+ "/miso/" f ".el"))) 23 | 24 | (add-load-path "") 25 | (add-load-path "config") 26 | 27 | (private "config") 28 | (include "init") 29 | (private "init") 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | .*~ 3 | private -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "jungle-theme"] 2 | path = jungle-theme 3 | url = https://github.com/azer/emacs-jungle-theme 4 | 5 | [submodule "use-package"] 6 | path = use-package 7 | url = https://github.com/jwiegley/use-package 8 | [submodule "copilot.el"] 9 | path = copilot.el 10 | url = https://github.com/zerolfx/copilot.el 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # miso-emacs 2 | 3 | Opinionated Emacs distro for minimalists. 4 | 5 | | Writing-mode | Programming-mode | 6 | | --- | --- | 7 | | Centered writing layout, spell correction, dictionary and pronounciation shortcuts in markdown modes | Dark color scheme, LSP mode enabled for programing | 8 | | Screenshot 2024-05-29 at 10 32 45 | Screenshot 2024-05-29 at 10 32 11 | 9 | 10 | 11 | **Table of Contents** 12 | 13 | - [Install](#install) 14 | - [Bindings](#Bindings) 15 | - [Customize](#customize) 16 | 17 | 18 | 19 | # Install 20 | 21 | Setup miso-emacs: 22 | 23 | ```bash 24 | $ git clone git@github.com:azer/miso-emacs.git ~/.miso-emacs 25 | $ ln -s .miso-emacs/.emacs .emacs 26 | ``` 27 | 28 | **Dependencies:** 29 | 30 | For faster LSP-mode, make sure [LSP booster](https://github.com/blahgeek/emacs-lsp-booster) is available as executable. 31 | 32 | Install icon fonts; 33 | 34 | ``` 35 | M-x all-the-icons-install-fonts 36 | M-x nerd-icons-install-fonts 37 | ``` 38 | 39 | Install ispell: 40 | 41 | ``` 42 | $ brew install ispell 43 | ``` 44 | 45 | # Bindings 46 | 47 | Editing: 48 | 49 | | Key | Command | 50 | | --- | ------- | 51 | | C-z | Undo | 52 | | C-shift-z | Redo | 53 | 54 | Navigation: 55 | 56 | | Key | Command | 57 | | --- | ------- | 58 | | S-Up | Jump N lines up | 59 | | S-Down | Jump N lines down | 60 | | M-Left | Switch to left window | 61 | | M-Right | Switch to right window | 62 | | M-Down | Switch to window below (or minibuffer) | 63 | | M-Up | Switch to window above | 64 | | M-o | Switch windows w/ ace-window | 65 | | M-s | Search buffer w/ swiper | 66 | 67 | Programming: 68 | 69 | | Key | Command | 70 | | --- | ------- | 71 | | M-i e | List errors (LSP) | 72 | | M-i d | Toggle debugging mode | 73 | | M-i r | Rename (LSP) | 74 | | M-i a | Execute code action suggested by LSP | 75 | | M-i j | Jump to a symbol in the buffer | 76 | | M-i i | Re-organize imports | 77 | | M-i g | Go-to-imlementation | 78 | | M-i t | Go to type definition | 79 | | M-i d | Find references | 80 | | M-i f | Format buffer | 81 | | M-i l | Go to last change | 82 | | M-i - | Revert buffer | 83 | | M-\ | Yasnippet | 84 | | M-RET | Trigger + Complete Copilot | 85 | | M-y | Trigger + Complete Copilot | 86 | | M-\ | Yasnippet | 87 | | M-\ | Yasnippet menu | 88 | | M-i y | Yasnippet menu | 89 | 90 | Copilot: 91 | 92 | | Key | Command | 93 | | --- | ------- | 94 | | M-y | Complete or accept | 95 | | C-Ret | Accept by line | 96 | | M-Ret | Accept by word | 97 | 98 | Writing: 99 | 100 | | Key | Command | 101 | | --- | ------- | 102 | | M-i d | Define word at point | 103 | | M-i t | Generate ToC for Markdown | 104 | | M-i j | Jump to a title | 105 | | M-i w | Create and switch to a new scratch buffer | 106 | | M-i t | Google translate at point | 107 | | M-i p | Pronounce at point | 108 | | M-i = | Reset sizing | 109 | 110 | 111 | Project(ile): 112 | 113 | | Key | Command | 114 | | --- | ------- | 115 | | M-p f | Find file in the project | 116 | | M-p p | Switch projects | 117 | | M-p b | Switch to buffer | 118 | | M-p s | Search project | 119 | | M-p r | Search & replace project | 120 | 121 | Git: 122 | 123 | | Key | Command | 124 | | --- | ------- | 125 | | M-g s | Git status | 126 | | M-g c | Create commit | 127 | | M-g d | Git diff for working tree | 128 | | M-g f | Git diff for the active buffer | 129 | | M-i up | Push local branch to remote | 130 | | M-i down | Pull from remote branch | 131 | 132 | Others: 133 | 134 | | Key | Command | 135 | | --- | ------- | 136 | | M-Backspace | Delete backwards | 137 | | C-w | Kill region | 138 | | C-r | Query & replace regexp in the buffer | 139 | | C-M-r | Query replace at cursor thing | 140 | | M-; | Comment/uncomment region | 141 | | M-c | Capitalize the word | 142 | 143 | # Customize 144 | 145 | Create a `private` folder under `.miso-emacs` and have an `init.el` file to execute custom Elisp. 146 | 147 | # Troubleshooting 148 | 149 | * **LSP-mode fails to initialize with JSON parsing errors:** 150 | 151 | Clean up all packages and start Emacs with env variable below: 152 | 153 | ```bash 154 | export LSP_USE_PLISTS=true 155 | ``` 156 | 157 | Source: https://emacs-lsp.github.io/lsp-mode/page/performance/#use-plists-for-deserialization 158 | -------------------------------------------------------------------------------- /canggu-theme/README.md: -------------------------------------------------------------------------------- 1 | # canggu-theme 2 | 3 | ![](https://user-images.githubusercontent.com/13072/132133149-206a8907-8646-432d-9f49-cbc4467edbd9.png) 4 | -------------------------------------------------------------------------------- /canggu-theme/canggu-theme.el: -------------------------------------------------------------------------------- 1 | ;;; canggu-theme.el -*- lexical-binding: t; no-byte-compile: t; -*- 2 | ;; 3 | ;; Author: Azer Koculu 4 | ;; Created: September 5, 2021 5 | ;; Version: 1.0.1 6 | ;; Keywords: custom themes, faces 7 | ;; Homepage: https://github.com/azer/canggu-theme 8 | ;; Package-Requires: ((emacs "29.1") (cl-lib "0.5") (doom-themes "2.2.1")) 9 | ;; 10 | ;; commentary 11 | ;; 12 | ;; forked doom-one and customized colors of azer/jungle-theme 13 | ;; 14 | ;;; Code: 15 | 16 | (require 'doom-themes) 17 | 18 | ;; 19 | ;;; Variables 20 | 21 | (defgroup canggu-theme nil 22 | "Options for the `canggu' theme." 23 | :group 'doom-themes) 24 | 25 | (defcustom canggu-brighter-modeline nil 26 | "If non-nil, more vivid colors will be used to style the mode-line." 27 | :group 'canggu-theme 28 | :type 'boolean) 29 | 30 | (defcustom canggu-brighter-comments nil 31 | "If non-nil, comments will be highlighted in more vivid colors." 32 | :group 'canggu-theme 33 | :type 'boolean) 34 | 35 | (defcustom canggu-padded-modeline doom-themes-padded-modeline 36 | "If non-nil, adds a 4px padding to the mode-line. 37 | Can be an integer to determine the exact padding." 38 | :group 'canggu-theme 39 | :type '(choice integer boolean)) 40 | 41 | ;; 42 | ;;; Theme definition 43 | 44 | (def-doom-theme canggu 45 | "A dark theme" 46 | 47 | ;; name default 256 16 48 | ((bg '("#1b1d22" "black" "black" )) 49 | (fg '("#C8CCD4" "#f8f8f2" "brightwhite" )) 50 | 51 | ;; These are off-color variants of bg/fg, used primarily for `solaire-mode', 52 | ;; but can also be useful as a basis for subtle highlights (e.g. for hl-line 53 | ;; or region), especially when paired with the `doom-darken', `doom-lighten', 54 | ;; and `doom-blend' helper functions. 55 | (bg-alt '("#252931" "black" "black" )) 56 | (fg-alt '("#eeeeee" "#eeeeee" "white" )) 57 | 58 | ;; These should represent a spectrum from bg to fg, where base0 is a starker 59 | ;; bg and base8 is a starker fg. For example, if bg is light grey and fg is 60 | ;; dark grey, base0 should be white and base8 should be black. 61 | (base0 '("#1B2229" "black" "black" )) 62 | (base1 '("#1c1f24" "#1e1e1e" "brightblack" )) 63 | (base2 '("#202328" "#2e2e2e" "brightblack" )) 64 | (base3 '("#23272e" "#262626" "brightblack" )) 65 | (base4 '("#3f444a" "#3f3f3f" "brightblack" )) 66 | (base5 '("#5B6268" "#525252" "brightblack" )) 67 | (base6 '("#73797e" "#6b6b6b" "brightblack" )) 68 | (base7 '("#9ca0a4" "#979797" "brightblack" )) 69 | (base8 '("#f8f8f2" "#f8f8f2" "white" )) 70 | 71 | (grey base4) 72 | (red '("#F2786D" "#F2786D" "red" )) 73 | (orange '("#FFA14F" "#FFA14F" "brightred" )) 74 | (melon '("#FFbb88" "#FFbb88" "yellow" )) 75 | (dark-melon '("#cc9955" "#cc9955" "yellow" )) 76 | (green '("#66D977" "#66D977" "green" )) 77 | (teal '("#A6E22E" "#A6E22E" "brightgreen" )) 78 | (yellow '("#D9C27E" "#D9C27E" "yellow" )) 79 | (blue '("#66D9EF" "#66D9EF" "brightblue" )) 80 | (dark-blue '("#4AA3BD" "#4AA3BD" "blue" )) 81 | (magenta '("#FE7AB2" "#FE7AB2" "brightmagenta")) 82 | (violet '("#B488F2" "#B488F2" "magenta" )) 83 | (light-cyan '("#ACF2E4" "#ACF2E4" "brightcyan")) 84 | (cyan '("#66D9EF" "#66D9EF" "brightcyan" )) 85 | (dark-cyan '("#77C3B4" "#77C3B4" "cyan" )) 86 | 87 | ;; These are the "universal syntax classes" that doom-themes establishes. 88 | ;; These *must* be included in every doom themes, or your theme will throw an 89 | ;; error, as they are used in the base theme defined in doom-themes-base. 90 | (highlight blue) 91 | (vertical-bar (doom-darken base1 0.1)) 92 | (selection dark-blue) 93 | (builtin violet) 94 | (comments (if canggu-brighter-comments dark-cyan base5)) 95 | (doc-comments (doom-lighten (if canggu-brighter-comments dark-cyan base5) 0.25)) 96 | (constants (doom-lighten dark-melon 0.5)) 97 | (functions cyan) 98 | (keywords cyan) 99 | (methods violet) 100 | (operators magenta) 101 | (type green) 102 | (strings red) 103 | (variables melon) 104 | (numbers yellow) 105 | (region (doom-lighten bg 0.1)) 106 | ;;(region `(,(doom-lighten (car bg-alt) 0.05) ,@(doom-lighten (cdr base1) 0.35))) 107 | (error red) 108 | (warning yellow) 109 | (success green) 110 | (vc-modified orange) 111 | (vc-added green) 112 | (vc-deleted red) 113 | 114 | ;; These are extra color variables used only in this theme; i.e. they aren't 115 | ;; mandatory for derived themes. 116 | (modeline-fg fg) 117 | (modeline-fg-alt base5) 118 | (modeline-bg (if canggu-brighter-modeline 119 | (doom-darken blue 0.45) 120 | (doom-darken bg-alt 0.1))) 121 | (modeline-bg-alt (if canggu-brighter-modeline 122 | (doom-darken blue 0.475) 123 | `(,(doom-darken (car bg-alt) 0.15) ,@(cdr bg)))) 124 | (modeline-bg-inactive `(,(car bg-alt) ,@(cdr base1))) 125 | (modeline-bg-inactive-alt `(,(doom-darken (car bg-alt) 0.1) ,@(cdr bg))) 126 | 127 | (-modeline-pad 128 | (when canggu-padded-modeline 129 | (if (integerp canggu-padded-modeline) canggu-padded-modeline 4)))) 130 | 131 | 132 | ;;;; Base theme face overrides 133 | (((line-number &override) :foreground base4 :family "Inconsolata" :height 160 :slant 'normal) 134 | ((line-number-current-line &override) :foreground fg :family "Inconsolata" :height 160 :slant 'normal :weight 'bold) 135 | ((font-lock-comment-face &override) 136 | :background (if canggu-brighter-comments (doom-lighten bg 0.05))) 137 | (mode-line 138 | :background modeline-bg :foreground modeline-fg 139 | :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg))) 140 | (mode-line-inactive 141 | :background modeline-bg-inactive :foreground modeline-fg-alt 142 | :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive))) 143 | (mode-line-emphasis :foreground (if canggu-brighter-modeline base8 highlight)) 144 | 145 | ;;;; css-mode / scss-mode 146 | (css-proprietary-property :foreground orange) 147 | (css-property :foreground green) 148 | (css-selector :foreground blue) 149 | ;;;; doom-modeline 150 | (doom-modeline-bar :background (if canggu-brighter-modeline modeline-bg highlight)) 151 | (doom-modeline-buffer-file :inherit 'mode-line-buffer-id :weight 'bold) 152 | (doom-modeline-buffer-path :inherit 'mode-line-emphasis :weight 'bold) 153 | (doom-modeline-buffer-project-root :foreground green :weight 'bold) 154 | ;;;; elscreen 155 | (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022") 156 | ;;;; ivy 157 | (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal) 158 | ;;;; LaTeX-mode 159 | (font-latex-math-face :foreground green) 160 | ;;;; markdown-mode 161 | (markdown-markup-face :foreground base5) 162 | (markdown-header-face :inherit 'bold :foreground red) 163 | ((markdown-code-face &override) :background (doom-lighten bg 0.05)) 164 | ;;;; rjsx-mode 165 | (rjsx-tag :foreground red) 166 | (rjsx-attr :foreground orange) 167 | ;;;; solaire-mode 168 | (solaire-mode-line-face 169 | :inherit 'mode-line 170 | :background modeline-bg-alt 171 | :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt))) 172 | (solaire-mode-line-inactive-face 173 | :inherit 'mode-line-inactive 174 | :background modeline-bg-inactive-alt 175 | :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-alt))) 176 | 177 | ;;;; lsp-headerline 178 | (lsp-headerline-breadcrumb-path-face :foreground grey :background bg) 179 | (lsp-headerline-breadcrumb-symbols-face :foreground base7 :background bg) 180 | ;; (lsp-headerline-breadcrumb-path-error-face :inherit lsp-headerline-breadcrumb-path-face) 181 | ;; (lsp-headerline-breadcrumb-path-hint-face :inherit lsp-headerline-breadcrumb-path-face) 182 | ;; (lsp-headerline-breadcrumb-path-info-face :inherit lsp-headerline-breadcrumb-path-face) 183 | ;; (lsp-headerline-breadcrumb-path-warning-face :inherit lsp-headerline-breadcrumb-path-face) 184 | ;; (lsp-headerline-breadcrumb-symbols-error-face :inherit lsp-headerline-breadcrumb-symbols-face) 185 | ;; (lsp-headerline-breadcrumb-symbols-hint-face :inherit lsp-headerline-breadcrumb-symbols-face) 186 | ;; (lsp-headerline-breadcrumb-symbols-info-face :inherit lsp-headerline-breadcrumb-symbols-face) 187 | ;; (lsp-headerline-breadcrumb-symbols-warning-face :inherit lsp-headerline-breadcrumb-symbols-face) 188 | (header-line :background bg :foreground base7 :box nil :family "Monaco" :height 0.8 :line-width 4) 189 | 190 | (markdown-header-delimiter-face :foreground base3) 191 | (markdown-header-face-1 :height 1.0 :foreground light-cyan :weight 'bold) 192 | (markdown-header-face-2 :foreground cyan) 193 | (markdown-header-face-3 :foreground dark-cyan) 194 | (markdown-header-face-4 :foreground yellow) 195 | (markdown-header-face-5 :foreground melon) 196 | (markdown-header-face-6 :foreground dark-melon) 197 | 198 | ;; treemacs 199 | (hl-line-face :background (doom-lighten bg 0.035)) 200 | (hl-line :background (doom-lighten bg 0.05)) 201 | ;;(set-face-background hl-line-face (doom-lighten bg 0.035)) 202 | (treemacs-hl-line-face :background (doom-lighten bg 0.035)) 203 | 204 | ;;;; tags 205 | (font-lock-function-name-face :foreground yellow :weight 'bold) 206 | (lsp-ui-doc-background :background base2) 207 | (button :foreground red) 208 | 209 | ;; Window divider 210 | (window-divider :foreground "#252931") 211 | 212 | ;; Custom faces 213 | (git-gutter:added :foreground "#50fa7b" :background "#50fa7b") 214 | (git-gutter:deleted :foreground "#ff79c6" :background "#ff79c6") 215 | (git-gutter:modified :foreground "#f1fa8c" :background "#f1fa8c") 216 | (lsp-ui-doc-header :background "red" :foreground "black") 217 | (lsp-ui-doc-highlight-hover :background "light green") 218 | (mode-line :family "Inconsolata" :height 150 :weight 'normal) 219 | (mode-line-active :family "Inconsolata" :height 150 :weight 'normal) 220 | (mode-line-inactive :family "Inconsolata" :height 150 :weight 'normal) 221 | ) 222 | 223 | ;;;; Base theme variable overrides 224 | () 225 | ) 226 | 227 | ;; Enable relative line numbers for programming modes 228 | (add-hook 'prog-mode-hook (lambda () 229 | (setq display-line-numbers 'relative) 230 | (setq display-line-numbers-type 'relative) 231 | (setq display-line-numbers-width 3) 232 | (setq display-line-numbers-grow-only t) 233 | (setq display-line-numbers-width-start t) 234 | (display-line-numbers-mode 1))) 235 | 236 | ;; Disable line numbers for some modes 237 | (dolist (mode '(org-mode-hook 238 | term-mode-hook 239 | shell-mode-hook 240 | treemacs-mode-hook 241 | eshell-mode-hook)) 242 | (add-hook mode (lambda () (display-line-numbers-mode 0)))) 243 | 244 | (provide 'canggu-theme) 245 | ;;; canggu-theme.el ends here 246 | -------------------------------------------------------------------------------- /dependencies.el: -------------------------------------------------------------------------------- 1 | (message "Setting up dependencies...") 2 | 3 | ;;(package-initialize) 4 | 5 | (setq package-archives 6 | '(("melpa" . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/melpa/") 7 | ("org" . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/org/") 8 | ("gnu" . "https://raw.githubusercontent.com/d12frosted/elpa-mirror/master/gnu/"))) 9 | 10 | 11 | (eval-when-compile 12 | (add-load-path "use-package") 13 | (require 'use-package)) 14 | 15 | (use-package exec-path-from-shell :ensure t 16 | :init 17 | (when (memq window-system '(mac ns x)) 18 | (exec-path-from-shell-initialize)) 19 | ) 20 | 21 | (use-package markdown-mode :ensure t) 22 | 23 | (use-package solaire-mode :ensure t) 24 | 25 | (use-package golden-ratio :ensure t 26 | :hook (after-init . golden-ratio-mode) 27 | ) 28 | 29 | (use-package treemacs :ensure t 30 | :bind ("" . treemacs) 31 | :custom 32 | (treemacs-is-never-other-window) 33 | :hook 34 | (treemacs-mode . treemacs-project-follow-mode) 35 | ) 36 | 37 | ;; The Emacs default split doesn't seem too intuitive for most users. 38 | (use-package emacs 39 | :ensure nil 40 | :preface 41 | (defun ian/split-and-follow-horizontally () 42 | "Split window below." 43 | (interactive) 44 | (split-window-below) 45 | (other-window 1)) 46 | (defun ian/split-and-follow-vertically () 47 | "Split window right." 48 | (interactive) 49 | (split-window-right) 50 | (other-window 1)) 51 | :config 52 | (global-set-key (kbd "C-x 2") #'ian/split-and-follow-horizontally) 53 | (global-set-key (kbd "C-x 3") #'ian/split-and-follow-vertically)) 54 | 55 | (use-package diminish 56 | :ensure t 57 | :demand t) 58 | 59 | (use-package ediff 60 | :ensure nil 61 | :config 62 | (setq ediff-window-setup-function #'ediff-setup-windows-plain) 63 | (setq ediff-split-window-function #'split-window-horizontally)) 64 | 65 | (use-package frame 66 | :preface 67 | :ensure nil 68 | :config 69 | (setq initial-frame-alist '((fullscreen . maximized)))) 70 | 71 | ;; Replace the active region just by typing text, just like modern editors. 72 | (use-package delsel 73 | :ensure nil 74 | :config (delete-selection-mode +1)) 75 | 76 | ;; auto-completion with company 77 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 78 | ;; (use-package company :ensure t ;; 79 | ;; :config ;; 80 | ;; (setq company-idle-delay 0) ;; 81 | ;; (setq company-minimum-prefix-length 1) ;; 82 | ;; (setq lsp-completion-provider :capf) ;; 83 | ;; :custom ;; 84 | ;; (lsp-enable-snippet t) ;; 85 | ;; ) ;; 86 | ;; ;; 87 | ;; (use-package company-quickhelp ;; 88 | ;; :ensure t ;; 89 | ;; :init ;; 90 | ;; (company-quickhelp-mode 1) ;; 91 | ;; (use-package pos-tip ;; 92 | ;; :ensure t)) ;; 93 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 94 | 95 | (use-package ace-window :ensure t) 96 | ;;(use-package counsel :ensure t) 97 | 98 | ;;(use-package ivy :ensure t) 99 | (use-package swiper :ensure t) 100 | (use-package projectile :ensure t) 101 | ;;(use-package counsel-projectile :ensure t) 102 | (use-package writeroom-mode :ensure t) 103 | ;;(use-package linum-relative :ensure t) 104 | (use-package undo-fu :ensure t) 105 | (use-package goto-last-change :ensure t) 106 | (use-package flyspell-correct 107 | :ensure t 108 | :bind (:map flyspell-mode-map ("M-i c" . flyspell-correct-wrapper))) 109 | 110 | (use-package flyspell-correct-ivy :ensure t :after flyspell-correct) 111 | 112 | ;; The `vertico' package applies a vertical layout to the minibuffer. 113 | ;; It also pops up the minibuffer eagerly so we can see the available 114 | ;; options without further interactions. This package is very fast 115 | ;; and "just works", though it also is highly customisable in case we 116 | ;; need to modify its behaviour. 117 | ;; 118 | ;; Further reading: https://protesilaos.com/emacs/dotemacs#h:cff33514-d3ac-4c16-a889-ea39d7346dc5 119 | (use-package vertico 120 | :ensure t 121 | :config 122 | (setq vertico-cycle t) 123 | (setq vertico-resize nil) 124 | (vertico-mode 1)) 125 | 126 | ;; The `marginalia' package provides helpful annotations next to 127 | ;; completion candidates in the minibuffer. The information on 128 | ;; display depends on the type of content. If it is about files, it 129 | ;; shows file permissions and the last modified date. If it is a 130 | ;; buffer, it shows the buffer's size, major mode, and the like. 131 | ;; 132 | ;; Further reading: https://protesilaos.com/emacs/dotemacs#h:bd3f7a1d-a53d-4d3e-860e-25c5b35d8e7e 133 | (use-package marginalia 134 | :ensure t 135 | :config 136 | (marginalia-mode 1)) 137 | 138 | ;; Ensure system PATH is correctly set in Emacs 139 | (use-package exec-path-from-shell 140 | :if (memq window-system '(mac ns x)) 141 | :config 142 | (exec-path-from-shell-initialize)) 143 | 144 | ;; Selectrum for completion 145 | (use-package selectrum 146 | :ensure t 147 | :config 148 | (selectrum-mode +1)) 149 | 150 | ;; Orderless for flexible matching 151 | (use-package orderless 152 | :ensure t 153 | :custom 154 | (completion-styles '(orderless)) 155 | :config 156 | (setq selectrum-refine-candidates-function #'orderless-filter) 157 | (setq selectrum-highlight-candidates-function #'orderless-highlight-matches)) 158 | 159 | ;; Marginalia for minibuffer annotations 160 | (use-package marginalia 161 | :config 162 | (marginalia-mode)) 163 | 164 | ;; Consult for enhanced search and navigation 165 | (use-package consult 166 | :config 167 | (setq consult-async-split-style nil) 168 | (setq consult-ripgrep-command "rg -F --null --line-buffered --color=ansi --max-columns=500 --no-heading --line-number . -e ARG OPTS") 169 | (setq consult-async-min-input 1) 170 | (setq consult-narrow-key nil) 171 | (setq xref-show-xrefs-function #'consult-xref 172 | xref-show-definitions-function #'consult-xref)) 173 | 174 | (use-package projectile 175 | :config 176 | (projectile-mode +1) 177 | :bind-keymap 178 | ("C-c p" . projectile-command-map)) 179 | 180 | (use-package consult-projectile 181 | :straight (consult-projectile :type git :host gitlab :repo "OlMon/consult-projectile" :branch "master")) 182 | 183 | (use-package embark 184 | :ensure t 185 | :bind (("C-." . embark-act) 186 | :map minibuffer-local-map 187 | ("C-c C-c" . embark-collect) 188 | ("C-c C-e" . embark-export))) 189 | 190 | ;; The `embark-consult' package is glue code to tie together `embark' 191 | ;; and `consult'.f 192 | (use-package embark-consult 193 | :ensure t) 194 | 195 | ;; The `wgrep' packages lets us edit the results of a grep search 196 | ;; while inside a `grep-mode' buffer. All we need is to toggle the 197 | ;; editable mode, make the changes, and then type C-c C-c to confirm 198 | ;; or C-c C-k to abort. 199 | ;; 200 | ;; Further reading: https://protesilaos.com/emacs/dotemacs#h:9a3581df-ab18-4266-815e-2edd7f7e4852 201 | (use-package wgrep 202 | :ensure t 203 | :bind ( :map grep-mode-map 204 | ("e" . wgrep-change-to-wgrep-mode) 205 | ("C-x C-q" . wgrep-change-to-wgrep-mode) 206 | ("C-c C-c" . wgrep-finish-edit))) 207 | 208 | ;; show icons in the ivy list 209 | (use-package all-the-icons-ivy 210 | :ensure t 211 | :init (add-hook 'after-init-hook 'all-the-icons-ivy-setup)) 212 | 213 | ;; Go 214 | (use-package go-mode :ensure t) 215 | 216 | ;; Elixir 217 | (use-package elixir-mode :ensure t) 218 | 219 | (use-package dockerfile-mode :ensure t) 220 | 221 | ;; rust 222 | (use-package cargo-mode :ensure t) 223 | (use-package rust-mode :ensure t 224 | :config 225 | (add-hook 'rust-mode-hook 226 | (lambda () (setq indent-tabs-mode nil))) 227 | (setq rust-format-on-save t) 228 | (add-hook 'rust-mode-hook 229 | (lambda () (prettify-symbols-mode))) 230 | (add-hook 'rust-mode-hook #'lsp) 231 | ) 232 | 233 | ;; TypeScript 234 | ;; (use-package typescript-mode 235 | ;; :after tree-sitter 236 | ;; :ensure t 237 | ;; :mode (("\\.ts\\'" . typescript-mode) 238 | ;; ("\\.tsx\\'" . typescriptreact-mode)) 239 | ;; :config 240 | ;; (setq typescript-indent-level 2) 241 | ;; (add-hook 'typescript-mode #'subword-mode) 242 | 243 | ;; (define-derived-mode typescriptreact-mode typescript-mode 244 | ;; "TypeScript TSX") 245 | 246 | ;; ;; use our derived mode for tsx files 247 | ;; (add-to-list 'auto-mode-alist '("\\.tsx?\\'" . typescriptreact-mode)) 248 | ;; ;; by default, typescript-mode is mapped to the treesitter typescript parser 249 | ;; ;; use our derived mode to map both .tsx AND .ts -> typescriptreact-mode -> treesitter tsx 250 | ;; (add-to-list 'tree-sitter-major-mode-language-alist '(typescriptreact-mode . tsx))) 251 | 252 | ;; (use-package eglot 253 | ;; :ensure t 254 | ;; :defer 3 255 | ;; :hook 256 | ;; ((js-mode 257 | ;; typescript-mode 258 | ;; typescriptreact-mode) . eglot-ensure) 259 | ;; :config 260 | ;; (cl-pushnew '((js-mode typescript-mode typescriptreact-mode) . ("typescript-language-server" "--stdio")) 261 | ;; eglot-server-programs 262 | ;; :test #'equal)) 263 | 264 | (use-package posframe 265 | :straight t 266 | :after dashboard 267 | ) 268 | 269 | (use-package markdown-mode 270 | :straight t 271 | :after dashboard 272 | ) 273 | 274 | ;; (use-package lsp-bridge 275 | ;; :straight '(lsp-bridge :type git :host github :repo "manateelazycat/lsp-bridge" 276 | ;; :files (:defaults "*.el" "*.py" "acm" "core" "langserver" "multiserver" "resources") 277 | ;; :build (:not compile)) 278 | ;; :init 279 | ;; (global-lsp-bridge-mode)) 280 | 281 | 282 | 283 | (use-package posframe :ensure t) 284 | (use-package dap-mode :ensure t) 285 | (use-package go-dlv :ensure t) 286 | 287 | ;; (use-package lsp-ui 288 | ;; :ensure t 289 | ;; :commands lsp-ui-mode 290 | ;; :init 291 | ;; :config 292 | ;; (setq lsp-headerline-breadcrumb-enable t) 293 | ;; (setq lsp-ui-doc-position 'at-point) 294 | ;; (setq lsp-ui-sideline--code-actions t) 295 | ;; :custom 296 | ;; (lsp-ui-doc-position 'bottom) 297 | ;; (lsp-ui-doc-delay 0) 298 | ;; ) 299 | 300 | ;; (use-package lsp-ivy :commands lsp-ivy-workspace-symbol) 301 | ;; (use-package lsp-treemacs 302 | ;; :commands lsp-treemacs-errors-list 303 | ;; :custom 304 | ;; (lsp-treemacs-sync-mode 1) 305 | ;; ) 306 | 307 | ;; m-x enhancements 308 | (use-package smex :ensure t) 309 | 310 | ;; better search & replace 311 | (use-package anzu :ensure t) 312 | 313 | (use-package ctrlf :ensure t) 314 | 315 | (use-package rg :ensure t 316 | :init 317 | (rg-enable-default-bindings) 318 | ) 319 | 320 | ;; preview markdown with github 321 | (use-package gh-md :ensure t) 322 | 323 | ;; generate ToC for markdown 324 | (use-package markdown-toc :ensure t) 325 | 326 | (use-package flycheck 327 | :ensure t 328 | :hook ((typescript-ts-mode . flycheck-mode) 329 | (tsx-ts-mode . flycheck-mode)) 330 | :config 331 | (flycheck-add-mode 'typescript-tslint 'typescript-ts-mode) 332 | (flycheck-add-mode 'typescript-tslint 'tsx-ts-mode) 333 | ) 334 | 335 | (use-package consult-flycheck 336 | :ensure t) 337 | 338 | (use-package all-the-icons :ensure t) 339 | 340 | (use-package doom-modeline 341 | :ensure t 342 | :init (doom-modeline-mode 1) 343 | :config (column-number-mode 1) 344 | :custom 345 | (doom-modeline-height 30) 346 | (doom-modeline-window-width-limit nil) 347 | (doom-modeline-buffer-file-name-style 'relative-from-project) 348 | (doom-modeline-minor-modes nil) 349 | (doom-modeline-enable-word-count t) 350 | (doom-modeline-buffer-encoding nil) 351 | (doom-modeline-buffer-modification-icon t) 352 | (doom-modeline-env-python-executable "python") 353 | ;;needs display-time-mode to be one 354 | (doom-modeline-time t) 355 | (doom-modeline-vcs-max-length 100)) 356 | 357 | 358 | (use-package doom-themes 359 | :ensure t 360 | :config 361 | ;; Global settings (defaults) 362 | (setq doom-themes-enable-bold t ; if nil, bold is universally disabled 363 | doom-themes-enable-italic t) ; if nil, italics is universally disabled 364 | ;;(load-theme 'doom-one t) 365 | 366 | ;; Enable flashing mode-line on errors 367 | (doom-themes-visual-bell-config) 368 | ;; Enable custom neotree theme (all-the-icons must be installed!) 369 | (doom-themes-neotree-config) 370 | ;; or for treemacs users 371 | ;;(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme 372 | (doom-themes-treemacs-config) 373 | ;; Corrects (and improves) org-mode's native fontification. 374 | (doom-themes-org-config)) 375 | 376 | ;; use ivy to correct words 377 | (use-package flyspell-correct 378 | :after flyspell 379 | :bind (:map flyspell-mode-map ("M-i c" . flyspell-correct-wrapper))) 380 | 381 | ;; dictionary 382 | (use-package define-word :ensure t) 383 | 384 | (use-package popup :ensure t) 385 | 386 | ;; translate 387 | (use-package google-translate :ensure t 388 | :config 389 | (require 'google-translate) 390 | (require 'google-translate-default-ui) 391 | ) 392 | 393 | ;; git 394 | (use-package git-modes :ensure t :defer t) 395 | (use-package magit 396 | :ensure t 397 | :custom 398 | (magit-auto-revert-mode nil) 399 | ) 400 | 401 | ;; display better diffs 402 | (use-package git-gutter 403 | :ensure t 404 | :custom 405 | (git-gutter:modified-sign "~") ;  406 | (git-gutter:added-sign "+++") ;  407 | (git-gutter:deleted-sign "-") ;  408 | :custom-face 409 | (git-gutter:modified ((t (:foreground "#f1fa8c" :background "#f1fa8c")))) 410 | (git-gutter:added ((t (:foreground "#50fa7b" :background "#50fa7b")))) 411 | (git-gutter:deleted ((t (:foreground "#ff79c6" :background "#ff79c6")))) 412 | ) 413 | 414 | ;;(use-package devdocs :ensure t) 415 | 416 | ;; move where I mean 417 | (use-package mwim 418 | :ensure t 419 | :bind 420 | ("C-a" . mwim-beginning-of-code-or-line) 421 | ("C-e" . mwim-end-of-code-or-line)) 422 | 423 | ;; Display available keybindings in popup 424 | (use-package which-key 425 | :ensure t 426 | :diminish which-key-mode 427 | :hook (after-init . which-key-mode)) 428 | 429 | ;; Ensure find-file-in-project is installed 430 | (use-package find-file-in-project 431 | :ensure t) 432 | 433 | (use-package web-mode 434 | :ensure t 435 | ) 436 | 437 | (use-package rjsx-mode 438 | :ensure t 439 | ) 440 | 441 | (use-package prettier 442 | :ensure t 443 | :hook ((typescript-ts-mode . prettier-mode) 444 | (tsx-ts-mode . prettier-mode))) 445 | 446 | (use-package yaml-mode :ensure t) 447 | 448 | ;; better editing experience with parenthesis 449 | (use-package smartparens 450 | :ensure t 451 | :hook 452 | (after-init . smartparens-global-mode) 453 | :config 454 | (require 'smartparens-config) 455 | (sp-pair "=" "=" :actions '(wrap)) 456 | (sp-pair "+" "+" :actions '(wrap)) 457 | (sp-pair "<" ">" :actions '(wrap)) 458 | (sp-pair "$" "$" :actions '(wrap))) 459 | 460 | (use-package yasnippet 461 | :ensure t 462 | :init (yas-global-mode 1) 463 | :hook ((typescript-ts-mode . yas-minor-mode) 464 | (tsx-ts-mode . yas-minor-mode)) 465 | :config 466 | (add-hook 'typescript-ts-mode-hook 467 | (lambda () (yas-activate-extra-mode 'typescript-mode))) 468 | (add-hook 'tsx-ts-mode-hook 469 | (lambda () (yas-activate-extra-mode 'typescript-mode))) 470 | ) 471 | 472 | (use-package calfw 473 | :ensure t 474 | ) 475 | 476 | (use-package calfw-org 477 | :ensure t 478 | ) 479 | 480 | (use-package dumb-jump 481 | :ensure t 482 | ) 483 | 484 | (use-package treesit 485 | :commands (treesit-install-language-grammar nf/treesit-install-all-languages) 486 | :init 487 | (setq treesit-language-source-alist 488 | '((bash . ("https://github.com/tree-sitter/tree-sitter-bash")) 489 | (c . ("https://github.com/tree-sitter/tree-sitter-c")) 490 | (cpp . ("https://github.com/tree-sitter/tree-sitter-cpp")) 491 | (css . ("https://github.com/tree-sitter/tree-sitter-css")) 492 | (cmake . ("https://github.com/uyha/tree-sitter-cmake")) 493 | (go . ("https://github.com/tree-sitter/tree-sitter-go")) 494 | (html . ("https://github.com/tree-sitter/tree-sitter-html")) 495 | (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript")) 496 | (json . ("https://github.com/tree-sitter/tree-sitter-json")) 497 | (julia . ("https://github.com/tree-sitter/tree-sitter-julia")) 498 | (lua . ("https://github.com/Azganoth/tree-sitter-lua")) 499 | (make . ("https://github.com/alemuller/tree-sitter-make")) 500 | (ocaml . ("https://github.com/tree-sitter/tree-sitter-ocaml" "master" "ocaml/src")) 501 | (python . ("https://github.com/tree-sitter/tree-sitter-python")) 502 | (php . ("https://github.com/tree-sitter/tree-sitter-php")) 503 | (typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")) 504 | (tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")) 505 | (ruby . ("https://github.com/tree-sitter/tree-sitter-ruby")) 506 | (rust . ("https://github.com/tree-sitter/tree-sitter-rust")) 507 | (sql . ("https://github.com/m-novikov/tree-sitter-sql")) 508 | (toml . ("https://github.com/tree-sitter/tree-sitter-toml")) 509 | (zig . ("https://github.com/GrayJack/tree-sitter-zig")))) 510 | :config 511 | (defun nf/treesit-install-all-languages () 512 | "Install all languages specified by `treesit-language-source-alist'." 513 | (interactive) 514 | (let ((languages (mapcar 'car treesit-language-source-alist))) 515 | (dolist (lang languages) 516 | (treesit-install-language-grammar lang) 517 | (message "`%s' parser was installed." lang) 518 | (sit-for 0.75))))) 519 | 520 | (use-package treesit-auto 521 | :ensure t 522 | :config 523 | (global-treesit-auto-mode)) 524 | 525 | (use-package treesit-auto 526 | :config 527 | (global-treesit-auto-mode)) 528 | 529 | (use-package yasnippet 530 | :ensure t) 531 | 532 | (use-package yasnippet-snippets 533 | :ensure t) 534 | 535 | (use-package consult-yasnippet 536 | :ensure t) 537 | 538 | (use-package copilot 539 | :load-path (lambda () (concat +emacs-dir+ "/copilot.el")) 540 | ;; don't show in mode line 541 | :diminish) 542 | 543 | (use-package dtrt-indent 544 | :ensure t) 545 | 546 | ;;;; Code Completion 547 | (use-package corfu 548 | :ensure t 549 | ;; Optional customizations 550 | :custom 551 | (corfu-cycle t) ; Allows cycling through candidates 552 | (corfu-auto t) ; Enable auto completion 553 | (corfu-auto-prefix 2) ; Minimum length of prefix for completion 554 | (corfu-auto-delay 0) ; No delay for completion 555 | (corfu-popupinfo-delay '(0.5 . 0.2)) ; Automatically update info popup after that numver of seconds 556 | (corfu-preview-current 'insert) ; insert previewed candidate 557 | (corfu-preselect 'prompt) 558 | (corfu-on-exact-match nil) ; Don't auto expand tempel snippets 559 | ;; Optionally use TAB for cycling, default is `corfu-complete'. 560 | :bind (:map corfu-map 561 | ("M-SPC" . corfu-insert-separator) 562 | ("TAB" . corfu-next) 563 | ([tab] . corfu-next) 564 | ("S-TAB" . corfu-previous) 565 | ([backtab] . corfu-previous) 566 | ("S-" . corfu-insert) 567 | ("RET" . corfu-insert)) 568 | 569 | :init 570 | (global-corfu-mode) 571 | (corfu-history-mode) 572 | (corfu-popupinfo-mode) ; Popup completion info 573 | :config 574 | (add-hook 'eshell-mode-hook 575 | (lambda () (setq-local corfu-quit-at-boundary t 576 | corfu-quit-no-match t 577 | corfu-auto nil) 578 | (corfu-mode)) 579 | nil 580 | t)) 581 | 582 | ;; auto-format different source code files extremely intelligently 583 | ;; https://github.com/radian-software/apheleia 584 | (use-package apheleia 585 | :ensure apheleia 586 | :diminish "" 587 | :defines 588 | apheleia-formatters 589 | apheleia-mode-alist 590 | [] :functions 591 | apheleia-global-mode 592 | :config 593 | (setf (alist-get 'prettier-json apheleia-formatters) 594 | '("prettier" "--stdin-filepath" filepath)) 595 | (apheleia-global-mode +1)) 596 | 597 | (use-package treesit-auto 598 | :custom 599 | (treesit-auto-install 'prompt) 600 | :config 601 | (global-treesit-auto-mode)) 602 | 603 | (use-package tree-sitter-langs 604 | :ensure t) 605 | -------------------------------------------------------------------------------- /init.el: -------------------------------------------------------------------------------- 1 | (message "Setting up Misomacs") 2 | 3 | (setenv "LSP_USE_PLISTS" "true") 4 | 5 | ;; make sure dependencies are installed 6 | (enable "straight") 7 | (include "dependencies") 8 | 9 | (enable "emacs") 10 | (enable "consult") 11 | (enable "writing-mode") 12 | (enable "markdown") 13 | (enable "rabbit-mode") 14 | (enable "trailing-whitespace") 15 | (enable "rename-current-buffer") 16 | (enable "programming") 17 | (enable "go") 18 | (enable "typescript") 19 | (enable "javascript") 20 | (enable "project") 21 | (enable "anzu") 22 | (enable "modeline") 23 | (enable "scratch") 24 | (enable "debugging") 25 | (enable "windows") 26 | (enable "git") 27 | (enable "mac") 28 | (enable "colors") 29 | (enable "tabs") 30 | (enable "copilot") 31 | (enable "lsp") 32 | (enable "warnings") 33 | 34 | (set-cursor-color "#77B8E9") 35 | (setq cursor-type '(bar . 8)) 36 | 37 | (setq doom-themes-treemacs-enable-variable-pitch nil) 38 | 39 | (set-frame-parameter (selected-frame) 'alpha '(97 97)) 40 | (add-to-list 'default-frame-alist '(alpha 97 97)) 41 | -------------------------------------------------------------------------------- /miso/anzu.el: -------------------------------------------------------------------------------- 1 | (global-set-key (kbd "C-r") 'anzu-query-replace-regexp) 2 | (global-set-key (kbd "C-M-r") 'anzu-query-replace-at-cursor-thing) 3 | -------------------------------------------------------------------------------- /miso/colors.el: -------------------------------------------------------------------------------- 1 | (load-local-file "canggu-theme/canggu-theme") 2 | (add-hook 'after-init-hook (lambda () 3 | (enable-theme 'canggu) 4 | (set-face-attribute 'default nil 5 | :family "Inconsolata" 6 | :height 170 7 | :weight 'normal 8 | :width 'normal) 9 | 10 | )) 11 | 12 | (add-hook 'after-init-hook (doom-modeline-mode)) 13 | 14 | (setq doom-themes-enable-bold t ; if nil, bold is universally disabled 15 | doom-themes-enable-italic t) ; if nil, italics is universally disabled 16 | 17 | (custom-set-variables 18 | '(window-divider-default-bottom-width 1) 19 | '(window-divider-default-places t) 20 | '(window-divider-default-right-width 1) 21 | '(window-divider-mode t)) 22 | -------------------------------------------------------------------------------- /miso/completion.elc: -------------------------------------------------------------------------------- 1 | ;ELC 2 | ;;; Compiled 3 | ;;; in Emacs version 29.4 4 | ;;; with all optimizations. 5 | 6 | 7 | 8 | (byte-code "\302\303\304\"\210\302\305\306\"\210\302\307\306\"\210\302\310\311\"\210\312\313\302\207" [consult-async-min-input consult-narrow-key global-set-key "" consult-line [M-tab] consult-buffer "b" "" consult-find 1 "<"] 3) 9 | -------------------------------------------------------------------------------- /miso/consult.el: -------------------------------------------------------------------------------- 1 | ;; New and modified functions 2 | (defun miso/get-search-dir () 3 | "Get the appropriate search directory." 4 | (or (projectile-project-root) 5 | (and buffer-file-name (file-name-directory buffer-file-name)) 6 | default-directory)) 7 | 8 | (defun miso/consult-find () 9 | "Run consult-find in the current project or current directory." 10 | (interactive) 11 | (let ((search-dir (miso/get-search-dir))) 12 | (consult-find search-dir))) 13 | 14 | (defun miso/consult-ripgrep () 15 | "Run consult-ripgrep in the current project or current directory." 16 | (interactive) 17 | (let ((search-dir (miso/get-search-dir))) 18 | (consult-ripgrep search-dir))) 19 | 20 | ;; Enhanced goto-line with preview 21 | (defun miso/goto-line-preview () 22 | "Go to line with preview." 23 | (interactive) 24 | (consult-goto-line)) 25 | 26 | ;; shortcuts 27 | (global-set-key "\C-s" 'consult-line) 28 | (global-set-key (kbd "M-g g") 'consult-goto-line) 29 | (global-set-key (kbd "M-g M-g") 'consult-goto-line) 30 | (global-set-key (kbd "M-") 'consult-buffer) 31 | (global-set-key (kbd "M-l") 'miso/goto-line-preview) ; New ergonomic shortcut 32 | (global-set-key (kbd "C-x b") 'consult-buffer) 33 | -------------------------------------------------------------------------------- /miso/copilot.el: -------------------------------------------------------------------------------- 1 | ;; Ensure required packages are available 2 | (require 'cl-lib) 3 | (require 's) 4 | (require 'dash) 5 | (require 'editorconfig) 6 | 7 | ;; Initialize packages if not already installed 8 | (let ((pkg-list '(use-package s dash editorconfig))) 9 | (package-initialize) 10 | (when-let ((to-install (seq-filter (lambda (pkg) (not (package-installed-p pkg))) pkg-list))) 11 | (package-refresh-contents) 12 | (mapc #'package-install pkg-list))) 13 | 14 | ;; Make sure editorconfig is properly initialized 15 | (editorconfig-mode 1) 16 | 17 | ;; Copilot completion functions 18 | (defun miso/copilot-complete-or-accept () 19 | "Command that either triggers a completion or accepts one if one is available." 20 | (interactive) 21 | (if (copilot--overlay-visible) 22 | (copilot-accept-completion) 23 | (copilot-complete))) 24 | 25 | (defun miso/setup-copilot-keys () 26 | "Set up Copilot key bindings for the current buffer." 27 | (when (derived-mode-p 'prog-mode) 28 | (let ((map (make-sparse-keymap))) 29 | ;; Create key bindings 30 | (define-key map (kbd "M-C-") #'copilot-next-completion) 31 | (define-key map (kbd "M-C-") #'copilot-previous-completion) 32 | (define-key map (kbd "M-C-") #'copilot-accept-completion-by-word) 33 | (define-key map (kbd "M-C-") #'copilot-accept-completion-by-line) 34 | (define-key map (kbd "C-") #'copilot-accept-completion-by-line) 35 | (define-key map (kbd "M-") #'copilot-accept-completion-by-word) 36 | (define-key map (kbd "M-y") #'miso/copilot-complete-or-accept) 37 | ;; Set as buffer-local map 38 | (setq-local minor-mode-overriding-map-alist 39 | (cons (cons 'copilot-mode map) 40 | (default-value 'minor-mode-overriding-map-alist)))))) 41 | 42 | ;; Hook setup 43 | (add-hook 'prog-mode-hook #'copilot-mode) 44 | (add-hook 'prog-mode-hook #'miso/setup-copilot-keys) 45 | 46 | ;; Ensure proper indentation handling 47 | (setq copilot-indent-offset-alist 48 | '((python-mode . 4) 49 | (js-mode . 2) 50 | (typescript-mode . 2) 51 | (tsx-mode . 2) 52 | (go-mode . 8) 53 | (c-mode . 4) 54 | (c++-mode . 4))) 55 | 56 | ;; The packages required for it to work are: s, dash, editorconfig (and I also use company, use-package and 57 | ;; Emacs built-in cl package here as I find those very helpful). Install them like this: 58 | ;; https://robert.kra.hn/posts/2023-02-22-copilot-emacs-setup/ 59 | (require 'cl) 60 | (let ((pkg-list '(use-package 61 | s 62 | dash 63 | editorconfig 64 | ))) 65 | (package-initialize) 66 | (when-let ((to-install (map-filter (lambda (pkg _) (not (package-installed-p pkg))) pkg-list))) 67 | (package-refresh-contents) 68 | (mapc (lambda (pkg) (package-install pkg)) pkg-list))) 69 | 70 | (defun miso/copilot-complete-or-accept () 71 | "Command that either triggers a completion or accepts one if one is available." 72 | (interactive) 73 | (if (copilot--overlay-visible) 74 | (copilot-accept-completion) 75 | (copilot-complete))) 76 | 77 | (defun miso/setup-copilot-keys () 78 | "Set up Copilot key bindings for the current buffer." 79 | (when (derived-mode-p 'prog-mode) 80 | (define-key copilot-mode-map (kbd "M-C-") #'copilot-next-completion) 81 | (define-key copilot-mode-map (kbd "M-C-") #'copilot-previous-completion) 82 | (define-key copilot-mode-map (kbd "M-C-") #'copilot-accept-completion-by-word) 83 | (define-key copilot-mode-map (kbd "M-C-") #'copilot-accept-completion-by-line) 84 | (define-key (current-local-map) (kbd "C-") #'copilot-accept-completion-by-line) 85 | (define-key (current-local-map) (kbd "M-") #'copilot-accept-completion-by-word) 86 | (define-key (current-local-map) (kbd "M-y") #'miso/copilot-complete-or-accept))) 87 | 88 | ;; (dolist (mode-indent miso/mode-indent-alist) 89 | ;; (let* ((mode (car mode-indent)) 90 | ;; (indent-info (cdr mode-indent)) 91 | ;; (indent (if (listp indent-info) (car indent-info) indent-info))) 92 | ;; (add-to-list 'copilot-indentation-alist (cons mode indent)))) 93 | 94 | (add-hook 'prog-mode-hook #'copilot-mode) 95 | (add-hook 'prog-mode-hook #'miso/setup-copilot-keys) 96 | -------------------------------------------------------------------------------- /miso/debugging.el: -------------------------------------------------------------------------------- 1 | ;; enable dap mode 2 | (setq dap-auto-configure-features '(sessions locals controls tooltip)) 3 | 4 | (setq debugging-mode-server-cmd "make start-remote-dlv") 5 | 6 | (defun start-remote-delve () 7 | (interactive) 8 | (setq debugging-mode-server-cmd (read-from-minibuffer "Start Remote DLV: " debugging-mode-server-cmd)) 9 | (projectile-with-default-dir (projectile-project-root) 10 | ;; (eshell-command (concat debugging-mode-server-cmd " &") t) 11 | (start-process "delve-remote" "*delve-remote*" "make" "start-remote-dlv") 12 | ) 13 | (let ((new-buffer (get-buffer-create "*delve-remote*"))) 14 | ;; (switch-to-buffer-other-window new-buffer) 15 | (message (concat "Executing remote debugging server command: " debugging-mode-server-cmd)))) 16 | 17 | (defun start-debugging-mode () 18 | (interactive) 19 | (dap-mode t) 20 | (dap-ui-mode t) 21 | (dap-tooltip-mode) 22 | (dap-ui-controls-mode 1) 23 | (dap-ui-sessions) 24 | (dap-ui-locals) 25 | (dap-ui-breakpoints) 26 | (dap-ui-repl) 27 | ) 28 | 29 | (defun stop-debugging-mode () 30 | (interactive) 31 | (dap-delete-all-sessions) 32 | (dap-breakpoint-delete-all) 33 | (dap-mode 0) 34 | (dap-ui-mode 0) 35 | (dap-ui-controls-mode 0) 36 | (delete-other-windows) 37 | (kill-buffer "*dap-ui-repl*") 38 | (kill-buffer "*dap-ui-breakpoints*") 39 | (kill-buffer "*dap-ui-locals*") 40 | (kill-buffer "*dap-ui-sessions*") 41 | ) 42 | 43 | (defun debugging-mode () 44 | (interactive) 45 | (if (bound-and-true-p dap-mode) 46 | (stop-debugging-mode) 47 | (start-debugging-mode) 48 | )) 49 | 50 | 51 | (add-hook 'prog-mode-hook (lambda () 52 | (interactive) 53 | (local-set-key (kbd "M-i b") 'debugging-mode))) 54 | -------------------------------------------------------------------------------- /miso/elixir.el: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /miso/emacs.el: -------------------------------------------------------------------------------- 1 | ;; hide menu / toolbars 2 | ;;(add-to-list 'default-frame-alist '(undecorated . t)) 3 | (add-to-list 'default-frame-alist '(ns-transparent-titlebar . t)) 4 | (add-to-list 'default-frame-alist '(ns-appearance . dark)) 5 | (setq ns-use-proxy-icon nil) 6 | 7 | ;;(setq ns-auto-hide-menu-bar t) 8 | 9 | (menu-bar-mode -1) 10 | (scroll-bar-mode -1) 11 | (tool-bar-mode -1) 12 | 13 | ;;(counsel-mode 1) 14 | ;;(ivy-mode 1) 15 | (doom-modeline-mode 1) 16 | (add-hook 'after-init-hook #'doom-modeline-mode) 17 | 18 | (save-place-mode 1) 19 | (global-auto-revert-mode 1) 20 | 21 | ;; remove ugly window divider 22 | (window-divider-mode -1) 23 | (setq window-divider-default-bottom-width 0) 24 | 25 | ;; hide splash screen 26 | (setq inhibit-splash-screen t) 27 | (setq inhibit-startup-message t) 28 | 29 | ;; sane defaults for emacs 30 | (defalias 'yes-or-no-p 'y-or-n-p) 31 | (setq make-backup-files nil) 32 | (setq backup-inhibited t) 33 | (setq auto-save-default nil) 34 | (setq temporary-file-directory "/tmp/") 35 | (setq create-lockfiles nil) 36 | (setq auto-save-file-name-transforms 37 | `((".*" ,temporary-file-directory t))) 38 | 39 | (setq confirm-kill-emacs nil) 40 | (set-default 'truncate-lines t) 41 | 42 | ;; change cursor color 43 | (set-cursor-color "#77B8E9") 44 | 45 | (when (fboundp 'windmove-default-keybindings) 46 | (windmove-default-keybindings)) 47 | 48 | (windmove-default-keybindings 'meta) 49 | 50 | (global-unset-key (kbd "C-z")) 51 | (global-set-key (kbd "C-z") 'undo-fu-only-undo) 52 | (global-set-key (kbd "C-S-z") 'undo-fu-only-redo) 53 | 54 | (defun install-fonts () 55 | (nerd-icons-install-fonts) 56 | (all-the-icons-install-fonts) 57 | ) 58 | -------------------------------------------------------------------------------- /miso/git.el: -------------------------------------------------------------------------------- 1 | (defun miso/git-commit-all () 2 | "Stage all changes and create a commit." 3 | (interactive) 4 | (magit-stage-modified t) 5 | (magit-commit-create)) 6 | 7 | (defvar miso/git-command-map 8 | (let ((map (make-sparse-keymap))) 9 | (define-key map (kbd "b") 'magit-blame-echo) 10 | (define-key map (kbd "f") 'magit-diff-buffer-file) 11 | (define-key map (kbd "d") 'magit-diff-working-tree) 12 | (define-key map (kbd "s") 'magit-status) 13 | (define-key map (kbd "c") 'magit-commit-create) 14 | (define-key map (kbd "C") 'miso/git-commit-all) 15 | (define-key map (kbd "") 'magit-push-current-to-upstream) 16 | (define-key map (kbd "") 'magit-pull-from-upstream) 17 | map) 18 | "Keymap for Miso git commands.") 19 | 20 | (global-set-key (kbd "M-g") miso/git-command-map) 21 | -------------------------------------------------------------------------------- /miso/go.el: -------------------------------------------------------------------------------- 1 | ;; Basic Go mode configuration 2 | (require 'dap-go) 3 | 4 | ;; LSP hooks and configuration for Go 5 | (add-hook 'go-mode-hook #'lsp-deferred) 6 | (add-hook 'go-ts-mode-hook #'lsp-deferred) 7 | 8 | ;; Configure gopls settings 9 | (with-eval-after-load 'lsp-mode 10 | (setq lsp-go-analyses 11 | '((shadow . t) 12 | (unusedparams . t) 13 | (unusedwrite . t) 14 | (useany . t) 15 | (fillreturns . t))) 16 | 17 | (setq lsp-go-hover-kind "FullDocumentation" 18 | lsp-go-link-target "pkg.go.dev" 19 | lsp-go-codelenses '((gc_details . t) 20 | (generate . t) 21 | (regenerate_cgo . t) 22 | (tidy . t) 23 | (upgrade_dependency . t) 24 | (vendor . t))) 25 | 26 | (lsp-register-custom-settings 27 | '(("gopls.completeUnimported" t t) 28 | ("gopls.staticcheck" t t) 29 | ("gopls.analyses.unusedparams" t t) 30 | ("gopls.analyses.shadow" t t)))) 31 | [] 32 | ;; Setup function for Go programming mode 33 | (defun miso/go-mode-setup () 34 | "Setup for Go programming mode." 35 | (lsp-deferred) ; Ensure LSP is started 36 | (add-hook 'before-save-hook #'lsp-format-buffer t t) 37 | (add-hook 'before-save-hook #'lsp-organize-imports t t) 38 | (setq tab-width 4) 39 | (setq indent-tabs-mode t) 40 | ;; Go specific keybindings 41 | (local-set-key (kbd "M-i t") 'go-test-current-test) 42 | (local-set-key (kbd "M-i f") 'go-test-current-file) 43 | (local-set-key (kbd "M-i p") 'go-test-current-project)) 44 | 45 | ;; Add the setup hooks 46 | (add-hook 'go-mode-hook #'miso/go-mode-setup) 47 | (add-hook 'go-ts-mode-hook #'miso/go-mode-setup) 48 | 49 | ;; Set up debugging support 50 | (dap-go-setup) 51 | -------------------------------------------------------------------------------- /miso/javascript.el: -------------------------------------------------------------------------------- 1 | (add-hook 'js2-mode-hook 'prettier-mode) 2 | (add-hook 'rjsx-mode 'prettier-mode) 3 | (add-to-list 'auto-mode-alist '("\\.js\\'" . rjsx-mode)) 4 | (add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode)) 5 | 6 | (custom-set-variables '(js2-strict-inconsistent-return-warning nil)) 7 | (custom-set-variables '(js2-strict-missing-semi-warning nil)) 8 | 9 | (setq js-indent-level 2) 10 | (setq js2-indent-level 2) 11 | (setq js2-basic-offset 2) 12 | 13 | (setq web-mode-markup-indent-offset 2) 14 | (setq web-mode-code-indent-offset 2) 15 | 16 | (add-hook 'web-mode-hook 17 | (lambda () 18 | (when (string-equal "jsx" (file-name-extension buffer-file-name)) 19 | (rjsx-mode)) 20 | )) 21 | -------------------------------------------------------------------------------- /miso/lsp.el: -------------------------------------------------------------------------------- 1 | (setq lsp-use-plists t) 2 | 3 | (use-package lsp-mode 4 | :diminish "LSP" 5 | :ensure t 6 | :hook ((lsp-mode . lsp-diagnostics-mode) 7 | (lsp-mode . lsp-enable-which-key-integration) 8 | ((tsx-ts-mode 9 | typescript-ts-mode 10 | js-ts-mode) . lsp-deferred)) 11 | :custom 12 | (lsp-keymap-prefix "C-c l") ; Prefix for LSP actions 13 | (lsp-completion-provider :none) ; Using Corfu as the provider 14 | (lsp-diagnostics-provider :flycheck) 15 | (lsp-session-file (locate-user-emacs-file ".lsp-session")) 16 | (lsp-log-io nil) ; IMPORTANT! Use only for debugging! Drastically affects performance 17 | (lsp-keep-workspace-alive nil) ; Close LSP server if all project buffers are closed 18 | (lsp-idle-delay 0.5) ; Debounce timer for `after-change-function' 19 | ;; core 20 | (lsp-enable-xref t) ; Use xref to find references 21 | (lsp-auto-configure t) ; Used to decide between current active servers 22 | (lsp-eldoc-enable-hover t) ; Display signature information in the echo area 23 | (lsp-enable-dap-auto-configure t) ; Debug support 24 | (lsp-enable-file-watchers nil) 25 | (lsp-enable-folding nil) ; I disable folding since I use origami 26 | (lsp-enable-imenu t) 27 | (lsp-enable-indentation nil) ; I use prettier 28 | (lsp-enable-links nil) ; No need since we have `browse-url' 29 | (lsp-enable-on-type-formatting nil) ; Prettier handles this 30 | (lsp-enable-suggest-server-download t) ; Useful prompt to download LSP providers 31 | (lsp-enable-symbol-highlighting t) ; Shows usages of symbol at point in the current buffer 32 | (lsp-enable-text-document-color nil) ; This is Treesitter's job 33 | 34 | (lsp-ui-sideline-show-hover nil) ; Sideline used only for diagnostics 35 | (lsp-ui-sideline-diagnostic-max-lines 20) ; 20 lines since typescript errors can be quite big 36 | ;; completion 37 | (lsp-completion-enable t) 38 | (lsp-completion-enable-additional-text-edit t) ; Ex: auto-insert an import for a completion candidate 39 | (lsp-enable-snippet t) ; Important to provide full JSX completion 40 | (lsp-completion-show-kind t) ; Optional 41 | ;; headerline 42 | (lsp-headerline-breadcrumb-enable t) ; Optional, I like the breadcrumbs 43 | (lsp-headerline-breadcrumb-enable-diagnostics nil) ; Don't make them red, too noisy 44 | (lsp-headerline-breadcrumb-enable-symbol-numbers nil) 45 | (lsp-headerline-breadcrumb-icons-enable nil) 46 | ;; modeline 47 | (lsp-modeline-code-actions-enable nil) ; Modeline should be relatively clean 48 | (lsp-modeline-diagnostics-enable nil) ; Already supported through `flycheck' 49 | (lsp-modeline-workspace-status-enable nil) ; Modeline displays "LSP" when lsp-mode is enabled 50 | (lsp-signature-doc-lines 1) ; Don't raise the echo area. It's distracting 51 | (lsp-ui-doc-use-childframe t) ; Show docs for symbol at point 52 | (lsp-eldoc-render-all nil) ; This would be very useful if it would respect `lsp-signature-doc-lines', currently it's distracting 53 | ;; lens 54 | (lsp-lens-enable nil) ; Optional, I don't need it 55 | ;; semantic 56 | (lsp-semantic-tokens-enable nil) ; Related to highlighting, and we defer to treesitter 57 | 58 | :init 59 | (setq lsp-use-plists t) 60 | 61 | ;; enable lsp booster 62 | :preface 63 | (defun lsp-booster--advice-json-parse (old-fn &rest args) 64 | "Try to parse bytecode instead of json." 65 | (or 66 | (when (equal (following-char) ?#) 67 | 68 | (let ((bytecode (read (current-buffer)))) 69 | (when (byte-code-function-p bytecode) 70 | (funcall bytecode)))) 71 | (apply old-fn args))) 72 | (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) 73 | "Prepend emacs-lsp-booster command to lsp CMD." 74 | (let ((orig-result (funcall old-fn cmd test?))) 75 | (if (and (not test?) ;; for check lsp-server-present? 76 | (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper 77 | lsp-use-plists 78 | (not (functionp 'json-rpc-connection)) ;; native json-rpc 79 | (executable-find "emacs-lsp-booster")) 80 | (progn 81 | (message "Using emacs-lsp-booster for %s!" orig-result) 82 | (cons "emacs-lsp-booster" orig-result)) 83 | orig-result))) 84 | :init 85 | (setq lsp-use-plists t) 86 | ;; Initiate https://github.com/blahgeek/emacs-lsp-booster for performance 87 | (advice-add (if (progn (require 'json) 88 | (fboundp 'json-parse-buffer)) 89 | 'json-parse-buffer 90 | 'json-read) 91 | :around 92 | #'lsp-booster--advice-json-parse) 93 | (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)) 94 | 95 | (use-package lsp-completion 96 | :no-require 97 | :hook ((lsp-mode . lsp-completion-mode))) 98 | 99 | (use-package lsp-ui 100 | :ensure t 101 | :commands 102 | (lsp-ui-doc-show 103 | lsp-ui-doc-glance) 104 | :bind (:map lsp-mode-map 105 | ("C-c C-d" . 'lsp-ui-doc-glance)) 106 | :after (lsp-mode evil) 107 | :config (setq lsp-ui-doc-enable t 108 | evil-lookup-func #'lsp-ui-doc-glance ; Makes K in evil-mode toggle the doc for symbol at point 109 | lsp-ui-doc-show-with-cursor nil ; Don't show doc when cursor is over symbol - too distracting 110 | lsp-ui-doc-include-signature t ; Show signature 111 | lsp-ui-doc-position 'at-point)) 112 | 113 | (use-package lsp-eslint 114 | :demand t 115 | :after lsp-mode) 116 | 117 | (setenv "LSP_USE_PLISTS" "true") ;; in early-init.el 118 | 119 | ;; init.el 120 | ;;;; per https://github.com/emacs-lsp/lsp-mode#performance 121 | (setq read-process-output-max (* 10 1024 1024)) ;; 10mb 122 | (setq gc-cons-threshold 200000000) 123 | 124 | ;; prevent auto execution 125 | (eval-after-load 'lsp-mode 126 | '(setq lsp-auto-execute-action nil)) 127 | 128 | ;; LSP UI customization 129 | (custom-set-variables 130 | '(lsp-headerline-breadcrumb-enable-symbol-numbers nil) 131 | '(lsp-headerline-breadcrumb-icons-enable nil)) 132 | -------------------------------------------------------------------------------- /miso/mac.el: -------------------------------------------------------------------------------- 1 | (defun enable-mac-config () 2 | (interactive) 3 | (global-set-key (kbd "s-c") 'kill-ring-save) 4 | (global-set-key (kbd "s-x") 'kill-region) 5 | (global-set-key (kbd "s-v") 'yank) 6 | (global-set-key (kbd "s-l") 'mark-from-point-to-end-of-line) 7 | (global-set-key (kbd "C-l") 'set-mark-command) 8 | (global-set-key (kbd "s-z") 'undo) 9 | (global-set-key (kbd "s-Z") 'redo) 10 | ;;(global-set-key (kbd "s-p") 'counsel-projectile-find-file) 11 | (setq mac-right-option-modifier nil) 12 | (setq ns-right-alternate-modifier nil) 13 | (setq ns-alternate-modifier 'meta) 14 | (setq ns-right-alternate-modifier 'none) 15 | ) 16 | 17 | (defun mark-from-point-to-end-of-line () 18 | "Marks everything from point to end of line" 19 | (interactive) 20 | (set-mark (line-end-position)) 21 | (activate-mark)) 22 | 23 | (enable-mac-config) 24 | -------------------------------------------------------------------------------- /miso/markdown.el: -------------------------------------------------------------------------------- 1 | (add-hook 'markdown-mode-hook 'writing-mode) 2 | (add-hook 'markdown-mode-hook 'rabbit-mode) 3 | -------------------------------------------------------------------------------- /miso/minibuffer.el: -------------------------------------------------------------------------------- 1 | ;; Define a function to exit the minibuffer 2 | (defun miso/minibuffer-keyboard-quit () 3 | "Abort recursive edit. 4 | In Delete Selection mode, if the mark is active, just deactivate it; 5 | then it takes a second \\[keyboard-quit] to abort the minibuffer." 6 | (interactive) 7 | (if (and delete-selection-mode transient-mark-mode mark-active) 8 | (setq deactivate-mark t) 9 | (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) 10 | (abort-recursive-edit))) 11 | 12 | 13 | 14 | ;; Make ESC quit minibuffer 15 | (define-key minibuffer-local-map (kbd "ESC") 'keyboard-escape-quit) 16 | (define-key minibuffer-local-map [escape] 'miso/minibuffer-keyboard-quit) 17 | (define-key minibuffer-local-ns-map [escape] 'miso/minibuffer-keyboard-quit) 18 | (define-key minibuffer-local-completion-map [escape] 'miso/minibuffer-keyboard-quit) 19 | (define-key minibuffer-local-must-match-map [escape] 'miso/minibuffer-keyboard-quit) 20 | (define-key minibuffer-local-isearch-map [escape] 'miso/minibuffer-keyboard-quit) 21 | 22 | ;; If you're using `vertico`, you might also want to add this: 23 | (with-eval-after-load 'vertico 24 | (define-key vertico-map [escape] 'miso/minibuffer-keyboard-quit)) 25 | -------------------------------------------------------------------------------- /miso/modeline.el: -------------------------------------------------------------------------------- 1 | ;; enable doom modeline 2 | (doom-modeline-mode) 3 | 4 | ;; Display word count in writing mode 5 | (setq doom-modeline-continuous-word-count-modes '(markdown-mode)) 6 | 7 | ;; buffer encoding 8 | (setq doom-modeline-buffer-encoding nil) 9 | 10 | ;; turn off percentage 11 | (setq doom-modeline-percent-position nil) 12 | 13 | (setq doom-modeline-major-mode nil) 14 | 15 | (custom-set-faces 16 | '(mode-line ((t (:family "Inconsolata" :height 150 :weight normal)))) 17 | '(mode-line-active ((t (:family "Inconsolata" :height 150 :weight normal)))) ; For 29+ 18 | '(mode-line-inactive ((t (:family "Inconsolata" :height 150 :weight normal))))) 19 | -------------------------------------------------------------------------------- /miso/programming.el: -------------------------------------------------------------------------------- 1 | ;;; programming.el --- Programming mode configurations for miso-emacs 2 | 3 | ;;; Commentary: 4 | ;; This file contains configurations for programming modes in miso-emacs. 5 | 6 | ;;; Code: 7 | 8 | ;; General programming mode hooks 9 | (defun miso/prog-mode-setup () 10 | "Setup for programming modes." 11 | (interactive) 12 | (hl-line-mode) 13 | (copilot-mode) 14 | ;;(lsp-mode) 15 | (miso/set-prog-mode-keybindings)) 16 | 17 | (defun miso/set-prog-mode-keybindings () 18 | "Set keybindings for programming modes." 19 | (local-set-key (kbd "M-\\") 'consult-yasnippet) 20 | (local-set-key (kbd "M-i e") 'consult-flycheck) 21 | (local-set-key (kbd "M-i a") 'lsp-execute-code-action) 22 | (local-set-key (kbd "M-i r") 'lsp-rename) 23 | (local-set-key (kbd "M-i j") 'consult-imenu) 24 | (local-set-key (kbd "M-i w") 'write) 25 | (local-set-key (kbd "M-i i") 'lsp-organize-imports) 26 | (local-set-key (kbd "M-i g") 'lsp-find-definition) 27 | (local-set-key (kbd "M-i t") 'lsp-goto-type-definition) 28 | ;;(local-set-key (kbd "M-i d") 'dumb-jump-go) 29 | (local-set-key (kbd "M-i d") 'lsp-find-references) 30 | (local-set-key (kbd "M-i l") 'goto-last-change) 31 | (local-set-key (kbd "M-i -") 'revert-buffer) 32 | (local-set-key (kbd "M-i f") 'apheleia-format-buffer) 33 | ;;(local-set-key (kbd "M-i .") 'devdocs-lookup) 34 | (local-set-key (kbd "M-i y") 'consult-yasnippet) 35 | (local-set-key (kbd "M-i ") 'magit-push-current-to-upstream) 36 | (local-set-key (kbd "M-i ") 'magit-pull-from-upstream)) 37 | 38 | ;; Hook setup for programming and configuration modes 39 | (defun miso/add-common-hooks (mode-hook) 40 | "Add common hooks to MODE-HOOK." 41 | (add-hook mode-hook 'rabbit-mode) 42 | ;; (add-hook mode-hook 'company-mode) 43 | ;; (add-hook mode-hook 'git-gutter-mode) ;; Commented out as in original 44 | (add-hook mode-hook 'show-paren-mode)) 45 | 46 | (miso/add-common-hooks 'prog-mode-hook) 47 | (miso/add-common-hooks 'conf-mode-hook) 48 | (add-hook 'prog-mode-hook 'miso/prog-mode-setup) 49 | 50 | ;; Auto-complete configuration 51 | ;;(eval-after-load "auto-complete" 52 | ;; '(add-to-list 'ac-sources 'ac-source-yasnippet)) 53 | 54 | ;; LSP performance improvements 55 | (setq load-prefer-newer t) 56 | (setq large-file-warning-threshold (* 64 1000000)) 57 | (setq undo-outer-limit (* 64 1000000)) 58 | (setq read-process-output-max (* 1024 1024)) ; 1 MB 59 | 60 | ;; XRef configuration 61 | (defun miso/do-then-quit (&rest args) 62 | "Execute function and quit window." 63 | (let ((win (selected-window))) 64 | (apply (car args) (cdr args)) 65 | (quit-window nil win))) 66 | 67 | (advice-add #'xref-goto-xref :around #'miso/do-then-quit) 68 | 69 | ;; Line number display configuration 70 | (setq display-line-numbers-type 'relative) 71 | (setq display-line-numbers-width 3) 72 | (setq display-line-numbers-grow-only t) 73 | (setq display-line-numbers-width-start t) 74 | 75 | ;;(add-hook 'prog-mode-hook #'display-line-numbers-mode) 76 | 77 | (setq treesit-auto-install 'prompt) 78 | -------------------------------------------------------------------------------- /miso/project.el: -------------------------------------------------------------------------------- 1 | (projectile-mode +1) 2 | 3 | (defun miso/list-directories (root) 4 | "Return a list of all directories under ROOT." 5 | (let ((cmd (format "find %s -type d" (shell-quote-argument root)))) 6 | (mapcar (lambda (dir) 7 | (file-name-as-directory (expand-file-name dir root))) 8 | (split-string (shell-command-to-string cmd) "\n" t)))) 9 | 10 | (defun miso/find-or-create-file (directory) 11 | "Find or create a file in DIRECTORY using consult. Excludes .git directory from the search results." 12 | (let* ((default-directory (expand-file-name directory)) 13 | (files (directory-files-recursively default-directory "" t)) 14 | (files-filtered (seq-filter 15 | (lambda (file) 16 | (not (string-match-p "/\\.git/" file))) 17 | files))) 18 | (find-file 19 | (let ((selected (consult--read 20 | (mapcar (lambda (path) (file-relative-name path default-directory)) 21 | files-filtered) 22 | :prompt "Find or create file: " 23 | :sort nil 24 | :require-match nil ; Allow non-existing files 25 | :category 'file))) 26 | (expand-file-name selected default-directory))))) 27 | 28 | (defun miso/jump-to-directory (root) 29 | "Jump to a directory under ROOT and create/visit a file." 30 | (interactive) ; Make sure this is interactive 31 | (let* ((directories (miso/list-directories root)) 32 | (has-subdirs (> (length directories) 1))) 33 | (if has-subdirs 34 | (let* ((selected-dir (consult--read 35 | directories 36 | :prompt "Select directory: " 37 | :category 'file 38 | :sort nil 39 | :require-match t 40 | :state (consult--file-preview) 41 | :history 'file-name-history 42 | :default (file-name-as-directory root))) 43 | (default-directory selected-dir)) 44 | (call-interactively 'find-file)) 45 | (let ((default-directory root)) 46 | (call-interactively 'find-file))))) 47 | 48 | (defun miso/jump-to-file () 49 | "Jump to a directory and create/visit a file in the project or current directory." 50 | (interactive) ; Ensure this is marked as interactive 51 | (if (projectile-project-p) 52 | (miso/jump-to-directory (projectile-project-root)) 53 | (let ((current-dir (if buffer-file-name 54 | (file-name-directory buffer-file-name) 55 | default-directory))) 56 | (miso/jump-to-directory current-dir)))) 57 | 58 | (defun miso/project-ripgrep () 59 | "Run ripgrep in the current project or current directory using consult-ripgrep." 60 | (interactive) 61 | (let ((search-dir (or (projectile-project-root) 62 | (and buffer-file-name (file-name-directory buffer-file-name)) 63 | default-directory))) 64 | (consult-ripgrep search-dir))) 65 | 66 | (defvar miso/command-map 67 | (let ((map (make-sparse-keymap))) 68 | (define-key map (kbd "f") 'projectile-find-file) 69 | (define-key map (kbd "p") 'projectile-switch-project) 70 | (define-key map (kbd "b") 'projectile-switch-to-buffer) 71 | (define-key map (kbd "s") 'miso/project-ripgrep) 72 | (define-key map (kbd "r") 'projectile-replace-regexp) 73 | (define-key map (kbd "n") 'miso/jump-to-file) 74 | map) 75 | "Keymap for Miso custom commands.") 76 | 77 | (global-set-key (kbd "M-p") miso/command-map) 78 | -------------------------------------------------------------------------------- /miso/rabbit-mode.el: -------------------------------------------------------------------------------- 1 | (defun rabbit-mode () 2 | (interactive) 3 | ;;(local-set-key [(meta left)] 'undo-fu-only-undo) 4 | ;;(local-set-key [(meta right)] 'undo-fu-only-redo) 5 | ;;(define-key input-decode-map "\e\eOA" [(meta up)]) 6 | ;;(define-key input-decode-map "\e\eOB" [(meta down)]) 7 | ;;(local-set-key [(meta up)] 'scroll-down-command) 8 | ;;(local-set-key [(meta down)] 'scroll-up-command) 9 | (local-set-key (kbd "s-") 'rabbit-previous) 10 | (local-set-key (kbd "s-") 'rabbit-forward) 11 | ) 12 | 13 | (defun global-rabbit-mode () 14 | (interactive) 15 | (global-set-key (kbd "s-") 'rabbit-previous) 16 | (global-set-key (kbd "s-") 'rabbit-forward) 17 | ;;(global-set-key [(meta left)] 'undo-fu-only-undo) 18 | ;;(global-set-key [(meta right)] 'undo-fu-only-redo) 19 | ;;(define-key input-decode-map "\e\eOA" [(meta up)]) 20 | ;;(define-key input-decode-map "\e\eOB" [(meta down)]) 21 | ;;(global-set-key [(meta up)] 'scroll-down-command) 22 | ;;(global-set-key [(meta down)] 'scroll-up-command) 23 | ;;(global-set-key [(meta up)] 'rabbit-previous) 24 | ;;(global-set-key [(meta down)] 'rabbit-forward) 25 | ) 26 | 27 | (defun rabbit-forward (n) 28 | (interactive "n Jump to forward line: ") 29 | (forward-line n)) 30 | 31 | (defun rabbit-previous (n) 32 | (interactive "n Jump to previous line: ") 33 | (previous-line n)) 34 | 35 | (global-rabbit-mode) 36 | -------------------------------------------------------------------------------- /miso/rename-current-buffer.el: -------------------------------------------------------------------------------- 1 | (defun miso/rename-this-buffer-and-file () 2 | "Renames current buffer and file it is visiting." 3 | (interactive) 4 | (let ((name (buffer-name)) 5 | (filename (buffer-file-name))) 6 | (if (not (and filename (file-exists-p filename))) 7 | (error "Buffer '%s' is not visiting a file!" name) 8 | (let ((new-name (read-file-name "New name: " filename))) 9 | (cond ((get-buffer new-name) 10 | (error "A buffer named '%s' already exists!" new-name)) 11 | (t 12 | (rename-file filename new-name 1) 13 | (rename-buffer new-name) 14 | (set-visited-file-name new-name) 15 | (set-buffer-modified-p nil) 16 | (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) 17 | -------------------------------------------------------------------------------- /miso/scratch.el: -------------------------------------------------------------------------------- 1 | ;; scratch-mode 2 | (setq initial-scratch-message (concat "\n\n# " (format-time-string "%Y-%m-%d") "\n ")) 3 | 4 | (defun write () 5 | (interactive) 6 | (switch-to-buffer (get-buffer-create "*scratch*")) 7 | (delete-other-windows) 8 | (writing-mode) 9 | ) 10 | -------------------------------------------------------------------------------- /miso/straight.el: -------------------------------------------------------------------------------- 1 | (defvar bootstrap-version) 2 | (let ((bootstrap-file 3 | (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) 4 | (bootstrap-version 6)) 5 | (unless (file-exists-p bootstrap-file) 6 | (with-current-buffer 7 | (url-retrieve-synchronously 8 | "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 9 | 'silent 'inhibit-cookies) 10 | (goto-char (point-max)) 11 | (eval-print-last-sexp))) 12 | (load bootstrap-file nil 'nomessage)) 13 | -------------------------------------------------------------------------------- /miso/tabs.el: -------------------------------------------------------------------------------- 1 | ;; Enable dtrt-indent for automatic indentation style detection 2 | (dtrt-indent-global-mode 1) 3 | 4 | ;; Configure dtrt-indent 5 | (setq dtrt-indent-verbosity 0) ; Reduce verbosity of messages 6 | (setq dtrt-indent-min-quality 80.0) ; Set minimum quality for indentation guessing 7 | 8 | ;; Define default tab settings for various programming modes 9 | (setq miso/mode-indent-alist 10 | '((c-mode . (4 . nil)) 11 | (c++-mode . (4 . nil)) 12 | (java-mode . (4 . nil)) 13 | (js-mode . (2 . nil)) 14 | (typescript-mode . (2 . nil)) 15 | (python-mode . (4 . nil)) 16 | (ruby-mode . (2 . nil)) 17 | (rust-mode . (4 . nil)) 18 | (go-mode . (8 . t)) 19 | (elm-mode . (4 . nil)) 20 | (haskell-mode . (2 . nil)) 21 | (sh-mode . (2 . nil)) 22 | (lisp-mode . (2 . nil)) 23 | (emacs-lisp-mode . (2 . nil)) 24 | (yaml-mode . (2 . nil)) 25 | (json-mode . (2 . nil)) 26 | (html-mode . (2 . nil)) 27 | (css-mode . (2 . nil)) 28 | (scss-mode . (2 . nil)) 29 | (web-mode . (2 . nil)))) 30 | 31 | (defun miso/set-indentation-hook () 32 | "Set indentation based on mode-specific defaults if not auto-detected." 33 | (let* ((mode-indent (cdr (assoc major-mode miso/mode-indent-alist))) 34 | (indent-width (car mode-indent)) 35 | (use-tabs (cdr mode-indent))) 36 | (when mode-indent 37 | (unless (dtrt-indent-try-set-offset) 38 | (miso/set-indent-internal indent-width use-tabs))))) 39 | 40 | (defun miso/set-indent-internal (width use-tabs) 41 | "Set indentation to WIDTH and use tabs if USE-TABS is non-nil." 42 | (setq-local tab-width width) 43 | (setq-local indent-tabs-mode use-tabs) 44 | (when (derived-mode-p 'prog-mode) 45 | (setq-local standard-indent width))) 46 | 47 | (defun miso/set-indent-as-tab () 48 | "Set indentation to use tabs." 49 | (interactive) 50 | (miso/set-indent-internal tab-width t) 51 | (message "Indentation set to tabs")) 52 | 53 | (defun miso/set-indent-as-space (num-spaces) 54 | "Set indentation to use NUM-SPACES spaces." 55 | (interactive "nNumber of spaces: ") 56 | (miso/set-indent-internal num-spaces nil) 57 | (message "Indentation set to %d spaces" num-spaces)) 58 | 59 | ;; Apply the indentation hook to all programming modes 60 | (add-hook 'prog-mode-hook #'miso/set-indentation-hook) 61 | 62 | ;; Additional mode-specific hooks 63 | (add-hook 'yaml-mode-hook #'miso/set-indentation-hook) 64 | (add-hook 'json-mode-hook #'miso/set-indentation-hook) 65 | (add-hook 'web-mode-hook #'miso/set-indentation-hook) 66 | 67 | ;; Ensure tabs are visible 68 | (setq whitespace-style '(face tabs tab-mark trailing)) 69 | (global-whitespace-mode 1) 70 | 71 | (defun miso/get-current-indentation () 72 | "Get the current indentation settings." 73 | (interactive) 74 | (message "Current indentation: %s" 75 | (if indent-tabs-mode 76 | "Tabs" 77 | (format "%d spaces" tab-width)))) 78 | 79 | (defun miso/set-indentation () 80 | "Set the indentation for the current buffer using consult." 81 | (interactive) 82 | (let* ((current-indent (if indent-tabs-mode 83 | "Tabs" 84 | (format "%d spaces" tab-width))) 85 | (options '("Tabs" "2 spaces" "4 spaces" "8 spaces")) 86 | (selection (consult--read 87 | options 88 | :prompt "Select indentation: " 89 | :default current-indent 90 | :category 'indentation))) 91 | (pcase selection 92 | ("Tabs" (miso/set-indent-as-tab)) 93 | ("2 spaces" (miso/set-indent-as-space 2)) 94 | ("4 spaces" (miso/set-indent-as-space 4)) 95 | ("8 spaces" (miso/set-indent-as-space 8))))) 96 | -------------------------------------------------------------------------------- /miso/trailing-whitespace.el: -------------------------------------------------------------------------------- 1 | (add-hook 'before-save-hook 'delete-trailing-whitespace) 2 | 3 | (defun delete-trailing-blank-lines () 4 | "Deletes all blank lines at the end of the file." 5 | (interactive) 6 | (save-excursion 7 | (save-restriction 8 | (widen) 9 | (goto-char (point-max)) 10 | (delete-blank-lines)))) 11 | -------------------------------------------------------------------------------- /miso/typescript.el: -------------------------------------------------------------------------------- 1 | ;; Auto-mode settings for TypeScript and TSX files 2 | (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode)) 3 | (add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode)) 4 | 5 | ;; Flycheck configuration for TypeScript 6 | (with-eval-after-load 'flycheck 7 | (flycheck-add-mode 'typescript-tslint 'typescript-ts-mode) 8 | (flycheck-add-mode 'typescript-tslint 'tsx-ts-mode)) 9 | 10 | ;; LSP configuration for TypeScript 11 | (with-eval-after-load 'lsp-mode 12 | (add-hook 'typescript-ts-mode-hook #'lsp-deferred) 13 | (add-hook 'tsx-ts-mode-hook #'lsp-deferred) 14 | (setq lsp-typescript-suggest-complete-function-calls t) 15 | (setq lsp-typescript-surveys-enabled nil)) 16 | 17 | ;; YASnippet configuration for TypeScript 18 | (with-eval-after-load 'yasnippet 19 | (add-hook 'typescript-ts-mode-hook #'yas-minor-mode) 20 | (add-hook 'tsx-ts-mode-hook #'yas-minor-mode) 21 | (add-hook 'typescript-ts-mode-hook 22 | (lambda () (yas-activate-extra-mode 'typescript-mode))) 23 | (add-hook 'tsx-ts-mode-hook 24 | (lambda () (yas-activate-extra-mode 'typescript-tsx-mode)))) 25 | 26 | ;; Prettier configuration (if prettier package is available) 27 | (with-eval-after-load 'prettier 28 | (add-hook 'typescript-ts-mode-hook #'prettier-mode) 29 | (add-hook 'tsx-ts-mode-hook #'prettier-mode)) 30 | 31 | ;; Additional TypeScript-specific settings 32 | (defun miso/typescript-mode-hook () 33 | "Custom hook for TypeScript modes." 34 | (setq-local typescript-indent-level 2) 35 | (setq-local indent-tabs-mode nil) 36 | (setq-local js-indent-level 2)) 37 | 38 | (add-hook 'typescript-ts-mode-hook #'miso/typescript-mode-hook) 39 | (add-hook 'tsx-ts-mode-hook #'miso/typescript-mode-hook) 40 | 41 | ;; Optional: Organize imports on save (if lsp-mode is available) 42 | ;; (add-hook 'before-save-hook #'lsp-organize-imports) 43 | 44 | ;; Tree-sitter configuration 45 | (with-eval-after-load 'treesit 46 | (add-to-list 'treesit-language-source-alist 47 | '(typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src"))) 48 | (add-to-list 'treesit-language-source-alist 49 | '(tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")))) 50 | -------------------------------------------------------------------------------- /miso/warnings.el: -------------------------------------------------------------------------------- 1 | ;; Prevent *Warnings* buffer from popping up 2 | (setq warning-minimum-level :error) ; Only show errors, not warnings 3 | 4 | ;; Configure display-warning behavior 5 | (setq display-warning-minimum-level :error) 6 | 7 | ;; Use mini-buffer for warnings instead of separate buffer 8 | (setq warning-suppress-types nil) 9 | (setq warning-suppress-log-types nil) 10 | (setq warning-fill-prefix " ") 11 | 12 | ;; Custom function to display warnings in echo area 13 | (defun display-warning-echo-area (type message &optional level buffer-name) 14 | "Display a warning message in the echo area instead of a buffer." 15 | (message (format "[%s] %s" type message))) 16 | 17 | ;; Override the default warning display function 18 | (setq display-warning-function #'display-warning-echo-area) 19 | 20 | ;; Prevent warnings buffer from splitting windows 21 | (add-to-list 'display-buffer-alist 22 | '("\\*Warnings\\*" 23 | (display-buffer-no-window) 24 | (allow-no-window . t))) 25 | -------------------------------------------------------------------------------- /miso/windows.el: -------------------------------------------------------------------------------- 1 | (global-set-key (kbd "M-o") 'ace-window) 2 | -------------------------------------------------------------------------------- /miso/writing-mode.el: -------------------------------------------------------------------------------- 1 | (defun writing-mode () 2 | "Enable writing mode with focused editing environment." 3 | (interactive) 4 | ;; Set font face 5 | (setq buffer-face-mode-face 6 | (if (eq system-type 'darwin) 7 | '(:family "Monaco" :height 170) 8 | '(:family "dejavu sans mono" :height 150))) 9 | (buffer-face-mode) 10 | 11 | ;; Enable various modes 12 | (writeroom-mode 1) 13 | (blink-cursor-mode) 14 | (visual-line-mode 1) 15 | (flyspell-mode) 16 | 17 | ;; Disable some modes 18 | (git-gutter-mode -1) 19 | 20 | ;; Set various variables 21 | (setq truncate-lines nil 22 | hl-line-mode nil 23 | doom-modeline-enable-word-count t) 24 | (setq-default line-spacing 5) 25 | 26 | ;; Add window resize hook 27 | (add-hook 'window-size-change-functions 'on-window-resize)) 28 | 29 | (defun on-window-resize (frame) 30 | "Adjust writeroom window on resize." 31 | (writeroom-fit-window)) 32 | 33 | (defun writing-block-size () 34 | "Calculate the appropriate writing block size based on window width." 35 | (cond ((< (window-total-width) 80) (- (window-total-width) 10)) 36 | ((< (window-total-width) 160) (- (window-total-width) 30)) 37 | ((< (window-total-width) 300) 130) 38 | (t 200))) 39 | 40 | (defun writeroom-fit-window () 41 | "Adjust the visual-fill-column-width based on the window size." 42 | (interactive) 43 | (setq visual-fill-column-width (writing-block-size))) 44 | 45 | ;; Configuration for writeroom-mode 46 | (customize-set-variable 'writeroom-mode-line t) 47 | (setq writeroom-global-effects 48 | (delq 'writeroom-set-fullscreen writeroom-global-effects)) 49 | 50 | ;; Configuration for initial major mode and Google Translate 51 | (setq initial-major-mode 'markdown-mode) 52 | (setq google-translate-default-source-language "auto") 53 | (setq google-translate-default-target-language "en") 54 | 55 | ;; Function to get selected text or word at point 56 | (defun get-selected-text (start end) 57 | "Get the selected text or word at point." 58 | (if (use-region-p) 59 | (buffer-substring start end) 60 | (thing-at-point 'word))) 61 | 62 | ;; Function to pronounce word at point (simplified) 63 | (defun pronounce-at-point () 64 | "Pronounce the word at point using Cambridge Dictionary." 65 | (interactive) 66 | (let* ((word (get-selected-text (region-beginning) (region-end))) 67 | (url (concat "https://dictionary.cambridge.org/dictionary/english/" (s-dashed-words word))) 68 | (audio-url (with-temp-buffer 69 | (call-process "curl" nil t nil "-s" url) 70 | (goto-char (point-min)) 71 | (when (re-search-forward "/media/english/us_pron/[/\\w]+\\.mp3" nil t) 72 | (concat "https://dictionary.cambridge.org" (match-string 0)))))) 73 | (when audio-url 74 | (start-process "pronounce" "*pronounce*" "mplayer" audio-url)))) 75 | -------------------------------------------------------------------------------- /miso/yasnippet.el: -------------------------------------------------------------------------------- 1 | ;; Set up the snippet directories 2 | (setq yas-snippet-dirs 3 | '("~/.miso-emacs/snippets" ; miso snippets 4 | "~/.miso-emacs/private/snippets" 5 | yas-installed-snippets-dir)) ; default snippets 6 | 7 | ;; Enable YASnippet globally 8 | (yas-global-mode 1) 9 | 10 | ;; Load all snippets 11 | (yas-reload-all) 12 | 13 | ;; Enable YASnippet in specific modes 14 | (add-hook 'prog-mode-hook #'yas-minor-mode) 15 | (add-hook 'text-mode-hook #'yas-minor-mode) 16 | 17 | ;; Use hippie-expand as well 18 | (add-to-list 'hippie-expand-try-functions-list 'yas-hippie-try-expand) 19 | 20 | ;; Allow nested expansions 21 | (setq yas-triggers-in-field t) 22 | 23 | ;; Wrap around region 24 | (setq yas-wrap-around-region t) 25 | 26 | ;; Key bindings 27 | (define-key yas-minor-mode-map (kbd "M-i ") #'yas-expand) 28 | ;;(define-key yas-minor-mode-map (kbd "M-i Y") #'yas-insert-snippet) 29 | (define-key yas-keymap (kbd "C-h") #'yas-next-field-or-maybe-expand) 30 | (define-key yas-keymap (kbd "C-l") #'yas-prev-field) 31 | --------------------------------------------------------------------------------