#+title: Emacs Config #+author: Venomade * Contents :toc_2: - [[#straight-package-manager][Straight Package Manager]] - [[#configs][Configs]] - [[#custom-functions][Custom Functions]] - [[#fix-annoyances][Fix Annoyances]] - [[#keybindings][Keybindings]] - [[#setup-line-numbers][Setup Line Numbers]] - [[#general][General]] - [[#avy][Avy]] - [[#colors][Colors]] - [[#dired][Dired]] - [[#eshell][EShell]] - [[#git][Git]] - [[#move-text][Move Text]] - [[#ivy-counsel][Ivy (Counsel)]] - [[#simple-modeline][Simple Modeline]] - [[#smart-parentheses-pairing][Smart Parentheses Pairing]] - [[#undo-tree][Undo Tree]] - [[#org-mode][Org Mode]] - [[#table-of-contents][Table of Contents]] - [[#bullet-headers][Bullet Headers]] - [[#org-agenda][Org Agenda]] - [[#org-babel][Org Babel]] - [[#org-tempo][Org Tempo]] - [[#styling][Styling]] - [[#programming][Programming]] - [[#projects][Projects]] - [[#lsp][LSP]] - [[#treesitter][TreeSitter]] - [[#languages][Languages]] - [[#company][Company]] - [[#cape][Cape]] - [[#utilities][Utilities]] - [[#user-interface][User Interface]] - [[#add-nerd-icons][Add Nerd Icons]] - [[#fonts][Fonts]] - [[#theme][Theme]] - [[#niceties][Niceties]] - [[#modern-looking-emacs][Modern Looking Emacs]] * Straight Package Manager I'm using the Straight package manager instead of use-package because it is only available in Emacs 29 and above. #+begin_src emacs-lisp (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 6)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) (setq straight-use-package-by-default t) #+end_src * Configs ** Custom Functions *** Cursor follow on split This is so that action can be taken as soon as a split takes place, to either close/move the window or perform an action inside of it. #+begin_src emacs-lisp (defun split-and-follow-horizontally() (interactive) (split-window-below) (balance-windows) (other-window 1)) (defun split-and-follow-vertically() (interactive) (split-window-right) (balance-windows) (other-window 1)) #+end_src *** Duplicate Line Duplicates the current line to the line below. #+begin_src emacs-lisp (defun duplicate-line () (interactive) (let ((column (- (point) (point-at-bol))) (line (let ((s (thing-at-point 'line t))) (if s (string-remove-suffix "\n" s) "")))) (move-end-of-line 1) (newline) (insert line) (move-beginning-of-line 1) (forward-char column))) (keymap-global-set "C-c y d" 'duplicate-line) #+end_src *** Open Line above and below Vim's o and S-o implemented for Emacs bindings. #+begin_src emacs-lisp (defun vi-open-line-above () (interactive) (unless (bolp) (beginning-of-line)) (newline) (forward-line -1) (indent-according-to-mode)) (defun vi-open-line-below () (interactive) (unless (eolp) (end-of-line)) (newline-and-indent)) (keymap-global-set "C-c O" 'vi-open-line-below) (keymap-global-set "C-c o" 'vi-open-line-above) #+end_src *** C-a to indentation Have c-a move the cursor to the start after indentation unless already there. #+begin_src emacs-lisp (defun smart-beginning-of-line () (interactive) (let ((initial-point (point))) (back-to-indentation) (when (eq initial-point (point)) (move-beginning-of-line 1)))) (defun setup-prog-mode-c-a () (local-set-key (kbd "C-a") 'smart-beginning-of-line)) (add-hook 'prog-mode-hook 'setup-prog-mode-c-a) #+end_src *** Automatically Cull Whitespace Remove trailing whitespaces when saving in prog-modes. #+begin_src emacs-lisp (defun prog-nuke-trailing-whitespace () (when (derived-mode-p 'prog-mode) (delete-trailing-whitespace))) (add-hook 'before-save-hook 'prog-nuke-trailing-whitespace) #+end_src *** Quick Grep Quickly grep both my current project and the system include directory. #+begin_src emacs-lisp (defun grep-symbol-at-point () (interactive) (let ((symbol (thing-at-point 'symbol))) (if symbol (counsel-rg (concat symbol)) (message "No symbol at point.")))) (defun grep-symbol-in-include-at-point () (interactive) (let ((symbol (thing-at-point 'symbol))) (if symbol (counsel-rg (concat symbol) "/usr/include/") (message "No symbol at point.")))) (global-set-key (kbd "C-c g") 'grep-symbol-at-point) (global-set-key (kbd "C-c G") 'grep-symbol-in-include-at-point) #+end_src ** Fix Annoyances *** Disable Backups Living on the edge. #+begin_src emacs-lisp (setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups")))) (setq auto-save-file-name-transforms `(("." ,(concat user-emacs-directory "autosaves/") t))) (setq lock-file-name-transforms `(("." ,(concat user-emacs-directory "lock") t))) #+end_src *** Disable Bell Only flash, no sound, it gets annoying. #+begin_src emacs-lisp (setq ring-bell-function 'ignore) #+end_src *** Hide Warnings Fixing warnings is for nerds. This is basically necessary after more than 5 packages. #+begin_src emacs-lisp (setq warning-minimum-level :emergency) #+end_src *** Add Scroll Marginn This adds a scroll margin at the top and bottom of 10 lines to make it easier to scroll through the buffer. #+begin_src emacs-lisp (setq scroll-margin 10) #+end_src *** Save Place Go back to old position on file open. #+begin_src emacs-lisp (save-place-mode 1) #+end_src ** Keybindings *** Reload Emacs Reload Emacs by sourcing the init.el file. #+begin_src emacs-lisp (keymap-global-set "C-c e c" (lambda () (interactive) (load-file "~/.emacs.d/init.el"))) #+end_src *** Open Common Files Open the TODO, Bookmarks and Notes from synced Documents and the config file with simple shortcuts. #+begin_src emacs-lisp (keymap-global-set "C-c f c" (lambda () (interactive) (find-file "~/.emacs.d/config.org"))) (keymap-global-set "C-c f t" (lambda () (interactive) (find-file "~/Documents/TODO.org"))) (keymap-global-set "C-c f b" (lambda () (interactive) (find-file "~/Documents/Bookmarks.org"))) (keymap-global-set "C-c f n" (lambda () (interactive) (find-file "~/Documents/Notes.org"))) (keymap-global-set "C-c f i" (lambda () (interactive) (find-file "~/Documents/Ideas.org"))) #+end_src *** Switch and Revert Buffers Add shortcuts to switch buffers and to revert buffer. #+begin_src emacs-lisp (keymap-global-set "C-x C-b" 'ibuffer) (keymap-global-set "C-c b p" 'previous-buffer) (keymap-global-set "C-c b n" 'next-buffer) (keymap-global-set "C-c b r" 'revert-buffer) #+end_src *** Compile Mode Add shortcuts to build in compile-mode. #+begin_src emacs-lisp (setq compilation-scroll-output t) (keymap-global-set "C-c m c" 'compile) (keymap-global-set "C-c m r" 'recompile) #+end_src *** Emacs Add shortcuts to various Emacs functions. #+begin_src emacs-lisp (keymap-global-set "C-c e b" 'eval-buffer) (keymap-global-set "C-c e r" 'eval-region) (keymap-global-set "C-c e s" 'eshell) (keymap-global-set "C-c e t" 'ef-themes-load-random) #+end_src *** Regex and Copy from Above Add shortcuts to entering a regex replace and copying a line from above. #+begin_src emacs-lisp (keymap-global-set "C-c r" 'replace-regexp) (keymap-global-set "C-c y a" 'copy-from-above-command) #+end_src *** Window Management Add shortcuts to scrolling and moving between windows. #+begin_src emacs-lisp (keymap-global-set "C-c v" 'scroll-other-window) (keymap-global-set "C-c V" 'scroll-other-window-down) (keymap-global-set "C-c w n" 'other-window) (keymap-global-set "C-c w f" 'other-window) (keymap-global-set "C-c w p" (lambda () (interactive) (other-window -1))) (keymap-global-set "C-c w b" (lambda () (interactive) (other-window -1))) #+end_src ** Setup Line Numbers *** Always show line numbers Show line numbers and highlight the current line. #+begin_src emacs-lisp (add-hook 'prog-mode-hook 'display-line-numbers-mode) (global-visual-line-mode t) (add-hook 'prog-mode-hook (lambda () (visual-line-mode -1))) (setq-default truncate-lines t) (global-hl-line-mode 1) #+end_src *** Generally use spaces instead of tabs Generally, as in everywhere but Go. #+begin_src emacs-lisp (setq-default indent-tabs-mode nil) (setq tab-width 2) (setq tab-stop-list (number-sequence 2 100 2)) #+end_src *** Highlight Column Highlight a column at 120 chars to respect GNOME style. #+begin_src emacs-lisp (setq-default display-fill-column-indicator-column 120) (add-hook 'prog-mode-hook #'display-fill-column-indicator-mode) #+end_src * General ** Avy Keybind superfast cursor movement to "C-q". #+begin_src emacs-lisp (use-package avy :config (setq avy-keys '(?a ?r ?s ?t ?n ?e ?i ?o) avy-all-windows nil) (bind-key* "C-q" 'avy-goto-char)) #+end_src ** Colors *** Highlight Todo Highlight TODO items so they can be reviewed later. #+begin_src emacs-lisp (use-package hl-todo :hook ((org-mode . hl-todo-mode) (prog-mode . hl-todo-mode)) :config (setq hl-todo-highlight-punctuation ":" hl-todo-highlight-faces `(("TODO" warning bold) ("FIXME" error bold) ("HACK" font-lock-constant-face bold) ("REVIEW" font-lock-doc-face bold) ("NOTE" success bold) ("DEPRECATED" font-lock-doc-face bold)))) #+end_src *** Rainbow Delimiters Makes different brackets and other delimeters levels different colors so they can be quickly distinguished. #+begin_src emacs-lisp (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) #+end_src ** Dired A powerful built-in file manager. #+begin_src emacs-lisp (setq dired-listing-switches "-lh") #+end_src ** EShell A built in posix shell. #+begin_src emacs-lisp ;; Define custom faces for the prompt. These inherit from standard faces so they ;; automatically adapt to your current theme. (defface eshell-prompt-user-face '((t (:inherit font-lock-keyword-face))) "Face for the username in the eshell prompt." :group 'eshell-prompt) (defface eshell-prompt-venv-face '((t (:inherit font-lock-string-face))) "Face for the virtualenv name in the eshell prompt." :group 'eshell-prompt) (defface eshell-prompt-dir-face '((t (:inherit dired-directory))) "Face for the directory path in the eshell prompt." :group 'eshell-prompt) (defface eshell-prompt-git-face '((t (:inherit magit-tag))) "Face for the git branch in the eshell prompt." :group 'eshell-prompt) (defface eshell-prompt-git-dirty-face '((t (:inherit eshell-prompt-git-face))) "Face for the git dirty status in the eshell prompt." :group 'eshell-prompt) (defface eshell-prompt-symbol-face '((t (:inherit font-lock-builtin-face))) "Face for the prompt symbol (e.g. λ) in the eshell prompt." :group 'eshell-prompt) ;; A helper function to abbreviate long directory names. (defun my-abbreviate-dir (dir) "Abbreviate DIR to show only the first and the last two components. For example, \"~/Projects/Learning/C/GeneticsProject/TsodingGenetics\" becomes \"~/.../GeneticsProject/TsodingGenetics\"." (let* ((abbrev (abbreviate-file-name dir)) (components (split-string abbrev "/" t)) ; t omits empty strings (num-components (length components))) (if (>= num-components 4) (concat (car components) "/.../" (mapconcat #'identity (last components 2) "/")) abbrev))) ;; These are the same helper functions for git information you had. (defun my-prompt-git-branch () "Return the current git branch or short commit hash, if available." (when (and (executable-find "git") (locate-dominating-file default-directory ".git")) (with-temp-buffer (let ((ret (call-process "git" nil t nil "symbolic-ref" "--short" "HEAD"))) (if (zerop ret) (string-trim (buffer-string)) (when (zerop (call-process "git" nil t nil "rev-parse" "--short" "HEAD")) (string-trim (buffer-string)))))))) (defun my-prompt-git-dirty () "Return a dirty flag (✗ if dirty, ✓ if clean) for the git repository." (when (my-prompt-git-branch) (with-temp-buffer (call-process "git" nil t nil "status" "--porcelain") (if (> (buffer-size) 0) "✗" "✓")))) ;; Finally, build the prompt itself. (defun eshell-prompt () "Custom eshell prompt with theme-derived colors and shortened directory path." (let* ((user (propertize (user-login-name) 'face 'eshell-prompt-user-face)) (venv (when-let ((venv (getenv "VIRTUAL_ENV"))) (concat (propertize "(" 'face 'eshell-prompt-venv-face) (propertize (file-name-nondirectory venv) 'face 'eshell-prompt-venv-face) (propertize ")" 'face 'eshell-prompt-venv-face)))) (path (propertize (my-abbreviate-dir (eshell/pwd)) 'face 'eshell-prompt-dir-face)) (git-branch (my-prompt-git-branch)) (git-info (when git-branch (concat " " (propertize "on" 'face 'font-lock-number-face) " " (propertize git-branch 'face 'eshell-prompt-git-face) (propertize (my-prompt-git-dirty) 'face 'eshell-prompt-git-dirty-face)))) (prompt (concat user " " (propertize "in" 'face 'font-lock-number-face) " " (if venv (concat venv " ") "") path git-info "\n" (propertize "λ" 'face 'eshell-prompt-symbol-face) " "))) prompt)) ;; Tell eshell to use our prompt function. (setq eshell-prompt-function 'eshell-prompt) (setq eshell-prompt-regexp "^[^λ\n]*λ ") #+end_src ** Git Tools for the primary version control system. *** Magit A very extensive Git GUI for Emacs. #+begin_src emacs-lisp (use-package magit) #+end_src *** Magit Todos Show Todo list in Magit. #+begin_src emacs-lisp (use-package magit-todos :after magit :config (magit-todos-mode 1)) #+end_src *** Magit Forge Work with Git Forges from within Emacs. #+begin_src emacs-lisp (use-package forge :after magit :config (setq auth-sources '("~/.authinfo"))) #+end_src ** Move Text Move text up and down with simple keybindings. #+begin_src emacs-lisp (use-package move-text :config (keymap-global-set "M-p" 'move-text-up) (keymap-global-set "M-n" 'move-text-down)) #+end_src ** Ivy (Counsel) *** Counsel Adds better fuzzy completion to many Emacs commands. #+begin_src emacs-lisp (use-package counsel :after ivy :config (counsel-mode 1) (keymap-global-set "C-c f r" 'counsel-buffer-or-recentf) (keymap-global-set "C-c f f" 'counsel-fzf) (keymap-global-set "C-c f g" 'counsel-rg) (keymap-global-set "C-c f l" 'counsel-locate) (keymap-global-set "C-c s" 'swiper)) #+end_src *** Ivy Adds fuzzy completion to basic Emacs commands. #+begin_src emacs-lisp (use-package ivy :custom (setq ivy-use-virtual-buffers t) (setq ivy-count-format "(%d/%d) ") (setq enable-recursive-minibuffers t) :config (ivy-mode 1)) ;; (use-package ivy-prescient ;; :after counsel ;; :config ;; (ivy-prescient-mode 1)) #+end_src *** Ivy Rich Adds Icons to all the new fuzzy completed Emacs commands. #+begin_src emacs-lisp (use-package ivy-rich :after ivy :init (ivy-rich-mode 1) :custom (ivy-virtual-abbreviate 'full ivy-rich-switch-buffer-align-virtual-buffer t ivy-rich-path-style 'abbrev)) #+end_src ** Simple Modeline Make the modeline simple by hiding modes. #+begin_src emacs-lisp (setq-default mode-line-format (delq 'mode-line-modes mode-line-format) display-time-24hr-format t display-time-default-load-average nil) (display-battery-mode 1) (display-time-mode 1) #+end_src ** Smart Parentheses Pairing Automatically deals with parentheses in pairs. #+begin_src emacs-lisp (use-package smartparens :hook (prog-mode text-mode markdown-mode) :config (require 'smartparens-config) (sp-use-paredit-bindings)) #+end_src ** Undo Tree Makes undo history like a Git commit tree, very powerful. #+begin_src emacs-lisp (use-package undo-tree :config (setq undo-tree-history-directory-alist `(("." . ,(concat user-emacs-directory "undo")))) (global-undo-tree-mode 1)) #+end_src * Org Mode ** Table of Contents Automatically generate a table of contents for an Org file. #+begin_src emacs-lisp (use-package toc-org :commands toc-org-enable :init (add-hook 'org-mode-hook 'toc-org-enable) :config (setq org-src-window-setup 'current-window)) (add-hook 'org-mode-hook 'org-indent-mode) #+end_src ** Bullet Headers Stylize Org Mode headers with Nerd Icons. #+begin_src emacs-lisp (use-package org-bullets :config (setq org-bullets-bullet-list '( "" "" "" "" ""))) (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) #+end_src ** Org Agenda Manage a Todo list, a Calendar, and other organization tools with Org. #+begin_src emacs-lisp (setq org-agenda-files '("~/Documents/Org/agenda.org")) (setq org-fancy-priorities-list '("[A]" "[B]" "[C]") org-priority-faces '((?A :foreground "#ff6c6b" :weight bold) (?B :foreground "#ffff91" :weight bold) (?C :foreground "#aaffaa" :weight bold))) (setq org-agenda-custom-commands '(("v" "View Agenda" ((tags "PRIORITY=\"A\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "HIGH PRIORITY:"))) (tags "PRIORITY=\"B\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "Medium Priority:"))) (tags "PRIORITY=\"C\"" ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done)) (org-agenda-overriding-header "low priority:"))) (agenda "") (alltodo ""))))) #+end_src ** Org Babel Setup literate progamming in Org Mode. *** Config Don't ask for conformation when evaluating source blocks. #+begin_src emacs-lisp (setq org-confirm-babel-evaluate nil) #+end_src *** Load Languages #+begin_src emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((python . t) (lua . t))) #+end_src ** Org Tempo This provides shorthands for Org functions. #+begin_src emacs-lisp (require 'org-tempo) #+end_src ** Styling Hide markers for bold, italic and other types of text styling. #+begin_src emacs-lisp (setq org-hide-emphasis-markers t) #+end_src * Programming ** Projects Manage Project folders from within Emacs. *** Project.el Use project.el and set shortcuts with prefix "C-c p". #+begin_src emacs-lisp (require 'project) (keymap-global-set "C-c p b" 'project-list-buffers) (keymap-global-set "C-c p c" 'project-compile) (keymap-global-set "C-c p e" 'project-dired) (keymap-global-set "C-c p f" 'project-find-file) (keymap-global-set "C-c f p" 'project-find-file) (keymap-global-set "C-c p g" 'project-find-regexp) (keymap-global-set "C-c p o" 'project-find-dir) (keymap-global-set "C-c p p" 'project-switch-project) #+end_src *** Disproject Magit like interface ontop of project.el. #+begin_src emacs-lisp (use-package disproject ;; Replace `project-prefix-map' with `disproject-dispatch'. :bind ( :map ctl-x-map ("p" . disproject-dispatch))) #+end_src *** Run Project Run the current project. #+begin_src emacs-lisp (require 'project) (defvar-local project-binary-name nil) (defvar-local project-binary-args nil) (defvar-local project-debugger "gf2") (defun get-project-binary-info () (let* ((project (project-current t)) (project-root (project-root project)) (binary-name (or project-binary-name (downcase (file-name-nondirectory (directory-file-name project-root))))) (binary-path (expand-file-name binary-name project-root)) (args (or project-binary-args ""))) (list binary-path args))) (defun run-project-binary () (interactive) (let* ((binary-info (get-project-binary-info)) (binary-path (nth 0 binary-info)) (args (nth 1 binary-info)) (original-compile-command compile-command)) (if (file-executable-p binary-path) (progn (setq compile-command (concat binary-path " " args)) (unwind-protect (compile compile-command) (setq compile-command original-compile-command))) (error "Binary '%s' not found or not executable in project root" binary-path)))) (defun debug-project-binary () (interactive) (let* ((binary-info (get-project-binary-info)) (binary-path (nth 0 binary-info)) (args (nth 1 binary-info)) (debugger (or project-debugger "gdb")) (debug-command (concat debugger " --args " binary-path " " args)) (original-compile-command compile-command)) (if (file-executable-p binary-path) (progn (setq compile-command debug-command) (unwind-protect (compile compile-command) (setq compile-command original-compile-command))) (error "Binary '%s' not found or not executable in project root" binary-path)))) ;; Mark 'project-binary-name' and 'project-binary-args' as safe for dir-locals. (put 'project-binary-name 'safe-local-variable #'stringp) (put 'project-binary-args 'safe-local-variable #'stringp) (keymap-global-set "C-c p r" 'run-project-binary) (keymap-global-set "C-c p d" 'debug-project-binary) #+end_src ** LSP *** LSP Mode Use language servers to provide info and completion. #+begin_src emacs-lisp (use-package lsp-mode :init (setq lsp-completion-provider :none lsp-keymap-prefix "C-c l" lsp-headerline-breadcrumb-enable nil) :commands lsp lsp-deferred :config (lsp-enable-snippet t)) ;; (lsp-enable-which-key-integration t)) ;; (use-package lsp-ui ;; :commands lsp-ui-mode ;; :hook (prog-mode . lsp-ui-mode) ;; :config ;; (keymap-global-set "C-c l d" 'lsp-ui-doc-show)) ;; Instead: (keymap-global-set "C-c l d" 'lsp-describe-thing-at-point) #+end_src *** YASnippet Autocomplete Snippets to write common code patterns faster. #+begin_src emacs-lisp (use-package yasnippet :config (setq yas-snippet-dirs '("~/Documents/snippets")) (yas-global-mode 1) (keymap-global-set "M-" 'yas-next-field-or-maybe-expand) (keymap-global-set "C-'" 'yas-expand)) (straight-use-package '(yasnippet-capf :type git :host github :repo "elken/yasnippet-capf")) (use-package yasnippet-treesitter-shim :straight (:host github :repo "fbrosda/yasnippet-treesitter-shim" :files ("snippets/*")) :no-require t :config (add-to-list 'yas-snippet-dirs (straight--build-dir "yasnippet-treesitter-shim"))) #+end_src *** DevDocs Search documentation from within Emacs. #+begin_src emacs-lisp (use-package devdocs :config (keymap-global-set "C-c d" 'devdocs-lookup)) #+end_src ** TreeSitter Use advanced highlighting by default. #+begin_src emacs-lisp (require 'treesit) (use-package treesit-auto :config (global-treesit-auto-mode)) (setq major-mode-remap-alist (treesit-auto--build-major-mode-remap-alist)) #+end_src ** Languages *** C The Classic. #+begin_src emacs-lisp (add-hook 'c-mode-hook #'lsp) (add-hook 'c-ts-mode-hook #'lsp) ;; Use GNU Style in LSP-Mode for C (with-eval-after-load 'lsp-clangd (setq lsp-clients-clangd-args '("--header-insertion-decorators=0" "--fallback-style=GNU"))) ;; Automatically write header guards (defun insert-header-guards () (when (and (buffer-file-name) (string-match "\\.h\\'" (buffer-file-name))) (let* ((filename (file-name-nondirectory (buffer-file-name))) (guard (upcase (replace-regexp-in-string "[^a-zA-Z0-9]" "_" filename)))) (when (zerop (buffer-size)) ; Only insert if the file is empty (insert (format "#ifndef %s\n#define %s\n\n\n$0\n\n#endif // %s\n" guard guard guard)) (goto-char (point-min)) (search-forward "$0") (delete-char -3))))) (add-hook 'find-file-hook 'insert-header-guards) #+end_src *** COMMENT D C Interop with a GC. #+begin_src emacs-lisp (use-package d-mode :hook (d-mode . lsp)) #+end_src *** COMMENT Go A simple C-like language with a GC. #+begin_src emacs-lisp (use-package go-mode :config (setenv "PATH" (concat (concat (concat (expand-file-name "/usr/local/go/bin") ":") (getenv "PATH")))) (setenv "PATH" (concat (concat (concat (expand-file-name "~/.go/bin") ":") (getenv "PATH")))) (setq exec-path (append exec-path (list (expand-file-name "/usr/local/go/bin")))) (setq exec-path (append exec-path (list (expand-file-name "~/.go/bin")))) (add-hook 'go-mode-hook (lambda () (setq tab-width 4))) :hook (go-mode . lsp)) #+end_src *** Haskell Functionally Scottish. #+begin_src emacs-lisp (use-package haskell-mode :config (setenv "PATH" (concat (concat (concat (expand-file-name "~/.ghcup/bin") ":") (getenv "PATH")))) (setq exec-path (append exec-path (list (expand-file-name "~/.ghcup/bin"))))) (use-package lsp-haskell :hook (haskell-mode . lsp)) #+end_src *** COMMENT LISP Programming for Programmers. #+begin_src emacs-lisp ;; (use-package slime ;; :init ;; (slime-setup '(slime-fancy slime-quicklisp slime-asdf slime-mrepl)) ;; :config ;; (setq inferior-lisp-program "/usr/bin/sbcl") ;; (add-hook 'slime-repl-mode-hook 'smartparens-mode)) (use-package sly :config (setq inferior-lisp-program "ros -Q run" browse-url-browser-function '(("hyperspec" . eww-browse-url) ("." . browse-url-default-browser))) (add-hook 'sly-mrepl-mode-hook 'smartparens-mode) (add-hook 'sly-mrepl-mode-hook 'company-mode) (add-hook 'lisp-mode-hook (lambda () (define-key lisp-mode-map (kbd "C-c d") 'sly-documentation)))) ;; (with-eval-after-load 'sly ;; (load (expand-file-name "~/.roswell/helper.el"))) #+end_src *** COMMENT Lua A simple Python-like language with many implementations. #+begin_src emacs-lisp (straight-use-package '(lua-mode :type git :host github :repo "immerrr/lua-mode")) (add-hook 'lua-mode-hook #'lsp) (setq lua-indent-nested-block-content-align nil) (setq lua-indent-close-paren-align nil) (defun lua-at-most-one-indent (old-function &rest arguments) (let ((old-res (apply old-function arguments))) (if (> old-res lua-indent-level) lua-indent-level old-res))) (advice-add #'lua-calculate-indentation-block-modifier :around #'lua-at-most-one-indent) (setq lua-indent-level 2) (setq lua-electric-flag nil) (defun lua-abbrev-mode-off () (abbrev-mode 0)) (add-hook 'lua-mode-hook 'lua-abbrev-mode-off) (setq save-abbrevs nil) ;; is this still needed? #+end_src *** OCaml Installed with OPAM #+begin_src emacs-lisp (setenv "PATH" (concat (concat (concat (expand-file-name "~/.opam/default/bin") ":") (getenv "PATH")))) (setq exec-path (append exec-path (list (expand-file-name "~/.opam/default/bin")))) (use-package tuareg :hook (tuareg-mode . lsp)) (add-to-list 'load-path "/home/venomade/.opam/default/share/emacs/site-lisp") (require 'ocp-indent) (require 'dune) (require 'utop) #+end_src *** COMMENT Vala An OOP Language for C & GLib interop. #+begin_src emacs-lisp (use-package vala-mode) #+end_src ** Company A powerful auto-completion utility. #+begin_src emacs-lisp (use-package company :config (define-key company-active-map (kbd "RET") nil) (define-key company-active-map (kbd "") nil) (define-key company-active-map (kbd "C-m") nil) ;; TAB indents or selects a completion (define-key company-active-map (kbd "TAB") #'company-complete-selection) (define-key company-active-map (kbd "") #'company-complete-selection) ;; Use C-p and C-n to navigate the completion list (define-key company-active-map (kbd "C-p") #'company-select-previous) (define-key company-active-map (kbd "C-n") #'company-select-next) ;; Restore normal tab behavior outside company-mode completions (define-key company-mode-map (kbd "TAB") #'indent-for-tab-command) (define-key company-mode-map (kbd "") #'indent-for-tab-command) ;; Disable Autocomplete (setq company-idle-delay 0) ;; Disable Case Sensitivity (setq completion-ignore-case t) ;; Bind M-/ to company-complete (define-key global-map (kbd "M-/") 'company-complete) (define-key global-map (kbd "M-?") 'dabbrev-expand) :hook (prog-mode . company-mode)) (use-package company-quickhelp :config (company-quickhelp-mode 1) (setq company-quickhelp-delay 0.5) (setq company-quickhelp-color-background (face-attribute 'company-tooltip :background)) (add-hook 'enable-theme-functions (lambda (_) (setq company-quickhelp-color-background (face-attribute 'company-tooltip :background))))) #+end_src ** Cape Add non-lsp completions to the capf. #+begin_src emacs-lisp (use-package cape :ensure t :config (keymap-global-set "C-c c" 'cape-prefix-map) (setq dabbrev-case-fold-search t) ;;(add-hook 'completion-at-point-functions #'cape-dabbrev) ;; TODO: Check if this is slowing down comments? (add-hook 'completion-at-point-functions #'cape-file) (add-hook 'completion-at-point-functions #'cape-elisp-block) (add-hook 'completion-at-point-functions #'yasnippet-capf)) #+end_src ** Utilities *** Flycheck Syntax checking for Emacs. #+begin_src emacs-lisp (use-package flycheck :defer t :init (global-flycheck-mode 1) :config (setq-default flycheck-disabled-checkers '(emacs-lisp-checkdoc)) (setq-default flycheck-cppcheck-args "--enable=all") (flycheck-add-next-checker 'c/c++-gcc 'c/c++-cppcheck 'append) (setq flycheck-indication-mode nil) (set-face-attribute 'flycheck-warning nil :underline nil)) ;; Disable Warning Underline (NOT WORKING) #+end_src * User Interface ** Add Nerd Icons Use Icons from Nerd Font to add a little modern spice to Emacs. #+begin_src emacs-lisp (use-package nerd-icons :if (display-graphic-p)) (use-package nerd-icons-dired :hook (dired-mode . nerd-icons-dired-mode)) (use-package nerd-icons-ivy-rich :init (nerd-icons-ivy-rich-mode 1)) (setq welcome-dashboard-use-nerd-icons t) #+end_src ** Fonts *** Set Font Set font for both Monospace and Proportional text. #+begin_src emacs-lisp (defvar fontconf '((font . "Aporetic Sans Mono") (size . 13))) (set-face-attribute 'variable-pitch nil :font (cdr (assoc 'font fontconf)) :height (* (cdr (assoc 'size fontconf)) 10) :weight 'regular) (set-face-attribute 'fixed-pitch nil :font (cdr (assoc 'font fontconf)) :height (* (cdr (assoc 'size fontconf)) 10) :weight 'regular) (set-face-attribute 'default nil :font (cdr (assoc 'font fontconf)) :height (* (cdr (assoc 'size fontconf)) 10) :weight 'regular) (add-to-list 'default-frame-alist `(font . ,(concat (cdr (assoc 'font fontconf)) "-" (number-to-string (cdr (assoc 'size fontconf)))))) (set-face-attribute 'font-lock-comment-face nil :slant 'italic) (set-face-attribute 'font-lock-keyword-face nil :slant 'italic) ;;(set-frame-font "-misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1" t t) #+end_src *** Ligatures Make ligature symbols out of common function symbols. #+begin_src emacs-lisp (dolist (char/ligature-re `((?- . ,(rx (or (or "-->" "-<<" "->>" "-|" "-~" "-<" "->") (+ "-")))) (?/ . ,(rx (or (or "/==" "/=" "/>" "/**" "/*") (+ "/")))) (?* . ,(rx (or (or "*>" "*/") (+ "*")))) (?< . ,(rx (or (or "<<=" "<<-" "<|||" "<==>" "