My GNU Emacs configuration file is documented in the form of an Org file which is tangled. This would be continuously changing as I’m exploring Emacs and the vast number of packages available.
Credits:
In order to install packages, it is useful to configure the package sources.
(require 'package)
(setq-default
load-prefer-newer t
package-enable-at-startup nil)
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
(package-initialize)
To be able to manage its configuration with use-package
it is necessary to
first install it, if you don’t already.
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(use-package delight :ensure t)
(use-package use-package-ensure-system-package :ensure t)
If the current buffer is ‘init.org’ the code-blocks are tangled, and the tangled file is compiled.
(defun tangle-init ()
"If the current buffer is 'init.org' the code-blocks are
tangled, and the tangled file is compiled."
(when (equal (buffer-file-name)
(expand-file-name (concat user-emacs-directory "config.org")))
;; Avoid running hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle))))
(add-hook 'after-save-hook 'tangle-init)
Tidying up the UI elements.
(when window-system
(blink-cursor-mode 0) ; Disable the cursor blinking
(scroll-bar-mode 0) ; Disable the scroll bar
(tool-bar-mode 0) ; Disable the tool bar
(tooltip-mode 0)) ; Disable the tooltips
Personal preference for better defaults.
(setq-default
ad-redefinition-action 'accept ; Silence warnings for redefinition
auto-window-vscroll nil ; Lighten vertical scroll
cursor-in-non-selected-windows t ; Hide the cursor in inactive windows
display-time-default-load-average nil ; Don't display load average
display-time-format "%k:%M" ; Format the time string
fill-column 80 ; Set width for automatic line breaks
frame-title-format '("%b - [%f]") ; Set frame title format
help-window-select t ; Focus new help windows when opened
indent-tabs-mode nil ; Stop using tabs to indent
inhibit-startup-screen t ; Disable start-up screen
initial-scratch-message "" ; Empty the initial *scratch* buffer
scroll-conservatively most-positive-fixnum ; Always scroll by one line
scroll-margin 10 ; Add a margin when scrolling vertically
select-enable-clipboard t ; Merge system's and Emacs' clipboard
sentence-end-double-space nil ; End a sentence after a dot and a space
show-paren-delay 0 ; No delay before showing paren pair
show-trailing-whitespace nil ; Display trailing whitespaces
tab-width 4 ; Set width for tabs
use-package-always-ensure t ; Avoid the :ensure keyword for each package
x-stretch-cursor t) ; Stretch cursor to the glyph width
(delete-selection-mode 1) ; Replace region when inserting text
(desktop-save-mode 1) ; Saves desktop position on exit
(display-time-mode 1) ; Enable time in the mode-line
(fset 'yes-or-no-p 'y-or-n-p) ; Replace yes/no prompts with y/n
(global-linum-mode 1) ; Enables global line numbers
(global-subword-mode 1) ; Iterate through CamelCase words
(put 'downcase-region 'disabled nil) ; Enable downcase-region
(put 'upcase-region 'disabled nil) ; Enable upcase-region
(show-paren-mode 1) ; Enable showing paren pair
(cd "~/") ; Move to the user directory
Garbage-collect on focus-out, Emacs should feel snappier.
(add-hook 'focus-out-hook #'garbage-collect)
Currently have no need for backups, hence disabling.
(setq
auto-save-default nil
make-backup-files nil)
One is able to use the customization interface that is bundled within Emacs. It
is meant to help people who are not familiar with Emacs Lisp in the
configuration of Emacs itself. By default, changes in the customization will be
automatically detected and appended at the end of the configuration file,
init.el
.
Since that in my case, the actual configuration file is a new one, crafted by
org-mode
, adding code at the end of init.el
might mess things up. The
following tells Emacs to add extra code in another file that would be then
loaded, if existing.
(setq-default custom-file (expand-file-name ".custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file t))
Configure visibility of major/minor modes in mode line. Use C-h f
to identify
name of the library associated.
(delight '((org-indent-mode nil org-indent)
(auto-revert-mode nil autorevert)
(subword-mode nil subword)))
Declare fonts, and load Nord theme with spaceline.
(set-frame-font "Hack 10")
(set-fontset-font "fontset-default" 'han (font-spec
:family "Source Han Sans HW TC Regular"
:size 15))
(use-package nord-theme
:config
(load-theme 'nord t)
(add-to-list 'custom-theme-load-path (expand-file-name "~/.emacs.d/themes/"))
(setq nord-comment-brightness 20))
(use-package spaceline
:config
(require 'spaceline-config)
(spaceline-spacemacs-theme)
(setq spaceline-minor-modes-separator " "))
Auto-completion at point. Display a small pop-in containing the candidates.
Company is a text completion framework for Emacs. The name stands for “complete anything”. It uses pluggable back-ends and front-ends to retrieve and display completion candidates.
(use-package company
:defer 1
:delight
:config
(global-company-mode 1)
(setq-default
company-idle-delay .2
company-minimum-prefix-length 3
company-require-match nil
company-tooltip-align-annotations t))
Don’t
kill-buffer
,kill-this-buffer
instead.
(defun me/kill-this-buffer ()
"Kill the current buffer."
(interactive)
(kill-buffer (current-buffer)))
(global-set-key (kbd "C-x k") 'me/kill-this-buffer)
Allow undo’s and redo’s with window configurations.
Winner mode is a global minor mode that records the changes in the window configuration (i.e. how the frames are partitioned into windows) so that the changes can be “undone” using the command
winner-undo
. By default this one is bound to the key sequence ctrl-c left. If you change your mind (while undoing), you can press ctrl-c right (callingwinner-redo
).
(use-package winner
:delight
:defer 1
:config (winner-mode 1))
An extensible emacs startup screen showing you what’s most important.
(use-package dashboard
:config
(dashboard-setup-startup-hook)
(setq
dashboard-items '((recents . 5)
(agenda . 5))
dashboard-startup-banner 'logo))
Interactive completion
(use-package helm
:delight
:config
(require 'helm)
(require 'helm-config)
(helm-mode 1)
(helm-autoresize-mode 1)
(setq
helm-follow-mode-persistent t
helm-M-x-fuzzy-match t)
(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "M-y") 'helm-show-kill-ring)
(global-set-key (kbd "C-c h") 'helm-mini)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
(global-set-key (kbd "C-x b") 'helm-buffers-list)
(global-set-key (kbd "C-x C-b") 'helm-buffers-list)
(global-set-key (kbd "C-x c o") 'helm-occur))
For Github version control
(use-package magit)
Sidebar for Emacs leveraging Dired.
(use-package dired-sidebar
:bind (("C-x C-n" . dired-sidebar-toggle-sidebar))
:ensure t
:commands (dired-sidebar-toggle-sidebar)
:init
(add-hook 'dired-sidebar-mode-hook
(lambda ()
(unless (file-remote-p default-directory)
(auto-revert-mode))))
:config
(push 'toggle-window-split dired-sidebar-toggle-hidden-commands)
(push 'rotate-windows dired-sidebar-toggle-hidden-commands)
(setq dired-sidebar-subtree-line-prefix "__")
(setq dired-sidebar-theme 'vscode)
(setq dired-sidebar-use-term-integration t)
(setq dired-sidebar-use-custom-font t))
Separate section to consolidate smaller QoL packages.
Beautify icons
(use-package vscode-icon
:commands (vscode-icon-for-file))
Aids with learning emacs commands
(use-package which-key
:delight
:config
(which-key-mode)
(setq which-key-idle-delay 0.6))
Org related better defaults.
(use-package org
:delight org-mode "Org"
:hook
(org-mode . toc-org-enable)
:config
(setq-default
org-agenda-files (list "~/org" ; Location of org agenda files
"~/org/journal")
org-directory "~/org" ; Location of org files
org-log-done t ; Timestamp tasks done
org-log-into-drawer t ; Record state changes into drawer
org-startup-folded nil ; Expand all headlines on startup
org-startup-indented t ; Indent org headlines
org-support-shift-select t)) ; Allow shift selection with arrows
(setq org-tag-alist ; General Tags
'(("AD-HOC" . ?a)
("FINANCE" . ?$)
("URGENT" . ?u)
("PURCHASE". ?p))
org-todo-keywords ; General TODO keywords
'((sequence
"TODO(t!)"
"STARTED(s)"
"WAITING(w@/!)"
"SOMEDAY(.)"
"|"
"DONE(x!)"
"CANCELLED(c@/!)")))
Shortcuts for org.
(define-key global-map "\C-cc" 'org-capture)
(define-key global-map "\C-ca" 'org-agenda)
(define-key global-map "\C-cl" 'org-store-link)
Automatically updates the table of contents. Add :TOC:
tab to a headline.
(use-package toc-org :after org)
While writing this configuration file in Org mode, I have to write
code blocks all the time. Org has templates, so doing <s TAB
creates
a source code block. Here I create a custom template for emacs-lisp
specifically. So, <el TAB
creates the Emacs lisp code block and puts
the cursor inside.
(setq org-structure-template-alist
'(("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC")
("j" "[[http://jira-project.org/JIRA-?][JIRA-]")))
Quickly open to-do and init files with Esc-Esc-letter.
(global-set-key (kbd "\e\em") (lambda () (interactive) (find-file "~/org/todo.org")))
(global-set-key (kbd "\e\ec") (lambda () (interactive) (find-file "~/.emacs.d/config.org")))
org-journal
maintains a set of files, where each file represents a day.
Convenient bindings allow the creation of journal records in the current daily
file and search within all records or specified time intervals. All records can
be browsed and searched from the Emacs Calendar for convenience.
(use-package org-journal
;;:bind (("C-c t" . journal-file-today)
;; ("C-c y" . journal-file-yesterday))
:custom
(org-journal-dir "~/org/journal/")
(org-journal-file-format "%Y-%m-%d.org")
(org-journal-date-format "%e %b %Y (%A)")
(org-journal-time-format ""))
Define Singapore public holidays.
(setq holiday-general-holidays
'((holiday-fixed 1 1 "New Year's Day")
(holiday-fixed 2 16 "Chinese New Year")
(holiday-fixed 2 17 "Chinese New Year")
(holiday-fixed 3 30 "Good Friday")
(holiday-fixed 5 1 "Labour Day")
(holiday-fixed 5 29 "Vesak Day")
(holiday-fixed 6 15 "Hari Raya Puasa")
(holiday-fixed 8 9 "National Day")
(holiday-fixed 8 22 "Hari Raya Haji")
(holiday-fixed 11 6 "Deepavali")
(holiday-fixed 12 25 "Christmas Day")))
(setq holiday-local-holidays nil
holiday-solar-holidays nil
holiday-bahai-holidays nil
holiday-christian-holidays nil
holiday-hebrew-holidays nil
holiday-islamic-holidays nil
holiday-oriental-holidays nil
holiday-other-holidays nil)
(setq org-agenda-include-diary t)