I’m sure I’ll be tweaking it forever though, it’s almost as satisfying as actually using it.
When this configuration is loaded for the first time, the init.el
is
the file that is loaded.
;; This file replaces itself with the actual configuration at first run.
;; Tangle requires org
(require 'org)
;; Open the configuration
(find-file (concat user-emacs-directory "README.org"))
;; tangle init.org
(org-babel-tangle)
;; load init.el
(load-file (concat user-emacs-directory "init.el"))
;; byte-compile init.el
(byte-compile-file (concat user-emacs-directory "init.el"))
Lexical scoping for the init-file is needed, it can be specified in the header. This is the first line of the actual configuration:
;;; -*- lexical-binding: t -*-
Tangle and compile this file on save automatically:
(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 "README.org")))
;; Avoid running hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle)
(byte-compile-file (concat user-emacs-directory "init.el")))))
(add-hook 'after-save-hook 'tangle-init)
Define separate customize
file
(setq custom-file (concat user-emacs-directory ".custom.el"))
(load custom-file t)
(require 'package)
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
(not (gnutls-available-p))))
(proto (if no-ssl "http" "https")))
(add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
(when (< emacs-major-version 24)
;; For important compatibility libraries like cl-lib
(add-to-list 'package-archives '("gnu" . (concat proto "://elpa.gnu.org/packages/")))))
(package-initialize)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
(setq org-startup-folded 'overview)
(setq org-confirm-babel-evaluate nil)
(setq org-edit-src-content-indentation 0)
(setq org-src-window-setup 'current-window)
(setq org-directory "~/Dropbox/org")
(global-set-key (kbd "C-c c") 'org-capture)
(setq org-capture-templates
'(("t"
"TIL"
entry
(file+headline "~/Dropbox/org/til.org" "TIL")
"* %^{TIL} %^g\n%^{Description}\n%T"
:prepend t)
("l"
"Link"
entry
(file+headline "~/Dropbox/org/links.org" "Links")
"* %? %^L %^g\n%T"
:prepend t)
("k"
"Keybinding"
entry
(file "~/Dropbox/org/learn-keybindings.org")
"* =%^{Keybinding}= %^g\n%^{Description}")
("p"
"CP"
entry
(file+datetree "~/Dropbox/org/cp.org")
"**** %^{Link} %^g\n#+BEGIN_SRC cpp\n%?\n#+END_SRC"
:empty-lines 1)))
Use syntax highlighting via Minted
pip install Pygments
tlmgr install minted
(setq org-latex-listings 'minted
org-latex-packages-alist '(("" "minted"))
org-latex-pdf-process
'("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
Break long lines
(setq org-latex-minted-options '(("breaklines" "true")
("breakanywhere" "true")
("linenos")))
Ability to use a
to visit a new directory or file in dired
instead
of using RET
. RET
works just fine, but it will create a new buffer
for every interaction whereas a
reuses the current buffer.
(put 'dired-find-alternate-file 'disabled nil)
Human readable units
(setq-default dired-listing-switches "-alh")
(setq python-shell-interpreter "python3")
(use-package bufler)
(use-package company
:diminish
:config
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 2)
(setq company-selection-wrap-around t)
(setq company-tooltip-align-annotations t)
(global-company-mode t))
(use-package counsel
:config
(setq ivy-wrap t)
:bind (("M-x" . counsel-M-x)
("C-x f" . counsel-find-file)
("C-x b" . counsel-ibuffer)
("M-y" . counsel-yank-pop)))
(use-package swiper
:bind (("C-s" . swiper)
("C-c s" . swiper-thing-at-point)))
(use-package ivy
:diminish
:config
(setq ivy-use-virtual-buffers t)
(setq ivy-use-selectable-prompt t)
(setq ivy-count-format "[%d/%d] ")
(ivy-mode 1))
(use-package diminish)
(use-package expand-region
:bind ("M-=" . er/expand-region))
(use-package eglot
:hook
((c-mode c++-mode) . eglot-ensure)
:config
(add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd-10")))
(use-package evil
:init
(setq evil-mode-line-format '(before . mode-line-front-space))
(setq evil-move-cursor-back nil)
(setq
evil-normal-state-tag (propertize " " 'face '((:background "#ff5555")))
evil-insert-state-tag (propertize " " 'face '((:background "#50fa7b")))
evil-operator-state-tag (propertize " " 'face '((:background "#f8f8f2")))
evil-motion-state-tag (propertize " " 'face '((:background "#ffb86c")))
evil-emacs-state-tag (propertize " " 'face '((:background "#bd98f9")))
evil-visual-state-tag (propertize " " 'face '((:background "#f1fa8c"))))
:config
(evil-mode 1))
(use-package iedit)
(use-package magit
:defer t
:bind ("C-x g" . magit-status))
(use-package markdown-mode
:defer t
:init (setq markdown-command "multimarkdown")
:mode (("README\\.md\\'" . gfm-mode)
("\\.mdx?$\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode)))
(use-package mode-line-bell
:config
(mode-line-bell-mode))
Dependency: prettier
npm i -g prettier
(use-package prettier
:defer t)
(use-package projectile
:config
(projectile-mode)
(setq projectile-completion-system 'ivy)
:bind-keymap
("C-c p" . projectile-command-map))
(use-package counsel-projectile
:config
(counsel-projectile-mode))
(use-package pyvenv)
(use-package rainbow-mode
:defer t)
(use-package try
:defer t)
(use-package undo-tree
:diminish)
(use-package web-mode
:defer t
:mode ("\\.html\\'")
:config
(add-to-list 'web-mode-comment-formats '("javascript" . "//"))
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-code-indent-offset 2)
(setq web-mode-style-padding 0)
(setq web-mode-script-padding 0))
(use-package emmet-mode
:defer t
:diminish
:config
(setq emmet-indentation 2)
(defadvice emmet-preview-accept (after expand-and-fontify activate)
"Update the font-face after an emmet expantion."
(font-lock-flush))
:hook (web-mode css-mode))
(use-package which-key
:diminish which-key-mode
:config
(which-key-mode))
(use-package yasnippet
:diminish yas-minor-mode
:config (yas-global-mode 1))
(use-package yasnippet-snippets)
Set $MANPATH, $PATH and exec-path from shell even when started from
GUI helpers like dmenu
or Spotlight
(unless (package-installed-p 'exec-path-from-shell)
(package-refresh-contents)
(package-install 'exec-path-from-shell))
;; Safeguard, so this only runs on Linux (or MacOS)
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize))
Allow 20MB (instead of 0.76MB) before calling GC
(setq gc-cons-threshold 20000000)
(fset 'yes-or-no-p 'y-or-n-p)
(global-auto-revert-mode t)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(setq ibuffer-saved-filter-groups
'(("files"
("dired" (mode . dired-mode))
("org" (name . "^.*org$"))
("web" (or (mode . web-mode)
(mode . css-mode)))
("js" (mode . rjsx-mode))
("shell" (or (mode . eshell-mode)
(mode . shell-mode)))
("programming" (mode . python-mode))
("emacs" (or
(name . "^\\*scratch\\*$")
(name . "^\\*Compile-Log\\*$")
(name . "^\\*Messages\\*$"))))))
(add-hook 'ibuffer-mode-hook
(lambda ()
(ibuffer-auto-mode 1)
(ibuffer-switch-to-saved-filter-groups "files")))
(setq ibuffer-show-empty-filter-groups nil)
(setq ibuffer-expert t)
utf-8 encoding for all files, resolves \u...
in terminal
(set-charset-priority 'unicode)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(setq inhibit-startup-message t)
(setq initial-scratch-message nil)
(setq initial-major-mode 'org-mode)
Dracula
(use-package dracula-theme
:config (load-theme 'dracula t))
Victor Mono, Inter
(add-to-list 'default-frame-alist '(font . "Iosevka Term Curly 14"))
(set-face-font 'variable-pitch "Inter")
Use emoji in Emacs 27+
(if ( version< "27.0" emacs-version ) ; )
(set-fontset-font t 'symbol "Noto Color Emoji" nil 'prepend)
(warn "This Emacs version is too old to properly support emoji."))
Nicer scrolling behaviour https://zeekat.nl/articles/making-emacs-work-for-me.html
(setq scroll-step 1
scroll-conservatively 100
scroll-preserve-screen-position 1)
(setq mouse-wheel-follow-mouse 't)
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(scroll-bar-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1) ;; still accessible via <f10>
(setq echo-keystrokes 0.1)
(setq line-number-mode t)
(setq column-number-mode t)
(setq display-line-numbers-type 'relative)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(setq split-width-threshold 120)
(show-paren-mode 1)
(electric-pair-mode 1)
(setq make-backup-files nil)
(setq auto-save-default nil)
(setq create-lockfiles nil)
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
(setq sentence-end-double-space nil)
(put 'narrow-to-region 'disabled nil)
Set tab width to 2 spaces
(setq-default tab-width 2
indent-tabs-mode nil)
(setq require-final-newline t)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(delete-selection-mode 1)
(defun my-reload-config()
"Reload init.el"
(interactive)
(load-file user-init-file))
(defun my-create-scratch-buffer nil
"Create a new scratch buffer <*scratch-N*>."
(interactive)
(let ((n 0) bufname)
(while (progn
(setq bufname (concat "*scratch-"
(if (= n 0) "" (int-to-string n)) "*"))
(setq n (1+ n))
(get-buffer bufname)))
(switch-to-buffer (get-buffer-create bufname))
(org-mode)))
(defun my-rename-current-buffer-file ()
"Renames current buffer and file it is visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file" name)
(let ((new-name (read-file-name "New name: " filename)))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(message "File '%s' successfully renamed to '%s'"
name (file-name-nondirectory new-name)))))))
(setq compilation-ask-about-save nil)
(defun my-save-all-and-compile ()
(interactive)
(save-some-buffers 1)
(compile compile-command))
(global-set-key (kbd "<f5>") 'my-save-all-and-compile)