Skip to content

oakenhold/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emacs Configuration

Table of Contents

Introduction

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:

Initialization

Packages Sources

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)

Prepare Use Package

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)

Re-write init.el on Modification

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)

Bootstrap

Use better defaults

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)

Backup Handling

Currently have no need for backups, hence disabling.

(setq
  auto-save-default nil
  make-backup-files nil)

Load .custom.el

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))

Delighted Settings

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)))

Theme

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 " "))

Features

Auto-Completion

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.

Dmitry Gutov

(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))

Buffers and Windows

Don’t kill-buffer, kill-this-buffer instead.

Pragmatic Emacs

(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 (calling winner-redo).

Ivar Rummelhoff

(use-package winner
  :delight
  :defer 1
  :config (winner-mode 1))

Dashboard

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))

Helm

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))

Magit

For Github version control

(use-package magit)

Sidebar

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))

QoL Packages

Separate section to consolidate smaller QoL packages.

vscode-icon

Beautify icons

(use-package vscode-icon
  :commands (vscode-icon-for-file))

which-key

Aids with learning emacs commands

(use-package which-key
  :delight
  :config
  (which-key-mode)
  (setq which-key-idle-delay 0.6))

Org

Org Configurations

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

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 ""))

Holidays

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)