981 lines
36 KiB
Org Mode
981 lines
36 KiB
Org Mode
#+TITLE: KyleKrein's GNU Emacs Config
|
||
#+STARTUP: showeverything
|
||
#+OPTIONS: toc:2
|
||
#+PROPERTY: header-args:emacs-lisp :lexical t
|
||
|
||
* Table of contents :toc:
|
||
- [[#important-programs-to-load-first][IMPORTANT PROGRAMS TO LOAD FIRST]]
|
||
- [[#evil-mode][Evil Mode]]
|
||
- [[#recent-files][Recent Files]]
|
||
- [[#general-keybindings][General Keybindings]]
|
||
- [[#startup-time][Startup Time]]
|
||
- [[#app-launcher][App Launcher]]
|
||
- [[#standalone-run][Standalone run]]
|
||
- [[#company][Company]]
|
||
- [[#dashboard][Dashboard]]
|
||
- [[#diminish][Diminish]]
|
||
- [[#flycheck][FLYCHECK]]
|
||
- [[#fonts][Fonts]]
|
||
- [[#zooming-inout][Zooming In/Out]]
|
||
- [[#graphical-user-interface-tweaks][GRAPHICAL USER INTERFACE TWEAKS]]
|
||
- [[#disable-menubar-toolbars-and-scrollbars][Disable Menubar, Toolbars and Scrollbars]]
|
||
- [[#display-line-numbers-and-truncated-lines][Display Line Numbers and Truncated Lines]]
|
||
- [[#disable-gui-elements][Disable GUI elements]]
|
||
- [[#battery-info][Battery info]]
|
||
- [[#magit][MAGIT]]
|
||
- [[#minibuffer-escape][Minibuffer escape]]
|
||
- [[#modeline][Modeline]]
|
||
- [[#projectile][PROJECTILE]]
|
||
- [[#pdf-tools][PDF Tools]]
|
||
- [[#rainbow-delimiters][RAINBOW DELIMITERS]]
|
||
- [[#org-mode][ORG MODE]]
|
||
- [[#enabling-table-of-contents][Enabling Table of Contents]]
|
||
- [[#enabling-org-bullets][Enabling Org Bullets]]
|
||
- [[#disable-electric-indent][Disable Electric Indent]]
|
||
- [[#org-level-headers][Org Level Headers]]
|
||
- [[#source-code-block-tag-expansion][Source Code Block Tag Expansion]]
|
||
- [[#org-roam][ORG ROAM]]
|
||
- [[#org-roam-itself][Org Roam itself]]
|
||
- [[#org-roam-ui][Org Roam UI]]
|
||
- [[#org-agenda][Org Agenda]]
|
||
- [[#inbox][Inbox]]
|
||
- [[#todos-in-today][Todos in Today]]
|
||
- [[#rainbow-mode][RAINBOW MODE]]
|
||
- [[#shells-and-terminals][SHELLS AND TERMINALS]]
|
||
- [[#eshell][Eshell]]
|
||
- [[#vterm][Vterm]]
|
||
- [[#vterm-toggle][Vterm-Toggle]]
|
||
- [[#sudo-edit][SUDO EDIT]]
|
||
- [[#nerd-icons][Nerd Icons]]
|
||
- [[#nerd-icons-completion][Nerd Icons Completion]]
|
||
- [[#buffer-move][Buffer Move]]
|
||
- [[#vertico][Vertico]]
|
||
- [[#descriptions][Descriptions]]
|
||
- [[#theme][Theme]]
|
||
- [[#theme-loading][Theme loading]]
|
||
- [[#which-key][WHICH-KEY]]
|
||
|
||
* IMPORTANT PROGRAMS TO LOAD FIRST
|
||
** Evil Mode
|
||
#+begin_src emacs-lisp :lexical t
|
||
(use-package evil
|
||
:ensure t
|
||
:init ;; tweak evil's configuration before loading it
|
||
(setq evil-want-integration t) ;; This is optional since it's already set to t by default.
|
||
(setq evil-want-keybinding nil)
|
||
(setq evil-vsplit-window-right t)
|
||
(setq evil-split-window-below t)
|
||
(evil-mode))
|
||
(use-package evil-collection
|
||
:ensure t
|
||
:after evil
|
||
:config
|
||
(setq evil-collection-mode-list '(dashboard dired ibuffer))
|
||
(evil-collection-init))
|
||
(use-package evil-tutor
|
||
:ensure t)
|
||
#+end_src
|
||
** Recent Files
|
||
#+begin_src emacs-lisp
|
||
(recentf-mode t)
|
||
#+end_src
|
||
** General Keybindings
|
||
#+begin_src emacs-lisp
|
||
(use-package general
|
||
:ensure t
|
||
:config
|
||
(general-evil-setup)
|
||
)
|
||
(require 'general) ;; If i do this in :config, it says that function is wrong
|
||
;; set up 'SPC' as the global leader key
|
||
(general-create-definer kylekrein/leader-keys
|
||
:states '(normal insert visual emacs)
|
||
:keymaps 'override
|
||
:prefix "SPC" ;; set leader
|
||
:global-prefix "M-SPC") ;; access leader in insert mode
|
||
(kylekrein/leader-keys
|
||
"." '(find-file :wk "Find file")
|
||
"f r" '(recentf-open :wk "Open recent file")
|
||
"TAB TAB" '(comment-line :wk "Comment lines"))
|
||
(kylekrein/leader-keys
|
||
"b" '(:ignore t :wk "buffer")
|
||
"b b" '(switch-to-buffer :wk "Switch buffer")
|
||
"b i" '(ibuffer :wk "Ibuffer")
|
||
"b k" '(kill-current-buffer :wk "Kill current buffer")
|
||
"b n" '(next-buffer :wk "Next buffer")
|
||
"b p" '(previous-buffer :wk "Previous buffer")
|
||
"b r" '(revert-buffer :wk "Reload buffer"))
|
||
|
||
(kylekrein/leader-keys
|
||
"e" '(:ignore t :wk "Eshell/Evaluate")
|
||
"e b" '(eval-buffer :wk "Evaluate elisp in buffer")
|
||
"e d" '(eval-defun :wk "Evaluate defun containing or after point")
|
||
"e e" '(eval-expression :wk "Evaluate and elisp expression")
|
||
"e l" '(eval-last-sexp :wk "Evaluate elisp expression before point")
|
||
"e r" '(eval-region :wk "Evaluate elisp in region")
|
||
"e s" '(eshell :which-key "Eshell"))
|
||
|
||
(kylekrein/leader-keys
|
||
"h" '(:ignore t :wk "Help")
|
||
"h f" '(describe-function :wk "Describe function")
|
||
"h v" '(describe-variable :wk "Describe variable"))
|
||
;;"h r r" '((lambda () (interactive) (load-file "~/.config/emacs/init.el")) :wk "Reload emacs config"))
|
||
;;"h r r" '(reload-init-file :wk "Reload emacs config"))
|
||
|
||
(kylekrein/leader-keys
|
||
"t" '(:ignore t :wk "Toggle")
|
||
"t l" '(display-line-numbers-mode :wk "Toggle line numbers")
|
||
"t t" '(visual-line-mode :wk "Toggle truncated lines")
|
||
"t v" '(vterm-toggle :wk "Toggle vterm"))
|
||
(kylekrein/leader-keys
|
||
"o" '(:ignore t :wk "Open")
|
||
"o a" '(org-agenda :wk "Agenda")
|
||
)
|
||
(kylekrein/leader-keys
|
||
"n" '(:ignore t :wk "Notes")
|
||
"n r" '(:ignore t :wk "Roam")
|
||
"n r f" '(org-roam-node-find :wk "Find and open")
|
||
"n r i" '(org-roam-node-insert :wk "Insert link")
|
||
"n r l" '(org-roam-buffer-toggle :wk "Show backlinks")
|
||
"n r m" '(org-roam-dailies-map :wk "Dailies")
|
||
"n r s" '(org-roam-db-sync :wk "Sync Notes DB (After changes on another device)")
|
||
)
|
||
|
||
(kylekrein/leader-keys
|
||
"w" '(:ignore t :wk "Windows")
|
||
;; Window splits
|
||
"w c" '(evil-window-delete :wk "Close window")
|
||
"w n" '(evil-window-new :wk "New window")
|
||
"w s" '(evil-window-split :wk "Horizontal split window")
|
||
"w v" '(evil-window-vsplit :wk "Vertical split window")
|
||
;; Window motions
|
||
"w h" '(evil-window-left :wk "Window left")
|
||
"w j" '(evil-window-down :wk "Window down")
|
||
"w k" '(evil-window-up :wk "Window up")
|
||
"w l" '(evil-window-right :wk "Window right")
|
||
"w w" '(evil-window-next :wk "Goto next window")
|
||
;; Move Windows
|
||
"w H" '(buf-move-left :wk "Buffer move left")
|
||
"w J" '(buf-move-down :wk "Buffer move down")
|
||
"w K" '(buf-move-up :wk "Buffer move up")
|
||
"w L" '(buf-move-right :wk "Buffer move right"))
|
||
|
||
#+end_src
|
||
|
||
* Startup Time
|
||
#+begin_src emacs-lisp
|
||
;; Startup time
|
||
(defun efs/display-startup-time ()
|
||
(message
|
||
"Emacs loaded in %s with %d garbage collections."
|
||
(format
|
||
"%.2f seconds"
|
||
(float-time
|
||
(time-subtract after-init-time before-init-time)))
|
||
gcs-done))
|
||
|
||
(add-hook 'emacs-startup-hook #'efs/display-startup-time)
|
||
#+end_src
|
||
* App Launcher
|
||
This code creates a menu to launch linux apps, that have Desktop entry.
|
||
Code was taken from [[https://github.com/SebastienWae/app-launcher/blob/main/app-launcher.el][this awesome repo]]
|
||
#+begin_src emacs-lisp
|
||
(require 'xdg)
|
||
(require 'cl-seq)
|
||
|
||
(defcustom app-launcher-apps-directories
|
||
(mapcar (lambda (dir) (expand-file-name "applications" dir))
|
||
(cons (xdg-data-home)
|
||
(xdg-data-dirs)))
|
||
"Directories in which to search for applications (.desktop files)."
|
||
:type '(repeat directory))
|
||
|
||
(defcustom app-launcher--annotation-function #'app-launcher--annotation-function-default
|
||
"Define the function that genereate the annotation for each completion choices."
|
||
:type 'function)
|
||
|
||
(defcustom app-launcher--action-function #'app-launcher--action-function-default
|
||
"Define the function that is used to run the selected application."
|
||
:type 'function)
|
||
|
||
(defvar app-launcher--cache nil
|
||
"Cache of desktop files data.")
|
||
|
||
(defvar app-launcher--cache-timestamp nil
|
||
"Time when we last updated the cached application list.")
|
||
|
||
(defvar app-launcher--cached-files nil
|
||
"List of cached desktop files.")
|
||
|
||
(defun app-launcher-list-desktop-files ()
|
||
"Return an alist of all Linux applications.
|
||
Each list entry is a pair of (desktop-name . desktop-file).
|
||
This function always returns its elements in a stable order."
|
||
(let ((hash (make-hash-table :test #'equal))
|
||
result)
|
||
(dolist (dir app-launcher-apps-directories)
|
||
(when (file-exists-p dir)
|
||
(let ((dir (file-name-as-directory dir)))
|
||
(dolist (file (directory-files-recursively dir ".*\\.desktop$"))
|
||
(let ((id (subst-char-in-string ?/ ?- (file-relative-name file dir))))
|
||
(when (and (not (gethash id hash)) (file-readable-p file))
|
||
(push (cons id file) result)
|
||
(puthash id file hash)))))))
|
||
result))
|
||
|
||
(defun app-launcher-parse-files (files)
|
||
"Parse the .desktop files to return usable informations."
|
||
(let ((hash (make-hash-table :test #'equal)))
|
||
(dolist (entry files hash)
|
||
(let ((file (cdr entry)))
|
||
(with-temp-buffer
|
||
(insert-file-contents file)
|
||
(goto-char (point-min))
|
||
(let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t))
|
||
(end (re-search-forward "^\\[" nil t))
|
||
(visible t)
|
||
name comment exec)
|
||
(catch 'break
|
||
(unless start
|
||
(message "Warning: File %s has no [Desktop Entry] group" file)
|
||
(throw 'break nil))
|
||
|
||
(goto-char start)
|
||
(when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t)
|
||
(setq visible nil))
|
||
(setq name (match-string 1))
|
||
|
||
(goto-char start)
|
||
(unless (re-search-forward "^Type *= *Application *$" end t)
|
||
(throw 'break nil))
|
||
(setq name (match-string 1))
|
||
|
||
(goto-char start)
|
||
(unless (re-search-forward "^Name *= *\\(.+\\)$" end t)
|
||
(push file counsel-linux-apps-faulty)
|
||
(message "Warning: File %s has no Name" file)
|
||
(throw 'break nil))
|
||
(setq name (match-string 1))
|
||
|
||
(goto-char start)
|
||
(when (re-search-forward "^Comment *= *\\(.+\\)$" end t)
|
||
(setq comment (match-string 1)))
|
||
|
||
(goto-char start)
|
||
(unless (re-search-forward "^Exec *= *\\(.+\\)$" end t)
|
||
;; Don't warn because this can technically be a valid desktop file.
|
||
(throw 'break nil))
|
||
(setq exec (match-string 1))
|
||
|
||
(goto-char start)
|
||
(when (re-search-forward "^TryExec *= *\\(.+\\)$" end t)
|
||
(let ((try-exec (match-string 1)))
|
||
(unless (locate-file try-exec exec-path nil #'file-executable-p)
|
||
(throw 'break nil))))
|
||
|
||
(puthash name
|
||
(list (cons 'file file)
|
||
(cons 'exec exec)
|
||
(cons 'comment comment)
|
||
(cons 'visible visible))
|
||
hash))))))))
|
||
|
||
(defun app-launcher-list-apps ()
|
||
"Return list of all Linux .desktop applications."
|
||
(let* ((new-desktop-alist (app-launcher-list-desktop-files))
|
||
(new-files (mapcar 'cdr new-desktop-alist)))
|
||
(unless (and (equal new-files app-launcher--cached-files)
|
||
(null (cl-find-if
|
||
(lambda (file)
|
||
(time-less-p
|
||
app-launcher--cache-timestamp
|
||
(nth 5 (file-attributes file))))
|
||
new-files)))
|
||
(setq app-launcher--cache (app-launcher-parse-files new-desktop-alist))
|
||
(setq app-launcher--cache-timestamp (current-time))
|
||
(setq app-launcher--cached-files new-files)))
|
||
app-launcher--cache)
|
||
|
||
(defun app-launcher--annotation-function-default (choice)
|
||
"Default function to annotate the completion choices."
|
||
(let ((str (cdr (assq 'comment (gethash choice app-launcher--cache)))))
|
||
(when str (concat " - " (propertize str 'face 'completions-annotations)))))
|
||
|
||
(defun app-launcher--action-function-default (selected)
|
||
"Default function used to run the selected application."
|
||
(let* ((exec (cdr (assq 'exec (gethash selected app-launcher--cache))))
|
||
(command (let (result)
|
||
(dolist (chunk (split-string exec " ") result)
|
||
(unless (or (equal chunk "%U")
|
||
(equal chunk "%F")
|
||
(equal chunk "%u")
|
||
(equal chunk "%f"))
|
||
(setq result (concat result chunk " ")))))))
|
||
(call-process-shell-command command nil 0 nil)))
|
||
|
||
;;;###autoload
|
||
(defun app-launcher-run-app (&optional arg)
|
||
"Launch an application installed on your machine.
|
||
When ARG is non-nil, ignore NoDisplay property in *.desktop files."
|
||
(interactive)
|
||
(let* ((candidates (app-launcher-list-apps))
|
||
(result (completing-read
|
||
"Run app: "
|
||
(lambda (str pred flag)
|
||
(if (eq flag 'metadata)
|
||
'(metadata
|
||
(annotation-function . (lambda (choice)
|
||
(funcall
|
||
app-launcher--annotation-function
|
||
choice))))
|
||
(complete-with-action flag candidates str pred)))
|
||
(lambda (x y)
|
||
(if arg
|
||
t
|
||
(cdr (assq 'visible y))))
|
||
t nil 'app-launcher nil nil)))
|
||
(funcall app-launcher--action-function result)))
|
||
#+end_src
|
||
** Standalone run
|
||
This code snippet runs app launcher without emacs frame
|
||
To use it, create a global keyboard shortcut with the following code
|
||
~emacsclient -cF "((visibility . nil))" -e "(emacs-run-launcher)~
|
||
#+begin_src emacs-lisp
|
||
(defun emacs-run-launcher ()
|
||
"Create and select a frame called emacs-run-launcher which consists only of a minibuffer and has specific dimensions. Runs app-launcher-run-app on that frame, which is an emacs command that prompts you to select an app and open it in a dmenu like behaviour. Delete the frame after that command has exited"
|
||
(interactive)
|
||
(with-selected-frame
|
||
(make-frame '((name . "emacs-run-launcher")
|
||
(minibuffer . only)
|
||
(fullscreen . 0) ; no fullscreen
|
||
(undecorated . t) ; remove title bar
|
||
;;(auto-raise . t) ; focus on this frame
|
||
;;(tool-bar-lines . 0)
|
||
;;(menu-bar-lines . 0)
|
||
(internal-border-width . 10)
|
||
(width . 80)
|
||
(height . 11)))
|
||
(unwind-protect
|
||
(app-launcher-run-app)
|
||
(delete-frame))))
|
||
#+end_src
|
||
* Company
|
||
[[https://company-mode.github.io/][Company]] is a text completion framework for Emacs. The name stands for “complete anything”. Completion will start automatically after you type a few letters. Use M-n and M-p to select, <return> to complete or <tab> to complete the common part.
|
||
#+begin_src emacs-lisp
|
||
(use-package company
|
||
:ensure t
|
||
:defer 2
|
||
:diminish
|
||
:custom
|
||
(company-begin-commands '(self-insert-command))
|
||
(company-idle-delay .1)
|
||
(company-minimum-prefix-length 2)
|
||
(company-show-numbers t)
|
||
(company-tooltip-align-annotations 't)
|
||
(global-company-mode t))
|
||
|
||
(use-package company-box
|
||
:ensure t
|
||
:after company
|
||
:diminish
|
||
:hook (company-mode . company-box-mode))
|
||
#+end_src
|
||
* Dashboard
|
||
Emacs Dashboard is an extensible startup screen showing you recent files, bookmarks, agenda items and an Emacs banner.
|
||
#+begin_src emacs-lisp
|
||
(use-package dashboard
|
||
:ensure t
|
||
:init
|
||
(setq initial-buffer-choice 'dashboard-open)
|
||
(setq dashboard-set-heading-icons t)
|
||
(setq dashboard-set-file-icons t)
|
||
(setq dashboard-banner-logo-title "Emacs Is More Than A Text Editor!")
|
||
;;(setq dashboard-startup-banner 'logo) ;; use standard emacs logo as banner
|
||
;;(setq dashboard-startup-banner "/home/dt/.config/emacs/images/emacs-dash.png") ;; use custom image as banner
|
||
(setq dashboard-center-content nil) ;; set to 't' for centered content
|
||
(setq dashboard-items '((recents . 5)
|
||
(agenda . 5 )
|
||
(bookmarks . 3)
|
||
(projects . 3)
|
||
(registers . 3)))
|
||
:custom
|
||
(dashboard-modify-heading-icons '((recents . "file-text")
|
||
(bookmarks . "book")))
|
||
:config
|
||
(dashboard-setup-startup-hook))
|
||
#+end_src
|
||
* Diminish
|
||
This package implements hiding or abbreviation of the modeline displays (lighters) of minor-modes. With this package installed, you can add ‘:diminish’ to any use-package block to hide that particular mode in the modeline.
|
||
#+begin_src emacs-lisp
|
||
(use-package diminish :ensure t)
|
||
#+end_src
|
||
* FLYCHECK
|
||
Install luacheck from your Linux distro’s repositories for flycheck to work correctly with lua files. Install python-pylint for flycheck to work with python files. Haskell works with flycheck as long as haskell-ghc or haskell-stack-ghc is installed. For more information on language support for flycheck, [[https://www.flycheck.org/en/latest/languages.html][read this]].
|
||
#+begin_src emacs-lisp
|
||
(use-package flycheck
|
||
:ensure t
|
||
:defer t
|
||
:diminish
|
||
:init (global-flycheck-mode))
|
||
#+end_src
|
||
* Fonts
|
||
Defining the various fonts that Emacs will use.
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'default nil
|
||
:font "JetBrains Mono"
|
||
:height 110
|
||
:weight 'medium)
|
||
(set-face-attribute 'variable-pitch nil
|
||
:font "Ubuntu"
|
||
:height 120
|
||
:weight 'medium)
|
||
(set-face-attribute 'fixed-pitch nil
|
||
:font "JetBrains Mono"
|
||
:height 110
|
||
:weight 'medium)
|
||
;; Makes commented text and keywords italics.
|
||
;; This is working in emacsclient but not emacs.
|
||
;; Your font must have an italic face available.
|
||
(set-face-attribute 'font-lock-comment-face nil
|
||
:slant 'italic)
|
||
(set-face-attribute 'font-lock-keyword-face nil
|
||
:slant 'italic)
|
||
|
||
;; This sets the default font on all graphical frames created after restarting Emacs.
|
||
;; Does the same thing as 'set-face-attribute default' above, but emacsclient fonts
|
||
;; are not right unless I also add this method of setting the default font.
|
||
(add-to-list 'default-frame-alist '(font . "JetBrains Mono-11"))
|
||
|
||
;; Uncomment the following line if line spacing needs adjusting.
|
||
(setq-default line-spacing 0.12)
|
||
#+end_src
|
||
|
||
** Zooming In/Out
|
||
You can use the bindings CTRL plus =/- for zooming in/out. You can also use CTRL plus the mouse wheel for zooming in/out.
|
||
|
||
#+begin_src emacs-lisp
|
||
(global-set-key (kbd "C-=") 'text-scale-increase)
|
||
(global-set-key (kbd "C--") 'text-scale-decrease)
|
||
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)
|
||
(global-set-key (kbd "<C-wheel-down>") 'text-scale-decrease)
|
||
#+end_src
|
||
|
||
|
||
* GRAPHICAL USER INTERFACE TWEAKS
|
||
Let's make GNU Emacs look a little better.
|
||
|
||
** Disable Menubar, Toolbars and Scrollbars
|
||
#+begin_src emacs-lisp
|
||
(menu-bar-mode -1)
|
||
(tool-bar-mode -1)
|
||
(scroll-bar-mode -1)
|
||
#+end_src
|
||
|
||
** Display Line Numbers and Truncated Lines
|
||
#+begin_src emacs-lisp
|
||
(global-display-line-numbers-mode 1)
|
||
(global-visual-line-mode t)
|
||
#+end_src
|
||
** Disable GUI elements
|
||
#+begin_src emacs-lisp
|
||
(setq use-file-dialog nil) ;; No file dialog
|
||
(setq use-dialog-box nil) ;; No dialog box
|
||
(setq pop-up-windows nil) ;; No popup windows
|
||
#+end_src
|
||
** Battery info
|
||
#+begin_src emacs-lisp
|
||
(unless (equal "Battery status not available"
|
||
(battery))
|
||
(display-battery-mode 1))
|
||
#+end_src
|
||
* MAGIT
|
||
Magit is a full-featured git client for Emacs.
|
||
#+begin_src emacs-lisp
|
||
(use-package magit
|
||
:ensure t)
|
||
#+end_src
|
||
* Minibuffer escape
|
||
By default, Emacs requires you to hit ESC three times to escape quit the minibuffer.
|
||
#+begin_src emacs-lisp
|
||
(global-set-key [escape] 'keyboard-escape-quit)
|
||
#+end_src
|
||
* Modeline
|
||
The modeline is the bottom status bar that appears in Emacs windows. While you can create your own custom modeline, why go to the trouble when Doom Emacs already has a nice modeline package available. For more information on what is available to configure in the Doom modeline, check out: [[https://github.com/seagle0128/doom-modeline][Doom Modeline]]
|
||
#+begin_src emacs-lisp
|
||
(use-package doom-modeline
|
||
:ensure t
|
||
:init (doom-modeline-mode 1)
|
||
:config
|
||
(setq doom-modeline-height 35 ;; sets modeline height
|
||
doom-modeline-bar-width 5 ;; sets right bar width
|
||
doom-modeline-persp-name t ;; adds perspective name to modeline
|
||
doom-modeline-persp-icon t)) ;; adds folder icon next to persp name
|
||
#+end_src
|
||
* PROJECTILE
|
||
[[https://github.com/bbatsov/projectile][Projectile]] is a project interaction library for Emacs. It should be noted that many projectile commands do not work if you have set “fish” as the “shell-file-name” for Emacs.
|
||
#+begin_src emacs-lisp
|
||
(use-package projectile
|
||
:ensure t
|
||
:config
|
||
(projectile-mode 1))
|
||
#+end_src
|
||
* PDF Tools
|
||
[[https://github.com/vedang/pdf-tools][pdf-tools]] is a replacement of DocView for viewing PDF files inside Emacs. It uses the poppler library, which also means that ‘pdf-tools’ can by used to modify PDFs. I use to disable ‘display-line-numbers-mode’ in ‘pdf-view-mode’ because line numbers crash it.
|
||
#+begin_src emacs-lisp
|
||
(use-package pdf-tools
|
||
:ensure t
|
||
:defer t
|
||
:commands (pdf-loader-install)
|
||
:mode "\\.pdf\\'"
|
||
:bind (:map pdf-view-mode-map
|
||
("j" . pdf-view-next-line-or-next-page)
|
||
("k" . pdf-view-previous-line-or-previous-page)
|
||
("C-=" . pdf-view-enlarge)
|
||
("C--" . pdf-view-shrink))
|
||
:init (pdf-loader-install)
|
||
:config (add-to-list 'revert-without-query ".pdf"))
|
||
|
||
(add-hook 'pdf-view-mode-hook #'(lambda () (interactive) (display-line-numbers-mode -1)
|
||
(blink-cursor-mode -1)
|
||
(doom-modeline-mode -1)))
|
||
|
||
#+end_src
|
||
* RAINBOW DELIMITERS
|
||
Adding rainbow coloring to parentheses.
|
||
#+begin_src emacs-lisp
|
||
(use-package rainbow-delimiters
|
||
:ensure t
|
||
:hook ((emacs-lisp-mode . rainbow-delimiters-mode)
|
||
(clojure-mode . rainbow-delimiters-mode)))
|
||
#+end_src
|
||
* ORG MODE
|
||
** Enabling Table of Contents
|
||
#+begin_src emacs-lisp
|
||
(setq org-directory "~/Documents/org")
|
||
(use-package toc-org
|
||
:ensure t
|
||
:commands toc-org-enable
|
||
:init (add-hook 'org-mode-hook 'toc-org-enable))
|
||
#+end_src
|
||
|
||
** Enabling Org Bullets
|
||
Org-bullets gives us attractive bullets rather than asterisks.
|
||
|
||
#+begin_src emacs-lisp
|
||
(add-hook 'org-mode-hook 'org-indent-mode)
|
||
(use-package org-bullets :ensure t)
|
||
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
|
||
#+end_src
|
||
** Disable Electric Indent
|
||
Org mode source blocks have some really weird and annoying default indentation behavior. I think this has to do with electric-indent-mode, which is turned on by default in Emacs. So let's turn it OFF!
|
||
|
||
#+begin_src emacs-lisp
|
||
(electric-indent-mode -1)
|
||
#+end_src
|
||
|
||
** Org Level Headers
|
||
#+begin_src emacs-lisp
|
||
(custom-set-faces
|
||
'(org-level-1 ((t (:inherit outline-1 :height 1.45))))
|
||
'(org-level-2 ((t (:inherit outline-2 :height 1.35))))
|
||
'(org-level-3 ((t (:inherit outline-3 :height 1.30))))
|
||
'(org-level-4 ((t (:inherit outline-4 :height 1.25))))
|
||
'(org-level-5 ((t (:inherit outline-5 :height 1.20))))
|
||
'(org-level-6 ((t (:inherit outline-5 :height 1.15))))
|
||
'(org-level-7 ((t (:inherit outline-5 :height 1.10)))))
|
||
#+end_src
|
||
|
||
** Source Code Block Tag Expansion
|
||
Org-tempo is not a separate package but a module within org that can be enabled. Org-tempo allows for '<s' followed by TAB to expand to a begin_src tag. Other expansions available include:
|
||
|
||
| Typing the below + TAB | Expands to ... |
|
||
|------------------------+-----------------------------------------|
|
||
| <a | '#+BEGIN_EXPORT ascii' … '#+END_EXPORT |
|
||
| <c | '#+BEGIN_CENTER' … '#+END_CENTER' |
|
||
| <C | '#+BEGIN_COMMENT' … '#+END_COMMENT' |
|
||
| <e | '#+BEGIN_EXAMPLE' … '#+END_EXAMPLE' |
|
||
| <E | '#+BEGIN_EXPORT' … '#+END_EXPORT' |
|
||
| <h | '#+BEGIN_EXPORT html' … '#+END_EXPORT' |
|
||
| <l | '#+BEGIN_EXPORT latex' … '#+END_EXPORT' |
|
||
| <q | '#+BEGIN_QUOTE' … '#+END_QUOTE' |
|
||
| <s | '#+BEGIN_SRC' … '#+END_SRC' |
|
||
| <v | '#+BEGIN_VERSE' … '#+END_VERSE' |
|
||
#+begin_src emacs-lisp
|
||
(require 'org-tempo)
|
||
#+end_src
|
||
* ORG ROAM
|
||
** Org Roam itself
|
||
#+begin_src emacs-lisp
|
||
(use-package org-roam
|
||
:ensure t
|
||
:init
|
||
(setq org-roam-v2-ack t)
|
||
:custom
|
||
(org-roam-directory "~/Documents/org")
|
||
(org-roam-completion-everywhere t)
|
||
(org-roam-capture-templates
|
||
'(("d" "default" plain
|
||
"%?"
|
||
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n")
|
||
:unnarrowed t)
|
||
))
|
||
(org-roam-dailies-capture-templates
|
||
'(("d" "default" entry "* %<%I:%M %p>: %?"
|
||
:if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))))
|
||
:config
|
||
(require 'org-roam-dailies) ;; Ensure the keymap is available
|
||
(org-roam-db-autosync-mode)
|
||
(org-roam-setup))
|
||
#+end_src
|
||
** Org Roam UI
|
||
#+begin_src emacs-lisp
|
||
(use-package org-roam-ui
|
||
:ensure t
|
||
:after org-roam)
|
||
#+end_src
|
||
** Org Agenda
|
||
#+begin_src emacs-lisp
|
||
(require 'org-roam-node)
|
||
(defun kylekrein/org-roam-filter-by-tag (tag-name)
|
||
(lambda (node)
|
||
(member tag-name (org-roam-node-tags node))))
|
||
|
||
(defun kylekrein/org-roam-list-notes-by-tag (tag-name)
|
||
(mapcar #'org-roam-node-file
|
||
(seq-filter
|
||
(kylekrein/org-roam-filter-by-tag tag-name)
|
||
(org-roam-node-list))))
|
||
|
||
(defun kylekrein/org-roam-refresh-agenda-list ()
|
||
(interactive)
|
||
(setq org-agenda-files (kylekrein/org-roam-list-notes-by-tag "Project")))
|
||
|
||
;; Build the agenda list the first time for the session
|
||
(kylekrein/org-roam-refresh-agenda-list)
|
||
|
||
|
||
|
||
(setq org-agenda-files nil
|
||
org-roam-node-display-template "${title} ${tags}"
|
||
org-agenda-start-on-weekday 1 ;; Week starts on Monday instead of Sunday
|
||
)
|
||
#+end_src
|
||
** Inbox
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun kylekrein/org-roam-capture-inbox ()
|
||
(interactive)
|
||
(org-roam-capture- :node (org-roam-node-create)
|
||
:templates '(("i" "inbox" plain "* %?"
|
||
:if-new (file+head "Inbox.org" "#+title: Inbox\n")))))
|
||
#+end_src
|
||
** Todos in Today
|
||
Automatically copies all *DONE* TODOs to Today's daily
|
||
#+begin_src emacs-lisp
|
||
(defun kylekrein/org-roam-copy-todo-to-today ()
|
||
(interactive)
|
||
(let ((org-refile-keep t) ;; Set this to nil to delete the original!
|
||
(org-roam-dailies-capture-templates
|
||
'(("t" "tasks" entry "%?"
|
||
:if-new (file+head+olp "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n#+filetags: Daily\n" ("Completed Tasks:")))))
|
||
(org-after-refile-insert-hook #'save-buffer)
|
||
today-file
|
||
pos)
|
||
(save-window-excursion
|
||
(org-roam-dailies--capture (current-time) t)
|
||
(setq today-file (buffer-file-name))
|
||
(setq pos (point)))
|
||
|
||
;; Only refile if the target file is different than the current file
|
||
(unless (equal (file-truename today-file)
|
||
(file-truename (buffer-file-name)))
|
||
(org-refile nil nil (list "Tasks" today-file nil pos)))))
|
||
|
||
(add-to-list 'org-after-todo-state-change-hook
|
||
(lambda ()
|
||
(when (equal org-state "DONE")
|
||
(kylekrein/org-roam-copy-todo-to-today))))
|
||
#+end_src
|
||
* RAINBOW MODE
|
||
Display the actual color as a background for any hex color value (ex. #ffffff). The code block below enables rainbow-mode in all programming modes (prog-mode) as well as org-mode, which is why rainbow works in this document.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package rainbow-mode
|
||
:ensure t
|
||
:hook
|
||
((org-mode prog-mode) . rainbow-mode))
|
||
#+end_src
|
||
* SHELLS AND TERMINALS
|
||
** Eshell
|
||
Eshell is an Emacs 'shell' that is written in Elisp.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package eshell-syntax-highlighting
|
||
:ensure t
|
||
:after esh-mode
|
||
:config
|
||
(eshell-syntax-highlighting-global-mode +1))
|
||
#+end_src
|
||
** Vterm
|
||
Vterm is a terminal emulator within Emacs. The 'shell-file-name' setting sets the shell to be used in M-x shell, M-x term, M-x ansi-term and M-x vterm. By default, the shell is set to 'fish' but could change it to 'bash' or 'zsh' if you prefer.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package vterm
|
||
:ensure t
|
||
;;:config
|
||
)
|
||
#+end_src
|
||
|
||
** Vterm-Toggle
|
||
[[https://github.com/jixiuf/vterm-toggle][vterm-toggle]] toggles between the vterm buffer and whatever buffer you are editing.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package vterm-toggle
|
||
:ensure t
|
||
:after vterm
|
||
:config
|
||
(setq vterm-toggle-fullscreen-p nil)
|
||
(setq vterm-toggle-scope 'project)
|
||
(add-to-list 'display-buffer-alist
|
||
'((lambda (buffer-or-name _)
|
||
(let ((buffer (get-buffer buffer-or-name)))
|
||
(with-current-buffer buffer
|
||
(or (equal major-mode 'vterm-mode)
|
||
(string-prefix-p vterm-buffer-name (buffer-name buffer))))))
|
||
(display-buffer-reuse-window display-buffer-at-bottom)
|
||
;;(display-buffer-reuse-window display-buffer-in-direction)
|
||
;;display-buffer-in-direction/direction/dedicated is added in emacs27
|
||
;;(direction . bottom)
|
||
;;(dedicated . t) ;dedicated is supported in emacs27
|
||
(reusable-frames . visible)
|
||
(window-height . 0.3))))
|
||
#+end_src
|
||
|
||
|
||
* SUDO EDIT
|
||
[[https://github.com/nflath/sudo-edit][sudo-edit]] gives us the ability to open files with sudo privileges or switch over to editing with sudo privileges if we initially opened the file without such privileges.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package sudo-edit
|
||
:ensure t
|
||
:config
|
||
(kylekrein/leader-keys
|
||
"fu" '(sudo-edit-find-file :wk "Sudo find file")
|
||
"fU" '(sudo-edit :wk "Sudo edit file")))
|
||
#+end_src
|
||
* Nerd Icons
|
||
#+begin_src emacs-lisp
|
||
(use-package nerd-icons
|
||
:ensure t
|
||
;; :custom
|
||
;; The Nerd Font you want to use in GUI
|
||
;; "Symbols Nerd Font Mono" is the default and is recommended
|
||
;; but you can use any other Nerd Font if you want
|
||
;; (nerd-icons-font-family "Symbols Nerd Font Mono")
|
||
)
|
||
#+end_src
|
||
** Nerd Icons Completion
|
||
[[https://github.com/rainstormstudio/nerd-icons-completion]]
|
||
#+begin_src emacs-lisp
|
||
(use-package nerd-icons-completion
|
||
:ensure t
|
||
:after marginalia
|
||
:config
|
||
(nerd-icons-completion-mode)
|
||
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
|
||
#+end_src
|
||
* Buffer Move
|
||
Creating some functions to allow us to easily move windows (splits) around. The following block of code was taken from buffer-move.el found on the EmacsWiki:
|
||
https://www.emacswiki.org/emacs/buffer-move.el
|
||
#+begin_src emacs-lisp
|
||
(require 'windmove)
|
||
|
||
;;;###autoload
|
||
(defun buf-move-up ()
|
||
"Swap the current buffer and the buffer above the split.
|
||
If there is no split, ie now window above the current one, an
|
||
error is signaled."
|
||
;; "Switches between the current buffer, and the buffer above the
|
||
;; split, if possible."
|
||
(interactive)
|
||
(let* ((other-win (windmove-find-other-window 'up))
|
||
(buf-this-buf (window-buffer (selected-window))))
|
||
(if (null other-win)
|
||
(error "No window above this one")
|
||
;; swap top with this one
|
||
(set-window-buffer (selected-window) (window-buffer other-win))
|
||
;; move this one to top
|
||
(set-window-buffer other-win buf-this-buf)
|
||
(select-window other-win))))
|
||
|
||
;;;###autoload
|
||
(defun buf-move-down ()
|
||
"Swap the current buffer and the buffer under the split.
|
||
If there is no split, ie now window under the current one, an
|
||
error is signaled."
|
||
(interactive)
|
||
(let* ((other-win (windmove-find-other-window 'down))
|
||
(buf-this-buf (window-buffer (selected-window))))
|
||
(if (or (null other-win)
|
||
(string-match "^ \\*Minibuf" (buffer-name (window-buffer other-win))))
|
||
(error "No window under this one")
|
||
;; swap top with this one
|
||
(set-window-buffer (selected-window) (window-buffer other-win))
|
||
;; move this one to top
|
||
(set-window-buffer other-win buf-this-buf)
|
||
(select-window other-win))))
|
||
|
||
;;;###autoload
|
||
(defun buf-move-left ()
|
||
"Swap the current buffer and the buffer on the left of the split.
|
||
If there is no split, ie now window on the left of the current
|
||
one, an error is signaled."
|
||
(interactive)
|
||
(let* ((other-win (windmove-find-other-window 'left))
|
||
(buf-this-buf (window-buffer (selected-window))))
|
||
(if (null other-win)
|
||
(error "No left split")
|
||
;; swap top with this one
|
||
(set-window-buffer (selected-window) (window-buffer other-win))
|
||
;; move this one to top
|
||
(set-window-buffer other-win buf-this-buf)
|
||
(select-window other-win))))
|
||
|
||
;;;###autoload
|
||
(defun buf-move-right ()
|
||
"Swap the current buffer and the buffer on the right of the split.
|
||
If there is no split, ie now window on the right of the current
|
||
one, an error is signaled."
|
||
(interactive)
|
||
(let* ((other-win (windmove-find-other-window 'right))
|
||
(buf-this-buf (window-buffer (selected-window))))
|
||
(if (null other-win)
|
||
(error "No right split")
|
||
;; swap top with this one
|
||
(set-window-buffer (selected-window) (window-buffer other-win))
|
||
;; move this one to top
|
||
(set-window-buffer other-win buf-this-buf)
|
||
(select-window other-win))))
|
||
#+end_src
|
||
* Vertico
|
||
[[https://github.com/minad/vertico][Vertico]] provides a performant and minimalistic vertical completion UI based on the default completion system.
|
||
#+begin_src emacs-lisp
|
||
;; 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))
|
||
|
||
(vertico-mode t) ;; enable vertico for all buffers
|
||
;; Persist history over Emacs restarts. Vertico sorts by history position.
|
||
(use-package savehist
|
||
:ensure -1 ;;package is unavailable in nix
|
||
:init
|
||
(savehist-mode))
|
||
|
||
;; A few more useful configurations...
|
||
(use-package emacs
|
||
:custom
|
||
;; Support opening new minibuffers from inside existing minibuffers.
|
||
(enable-recursive-minibuffers t)
|
||
;; Hide commands in M-x which do not work in the current mode. Vertico
|
||
;; commands are hidden in normal buffers. This setting is useful beyond
|
||
;; Vertico.
|
||
(read-extended-command-predicate #'command-completion-default-include-p)
|
||
:init
|
||
;; Add prompt indicator to `completing-read-multiple'.
|
||
;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
|
||
(defun crm-indicator (args)
|
||
(cons (format "[CRM%s] %s"
|
||
(replace-regexp-in-string
|
||
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
|
||
crm-separator)
|
||
(car args))
|
||
(cdr args)))
|
||
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
|
||
|
||
;; Do not allow the cursor in the minibuffer prompt
|
||
(setq minibuffer-prompt-properties
|
||
'(read-only t cursor-intangible t face minibuffer-prompt))
|
||
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode))
|
||
|
||
;; Optionally use the `orderless' completion style.
|
||
(use-package orderless
|
||
:ensure t
|
||
:custom
|
||
;; Configure a custom style dispatcher (see the Consult wiki)
|
||
;; (orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch))
|
||
;; (orderless-component-separator #'orderless-escapable-split-on-space)
|
||
(completion-styles '(orderless basic))
|
||
(completion-category-defaults nil)
|
||
(completion-category-overrides '((file (styles partial-completion)))))
|
||
#+end_src
|
||
** Descriptions
|
||
*** Marginalia
|
||
[[https://github.com/minad/marginalia/]]
|
||
Descriptions for completions
|
||
#+begin_src emacs-lisp
|
||
;; Enable rich annotations using the Marginalia package
|
||
(use-package marginalia
|
||
:ensure t
|
||
;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding
|
||
;; available in the *Completions* buffer, add it to the
|
||
;; `completion-list-mode-map'.
|
||
:bind (:map minibuffer-local-map
|
||
("M-A" . marginalia-cycle))
|
||
|
||
;; The :init section is always executed.
|
||
:init
|
||
|
||
;; Marginalia must be activated in the :init section of use-package such that
|
||
;; the mode gets enabled right away. Note that this forces loading the
|
||
;; package.
|
||
(marginalia-mode))
|
||
#+end_src
|
||
* Theme
|
||
[[https://emacsfodder.github.io/emacs-theme-editor/][Emacs Theme Editor]]
|
||
** Theme loading
|
||
#+begin_src emacs-lisp
|
||
(use-package doom-themes
|
||
:ensure t
|
||
:config
|
||
;; Global settings (defaults)
|
||
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
|
||
doom-themes-enable-italic t) ; if nil, italics is universally disabled
|
||
(load-theme 'doom-one t)
|
||
|
||
;; Enable flashing mode-line on errors
|
||
(doom-themes-visual-bell-config)
|
||
;; Enable custom neotree theme (nerd-icons must be installed!)
|
||
(doom-themes-neotree-config)
|
||
;; or for treemacs users
|
||
(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
|
||
(doom-themes-treemacs-config)
|
||
;; Corrects (and improves) org-mode's native fontification.
|
||
(doom-themes-org-config))
|
||
#+end_src
|
||
* WHICH-KEY
|
||
#+begin_src emacs-lisp
|
||
(use-package which-key
|
||
:ensure t
|
||
:init
|
||
(which-key-mode 1)
|
||
:config
|
||
(setq which-key-side-window-location 'bottom
|
||
which-key-sort-order #'which-key-key-order-alpha
|
||
which-key-sort-uppercase-first nil
|
||
which-key-add-column-padding 1
|
||
which-key-max-display-columns nil
|
||
which-key-min-display-lines 6
|
||
which-key-side-window-slot -10
|
||
which-key-side-window-max-height 0.25
|
||
which-key-idle-delay 0.8
|
||
which-key-max-description-length 25
|
||
which-key-allow-imprecise-window-fit t
|
||
which-key-separator " → " ))
|
||
#+end_src
|