Notice: This page is duel licensed CC-BY-SA 4.0 and the GPLv3.
Raw files available at https://git.sr.ht/~taingram/emacs-init
GNU Emacs is a free (as in freedom) text editor for writing and code. You can read more about Emacs and it's history on Wikipedia.
If you are interested in learning Emacs check out the guided tour and the internal Emacs Tutorial (from within Emacs type Ctrl + h then type t). In addition, if you are interested in using Emacs for general writing (not programming) check out Org-mode, its great!
1. Why use GNU Emacs?
As a professional email writer (lol), amateur blogger, and programmer my primary input/output to the computer is through text. Emacs provides me with a solid text editor that has some standout features:
- Extensibility — a complete programming interface for enhancing my own user experience and automating repetitive tasks.
- Portable — a portable environment that works on all major operating systems. (Not all of us have the luxury of using GNU/Linux at work)
- Universal Interface — a universal text based interface for all tasks involving text. In addition, it's a consistent and distraction free interface all tasks.
- Community — Great community developing high quality packages. (magit, org-mode, eshell, etc.)
- Free Software — The ability to access and modify all the source code of Emacs allows for complete customization. The source code also provides an excellent resource for those wishing to learn Lisp, programming, and programming language development1. This factor combined with a rich history and an enthusiastic community ensure that Emacs will not disappear any time soon.
1.1. Emacs Lisp
One aside on Emacs Lisp, which is often disparaged as the worst surviving Lisp dialect. I will not argue that point directly, but I will posit that Emacs Lisp is a more than capable Lisp and very pleasant work in.
The surprising strength of Emacs Lisp is well captured in this excerpt from the Emacs calculator (calc) manual:
I chose Emacs Lisp, a) because I had always been curious about it and b) because, being only a text editor extension language after all, Emacs Lisp would surely reach its limits long before the project got too far out of hand.
To make a long story short, Emacs Lisp turned out to be a distressingly solid implementation of Lisp, and the humble task of calculating turned out to be more open-ended than one might have expected.
1.2. Shortcomings
A minor problem is the limited support for concurrency which causes some actions complete slowly or lock-up Emacs. However, I rarely find this causes significant annoyances. In most situations computationally intensive actions can be handed off to a separate Emacs process (see info:elisp#Processes) or a separate program entirely (e.g. using isync to retrieve mail).
Beyond technical limitations my main issue with Emacs is I cannot use it all the time. With the huge investment I've made on my computer it would be wonderful to have the power of Emacs in a smartphone type package. However, touchscreen displays do not translate well to the Emacs workflow. I continue to yearn for an ideal Emacs PDA.
1.3. Thoughts from other Emacs Users
I've found both these video essays by Protesilaos Stavrou to be a great summary of the thought process involved for why someone would want to use Emacs:
2. Using a Literate Configuration wih Org Mode
My Emacs configuration file is written in a literate programming-like style which allows for prose to be mixed with source code blocks. From that the relevant source blocks are extracted and copied to my Emacs configuration file.
I've held out for many years creating a literate config, but seeing other users' success has convinced me. The ability to maintain complete notes, links, and the configuration code all in one file is extremely convenient. In addition, the hierarchical structure of Org allows for a clearer organization of the code.
2.1. Setup
I have one org file init.org
where I combine all of my Emacs configuration
code with prose notes about it. That org file can be placed anywhere on my
system because it is not the actual initialization file used by Emacs. From
the org file my actual init.el
is exported (tangled) from the elisp source
blocks. In literate programming terms, the org file is where coded and
prose is woven together, then code is tangled out to just elisp that can be
evaluated by Emacs. That means using a literate config imposes no startup
or runtime performance penalty.
Adding the following to your org file will copy (tangle) the code
blocks into your init.el
file when you run org-babel-tangle
(C-c
C-v t).
#+PROPERTY: header-args :results silent :tangle "~/.config/emacs/init.el"
To exclude specific source blocks from being tangled add :tangle no
to the header.
I use the package org-auto-tangle (available on NonGNU ELPA) to automatically tangle the file on save. This can be enabled by adding the following to the org file.
#+AUTO_TANGLE: t
3. Emacs Boilerplate Setup
3.1. Early Init
Using an early-init.el
file can speed up Emacs startup, by avoiding loading
unnecessary UI elements. Below is my complete early-init.el
:
;;; early-init.el --- Early initialization -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: ;; Disable GUI (tool-bar-mode -1) (setq use-dialog-box t) (setq use-file-dialog nil) (setq-default frame-title-format '("%b - GNU Emacs")) ;; Hide the startup screen (setq inhibit-startup-screen t) ;; Increase font size (set-face-attribute 'default nil :height 130) ;; Disable bell sound. (setq ring-bell-function 'ignore) ;;; early-init.el ends here
3.2. Prefer UTF-8
(prefer-coding-system 'utf-8)
3.3. Customize
Emacs has its own customization functionality which can be useful for
experimenting and finding new Emacs options. Normally these settings
are appended to the end of the user's init file, setting
custom-variable
will save it there.
(setq custom-file (concat user-emacs-directory "customizations.el"))
Some prefer not to use this functionality as they prefer to code elisp themselves, but even if you do not use the customization interface loading it is still useful for setting safe file variables and themes.
(load custom-file 't)
3.4. Optimizations and elisp loading
Prefer newest elisp files
(setq load-prefer-newer t)
Increase the max amount allowed to be read from a process into Emacs.
(setq read-process-output-max (* 1024 1024))
Automatically remove compiled files not needed by current Emacs version.
(setq native-compile-prune-cache t)
3.5. Package Repositories
In 2025, most popular Emacs packages can be installed from the default Emacs Lisp Package Archives GNU ELPA and NonGNU ELPA. Both repositories contain only Free Software, but NonGNU packages do not have their copyright assigned to FSF and cannot be included in mainline Emacs for legal reasons.
These archives are well vetted and can be relatively assumed to be safe and secure.
3.6. use-package
Included with Emacs 29.1 use-package provides an easy way to configure Emacs packages and delay their loading so it does not negatively impact your loading time.
3.6.1. VC Install
The :vc keyword has been added to Emacs 30 which should make it easier to add packages outside the default archives. This is probably safer than using MELPA since you have to explicitly acknowledge you are installing an external package and verifying the repository source.
3.6.2. Hide minor modes in the mode-line
Delight is very similar to diminish.el, both are supported by
use-package
, but delight is included in GNU ELPA.
(use-package delight :ensure t)
3.7. Useful functions
(defun my/file-to-string (filename) "Convert contents of file FILENAME to a string." (string-trim (with-temp-buffer (insert-file-contents filename) (buffer-string))))
Swapping between light and dark themes is now built in with modus-themes-toggle. This function may be useful if I switch to a different theme.
;; TODO: Could make more flexible with a variable pair for light and ;; dark themes. Override default pairs with a user defined global ;; light/dark themes. I'd also like to automate with sunrise/sunset. ;; (defun my/toggle-light-dark-theme () ;; (interactive) ;; (cond ;; ((custom-theme-enabled-p 'modus-operandi) ;; (progn ;; (disable-theme 'modus-operandi) ;; (load-theme 'modus-vivendi))) ;; ((custom-theme-enabled-p 'modus-vivendi) ;; (progn ;; (disable-theme 'modus-vivendi) ;; (load-theme 'modus-operandi))) ;; ((message "Unknown theme"))) ;; (shell-command "change-theme"))
4. General usage
These are settings that improve overall Emacs usage.
4.1. Startup Screen
Trying out org-agenda as my login see that section below.
4.2. Mouse and Scrolling
Emacs 29 with pure GTK added a very smooth pixel scrolling feature (what you are used to when scrolling on your touchscreen phone etc.). I wasn't sure if I would like this, but when casually using the touchpad it makes the scrolling much easier to follow. Great for skimming through large text files.
(when (version<= emacs-version "29") (pixel-scroll-precision-mode))
4.3. Modeline formatting
Improve buffer naming convention when a buffer with a duplicate named buffer is opened.
(require 'uniquify) (setq uniquify-buffer-name-style 'forward)
4.4. Global Keybindings
(global-set-key (kbd "C-x m") 'man)
4.4.1. Unbind keys
Don't hide the frame
(global-set-key (kbd "C-z") nil) (global-set-key (kbd "C-x C-z") nil)
4.5. Keybinding reminders
When using Emacs there is always the problem of keeping track of the many keybindings used across multiple modes. One solution I recommend is keeping consistent bindings across modes as possible (many mode already attempt this to varying levels).
When it comes to remembering fringe keybindings that are useful to have, but inconsistent
. I have never quite been happy with which-key as I find the pop-ups overwhelming. Despite that, I do forget keybinding all the time.
(use-package which-key :ensure t :init (setq which-key-idle-delay 3) :config (which-key-mode))
4.6. Bookmarks
Emacs bookmarks are accessed from in the register keycords C-x r
- C-x r l
- open bookmarks list
- C-x r b
- switch buffer to bookmark
- C-x r m
- save bookmark
(setq bookmark-sort-flag 'last-modified)
4.7. Managing buffers
ibuffer is an included package that provides a number of improvements over the standard buffer-menu functions.
(use-package ibuffer :bind (("C-x C-b" . ibuffer)) :init (add-hook 'ibuffer-mode-hook #'hl-line-mode))
4.8. Windows Placement WIP
This is discussed in detail in the Emacs Manual Window Choice and in the Elisp Manual Displaying Buffers.
I don't feel like I fully comprehend how to use this. Basically I am frustrated with how randomly placed some new windows are (Help, Org Src, etc.) and I'd like those to appear more consistently.
;; (setq display-buffer-alist ;; `(("\\`\\*Async Shell Command\\*\\'" ;; (display-buffer-no-window)) ;; ("\\*Shortdoc .*\\*" ;; (display-buffer-reuse-window display-buffer-in-side-window)) ;; ("\\*Help\\*" ;; display-buffer-pop-up-window ;; (inhibit-same-window . t)) ;; ("\\*Org Src .*\\*" ;; display-buffer-below-selected)))
4.9. Remember History
Track recently opened files.
(require 'recentf) (recentf-mode 1)
Track minibuffer history.
(savehist-mode 1)
4.10. Mini Buffer Enhancements and Completion
4.10.1. Richer Information in Mini Buffer
Marginalia adds additional rich text to the completion sections in the mini buffer (M-x run commands, C-x b switch buffer, C-h f describe function, etc.)
(use-package marginalia :ensure t :init (marginalia-mode))
4.10.2. Vertico
Trying out vertico. I need to read through the documentation to better understand what it improves over the built in icomplete framework.
(use-package vertico :ensure t :init (vertico-mode) :config (setq vertico-resize t) (vertico-reverse-mode)) ;; Emacs 28: Hide commands in M-x which do not work in the current mode. ;; Vertico commands are hidden in normal buffers. (when (version<= "28" emacs-version) (setq read-extended-command-predicate #'command-completion-default-include-p))
4.10.3. Orderless
Match completions regardless of order input. Extremely helpful if you do not entirely remember the order of a command or file name. E.g. is it package-install or install-package entering package install will return the correct result either way.
(use-package orderless :ensure t :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles basic partial-completion)))))
4.11. Dired
Dired is the built in Emacs directory viewer (dir-ectory ed-itor), like a file explorer. I find Dired one of the more confusing Emacs tools.
(setq dired-listing-switches "-l --group-directories-first") (add-hook 'dired-mode-hook #'dired-hide-details-mode)
Allow using 'a' key in dired, this will open the next file/directory and kill the previous Dired buffer. Helpful to avoid creating a bunch of unneeded buffers.
(put 'dired-find-alternate-file 'disabled nil)
4.11.1. Delete to Trash
(setq delete-by-moving-to-trash t)
4.11.2. Open Certain File Types in External Applications
Currently using dired-open from the dired-hacks project. I think long term I'd like to improve on this solution. I really feel like dired should have this functionality built in.
(use-package dired-open :custom (dired-open-extensions '(("mkv" . "mpv") ("mp4" . "mpv") ("blend" . "blender") ("blend1" . "blender"))) :bind (:map dired-mode-map ("<mouse-2>" . dired-open-file)))
- Possible other solutions: https://git.sr.ht/~protesilaos/mandoura
4.12. Read only file View
Enables view mode in all read-only files
(setq view-read-only t)
4.13. Passwords
Currently I've found pass to be a really easy way to manage passwords. You can access those passwords automatically through auth-source.
(require 'auth-source) (auth-source-pass-enable)
If you need to access FTP servers over TRAMP then you should know it cannot retrieve passwords via auth-sources, see tramp#Password handling. You must use a netrc file instead and specify that to ange-ftp:
(customize-set-variable 'ange-ftp-netrc-filename "~/.authinfo.gpg")
4.14. Email
(setq user-full-name "Thomas Ingram" user-mail-address "thomas@taingram.org")
Configuration for sending emails over SMTP.
(require 'smtpmail) (setq smtpmail-default-smtp-server "smtp.fastmail.com") (setq smtpmail-smtp-server "smtp.fastmail.com") (setq smtpmail-stream-type 'ssl) (setq smtpmail-smtp-service 465) (setq send-mail-function 'smtp-send-it) (setq message-send-mail-function 'smtpmail-send-it) (setq message-signature "Thomas Ingram\nhttps://taingram.org/")
4.14.1. Mu4e
I manually build the latest version of mu4e and this is where it get installed.
(use-package mu4e :init (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e") :config (set-variable 'read-mail-command 'mu4e) :custom (mu4e-sent-folder "/Sent") (mu4e-refile-folder "/Archive") (mu4e-drafts-folder "/Drafts") (mu4e-trash-folder "/Trash") (mu4e-get-mail-command "mbsync -a") ;; Prevent mbsync "Maildir error: duplicate UID" (mu4e-change-filenames-when-moving t) (mu4e-use-fancy-chars t) (mail-user-agent 'mu4e-user-agent))
4.15. Remote file editing
Don't check for version control over tramp, this slows down tramp.
(setq vc-ignore-dir-regexp (format "\\(%s\\)\\|\\(%s\\)" vc-ignore-dir-regexp tramp-file-name-regexp))
4.16. Terminal
(global-set-key (kbd "C-x t") 'shell)
Compilation in shell
(add-hook 'shell-mode-hook 'compilation-shell-minor-mode)
4.17. Calendar and Diary
(use-package calendar :config (setq calendar-week-start-date 1) ; Monday (setq calendar-date-style 'iso) (setq calendar-view-diary-initially-flag t) (setq calendar-mark-holidays-flag t) (setq calendar-mark-diary-entries-flag t) (setq calendar-holidays '((holiday-fixed 1 1 "New Year's Day") (holiday-float 1 1 3 "Martin Luther King Day") (holiday-fixed 2 14 "Valentine's Day") (holiday-fixed 3 17 "St. Patrick's Day") (holiday-float 5 0 2 "Mother's Day") (holiday-float 5 1 -1 "Memorial Day") (holiday-float 6 0 3 "Father's Day") (holiday-fixed 7 4 "Independence Day") (holiday-float 9 1 1 "Labor Day") (holiday-fixed 10 31 "Halloween") (holiday-float 11 4 4 "Thanksgiving") (holiday-easter-etc) (holiday-fixed 12 25 "Christmas") (solar-equinoxes-solstices) (holiday-sexp calendar-daylight-savings-starts (format "Daylight Saving Time Begins %s" (solar-time-string (/ calendar-daylight-savings-starts-time (float 60)) calendar-standard-time-zone-name))) (holiday-sexp calendar-daylight-savings-ends (format "Daylight Saving Time Ends %s" (solar-time-string (/ calendar-daylight-savings-ends-time (float 60)) calendar-daylight-time-zone-name))))) (setq diary-date-forms diary-iso-date-forms) (defalias 'diary-birthday #'diary-anniversary))
4.18. Git
Magit provides an enhanced git interface over the built in vc-mode.
(use-package magit :ensure t :bind ("C-x g" . magit))
5. Editing Text
Configuration and packages that are useful wherever text is edited inside Emacs.
5.1. Delete trailing whitespace
(add-hook 'before-save-hook #'delete-trailing-whitespace)
5.2. Allow overwriting of selected text
(require 'delsel) (delete-selection-mode 1)
5.3. Improve handling long lines
so-long-mode
is a new mode in 27.1 that trys to improve Emacs's longstanding
issues with handling long lines.
(when (version< "27" emacs-version) (global-so-long-mode t))
5.4. Spell Checking
Emacs does not provide internal spellchecking but relies on external programs. The two most popular options are:
Aspell is generally faster and returns more results for English. Hunspell provides better spellchecking for other languages and is more widely used in other software (e.g. LibreOffice, Firefox, Google Chrome, and MacOS). On GNU/Linux either of these should be available from your distros package manager (or likely installed already).
Within Emacs there are two main ways to invoke the spellchecker invoke ispell
manually check a buffer or region for spelling errors, or enable flyspell-mode
to do so automatically like a word processor.
Enable flyspell globally in all text and programming modes:
(add-hook 'text-mode-hook #'flyspell-mode) (add-hook 'prog-mode-hook #'flyspell-prog-mode)
flyspell-prog-mode will only check spelling in comments and strings.
5.4.1. MS Windows
Aspell has not released a version for Windows since 2002, and in my experience I've found Hunspell to be easier.
- Download Hunspell from ezwinports maintained by Eli Zaretskii
- Extract the hunspell folder and put it wherever you'd like.
Add the following to your init file:
;; Set to wherever you put the hunspell folder (add-to-list 'exec-path "C:/hunspell/bin/") (setq ispell-program-name (locate-file "hunspell" exec-path exec-suffixes 'file-executable-p))
After that you should be all set to use spellchecking in Emacs
For further instructions see this guide by djc on the help-gnu-emacs@gnu.org mailing list. The guide contains some additional steps on setting up multiple dictionaries which is of no use to me as a stereotypical monolingual American.
5.5. Word Wrap
Disable fill-paragraph
when visual-line-mode
enabled (I have a habit of using it
without thinking).
(define-key visual-line-mode-map [remap fill-paragraph] 'ignore)
5.5.1. Wrap at fill column
This package visually warps likes at the fill-column, so it looks like they are wrapped at a reasonable length. Nice on occasion, but not great for writing in Org because SRC blocks also get wrapped.
(use-package visual-fill-column :ensure t)
5.6. TODO Electric Pair
5.7. Abbreviations
abbrev-mode is a built in minor mode that provides a convent way to expand abbreviations as you are writing. Abbreviations are expanded when a space or punctuation is typed after completing a word. For example you could have gv expand into government.
gv → government
Abbreviations can also preserve capitalization in useful ways:
Gv → Government
GV → GOVERNMENT
Capitalization works differently if your abbreviation expands to multiple words:
Gdp → Gross domestic product
GDP → Gross Domestic Product
By default abbrev commands can be accessed through C-x a
- C-x a g take a word and define a global abbreviation for it.
- C-x a l take a word and define a local (mode specific) abbreviation.
- C-x a i g define the word at point as a global abbreviation and then expand it.
- C-x a i l sames as above for a mode specific abbreviation.
Additional useful functions:
define-global-abbrev
- define both the abbreviation and expansion without pulling from the buffer.
define-mode-abbrev
- same as above for mode specific abbrev.
list-abbrevs
- List all defined abbrevs. Can edit these directly and reload with C-c C-c.
edit-abbrevs
- Functionally same as
list-abbrevs
but jumps you to mode specific definitions.
Abbreviations are automatically expanded when adding a space or punctuation. They can be manually expanded with C-x a e (this works even in buffers without abbrev-mode enabled).
Expansions can be escaped by typing C-q before typing your space/punctuation. Typing "G D P C-q ," would result in: GDP,
Alternatively if you need to prefix or suffix an abbrev you can note the end of the prefix and the start off the suffix with M-'
anit (M-') gv (M-') ental → antigovernmentental
Abbrev can automatically remind you when you forget to use
abbreviations by enabling abbrev-suggest
. You can get a summary of
how often abbrev-suggest
is showing with the
abbrev-suggest-show-report
command.
(setq abbrev-suggest 't) (setq abbrev-suggest-hint-threshold 1)
By default Emacs prompts you to save the abbrev file before closing,
this can be done automatically in the background by setting
save-abbrevs
(setq save-abbrevs 'silently)
Enable abbrev-mode in the modes you wish to use it:
(add-hook 'org-mode-hook #'abbrev-mode)
5.7.1. TODO Look into Dynamic Abbreviation
5.8. Languages
5.8.1. French
French postfix
5.8.2. Japanese 日本語
Occasionally I need to type Japanese to reference to video games, wood block printing, stationary, or Japanese carpentry. Emacs provides a lot of great functionality for writing Japanese (日本語). See: Using Emacs and org-mode with Japanese Text (archive)
- Kanji-mode
Kanji-mode is a really cool little package that gives you:
- Stroke order (M-s M-o)
- Kanji to hiragana (M-s M-h) or romanji (M-s M-h)
6. Programming
(use-package prog-mode :hook ((prog-mode . show-paren-mode)))
New feature Emacs 28.
(setq next-error-message-highlight 't)
6.1. Programming IDE-like features
6.1.1. Expand and collapse functions
Disabling this for now I do not currently use it and there are other options in Emacs to explore.
Hideshow is a minor mode for hiding and showing contents of functions and comment blocks.
;; (setq hs-hide-comments-when-hiding-all nil) ;; (setq hs-isearch-open t) ;; Backtab is equivalent to shift+tab ;; (define-key hs-minor-mode-map (kbd "<backtab>") 'hs-toggle-hiding) ;; (add-hook 'prog-mode-hook #'hs-minor-mode)
- TODO Replace with outline-mode
Stefan Monnier's talk at Emacs Conf convinced me to try using outline-mode instead of hideshow.
6.1.2. Snippets
(use-package yasnippet :ensure t :hook ((prog-mode) . yas-minor-mode) :config (yas-reload-all) (setq yas-snippet-dirs (concat user-emacs-directory "snippets/")))
6.1.3. Drop down auto-completion support
I am trying to replace company-mode with corfu. Daniel Mendler's packages have been extremely impressive, although the small packages can be a bit overwhelming when you are initially getting started.
(use-package corfu :ensure t ;; Optional customizations ;; :custom ;; (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match ;; (corfu-preview-current nil) ;; Disable current candidate preview ;; (corfu-preselect 'prompt) ;; Preselect the prompt ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches :hook ((prog-mode . corfu-mode) (shell-mode . corfu-mode) (eshell-mode . corfu-mode)) ;; Recommended: Enable Corfu globally. This is recommended since Dabbrev can ;; be used globally (M-/). See also the customization variable ;; `global-corfu-modes' to exclude certain modes. ;; :init ;; (global-corfu-mode) )
6.1.4. Language Server Protocol (LSP)
LSP is a recently developed standard communication protocol that allows development tools (code completion, documentation retrieval on hover, lookup definition, and linting/diagnostics). The protocol was originally developed by Microsoft for their Visual Studio Code editor.
There are two competing Emacs plugins
While lsp-mode has a larger development community and is more feature rich, eglot is simpler and included in GNU ELPA.
(use-package eglot :ensure t)
6.2. Emacs Lisp
(use-package paredit :ensure t :hook ((emacs-lisp-mode lisp-mode scheme-mode) . paredit-mode))
(use-package emacs-lisp-mode :bind (:map emacs-lisp-mode-map ("C-c C-r" . eval-region) ("C-c C-d" . eval-defun) ("C-c C-b" . eval-buffer)) :hook ((emacs-lisp-mode . flymake-mode)))
6.3. Shell
(add-hook 'sh-mode-hook 'flymake-mode)
6.4. C
(use-package c-mode :bind (:map c-mode-map ("C-c c" . compile) ("C-c C-c" . recompile) ("C-c g" . gdb) ("C-c C-r" . gdb-run)) :hook ((c-mode . electric-pair-mode) (c-mode . flymake-mode)) :config (setq c-block-comment-prefix "* "))
6.5. Go
Note that go-mode is an external package.
(use-package go-mode :ensure t :bind (:map go-mode-map ("C-c RET" . compile) ("C-c c" . compile) ("C-c C-c" . recompile) ("C-c d" . godoc) ("C-c f" . gofmt) ("C-c g" . gdb) ("C-c C-g" . gdb-run)) :config (defun my/go-mode-set-local () (set (make-local-variable 'compile-command) "go build -v ")) ;; Disables links to the web documentation (setq-default eglot-workspace-configuration '((:gopls . ((linksInHover . :json-false))))) :hook ((go-mode . my/go-mode-set-local) (go-mode . subword-mode) (go-mode . electric-pair-mode) (before-save . gofmt-before-save)))
6.6. Godot and GDScript
Been learning game development and excited to see Free Software tools have matured so much. Godot seems like a very powerful and well developed ecosystem.
(use-package gd-script-mode :vc (:url "https://github.com/godotengine/emacs-gdscript-mode.git" :rev :newest) :hook ((gdscript-mode . eglot-ensure) (gdscript-mode . auto-revert-mode)) ;; :init ;; (add-to-list project-vc-extra-root-markers "project.godot") :config (setq gdscript-godot-executable "/home/tom/bin/godot4") (setq gdscript-docs-local-path "/home/tom/Documents/godot4.3-docs"))
Note I specifically am disabling company-mode
because it causes
stuttering due to issue #128. Manual completions can be triggered at
point with C-M-i.
7. Writing Modes
7.1. Org mode
(use-package org :bind (("C-x c" . org-capture)) :hook ((org-mode . auto-fill-mode)) :config ;; Org src evaluation langauges (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (shell . t) (latex . t))) (require 'org-protocol) ;; Templates (e.g. <s expands to #+begin_src) (require 'org-tempo) (tempo-define-template "my-tempo-template-org-elisp-src" '("#+begin_src emacs-lisp" n p n "#+end_src" n) "<el" "Insert an Emacs Lisp source code block template") ;; Font style tweaks (set-face-attribute 'org-priority nil :inherit '(font-lock-comment-face default) :weight 'normal) (set-face-attribute 'org-ellipsis nil :inherit '(font-lock-comment-face default) :weight 'normal) ;; Extend line around source bocks (set-face-attribute 'org-block-begin-line nil :extend t) (set-face-attribute 'org-block-end-line nil :extend t) :custom ;; Visuals (org-ellipsis "⤵") (org-hide-leading-stars t) ;; (org-startup-indented t) ;; (org-adapt-indentation 'headline-data) (org-hide-emphasis-markers nil) ;; Push M-RET to bottom of section, except when inserting new list items (org-M-RET-may-split-line '((headline . nil) (item . t) (table . nil))) ;; These settings make C-c C-j org-goto much quicker when using a ;; completion package like vertico. (org-goto-interface 'outline-path-completion) (org-outline-path-complete-in-steps nil) (org-src-window-setup 'current-window) ;; Prevent org-capture from creating unnecessary bookmarks (org-bookmark-names-plist '(:last-capture "org-capture-last-stored")) (org-capture-templates `(("t" "Todo" entry (file+headline "~/todo.org" "General Goals and Tasks") "* TODO %^{TODO}\n%u\n\n%a%?") ("e" "Emacs Tweaks" entry (file+headline "~/todo.org" "Emacs Configuring") "* TODO %^{Emacs TODO}\n%u\n%?") ("w" "Writing Idea" entry (file+headline "~/Documents/taingram.org/todo.org" "Blogging") "* IDEA %^{Writing Idea}\n%u\n") ("g" "Game Idea" entry (file+headline "~/todo.org" "Game Development") "* IDEA %^{Game Idea}\n%u\n") ("j" "Journal" entry (file+headline "~/Documents/me.org" ,(substring (current-time-string) -4 nil)) "* %u %^{Entry title}\n %?\n") ("l" "Interesting Links" entry (file "~/Documents/taingram.org/org/interesting-links.org") "* %l\n%u" :prepend t) ;; Trying to get org-protocol to work (org capture) ("p" "Protocol" entry (file+headline ,(concat org-directory "notes.org") "Inbox") "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?") ("L" "Protocol Link" entry (file+headline ,(concat org-directory "notes.org") "Inbox") "* %? [[%:link][%:description]] \nCaptured On: %U"))) :config (add-hook 'org-mode-hook (lambda () (setq-local electric-pair-inhibit-predicate (lambda (c) (char-equal c ?\<))))))
7.1.1. Org Agenda
Org-agenda is really just an alternative way to view and manage all your org TODO tasks. It is definitely a little messy to setup if you want to customize it, but the functionality is all there and built-in.
I am trying to use it to manage ongoing projects so I don't loose track of what I'm currently working. I can easily distracted. This is also to encourage me to consolidate the and many paper notes I have into one place if the task cannot be finished immediately.
The org-agenda-prefix-format and org-agenda-prefix-format allow you customize how the org-agenda-todo-list is displayed.
(use-package org-agenda :bind (("C-x C-a" . org-agenda) :map org-agenda-mode-map ("o" . org-agenda-open-link) ("C-<return>" . org-agenda-tree-to-indirect-buffer)) :init (org-agenda nil "h") :custom ;; Org agenda setup (org-agenda-files '("~/todo.org" "~/Documents/taingram.org/todo.org")) (org-agenda-include-diary t) (org-agenda-todo-list-sublevels nil) ;; Hide TODO/DONE from agenda views ;; (org-agenda-todo-keyword-format "") (org-agenda-custom-commands '(("h" "General Hobby Tasks" ((agenda "" ((org-agenda-span 1))) (todo "PROG" ((org-agenda-overriding-header "Tasks In Progress: PROG"))) (tags-todo "-PROJECT-IDEA+TODO=\"TODO\"|+LEVEL=2+PROJECT+TODO=\"TODO\"" ((org-agenda-overriding-header "Other Tasks: TODO")))) ((org-agenda-prefix-format " ") (org-agenda-sorting-strategy '(priority-down tag-up)))) ("i" "Project and Writing Ideas" ((tags-todo "-DREAM+TODO=\"IDEA\"" ((org-agenda-overriding-header "Project Ideas: IDEA"))) (tags-todo "+DREAM+TODO=\"IDEA\"" ((org-agenda-overriding-header "Dream Project Ideas:")))) ((org-agenda-prefix-format " "))))))
7.1.2. Auto Tangle
This is useful for to avoid forgetting to tangle my init.org
file.
(use-package org-auto-tangle :ensure t :delight :config (add-hook 'org-mode-hook 'org-auto-tangle-mode))
7.1.3. Blogging
Load my htmlize
and blog's configuration file. For more information
on blogging with Org-mode see: Building a Emacs Org-Mode Blog
(use-package htmlize :ensure t) (load "~/Documents/taingram.org/publish.el")
7.2. Markdown
I personally am not a huge fan of markdown, org mode's syntax just makes much more sense to me. However it is unavoidable.
(use-package markdown-mode :ensure t)
7.3. LaTeX
Old setup, I haven't used LaTeX since I graduated college and it is unlikely that I'll need to use it any time soon…
(use-package tex :ensure nil ; auctex :mode ("\\.tex\\'" . latex-mode) :config (defun my/latex-compile () "My compile latex function" (interactive) (save-buffer) (TeX-command "LaTeX" 'TeX-master-file)) (setq TeX-command-default 'LaTeX) :bind (:map TeX-mode-map ("C-c _" . "\\textunderscore ")) :hook ((TeX-mode . auto-fill-mode)))
8. See Also
Other interesting literate configuration files that inspired me.
Footnotes:
How Emacs changed my life by Matz Yukihori the creator of Ruby. The talk explains how access to Emacs's source code directly inspired him in the development of Ruby.
Comments
Email comment@taingram.org.