Moved dotfiles to new location for switch to nix
This commit is contained in:
599
dotfiles/.emacs.d/config.org
Normal file
599
dotfiles/.emacs.d/config.org
Normal file
@@ -0,0 +1,599 @@
|
||||
* General Configuration
|
||||
|
||||
General configuration is configuration of vanilla Emacs. This includes making Emacs more minimal.
|
||||
|
||||
** Disable Error Bell
|
||||
|
||||
Disable error bell and visual bell. Visual bell would be nice on Linux, but on mac it is just annoying so I removed it temp.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq ring-bell-function 'ignore)
|
||||
(setq visual-bell nil)
|
||||
#+end_src
|
||||
|
||||
** Disable Dialog Box
|
||||
|
||||
Disables the dialog prompting box and instead prompts the user in the minibuffer.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq use-dialog-box nil)
|
||||
#+end_src
|
||||
|
||||
** Relocate Custom File
|
||||
|
||||
Change location of custom file. This will stop *custom* from appending to the config file.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq custom-file "~/.emacs.d/custom.el")
|
||||
(unless (file-exists-p custom-file)
|
||||
(make-empty-file custom-file))
|
||||
(load custom-file)
|
||||
#+end_src
|
||||
|
||||
** Move Backup File
|
||||
|
||||
This moves the backup files so that Emacs doesn't clutter up directories with backup files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq backup-directory-alist '(("." . "~/.emacs.d/backups/")))
|
||||
#+end_src
|
||||
|
||||
** White Space
|
||||
|
||||
Various configuration relating to white-space.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default electric-ident-inhibit t) ; Stop indentation of the previous line.
|
||||
#+end_src
|
||||
|
||||
*** Tabs/Spaces
|
||||
|
||||
Disable tabs and replace them with a custom number of spaces.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq-default indent-tabs-mode nil) ; Use spaces instead of tabs.
|
||||
(setq-default tab-width 4)
|
||||
(setq-default evil-shift-width tab-width)
|
||||
|
||||
; C Indentation
|
||||
(setq-default c-basic-offset 4)
|
||||
|
||||
; Yara Indentation
|
||||
(setq-default yara-indent-offset 4)
|
||||
(setq-default yara-indent-section 4)
|
||||
#+end_src
|
||||
|
||||
*** Visualizing White Space
|
||||
|
||||
Add a nice visualization for tabs and spaces. This can be helpful to identify which is which quickly to avoid submitting poorly spaced code.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(global-whitespace-mode)
|
||||
(setq whitespace-global-modes '(not org-mode dired-mode erc-mode))
|
||||
(setq whitespace-style '(face tabs spaces tab-mark space-mark trailing))
|
||||
(custom-set-faces
|
||||
'(whitespace-tab ((t (:foreground "#384551"))))
|
||||
'(whitespace-space ((t (:foreground "#384551")))))
|
||||
|
||||
|
||||
(setq whitespace-display-mappings
|
||||
'((tab-mark 9 [187 9] [92 9])
|
||||
(space-mark 32 [183] [46])))
|
||||
#+end_src
|
||||
|
||||
** SSH Remoting with Tramp
|
||||
|
||||
Below are a few configuration changes to avoid TRAMP freezes when attempting to SSH into another system with more complex config files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq tramp-remote-shell "/bin/sh")
|
||||
(setq tramp-remote-shell-login "-l")
|
||||
(setq tramp-remote-shell-args "-c")
|
||||
#+end_src
|
||||
|
||||
* Package Manager
|
||||
|
||||
Emacs and packages. Pretty much a requirement.
|
||||
|
||||
** Setup package
|
||||
|
||||
Initialize *package* and setup package archives. This lets you install packages from other archives such as [[https://melpa.org/][melpa]].
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(require 'package)
|
||||
|
||||
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
|
||||
("org" . "https://orgmode.org/elpa/")
|
||||
("elpa" . "https://elpa.gnu.org/packages/")))
|
||||
|
||||
(package-initialize)
|
||||
(unless package-archive-contents
|
||||
(package-refresh-contents))
|
||||
#+end_src
|
||||
|
||||
** Use-package
|
||||
|
||||
Install use package for easier installation of other packages.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(unless (package-installed-p 'use-package)
|
||||
(package-install 'use-package))
|
||||
|
||||
(require 'use-package)
|
||||
(setq use-package-always-ensure t)
|
||||
(setq use-package-compute-statistics t)
|
||||
#+end_src
|
||||
|
||||
* Cosmetic
|
||||
|
||||
Packages that change the look of Emacs in some way.
|
||||
|
||||
** Cosmetic Configuration
|
||||
|
||||
Disable the useless features that make Emacs bloated.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
; Disable startup message
|
||||
(setq inhibit-startup-message t)
|
||||
|
||||
(scroll-bar-mode -1) ; Disable scrollbar
|
||||
(tool-bar-mode -1) ; Disable toolbar
|
||||
(tooltip-mode -1) ; Disable tooltips
|
||||
(menu-bar-mode -1) ; Disable menu-bar
|
||||
(set-fringe-mode 10) ; Add gaps on left and right
|
||||
(setq scroll-margin 4) ; Scroll as cursor reaches bottom/top of page.
|
||||
#+end_src
|
||||
|
||||
*** Change font
|
||||
|
||||
Pretty self explanatory.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/set-font-faces ()
|
||||
(set-face-attribute 'default nil :font "Fira Code Retina" :height 140))
|
||||
#+end_src
|
||||
|
||||
Adding a fix for fonts when running Emacs as a daemon.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(if (daemonp)
|
||||
(add-hook 'after-make-frame-functions
|
||||
(lambda (frame)
|
||||
(with-selected-frame frame
|
||||
(jm/set-font-faces))))
|
||||
(jm/set-font-faces))
|
||||
#+end_src
|
||||
|
||||
** Doom Modeline
|
||||
|
||||
Use doom modeline to make the modeline look nicer.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons) ; requirement
|
||||
(use-package doom-modeline
|
||||
:init (doom-modeline-mode 1)
|
||||
:config
|
||||
(setq doom-modeline-height 45)
|
||||
(display-time))
|
||||
#+end_src
|
||||
|
||||
In order to avoid missing icons, you should also install the package ~all-the-icons-install-fonts~ through the Emacs command line.
|
||||
|
||||
** Doom Themes
|
||||
|
||||
Install doom themes for better themes.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package doom-themes
|
||||
:init (load-theme 'doom-city-lights t))
|
||||
#+end_src
|
||||
|
||||
** Rainbow Delimiters
|
||||
|
||||
Colors parenthesis for better lisp syntax highlighting.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package rainbow-delimiters
|
||||
:hook prog-mode)
|
||||
#+end_src
|
||||
|
||||
** Line Numbers
|
||||
|
||||
This adds relative line numbers while excluding certain modes.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
; Disable line numbers for certain modes
|
||||
(dolist (mode '(org-mode-hook
|
||||
erc-mode-hook
|
||||
mu4e-main-mode-hook
|
||||
term-mode-hook
|
||||
vterm-mode-hook
|
||||
shell-mode-hook
|
||||
eshell-mode-hook))
|
||||
(add-hook mode (lambda () (display-line-numbers-mode 0))))
|
||||
|
||||
; Enable relative line numbers
|
||||
(setq-default display-line-numbers-type 'visual)
|
||||
(global-display-line-numbers-mode t)
|
||||
#+end_src
|
||||
|
||||
* Keybindings
|
||||
|
||||
Contains the configuration for any keybindings or packages relating to keybindings.
|
||||
|
||||
** General Configurations
|
||||
|
||||
Remap quit command to make it easier to rescue a buffer. With this function, escape will be used instead of ~C-g~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
|
||||
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
|
||||
#+end_src
|
||||
|
||||
** Which-key
|
||||
|
||||
Lists all possible keybindings off of prefix.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package which-key
|
||||
:init (which-key-mode)
|
||||
:diminish which-key-mode)
|
||||
#+end_src
|
||||
|
||||
** General
|
||||
|
||||
General allows you to setup a prefix key easily. This makes it really easy to setup a bunch of keybindings with ease.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package general
|
||||
:config
|
||||
(general-create-definer jm/leader-keys
|
||||
:keymaps '(normal insert visual emacs)
|
||||
:prefix "SPC"
|
||||
:global-prefix "C-SPC")
|
||||
|
||||
(jm/leader-keys
|
||||
; Emacs related keybindings
|
||||
"r" '(rename-buffer :which-key "Rename buffer")
|
||||
"er" '((lambda () (interactive) (load-file "~/.emacs")) :which-key "Reload emacs config")
|
||||
"es" '(eshell :which-key "Open eshell terminal")))
|
||||
|
||||
#+end_src
|
||||
|
||||
** Evil
|
||||
|
||||
Evil is a package that adds vim keybindings to Emacs.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Setup vim keybindings with evil
|
||||
(use-package evil
|
||||
:init
|
||||
(setq evil-want-integration t)
|
||||
(setq evil-want-keybinding nil) ; replaced with evil collection
|
||||
(setq evil-want-C-u-scroll t)
|
||||
(setq evil-want-C-i-jump nil)
|
||||
:config
|
||||
(evil-mode 1)
|
||||
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
|
||||
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join)
|
||||
|
||||
; Use visual line motions even outside of visual-line-mode buffers.
|
||||
(evil-global-set-key 'motion "j" 'evil-next-visual-line)
|
||||
(evil-global-set-key 'motion "k" 'evil-previous-visual-line)
|
||||
|
||||
; Modify which modes use vim keybindings.
|
||||
(evil-set-initial-state 'messages-buffer-mode 'normal)
|
||||
(evil-set-initial-state 'dashboard-mode 'normal))
|
||||
#+end_src
|
||||
|
||||
*** Evil Collection
|
||||
|
||||
Evil collection is a package that replaces the bad ~evil-want-keybinding~ keybindings.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-collection
|
||||
:after evil
|
||||
:config (evil-collection-init))
|
||||
#+end_src
|
||||
|
||||
*** Evil Numbers
|
||||
|
||||
The /Evil Numbers/ package implements the ability to increment or decrement numbers as you would with vim using ~C-a~ and ~C-x~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-numbers
|
||||
:after evil
|
||||
:config
|
||||
(evil-define-key '(normal visual) 'global (kbd "C-c =") 'evil-numbers/inc-at-pt)
|
||||
(evil-define-key '(normal visual) 'global (kbd "C-c -") 'evil-numbers/dec-at-pt)
|
||||
(evil-define-key '(normal visual) 'global (kbd "C-c C-=") 'evil-numbers/inc-at-pt-incremental)
|
||||
(evil-define-key '(normal visual) 'global (kbd "C-c C--") 'evil-numbers/dec-at-pt-incremental))
|
||||
#+end_src
|
||||
|
||||
** Undo-Tree
|
||||
|
||||
Undo tree's use is self explanatory. While the built-in Emacs undo system is fine for me, *undo-tree* is required as it fixes an issue with evil where you can't redo.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
; Fix vim redo with undo tree
|
||||
(use-package undo-tree
|
||||
:after evil
|
||||
:config
|
||||
(evil-set-undo-system 'undo-tree)
|
||||
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
|
||||
(global-undo-tree-mode 1))
|
||||
#+end_src
|
||||
|
||||
* Other Packages
|
||||
|
||||
This is a list of installed packages not included in any other category.
|
||||
|
||||
** Perspective
|
||||
|
||||
*Perspective* is a package to help with managing buffers. It allows for multiple /workspaces/ or /perspectives/ which each contain their own sub list of buffers.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package perspective
|
||||
:bind (("C-x b" . persp-switch-to-buffer*)
|
||||
("C-x k" . persp-kill-buffer*))
|
||||
:custom (persp-mode-prefix-key (kbd "C-x w"))
|
||||
:init (persp-mode))
|
||||
#+end_src
|
||||
|
||||
** Projectile
|
||||
|
||||
Projectile is a package for managing various /projects/ in emacs. It adds functionality to let you interact with various /projects/ such as quickly searching filenames, switching between all projects, grepping all files, etc.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package projectile
|
||||
:bind-keymap
|
||||
("C-x p" . projectile-command-map)
|
||||
:config
|
||||
(projectile-mode +1)
|
||||
:init
|
||||
(when (file-directory-p "~/Projects")
|
||||
(setq projectile-project-search-path '("~/Projects"))))
|
||||
#+end_src
|
||||
|
||||
** Vertico
|
||||
|
||||
Vertico is a package that implements a drop-down like menu in the mini buffer allowing for much better searching.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package vertico
|
||||
:init
|
||||
(vertico-mode))
|
||||
#+end_src
|
||||
|
||||
When installing Vertico, the documentation mentions a few other packages that add some nice features that would come by default with something like /ivy/. I've added some descriptions of these below:
|
||||
|
||||
- ~savehist~ - One feature of Vertico that is really helpful is it's seamless integration with the built-in emacs package, ~savehist~, to save command history when navigating.
|
||||
- ~marginalia~ - Similar to the definition of /marginalia/, this emacs package implements descriptions besides each option in Vertico completion. Some examples of this would be definitions for Elisp functions, more verbose file information, etc.
|
||||
- ~orderless~ - By default, Vertico starts its completion from the start of the search the same way as default emacs completion. The ~orderless~ package changes this by implementing a nicer completion that searches for any similar options based on the provided search terms.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package savehist
|
||||
:init
|
||||
(savehist-mode))
|
||||
|
||||
(use-package marginalia
|
||||
:after vertico
|
||||
:init
|
||||
(marginalia-mode))
|
||||
|
||||
(use-package orderless
|
||||
:custom
|
||||
(completion-styles '(orderless basic))
|
||||
(completion-category-overrides '((file (styles basic partial-completion)))))
|
||||
#+end_src
|
||||
|
||||
** Helpful
|
||||
|
||||
*Helpful* is a package that improves the builtin Emacs help menus. The config below installs helpful and sets the keybindings to call helpful functions instead of the default emacs help.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package helpful
|
||||
:bind (("C-h f" . #'helpful-callable)
|
||||
("C-h v" . #'helpful-variable)
|
||||
("C-h k" . #'helpful-key)
|
||||
("C-h x" . #'helpful-command)))
|
||||
|
||||
#+end_src
|
||||
|
||||
** Magit
|
||||
|
||||
*Magit* adds several features to Emacs that make using git easier.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package magit
|
||||
:config
|
||||
(jm/leader-keys "gc" 'magit-clone))
|
||||
#+end_src
|
||||
|
||||
** Dashboard
|
||||
|
||||
The Emacs dashboard package provides a nice dashboard when first starting up emacs.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dashboard
|
||||
:init
|
||||
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))
|
||||
dashboard-startup-banner 'logo
|
||||
dashboard-icon-type 'nerd-icons
|
||||
dashboard-set-file-icons t
|
||||
dashboard-set-heading-icons t
|
||||
dashboard-items '((projects . 5)
|
||||
(recents . 5)
|
||||
(agenda . 5)))
|
||||
:config
|
||||
(set-face-attribute 'dashboard-items-face nil :font "Fira Code Retina" :weight 'regular :height 140)
|
||||
(dashboard-setup-startup-hook))
|
||||
#+end_src
|
||||
|
||||
** Ledger
|
||||
|
||||
Ledger is a Unix program that implements a finance tracking system or /ledger/. To implement this into emacs, you can install the ~ledger-mode~ emacs package.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ledger-mode
|
||||
:mode ("\\.ledger\\'")
|
||||
:config
|
||||
(setq ledger-report-use-strict t
|
||||
ledger-master-file (file-truename "~/Nextcloud/Ledger/toc.ledger")
|
||||
ledger-accounts-file (file-truename "~/Nextcloud/Ledger/accounts.ledger"))
|
||||
(setq ledger-reports `(("bal" ,(format "%%(binary) -f %s bal" ledger-master-file))
|
||||
("budget" ,(format "%%(binary) -f %s --budget -p 'this month' bal Expenses" ledger-master-file))
|
||||
("account" ,(format "%%(binary) -f %s reg %%(account)" ledger-master-file))
|
||||
("monthly bal" ,(format "%%(binary) -f %s bal -p 'this month'" ledger-master-file)))))
|
||||
#+end_src
|
||||
|
||||
** Alert
|
||||
|
||||
Alert is another library that better implements system notifications through emacs. As I use both MacOS and Linux, notifications don't work out of the box for both systems. Using alert, I can change this by selecting a working notify system for each OS.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package alert
|
||||
:config
|
||||
(setq alert-default-style
|
||||
(if (eq system-type 'darwin)
|
||||
'osx-notifier
|
||||
'libnotify)))
|
||||
#+end_src
|
||||
|
||||
** MacOS Environment Fix
|
||||
|
||||
When using emacs on MacOS, the environment variables are not synced properly and therefore require a separate package to fix this. In this case, this package is the ~exec-path-from-shell~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package exec-path-from-shell
|
||||
:config
|
||||
(when (memq window-system '(mac ns x))
|
||||
(exec-path-from-shell-initialize)))
|
||||
#+end_src
|
||||
|
||||
* Builtin Package Config
|
||||
** Dired
|
||||
|
||||
Dired is a built-in package in Emacs that allows for basic file navigation. While it serves its purpose, vanilla dired is far from a good file navigator. With some basic customization however, this can be changed.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired
|
||||
:ensure nil ; Melpa won't be able to find this package.
|
||||
:commands (dired dired-jump)
|
||||
:bind (("C-x C-j" . dired-jump))
|
||||
:custom ((dired-listing-switches "-ahgo"))
|
||||
:config
|
||||
(evil-collection-define-key 'normal 'dired-mode-map
|
||||
"h" 'dired-single-up-directory
|
||||
"l" 'dired-single-buffer))
|
||||
#+end_src
|
||||
|
||||
*** Dired Single
|
||||
|
||||
Vanilla dired opens a new buffer for every new directory it visits. When managing files, this will quickly fill up resulting in a ridiculous number of buffers. Though, single dired fixes this problem by instead modifying the current buffer when navigating through files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired-single :after dired)
|
||||
#+end_src
|
||||
|
||||
*** All the Icons Dired
|
||||
|
||||
~all-the-icons-dired~ is a dired plugin that adds icons to each of the files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons-dired
|
||||
:after dired
|
||||
:hook dired-mode)
|
||||
#+end_src
|
||||
|
||||
*** Hide Dotfiles
|
||||
|
||||
This hides all dotfiles in dired with the keybinding ~H~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired-hide-dotfiles
|
||||
:hook dired-mode
|
||||
:config
|
||||
(evil-collection-define-key 'normal 'dired-mode-map
|
||||
"H" 'dired-hide-dotfiles-mode))
|
||||
#+end_src
|
||||
** ERC
|
||||
|
||||
ERC is a builtin package that adds IRC chatting functionality to emacs.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
|
||||
;; Shotcuts for general
|
||||
(jm/leader-keys
|
||||
"cc" '(erc-tls :which-key "Connect to IRC over TLS")
|
||||
"cb" '(erc-switch-to-buffer :which-key "Switch IRC buffers"))
|
||||
|
||||
(use-package erc
|
||||
:ensure nil
|
||||
:defer t
|
||||
:custom
|
||||
(erc-nick "random936")
|
||||
(erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
|
||||
"353" "324" "329" "332" "333" "353" "477"))
|
||||
(erc-autojoin-channels-alist '((".*\.libera\.chat" "#emacs" "#gentoo" "#systemcrafters")))
|
||||
(erc-fill-column 120)
|
||||
(erc-fill-function 'erc-fill-static)
|
||||
(erc-fill-static-center 20)
|
||||
(erc-kill-buffer-on-part t)
|
||||
(erc-kill-queries-on-quit t)
|
||||
(erc-kill-server-buffer-on-quit t)
|
||||
:config
|
||||
(add-to-list 'erc-modules 'notifications)
|
||||
;; Fix for perspective.el not adding ERC buffers to active perspective.
|
||||
(add-hook 'erc-join-hook (lambda (&rest args)
|
||||
(persp-add-buffer (current-buffer)))))
|
||||
#+end_src
|
||||
|
||||
*** ERC Extensions
|
||||
|
||||
To highlight each nickname with a different color, I can use the ~erc-hl-nicks~ package. I can also use the ~erc-image~ package to render images sent by other users over IRC.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package erc-hl-nicks
|
||||
:after erc
|
||||
:config (add-to-list 'erc-modules 'hl-nicks))
|
||||
|
||||
(use-package erc-image
|
||||
:after erc
|
||||
:config
|
||||
(setq erc-image-inline-rescale 300)
|
||||
(add-to-list 'erc-modules 'image))
|
||||
#+end_src
|
||||
|
||||
*** ERC Alert Integration
|
||||
|
||||
Alert is a notification system that works with MacOS, however it is not integrated by default. To fix this, you need to create a function to hook with the ERC text matching.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/erc-alert-integration (match-type nick message)
|
||||
(alert message :title (format "%s in %s" nick (buffer-name)) :category 'erc))
|
||||
|
||||
(add-hook 'erc-text-matched-hook 'jm/erc-alert-integration)
|
||||
#+end_src
|
||||
|
||||
* Import Other Files
|
||||
|
||||
This is the section to include imports from other files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/load-config-if-exists (file-path)
|
||||
(if (file-exists-p file-path)
|
||||
(org-babel-load-file file-path)
|
||||
(warn (concat "Failed to load config: " file-path))))
|
||||
|
||||
(jm/load-config-if-exists "~/.emacs.d/org.org") ; Org-mode
|
||||
(jm/load-config-if-exists "~/.emacs.d/lsp.org") ; Language Server Protocol
|
||||
(jm/load-config-if-exists "~/.emacs.d/terminal.org") ; Emacs Terminal
|
||||
(jm/load-config-if-exists "~/.emacs.d/functions.org") ; Personal Elisp Functions
|
||||
(jm/load-config-if-exists "~/.emacs.d/email.org") ; Mu4e/SMTP Config
|
||||
|
||||
;; Load EXWM configuration if environment variable set.
|
||||
(let ((exwm-org-file "~/.emacs.d/exwm.org"))
|
||||
(when (and (file-exists-p exwm-org-file) (getenv "USING_EXWM"))
|
||||
(org-babel-load-file exwm-org-file)))
|
||||
#+end_src
|
||||
151
dotfiles/.emacs.d/email.org
Normal file
151
dotfiles/.emacs.d/email.org
Normal file
@@ -0,0 +1,151 @@
|
||||
#+TITLE: Email Configuration
|
||||
|
||||
* Initial Setup
|
||||
|
||||
Before installing any packages with emacs, there is some initial setup that needs to be done. The first part of this is installing isync. Isync is the actual program that is used to sync mail with remote imap servers such as the one used by gmail.
|
||||
|
||||
This can be installed with the following command:
|
||||
#+begin_src bash
|
||||
sudo pacman -S isync
|
||||
#+end_src
|
||||
|
||||
After this is installed, a config file must be created at the location ~~/.mbsyncrc~ to configure isync to connect to some gmail account. I've included this in the git repo, so after installing everything with ~stow .~, it should already be configured properly. However, some information such as the username and password might need to be updated.
|
||||
|
||||
The password uses GPG to decrypt some encrypted password file for added security. To create this file, run the following commands:
|
||||
#+begin_src bash
|
||||
vim ~/.passwords/gmail # Add your password to the file.
|
||||
gpg -c ~/.passwords/gmail # Creates a gmail.gpg file.
|
||||
rm ~/.passwords/gmail # Remove the plaintext password file.
|
||||
#+end_src
|
||||
|
||||
** Disclaimer
|
||||
|
||||
If you are using two factor authentication, this will not work. In this case, you will need to create an /app password/. A guide on how to do this can be found [[https://support.google.com/accounts/answer/185833][here]]. From here, I can just replace this value with what used to be my normal password.
|
||||
|
||||
** Installation for MacOS
|
||||
|
||||
MacOS doesn't include a certificate file in the typical ~/etc/ssl/certs~ directory. Due to this, you have to create a file using the ~Keychain Access~ app.
|
||||
#+begin_src bash
|
||||
Open the Application Keychain Access.app
|
||||
Select System Roots in the sidebar
|
||||
Select all items listen here – ⌘ + a
|
||||
Export the items with ⇧ + ⌘ + e to the file ~/.mail/certificates/root-certificates.pem
|
||||
#+end_src
|
||||
|
||||
* Authentication with Pass
|
||||
|
||||
Pass is a password manager made to be used on the Linux command line. To integrate /pass/ with Emacs, I can install the ~auth-source-pass~ package.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package auth-source-pass
|
||||
:init (auth-source-pass-enable))
|
||||
#+end_src
|
||||
|
||||
* Mu4e
|
||||
|
||||
In this section, I'm setting up ~mu4e~ to give emacs the capability to send emails using my gmail account. To start, you need to install the ~mu4e~ package outside of Emacs.
|
||||
|
||||
#+begin_src bash
|
||||
yay -S mu
|
||||
#+end_src
|
||||
|
||||
After installing the ~mu~ client, I also need to run a initial index using the following command:
|
||||
#+begin_src bash
|
||||
mbsync -a
|
||||
mu init --maildir=~/.mail --my-address=jadenprovost@gmail.com
|
||||
mu index
|
||||
#+end_src
|
||||
|
||||
From here, I can continue onto configuring the ~mu4e~ emacs package.
|
||||
#+begin_src emacs-lisp
|
||||
|
||||
;; Check which load-path exists for multi-platform support.
|
||||
(setq jm/mu4e-load-path
|
||||
(let ((linux-path "/usr/share/emacs/site-lisp/mu4e")
|
||||
(macos-path "/opt/homebrew/share/emacs/site-lisp/mu/mu4e"))
|
||||
(cond ((file-exists-p linux-path) linux-path)
|
||||
((file-exists-p macos-path) macos-path)
|
||||
(t (error "No mu4e load-path present. Is mu4e installed?")))))
|
||||
|
||||
(use-package mu4e
|
||||
:ensure nil
|
||||
:load-path jm/mu4e-load-path
|
||||
:bind ("C-x m" . mu4e)
|
||||
:config
|
||||
;; Avoids syncing issues.
|
||||
(setq mu4e-change-filenames-when-moving t)
|
||||
|
||||
;; Extend header view max message count.
|
||||
(setq mu4e-search-results-limit 2000)
|
||||
|
||||
;; Fix message citation style for gmail.
|
||||
(setq message-cite-style message-cite-style-gmail)
|
||||
(setq message-citation-line-format "On %a, %b %d, %Y at %H:%M %p %f wrote:")
|
||||
(setq message-citation-line-function 'message-insert-formatted-citation-line)
|
||||
|
||||
;; Refresh mail every X seconds. Set to 5 minutes currently
|
||||
(setq mu4e-update-interval (* 5 60))
|
||||
(setq mu4e-get-mail-command "mbsync -a")
|
||||
(setq mu4e-maildir "~/.mail")
|
||||
|
||||
;; Config mu4e folders
|
||||
(setq mu4e-drafts-folder "/Drafts"
|
||||
mu4e-sent-folder "/Sent"
|
||||
mu4e-trash-folder "/Trash"
|
||||
mu4e-refile-folder
|
||||
(lambda (msg)
|
||||
(cond
|
||||
((mu4e-message-contact-field-matches msg :from "no-reply@piazza.com") "/UCSC")
|
||||
((mu4e-message-contact-field-matches msg :from "notifications@instructure.com") "/UCSC")
|
||||
((mu4e-message-contact-field-matches msg :from "no-reply@gradescope.com") "/UCSC")
|
||||
((mu4e-message-contact-field-matches msg :from "notification@edstem.org") "/UCSC")
|
||||
((mu4e-message-contact-field-matches msg :from "onlinebanking@ealerts.bankofamerica.com") "/Finance")
|
||||
((s-starts-with-p "[SlugSec" (mu4e-message-field msg :subject)) "/Club")
|
||||
(t "/Archive"))))
|
||||
|
||||
;; Config mu4e bookmarks
|
||||
(setq mu4e-bookmarks
|
||||
'((:name "Filtered unread messages" :query "flag:unread AND (maildir:/Archive OR maildir:/Inbox) AND NOT flag:trashed" :key ?u)
|
||||
(:name "All unread messages" :query "flag:unread" :key ?U)
|
||||
(:name "Today's messages" :query "date:today..now" :key ?t)
|
||||
(:name "Last 7 days" :query "date:7d..now" :hide-unread t :key ?w)
|
||||
(:name "Flagged messages" :query "flag:flagged" :key ?f)))
|
||||
|
||||
(setq mu4e-maildir-shortcuts
|
||||
'((:maildir "/Inbox" :key ?i)
|
||||
(:maildir "/Archive" :key ?a)
|
||||
(:maildir "/Drafts" :key ?d)
|
||||
(:maildir "/Sent" :key ?s)
|
||||
(:maildir "/Trash" :key ?t)
|
||||
(:maildir "/Finance" :key ?f)
|
||||
(:maildir "/Club" :key ?c)
|
||||
(:maildir "/UCSC" :key ?u))))
|
||||
#+end_src
|
||||
|
||||
Adding some configuration to correct ~mu4e~'s default values.
|
||||
#+begin_src emacs-lisp
|
||||
(setq user-full-name "Jaden Provost Maxwell-Comfort")
|
||||
(setq user-mail-address "jadenprovost@gmail.com")
|
||||
#+end_src
|
||||
|
||||
* SMTP
|
||||
|
||||
In order to send mail with ~mu4e~, you must also configure an SMTP client. Based on the ~mu4e~ wiki, I was able to shamelessly steal some of the config for the gmail configuration found [[https://www.djcbsoftware.nl/code/mu/mu4e/Gmail-configuration.html][here]].
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package smtpmail
|
||||
:after mu4e
|
||||
:config
|
||||
(setq smtpmail-stream-type 'ssl
|
||||
smtpmail-smtp-server "smtp.gmail.com"
|
||||
smtpmail-smtp-service 465))
|
||||
|
||||
(setq send-mail-function 'smtpmail-send-it)
|
||||
#+end_src
|
||||
|
||||
When running this however, you need to authenticate by creating an ~~/.authinfo~ file. This file is formatted as follows:
|
||||
#+begin_src text
|
||||
machine smtp.gmail.com port 465 login "<USER>" password "<PASS>"
|
||||
#+end_src
|
||||
|
||||
Similarly to the password configured above for the IMAP server, you can also pass an ~authinfo.gpg~ file for some added security.
|
||||
98
dotfiles/.emacs.d/exwm.org
Normal file
98
dotfiles/.emacs.d/exwm.org
Normal file
@@ -0,0 +1,98 @@
|
||||
* General Config
|
||||
|
||||
This section contains the general configuration for EXWM.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/exwm-update-class ()
|
||||
(exwm-workspace-rename-buffer exwm-class-name))
|
||||
|
||||
(use-package exwm
|
||||
:config
|
||||
|
||||
; Set default number of workspaces
|
||||
(setq exwm-workspace-number 5)
|
||||
|
||||
; Add key remaps
|
||||
(start-process-shell-command "xmodmap" nil "xmodmap ~/.Xmodmap")
|
||||
|
||||
; Add hook to rename EXWM window to running application name
|
||||
(add-hook 'exwm-update-class-hook #'jm/exwm-update-class)
|
||||
|
||||
;; These keys should always pass through to Emacs
|
||||
(setq exwm-input-prefix-keys
|
||||
'(?\C-x
|
||||
?\C-w
|
||||
?\C-u
|
||||
?\C-h
|
||||
?\M-x
|
||||
?\M-`
|
||||
?\M-&
|
||||
?\M-:
|
||||
?\C-\M-j ;; Buffer list
|
||||
?\C-\ )) ;; Ctrl+Space
|
||||
|
||||
;; Set up global key bindings. These always work, no matter the input state!
|
||||
;; Keep in mind that changing this list after EXWM initializes has no effect.
|
||||
(setq exwm-input-global-keys
|
||||
`(
|
||||
;; Reset to line-mode (C-c C-k switches to char-mode via exwm-input-release-keyboard)
|
||||
([?\s-r] . exwm-reset)
|
||||
|
||||
;; Move window to other workspace
|
||||
([?\s-m] . exwm-workspace-move-window)
|
||||
|
||||
;; Launch applications via shell command
|
||||
([?\s-&] . (lambda (command)
|
||||
(interactive (list (read-shell-command "$ ")))
|
||||
(start-process-shell-command command nil command)))
|
||||
|
||||
;; Switch workspace
|
||||
([?\s-w] . exwm-workspace-switch)
|
||||
([?\s-`] . (lambda () (interactive) (exwm-workspace-switch-create 0)))
|
||||
|
||||
;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9)
|
||||
,@(mapcar (lambda (i)
|
||||
`(,(kbd (format "s-%d" i)) .
|
||||
(lambda ()
|
||||
(interactive)
|
||||
(exwm-workspace-switch-create ,i))))
|
||||
(number-sequence 0 9))))
|
||||
|
||||
(exwm-enable))
|
||||
#+end_src
|
||||
|
||||
* Randr
|
||||
|
||||
EXWM Randr is a built-in plugin that allows you to add two monitor support. By default EXWM merges the two monitors into one making the desktop environment unusable.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package exwm-randr
|
||||
:ensure nil
|
||||
:config
|
||||
(exwm-randr-enable)
|
||||
(start-process-shell-command "xrandr" nil "xrandr --output HDMI-1 --mode 2560x1080 --pos 0x694 --rotate normal --output DP-0 --off --output DP-1 --primary --mode 3440x1440 --pos 2560x0 --rotate normal --output DP-2 --off --output DP-3 --off --output DP-4 --off --output DP-5 --off")
|
||||
|
||||
;; This will need to be updated to the name of a display! You can find
|
||||
;; the names of your displays by looking at arandr or the output of xrandr
|
||||
(setq exwm-randr-workspace-monitor-plist '(2 "HDMI-1" 3 "HDMI-1")))
|
||||
|
||||
#+end_src
|
||||
|
||||
* System Tray
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package exwm-systemtray
|
||||
:ensure nil
|
||||
:config
|
||||
(exwm-systemtray-enable))
|
||||
#+end_src
|
||||
|
||||
* Volume Control
|
||||
|
||||
To control volume through EXWM you can install the ~pulseaudio-control~ package.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package pulseaudio-control
|
||||
:config
|
||||
(pulseaudio-control-default-keybindings))
|
||||
#+end_src
|
||||
189
dotfiles/.emacs.d/functions.org
Normal file
189
dotfiles/.emacs.d/functions.org
Normal file
@@ -0,0 +1,189 @@
|
||||
#+TITLE: Custom Elisp Functions
|
||||
|
||||
As of now, I haven't added anything here, though I do expect to start adding some custom functions as I learn more about Elisp.
|
||||
|
||||
* Org Roam Dailies Shortcuts
|
||||
|
||||
Shortcut to goto todays org-roam dailies document.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/dailies-file-p ()
|
||||
(when-let ((file (buffer-file-name))
|
||||
(file-base (file-name-base (buffer-file-name))))
|
||||
(s-matches-p "^[0-9]+-[0-9]+-[0-9]+$" file-base)))
|
||||
|
||||
(defun jm/org-roam-goto-day (days)
|
||||
(let* ((base-time (if (and (jm/dailies-file-p) (not (eq days 0)))
|
||||
(date-to-time (file-name-base (buffer-file-name)))
|
||||
(current-time)))
|
||||
(rel-time (time-add base-time (days-to-time days)))
|
||||
(path (format-time-string "%Y-%m-%d.org" rel-time))
|
||||
(full-path (file-name-concat org-roam-directory "daily" path)))
|
||||
(if (file-exists-p full-path)
|
||||
(find-file full-path)
|
||||
(org-roam-dailies--capture rel-time))))
|
||||
|
||||
(jm/leader-keys
|
||||
"oy" '((lambda () (interactive) (jm/org-roam-goto-day -1)) :which-key "Open/create yesterday's daily notes file")
|
||||
"ot" '((lambda () (interactive) (jm/org-roam-goto-day 0)) :which-key "Open/create today's daily notes file")
|
||||
"ok" '((lambda () (interactive) (jm/org-roam-goto-day 1)) :which-key "Open/create tomorrow's daily notes file"))
|
||||
#+end_src
|
||||
|
||||
* Capture Template Functions
|
||||
|
||||
These functions are for my org roam daily capture template.
|
||||
|
||||
** Helper Functions
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/dt-filter-tasks (helper query)
|
||||
(let ((entries (org-map-entries helper query 'agenda)))
|
||||
(string-join (delq nil entries) "\n")))
|
||||
|
||||
(defun jm/dt-format-link (prefix)
|
||||
(let ((item-name (org-entry-get nil "ITEM"))
|
||||
(item-id (org-id-get-create))
|
||||
(doc-title (org-get-title)))
|
||||
(if doc-title
|
||||
(format "%s [[id:%s][%s - %s]]" prefix item-id doc-title item-name)
|
||||
(format "%s [[id:%s][%s]]" prefix item-id item-name))))
|
||||
|
||||
(defun jm/dt-concat-todos (todo-lists)
|
||||
(let ((todos nil))
|
||||
(dolist (todo todo-lists todos)
|
||||
(setq todos (append todos (string-lines todo))))
|
||||
(string-join (delete "" (delete-dups todos)) "\n")))
|
||||
#+end_src
|
||||
|
||||
** Queries
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/dt-get-priority (priority &optional prompt)
|
||||
(jm/dt-filter-tasks
|
||||
(lambda () (when (equal priority (org-entry-get nil "PRIORITY"))
|
||||
(jm/dt-format-link (or prompt "-"))))
|
||||
"TODO=\"TODO\"|TODO=\"IN PROGRESS\""))
|
||||
|
||||
(defun jm/dt-get-status (status &optional prompt)
|
||||
(jm/dt-filter-tasks (lambda () (jm/dt-format-link (or prompt "- [ ]")))
|
||||
(concat "TODO=\"" status "\"")))
|
||||
|
||||
|
||||
(defconst jm/dt-deadline "DEADLINE")
|
||||
(defconst jm/dt-scheduled "SCHEDULED")
|
||||
|
||||
(defun jm/dt-get-within (type days &optional prompt)
|
||||
(unless (or (eq type jm/dt-deadline) (eq type jm/dt-scheduled))
|
||||
(error "Invalid type for jm/dt-get-within."))
|
||||
(let* ((time (or (org-capture-get :default-time) (current-time)))
|
||||
(date (time-add time (days-to-time days))))
|
||||
(jm/dt-filter-tasks
|
||||
(lambda () (when (member (org-get-todo-state) '("TODO" "WAITING" "IN PROGRESS"))
|
||||
(jm/dt-format-link (or prompt "-"))))
|
||||
(concat type (format-time-string "<=\"<%Y-%m-%d>\"" date)))))
|
||||
|
||||
(defun jm/dt-get-due-within (days &optional prompt)
|
||||
(jm/dt-get-within jm/dt-deadline days prompt))
|
||||
|
||||
(defun jm/dt-get-scheduled-within (days &optional prompt)
|
||||
(jm/dt-get-within jm/dt-scheduled days prompt))
|
||||
#+end_src
|
||||
|
||||
** Dynamic Habits
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/dt-habit (habit)
|
||||
(let* ((org-date (or (org-capture-get :default-time) (current-time)))
|
||||
(today (downcase (format-time-string "%a" org-date))))
|
||||
(when (seq-contains-p (cdr habit) today)
|
||||
(car habit))))
|
||||
|
||||
(defun jm/dt-habits (habits)
|
||||
(let ((out-list '()))
|
||||
(dolist (habit habits out-list)
|
||||
(when-let (out (jm/dt-habit habit))
|
||||
(push out out-list)))
|
||||
(string-join out-list "\n")))
|
||||
#+end_src
|
||||
|
||||
** Weekly Scorecard
|
||||
|
||||
Taken from the book /12 Week Year/, the weekly scorecard is a way to measure how well you've been acting on your plan towards your weekly goal. By seeing how effective you're execution is, you are forced to face the objective truths about your productivity.
|
||||
|
||||
- [ ] My test checkbox.
|
||||
- [ ] Other checkbox.
|
||||
- [X] My test checkbox.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/checkbox-checked-p (checkbox)
|
||||
(eq 'on (org-element-property :checkbox checkbox)))
|
||||
|
||||
(defun jm/catalog-checkboxes (buffer)
|
||||
(with-current-buffer buffer
|
||||
(let* ((filter-fn (lambda (elem) (when (org-element-property :checkbox elem) elem)))
|
||||
(elem-list (org-element-map (org-element-parse-buffer) 'item filter-fn)))
|
||||
(delq nil elem-list))))
|
||||
|
||||
(defun jm/score-checkboxes (buffer &optional dictionary)
|
||||
(dolist (box (jm/catalog-checkboxes buffer) dictionary)
|
||||
(with-current-buffer buffer
|
||||
(let* ((start (org-element-property :contents-begin box))
|
||||
(end (progn (goto-char start)
|
||||
(or (- (search-forward "\n" nil t) 1) (point-max))))
|
||||
(key (buffer-substring-no-properties start end))
|
||||
(checked (if (jm/checkbox-checked-p box) 1 0))
|
||||
(pair (assoc key dictionary))
|
||||
(counts (cdr pair)))
|
||||
(if pair
|
||||
(setcdr pair (list (+ checked (car counts)) (1+ (cadr counts))))
|
||||
(push (cons key (list checked 1)) dictionary))))))
|
||||
|
||||
(defun jm/n-day-scorecard (n &optional start-time)
|
||||
(let ((time (or start-time (org-capture-get :default-time) (current-time)))
|
||||
(dailies-directory (expand-file-name org-roam-dailies-directory org-roam-directory))
|
||||
(dict nil))
|
||||
(dotimes (i n dict)
|
||||
(let* ((day (time-subtract time (days-to-time i)))
|
||||
(file-name (format-time-string "%Y-%m-%d.org" day))
|
||||
(file-path (expand-file-name file-name dailies-directory))
|
||||
(open (get-file-buffer file-path))
|
||||
(buffer (find-file-noselect file-path)))
|
||||
(setq dict (jm/score-checkboxes buffer dict))
|
||||
(unless open (kill-buffer buffer))))))
|
||||
|
||||
(defun jm/scorecard-table (tasks)
|
||||
(let* ((separator "|---|---|---|---|\n")
|
||||
(table (concat "| Task | Completed | Total | Percentage |\n" separator))
|
||||
(checked-sum 0)
|
||||
(total-sum 0))
|
||||
(dolist (box tasks table)
|
||||
(let* ((name (car box))
|
||||
(checked (cadr box))
|
||||
(total (cadr (cdr box)))
|
||||
(percentage (* (/ (float checked) total) 100)))
|
||||
(setq total-sum (+ total total-sum)
|
||||
checked-sum (+ checked checked-sum)
|
||||
table (format "%s| %s | %d | %d | %d%% |\n"
|
||||
table name checked total percentage))))
|
||||
(format "%s%s| Average | %d | %d | %d%% |\n"
|
||||
table separator checked-sum total-sum
|
||||
(* (/ (float checked-sum) total-sum) 100))))
|
||||
|
||||
(defun jm/scorecard (days &optional start-time)
|
||||
(interactive)
|
||||
(jm/scorecard-table (jm/n-day-scorecard days start-time)))
|
||||
|
||||
(defun jm/scorecard-from-heading ()
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(org-back-to-heading-or-point-min)
|
||||
(org-narrow-to-subtree)
|
||||
(let* ((score (jm/score-checkboxes (current-buffer)))
|
||||
(table (jm/scorecard-table score)))
|
||||
(org-end-of-subtree)
|
||||
(insert "\n" table "\n")))))
|
||||
|
||||
(jm/leader-keys
|
||||
"os" '(jm/scorecard-from-heading :which-key "Open/create yesterday's daily notes file"))
|
||||
#+end_src
|
||||
216
dotfiles/.emacs.d/lsp.org
Normal file
216
dotfiles/.emacs.d/lsp.org
Normal file
@@ -0,0 +1,216 @@
|
||||
|
||||
Language servers provide auto completion and syntax highlighting capabilities making them essential for development.
|
||||
|
||||
* Lsp Mode
|
||||
|
||||
Lsp Mode is a package that adds language server functionalities to Emacs.
|
||||
|
||||
** Breadcrumb Header Line
|
||||
|
||||
This adds a headerline that shows the scope of where the cursor is in the code. For example if the user is in the main function, the headerline will contain main.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/lsp-mode-setup ()
|
||||
(setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
|
||||
(lsp-headerline-breadcrumb-mode))
|
||||
#+end_src
|
||||
|
||||
** Install Lsp Mode
|
||||
|
||||
Below I am installing the actual package and adding some basic configuration.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package lsp-mode
|
||||
:init (setq lsp-keymap-prefix "C-c l") ; Lsp mode prefix
|
||||
:hook (lsp-mode . jm/lsp-mode-setup)
|
||||
:commands (lsp lsp-deferred) ; Startup commands
|
||||
:config (lsp-enable-which-key-integration t))
|
||||
#+end_src
|
||||
|
||||
** Lsp Additional Packages
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package lsp-ui
|
||||
:hook (lsp-mode . lsp-ui-mode)
|
||||
:config (setq lsp-ui-sideline-show-diagnostics t))
|
||||
#+end_src
|
||||
|
||||
** Company Mode
|
||||
|
||||
Company is a package that automatically finds completions instead of making the user run a command for completions.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package company
|
||||
:after lsp-mode
|
||||
:hook (lsp-mode . company-mode)
|
||||
:bind (:map company-active-map ; Map tab to select completion
|
||||
("<tab>" . company-complete-selection))
|
||||
(:map lsp-mode-map
|
||||
("<tab>" . company-indent-or-complete-common)))
|
||||
#+end_src
|
||||
|
||||
** Flycheck
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package flycheck
|
||||
:init (global-flycheck-mode))
|
||||
#+end_src
|
||||
|
||||
* Language Servers
|
||||
|
||||
This will include any language server packages and configuration.
|
||||
|
||||
** HTML
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package web-mode
|
||||
:defer t
|
||||
:mode "\\.html\\'"
|
||||
:hook (web-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** JavaScript/Typescript
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package typescript-mode
|
||||
:defer t
|
||||
:mode ("\\.ts\\'" "\\.js\\'")
|
||||
:hook (typescript-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
Install the ~typescript-language-server~ through npm.
|
||||
|
||||
#+begin_src sh
|
||||
npm install -g typescript-language-server
|
||||
#+end_src
|
||||
|
||||
** Python
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package python-mode
|
||||
:defer t
|
||||
:mode ("\\.py\\'")
|
||||
:hook (python-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
Install the ~python-lsp-server~ though pip.
|
||||
|
||||
#+begin_src sh
|
||||
pip install python-lsp-server
|
||||
#+end_src
|
||||
|
||||
** C/C++
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ccls
|
||||
:defer t
|
||||
:hook ((c-mode cc-mode c++-mode objc-mode cuda-mode) .
|
||||
(lambda () (require 'ccls) (lsp)))
|
||||
:config
|
||||
(setq ccls-executable "/usr/bin/ccls"))
|
||||
#+end_src
|
||||
|
||||
Install ~ccls~ with homebrew using the following command.
|
||||
|
||||
#+begin_src sh
|
||||
sudo apt install ccls
|
||||
#+end_src
|
||||
|
||||
** Golang
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package go-mode
|
||||
:defer t
|
||||
:hook (go-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** Rust
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package rustic
|
||||
:defer t
|
||||
:hook (rust-mode . lsp-deferred)
|
||||
:init
|
||||
(let ((brew-prefix (string-trim (shell-command-to-string "brew --prefix"))))
|
||||
(when (and (memq window-system '(mac ns x)) brew-prefix (f-directory-p brew-prefix))
|
||||
(setenv "YARA_LIBRARY_PATH" (expand-file-name "lib" brew-prefix))
|
||||
(setenv "YARA_INCLUDE_DIR" (expand-file-name "include" brew-prefix)))))
|
||||
#+end_src
|
||||
|
||||
** C#
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package csharp-mode
|
||||
:defer t
|
||||
:hook (csharp-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** JSON
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package json-mode
|
||||
:defer t
|
||||
:hook (json-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** Yaml
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yaml-mode
|
||||
:defer t
|
||||
:hook (yaml-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** Yara
|
||||
|
||||
To install the corresponding LSP, you need to install ~yls~. Using the command ~pip install -U yls-yara~. Keep in mind that ~yls~ is dependent on an up to date version of ~yara-python~.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package yara-mode
|
||||
:defer t
|
||||
:hook (yara-mode . lsp-deferred)
|
||||
:config
|
||||
(with-eval-after-load 'lsp-mode
|
||||
(add-to-list 'lsp-language-id-configuration
|
||||
'(yara-mode . "yara"))
|
||||
|
||||
(lsp-register-client
|
||||
(make-lsp-client :new-connection (lsp-stdio-connection "yls")
|
||||
:activation-fn (lsp-activate-on "yara")
|
||||
:server-id 'yls))))
|
||||
#+end_src
|
||||
|
||||
** R
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ess
|
||||
:defer t
|
||||
:hook (R-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** Haskell
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package haskell-mode
|
||||
:defer t
|
||||
:hook (haskell-mode . lsp-deferred))
|
||||
|
||||
(use-package lsp-haskell
|
||||
:defer t
|
||||
:hook (lsp-literate-mode . lsp-deferred))
|
||||
#+end_src
|
||||
|
||||
** Ebuild
|
||||
|
||||
Ebuild is the language used for Gentoo packages installed with the ~emerge~ utility. As this package is Gentoo specific, you will have to install it the command below:
|
||||
|
||||
#+begin_src bash
|
||||
sudo emerge -v app-emacs/ebuild-mode
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ebuild-mode
|
||||
:ensure nil
|
||||
:defer t
|
||||
:hook (ebuild-mode . lsp-deferred))
|
||||
#+end_src
|
||||
317
dotfiles/.emacs.d/org.org
Normal file
317
dotfiles/.emacs.d/org.org
Normal file
@@ -0,0 +1,317 @@
|
||||
Org is a package that allows you to create files like this one that look nice while also being able to run code. In this file, the code being run is stored in code blocks and all other text is disregarded.
|
||||
|
||||
* Org Setup
|
||||
|
||||
This installs the org package and creates a setup function to enable/disable certain functionalities.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Setup org mode
|
||||
(defun jm/org-mode-setup ()
|
||||
(org-indent-mode)
|
||||
(flyspell-mode)
|
||||
(variable-pitch-mode 1)
|
||||
(visual-line-mode 1)
|
||||
(add-to-list 'org-link-frame-setup '(file . find-file))) ; Open link in current window not other window.
|
||||
|
||||
(use-package org
|
||||
:hook (org-mode . jm/org-mode-setup)
|
||||
:config
|
||||
(setq jm/inbox-file "~/Nextcloud/org/inbox.org"
|
||||
org-ellipsis " ▾"
|
||||
org-hide-emphasis-markers t
|
||||
org-src-preserve-indentation t
|
||||
|
||||
;; Default export configuration
|
||||
org-export-with-toc nil
|
||||
org-export-with-section-numbers nil
|
||||
org-export-with-sub-superscripts nil
|
||||
org-latex-src-block-backend 'listings
|
||||
org-format-latex-options (plist-put org-format-latex-options :scale 1.3)
|
||||
|
||||
;; Org agenda timestamp formatting
|
||||
org-display-custom-times t
|
||||
org-time-stamp-custom-formats '("%m-%d-%y %a" . "%m-%d-%y %a %I:%M %p")
|
||||
|
||||
;; Capture templates
|
||||
org-capture-templates '(("i" "Inbox" entry (file jm/inbox-file) "* %?\n")))
|
||||
|
||||
(jm/leader-keys
|
||||
"oa" '(org-agenda :which-key "Org agenda")
|
||||
"oc" '(org-capture :which-key "Org capture")
|
||||
"oi" '((lambda () (interactive) (find-file jm/inbox-file)) :which-key "Open inbox file")))
|
||||
#+end_src
|
||||
|
||||
* Cosmetics
|
||||
|
||||
** Org-Bullets
|
||||
|
||||
Org-bullets is a package that adds bullets to each heading instead of asterisks. It just makes org files nicer to look at.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Org-bullets for better headings
|
||||
(use-package org-bullets
|
||||
:after org
|
||||
:hook (org-mode . org-bullets-mode)
|
||||
:custom
|
||||
(org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
|
||||
#+end_src
|
||||
|
||||
** Add List Dots
|
||||
|
||||
By default lists are started with a hyphen, though this doesn't really match the aesthetic of the rest of the org file. Due to that, I added this line which replaces the hyphen with a dot.
|
||||
|
||||
- Bullet point 1
|
||||
- Bullet point 2
|
||||
- Bullet point 3
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Replace - lists with a dot
|
||||
(font-lock-add-keywords 'org-mode
|
||||
'(("^ *\\([-]\\) "
|
||||
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
|
||||
#+end_src
|
||||
|
||||
** Font Changes
|
||||
|
||||
Org-faces changes the font size of the headings to make them bigger in the org file. Though this code also changes the font to a variable-pitch font. To make it so that only fixed-pitch fonts are used in things like code blocks, *set-face-attribute* is used below.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'org-faces
|
||||
;; Set faces for heading size levels
|
||||
(dolist (face '((org-level-1 . 1.2)
|
||||
(org-level-2 . 1.1)
|
||||
(org-level-3 . 1.05)
|
||||
(org-level-4 . 1.0)
|
||||
(org-level-5 . 1.0)
|
||||
(org-level-6 . 1.0)
|
||||
(org-level-7 . 1.0)
|
||||
(org-level-8 . 1.0)))
|
||||
(set-face-attribute (car face) nil :font "Fira Code Light" :weight 'regular :height (cdr face)))
|
||||
|
||||
;; Ensure that anything that should be fixed-pitch in Org files appears that way
|
||||
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
|
||||
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
|
||||
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
|
||||
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'line-number nil :inherit 'fixed-pitch)
|
||||
(set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch))
|
||||
#+end_src
|
||||
|
||||
** Visual Fill Column
|
||||
|
||||
Visual fill column is a package that allows you to center text and add borders to the sides of an org file. By default org files are displayed completely to the left side of the page like normal text files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; Set left-right margins with visual-fill-column
|
||||
(defun jm/org-mode-visual-fill ()
|
||||
(setq visual-fill-column-width 100
|
||||
visual-fill-column-center-text t)
|
||||
(visual-fill-column-mode 1))
|
||||
|
||||
(use-package visual-fill-column
|
||||
:after org
|
||||
:hook (org-mode . jm/org-mode-visual-fill))
|
||||
#+end_src
|
||||
|
||||
** Syntax Highlighting in Latex Exports
|
||||
|
||||
By default the syntax highlighting for latex/PDF documents exported with Emacs is pretty lackluster. To improve this, I can install the ~engrave-faces~ package.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package engrave-faces
|
||||
:after ox-latex
|
||||
:config
|
||||
(setq org-latex-src-block-backend 'engraved))
|
||||
#+end_src
|
||||
|
||||
* Evil Org
|
||||
|
||||
By default, many of the org specific keybindings do not feel intuitive when using evil mode. ~evil-org~ is a package that attempts to fix this by rebinding many of the default org keybindings to work better with Evil mode.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil-org
|
||||
:after org
|
||||
:hook (org-mode . (lambda () evil-org-mode))
|
||||
:config
|
||||
(require 'evil-org-agenda)
|
||||
(evil-org-agenda-set-keys))
|
||||
#+end_src
|
||||
|
||||
* Org Agenda
|
||||
|
||||
Org mode by default contains an /agenda/ system which is like a basic calendar that allows you to schedule todo items from org documents. All of the todo items from each org document are stored in a central area to allow for a formation of an /agenda/.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-agenda-start-with-log-mode t)
|
||||
(setq org-log-done 'time)
|
||||
(setq org-log-into-drawer t)
|
||||
|
||||
(setq org-priority-default ?D)
|
||||
(setq org-priority-lowest ?D)
|
||||
#+end_src
|
||||
|
||||
** Refresh Org Agenda Files
|
||||
|
||||
Creates a function to refresh the ~org-agenda-files~ variable to be set to include all org roam notes files.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/org-roam-refresh-agenda-list ()
|
||||
(interactive)
|
||||
(let ((directory (expand-file-name org-roam-dailies-directory org-roam-directory)))
|
||||
(setq org-agenda-files
|
||||
(seq-filter
|
||||
(lambda (file-path) (not (s-starts-with-p directory file-path)))
|
||||
(org-roam-list-files)))))
|
||||
#+end_src
|
||||
|
||||
To use this function, I'll add it to some hooks to make sure to run it before the agenda list is needed.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(advice-add 'org-agenda :before #'jm/org-roam-refresh-agenda-list)
|
||||
(advice-add 'org-todo-list :before #'jm/org-roam-refresh-agenda-list)
|
||||
(advice-add 'dashboard-get-agenda :before #'jm/org-roam-refresh-agenda-list)
|
||||
#+end_src
|
||||
|
||||
** Custom States
|
||||
|
||||
Adds custom states to tasks such as ~IN PROGRESS~, ~CANCELLED~, etc. I've also added some changes to the color of the todo items based on the status. For example, turning the task face orange if it is /in progress/.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-todo-keyword-faces '(("IN PROGRESS" . (:foreground "orange" :weight bold))
|
||||
("WAITING" . (:foreground "yellow" :weight bold))))
|
||||
|
||||
(setq org-todo-keywords
|
||||
'((sequence
|
||||
"TODO(t)"
|
||||
"IN PROGRESS(i)"
|
||||
"WAITING(w)"
|
||||
"|"
|
||||
"DONE(d)"
|
||||
"CANCELLED(c)"
|
||||
"FAILED(f)")))
|
||||
|
||||
(setq org-clock-in-switch-to-state "IN PROGRESS")
|
||||
#+end_src
|
||||
|
||||
** Refresh Checkboxes
|
||||
|
||||
Adds a hook to repeated tasks in org agenda that, when repeated, checkboxes will be reset to an unchecked state.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'org-todo-repeat-hook #'org-reset-checkbox-state-subtree)
|
||||
#+end_src
|
||||
|
||||
* Org Roam
|
||||
|
||||
Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem such as org-file linking, etc.
|
||||
|
||||
** Custom Indexing Functions
|
||||
|
||||
Before getting into the main config for Org-roam, I've created a few functions for better indexing nodes stored in the org-roam database. Specifically, these functions separate the org roam dailies nodes from other nodes.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun jm/org-roam-find-filter (node)
|
||||
(let ((directory (expand-file-name org-roam-dailies-directory org-roam-directory)))
|
||||
(string= (file-name-directory (org-roam-node-file node))
|
||||
directory)))
|
||||
|
||||
(defun jm/org-roam-dailies-find ()
|
||||
(interactive)
|
||||
(org-roam-node-find nil nil #'jm/org-roam-find-filter))
|
||||
|
||||
(defun jm/org-roam-find ()
|
||||
(interactive)
|
||||
(org-roam-node-find
|
||||
nil nil
|
||||
(lambda (node) (not (jm/org-roam-find-filter node)))))
|
||||
#+end_src
|
||||
|
||||
** Main Config
|
||||
|
||||
Below is the main config for org-roam.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-roam
|
||||
:init (require 'org-roam-dailies)
|
||||
:custom
|
||||
(org-roam-directory (file-truename "~/Nextcloud/org"))
|
||||
(org-roam-node-display-template "${title:60} ${file-title}")
|
||||
:bind (("C-c n l" . org-roam-buffer-toggle)
|
||||
("C-c n f" . jm/org-roam-find)
|
||||
("C-c n d" . jm/org-roam-dailies-find)
|
||||
("C-c n i" . org-roam-node-insert)
|
||||
("C-c n c" . org-roam-capture)
|
||||
("C-c n o" . org-id-get-create)
|
||||
|
||||
;; Dailies
|
||||
("C-c n t" . org-roam-dailies-capture-today)
|
||||
("C-c n k" . org-roam-dailies-capture-tomorrow))
|
||||
:config
|
||||
;; Config for org-roam capture templates.
|
||||
(setq jm/org-roam-templates-directory (expand-file-name "templates" org-roam-directory)
|
||||
org-roam-capture-templates
|
||||
`(("d" "Default" plain "%?"
|
||||
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
||||
:unnarrowed t)
|
||||
("p" "Project" plain
|
||||
(file ,(expand-file-name "project.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
|
||||
"#+title: ${title}\n")
|
||||
:unnarrowed t)
|
||||
("y" "12 Week Year" plain
|
||||
(file ,(expand-file-name "12-week-year.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
|
||||
"#+title: ${title}\n")
|
||||
:unnarrowed t)))
|
||||
(setq org-roam-dailies-capture-templates
|
||||
`(("d" "Default" entry "* %?"
|
||||
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))
|
||||
("r" "Reflection" entry
|
||||
(file ,(expand-file-name "reflection.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
|
||||
:unnarrowed t)
|
||||
("S" "Weekly Scorecard" entry
|
||||
(file ,(expand-file-name "weekly-scorecard.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
|
||||
:unnarrowed t)
|
||||
("s" "Daily Scorecard" entry
|
||||
(file ,(expand-file-name "daily-scorecard.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
|
||||
:unnarrowed t)
|
||||
("t" "Todos" entry
|
||||
(file ,(expand-file-name "daily.org" jm/org-roam-templates-directory))
|
||||
:target (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")
|
||||
:unnarrowed t)))
|
||||
|
||||
;; Create org roam directory and templates directory if not found.
|
||||
(unless (file-directory-p org-roam-directory)
|
||||
(make-directory org-roam-directory))
|
||||
(unless (file-directory-p jm/org-roam-templates-directory)
|
||||
(make-directory jm/org-roam-templates-directory))
|
||||
|
||||
(org-roam-db-autosync-mode))
|
||||
#+end_src
|
||||
|
||||
* Fix Snippets
|
||||
|
||||
This is required as of org 9.2 as snippets such as ~<s~ don't work. Without this fix, you are required to manually type out structures like code blocks.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(require 'org-tempo)
|
||||
#+end_src
|
||||
|
||||
* Ispell
|
||||
|
||||
Configure ~Ispell~ to not spell check certain org mode specific keywords. By default, ~Ispell~ doesn't have a default dictionary selected. This can be changed by running ~ispell-change-dictionary~. If no dictionaries are found, you can install them from the ~hunspell-en_us~ pacman package.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")) ;
|
||||
(add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC"))
|
||||
(add-to-list 'ispell-skip-region-alist '("~" . "~"))
|
||||
(add-to-list 'ispell-skip-region-alist '("\\[\\[" . "\\]"))
|
||||
#+end_src
|
||||
4
dotfiles/.emacs.d/start-exwm.sh
Executable file
4
dotfiles/.emacs.d/start-exwm.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
export USING_EXWM=t
|
||||
exec dbus-launch --exit-with-session emacs -mm --debug-init
|
||||
45
dotfiles/.emacs.d/terminal.org
Normal file
45
dotfiles/.emacs.d/terminal.org
Normal file
@@ -0,0 +1,45 @@
|
||||
Emacs also has the functionality to run a terminal environment. While many other terminals will try to have similar capabilities with keybindings, nothing matches just integrating your terminal in emacs.
|
||||
|
||||
* VTerm
|
||||
|
||||
VTerm is a terminal emulator written in C. While emacs has a few built-in terminal all of them either lack speed or are missing many escape sequences.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package vterm
|
||||
:config
|
||||
(setq vterm-max-scrollback 10000)
|
||||
; Fixes vterm issue with cursor not updating
|
||||
(advice-add #'vterm--redraw :after (lambda (&rest args) (evil-refresh-cursor evil-state))))
|
||||
#+end_src
|
||||
|
||||
There are a few packages that you need to install in order to use VTerm.
|
||||
|
||||
#+begin_src bash
|
||||
sudo apt install cmake libtool-bin
|
||||
#+end_src
|
||||
|
||||
|
||||
* Multi-Vterm
|
||||
|
||||
Multi-vterm is a package that adds the capability to easily create multiple vterm terminal buffers without having to manually rename them each time.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package multi-vterm
|
||||
:after vterm
|
||||
:config
|
||||
(jm/leader-keys
|
||||
"vj" '(multi-vterm-next :which-key "Go to next vterm window")
|
||||
"vk" '(multi-vterm-next :which-key "Go to previous vterm window")
|
||||
"vn" '(multi-vterm :which-key "Create new vterm terminal")))
|
||||
#+end_src
|
||||
|
||||
* Change Terminal Font
|
||||
|
||||
When using zsh with powerlevel10k, the ~MesloLGS NF~ font is required to make the prompt align properly. Due to this, this code is implemented to change the font only when VTerm is being used.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'vterm-mode-hook
|
||||
(lambda ()
|
||||
(set (make-local-variable 'buffer-face-mode-face) '(:family "MesloLGS NF" :height 135))
|
||||
(buffer-face-mode t)))
|
||||
#+end_src
|
||||
Reference in New Issue
Block a user