9.5 KiB
My Emacs
- Elpaca
- Vertico-stack
- General config
- Dired
- Whole-line-or-region
- Terminal
- Theme
- Dashboard
- Hydra
- Programming
- Multiple cursors
- Comment-dwim-2
- Projectile
- Custom

Elpaca
(defvar elpaca-installer-version 0.7)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (< emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
;; Install use-package support
(elpaca elpaca-use-package
;; Enable use-package :ensure support for Elpaca.
(elpaca-use-package-mode)
)
Vertico-stack
Vertico
;; Enable vertico
(use-package vertico
:ensure t
;; :custom
;; (vertico-scroll-margin 0) ;; Different scroll margin
;; (vertico-count 20) ;; Show more candidates
;; (vertico-resize t) ;; Grow and shrink the Vertico minibuffer
;; (vertico-cycle t) ;; Enable cycling for `vertico-next/previous'
:init
(vertico-mode))
General config
Delete trailing whitespaces
(add-hook 'before-save-hook 'delete-trailing-whitespace)
Save history and recent files
;; The built-in `savehist-mode' saves minibuffer histories. Vertico
;; can then use that information to put recently selected options at
;; the top.
;;
;; Further reading: https://protesilaos.com/emacs/dotemacs#h:25765797-27a5-431e-8aa4-cc890a6a913a
(savehist-mode 1)
;; The built-in `recentf-mode' keeps track of recently visited files.
;; You can then access those through the `consult-buffer' interface or
;; with `recentf-open'/`recentf-open-files'.
;;
;; I do not use this facility, because the files I care about are
;; either in projects or are bookmarked.
(recentf-mode 1)
Yes-or-no
Because I'm lazy, important yes-or-no questions can be answered with y-or-n:
(defalias 'yes-or-no-p 'y-or-n-p)
Switch windows
(global-set-key (kbd "M-o") 'other-window)
Maximize at startup
More info : https://www.emacswiki.org/emacs/FullScreen
(push '(fullscreen . maximized) default-frame-alist)
ibuffer
Use list-buffers bigger brother.
(global-set-key [remap list-buffers] 'ibuffer)
Mark
(global-set-key (kbd "M-SPC") 'mark-word)
Isearch
Display number of matches:
(setq-default isearch-lazy-count t)
Reference that might be interesting for later: https://endlessparentheses.com/leave-the-cursor-at-start-of-match-after-isearch.html
Sudo file
(defun sudo ()
"Use TRAMP to `sudo' the current buffer."
(interactive)
(when buffer-file-name
(find-alternate-file
(concat "/sudo:root@localhost:"
buffer-file-name)
)
)
)
Abbrev
(global-set-key [remap dabbrev-expand] 'hippie-expand)
Zap
(global-set-key (kbd "M-S-z") 'zap-up-to-char)
Spell checking
Look into customizing the 'ispell' group.
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
Dired
(require 'dired-x)
Whole-line-or-region
Source: https://github.com/purcell/whole-line-or-region
Operate on the current line if no region is active.
(use-package whole-line-or-region
:ensure t
:config
(whole-line-or-region-global-mode 1)
)
Terminal
Toggle between char- and line-mode
Courtesy goes to https://joelmccracken.github.io/entries/switching-between-term-mode-and-line-mode-in-emacs-term/
(require 'term)
(defun jnm/term-toggle-mode ()
"Toggles term between line mode and char mode"
(interactive)
(if (term-in-line-mode)
(term-char-mode)
(term-line-mode)))
(define-key term-mode-map (kbd "C-c C-j") 'jnm/term-toggle-mode)
(define-key term-mode-map (kbd "C-c C-k") 'jnm/term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-j") 'jnm/term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-k") 'jnm/term-toggle-mode)
For the keybindings, we have to defien them in both raw and line mode. From the help page of term mode: If you define custom keybindings, make sure to assign them to the correct keymap (or to both): use ‘term-raw-map’ in raw mode and ‘term-mode-map’ in line mode.
Theme
(use-package monokai-theme
:ensure t
:init
(load-theme 'monokai t)
)
Dashboard
(use-package dashboard
:ensure t
:config
(add-hook 'elpaca-after-init-hook #'dashboard-insert-startupify-lists)
(add-hook 'elpaca-after-init-hook #'dashboard-initialize)
(dashboard-setup-startup-hook))
Hydra
Install and wait for hydra to be available since we are using it in this init.el :
(use-package hydra
:ensure (:wait t)
)
Text zoom
(defhydra hydra-zoom (global-map "<f1>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out")
)
Programming
Electric pair
(add-hook 'prog-mode-hook 'electric-pair-mode)
Eglot
(use-package eglot
:ensure t
:defer t
;; This doesn't work for some reason, workaround below
;;:hook (prog-mode . eglot-ensure)
;; :config
;; (add-hook 'prog-mode-hook 'eglot-ensure)
)
Workaround to enable eglot in all programming modes:
(add-hook 'prog-mode-hook 'eglot-ensure)
Yasnippet
(use-package yasnippet
:ensure t
:config
(yas-reload-all)
(add-hook 'prog-mode-hook 'yas-minor-mode)
)
Magit
Transient
Magit depends on this and it seems it's not installed as a dependency, so install it explicitly.
(use-package transient
:ensure t
)
Core
(use-package magit
:ensure t
)
Smartparens
Smart minor-mode to deal with pairs.
https://github.com/Fuco1/smartparens
(use-package smartparens
:ensure t
:bind
("C-M-w" . sp-copy-sexp)
:hook (prog-mode text-mode markdown-mode)
:config
(require 'smartparens-config)
)
Multiple cursors
(use-package multiple-cursors
:ensure t
:bind
("C-x r a" . mc/edit-beginnings-of-lines)
("C-x r e" . mc/edit-ends-of-lines)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C->" . mc/mark-all-like-this)
)
Comment-dwim-2
Replacement for built-in comment-dwim, more comment features.
https://github.com/remyferre/comment-dwim-2
(use-package comment-dwim-2
:ensure t
:config
(global-set-key (kbd "M-;") 'comment-dwim-2)
)
Projectile
(use-package projectile
:ensure t
:config
(setq projectile-indexing-method 'alien)
(setq projectile-enable-caching t)
(define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map)
(projectile-mode +1)
(require 'project)
(add-hook 'project-find-functions #'project-projectile)
)
Custom
Save symbol at point
(defun myrmi/save-symbol-at-point ()
"Make symbol at point the latest kill in the kill ring."
(interactive)
(let ((symbol (thing-at-point 'symbol)))
(when symbol (kill-new symbol))))
(global-set-key (kbd "C-M-w") 'myrmi/save-symbol-at-point)