Some of the biggest new features are:
- Use of lsp-mode for a consistent developer environment across languages.
- Use of straight.el for package management. This has been moved to init.el for early package loading.
- Loading org-mode in the init.el, to prevent version conflicts
(setq vc-follow-symlinks t
frame-resize-pixelwise t
tab-always-indent 'complete
enable-recursive-minibuffers t
read-process-output-max (* 1024 1024)
bookmark-save-flag 1)
A work around for copying & pasting in WSL.
(defun wsl-copy (start end)
(interactive "r")
(shell-command-on-region start end "clip.exe")
(deactivate-mark))
(defun wsl-paste ()
(interactive)
(let ((clipboard
(shell-command-to-string "powershell.exe -command 'Get-Clipboard' 2> /dev/null")))
(setq clipboard (replace-regexp-in-string "\r" "" clipboard)) ; Remove Windows ^M characters
(setq clipboard (substring clipboard 0 -1)) ; Remove newline added by Powershell
(insert clipboard)))
`exec-path-from-shell` uses Bash to set MANPATH, PATH, and exec-path from those defined in the user’s shell config. This won’t work on Windows.
(use-package exec-path-from-shell
:if (memq window-system '(mac ns x))
:config
(setq exec-path-from-shell-variables '("PATH" "MANPATH" "SHELL")
exec-path-from-shell-check-startup-files nil)
(exec-path-from-shell-initialize))
(cd "~")
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
'(safe-local-variable-values '((eval add-hook 'after-save-hook 'org-babel-tangle 0 t)))
`which-key` makes keybindings discoverable.
(use-package which-key
:config
(which-key-mode))
Store backups and autosaves in a centralised place.
(make-directory (expand-file-name "~/.emacs.d/autosaves") t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/autosaves/" t)))
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
A function to reload my init file. It reloads the major mode after the init file is loaded to rebind keymappings.
(defun reload-init-file ()
(interactive)
(load-file "~/.emacs.d/README.el")
(funcall major-mode))
And another one to edit it:
(defun find-init-file ()
(interactive)
(find-file "~/.emacs.d/README.org"))
(require 'epa-file)
(epa-file-enable)
(setq epa-file-select-keys nil)
(setf epa-pinentry-mode 'loopback)
Toggle line numbers.
(setq display-line-numbers-type t)
Toggle line numbering mode (normal or relative).
(defun toggle-line-number-mode ()
(interactive)
(when display-line-numbers
(if (eq display-line-numbers 'visual)
(progn
(setq display-line-numbers t)
(setq display-line-numbers-type t))
(progn
(setq display-line-numbers 'visual)
(setq display-line-numbers-type 'visual)))))
Display line numbers by default in code and org-mode buffers.
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
(add-hook 'org-mode-hook #'display-line-numbers-mode)
Quick way to move between windows.
(use-package ace-window
:bind ("C-x o" . ace-window))
(use-package doom-themes
:config
(setq doom-themes-enable-bold t
doom-themes-enable-italic t)
(load-theme 'doom-city-lights t)
(doom-themes-org-config))
General UI settings
(tool-bar-mode -1)
(menu-bar-mode -1)
(set-scroll-bar-mode nil)
(setq inhibit-startup-screen t)
(setq default-frame-alist '((font . "Monaco-15")))
Standarise the tab size
(defconst indent-size 2)
(setq-default tab-width indent-size)
(setq-default indent-tabs-mode nil)
(setq-default indent-line-function 'insert-tab)
Get rid of the confirmation prompt:
(setq org-confirm-babel-evaluate nil)
(setq org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)" "|" "WAITING(w)")
(sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")
(sequence "|" "CANCELED(c)")))
(setq org-tag-alist '(("@orientation" . ?a)
("@coding" . ?b)
("@help" . ?c)
("@phone" . ?d)
("@documentation" . ?e)
("@meeting" . ?f)
("@email" . ?g)
("@break" . ?h)
("@study" . ?i)
("@slack" . ?j)
("@chat" . ?k)
))
(setq org-columns-default-format '"%40ITEM(Task) %10TAGS %17Effort(Estimated Effort){:} %CLOCKSUM %CLOCKSUM_T")
(setq org-global-properties '(("Effort_ALL". "0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00 8:00 16:00 24:00 32:00 40:00")))
(setq org-time-clocksum-format '(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t))
Magit is objectively the best Git interface.
(use-package magit
:bind ("C-x g" . magit-status)
:commands (magit-status
magit-blame
magit-find-file
magit-name-local-branch))
(use-package projectile
:commands (projectile-find-file
projectile-grep
projectile-switch-project
projectile-project-root)
:config
(projectile-mode))
(use-package helm-projectile
:bind ("C-c h" . helm-projectile))
(defmacro with-projectile-root (&rest body)
`(with-temp-buffer
(when (projectile-project-root)
(cd (projectile-project-root)))
,@body))
(use-package helm
:ensure t
:config
(setq helm-ff-transformer-show-only-basename nil
helm-adaptative-history-file "~/.emacs.d/data/helm-adaptative-history-file"
helm-boring-file-regexp-list '("\\.git$" "\\.svn$" "\\.elc$")
helm-yank-symbol-first t
helm-buffers-fuzzy-matching t
helm-ff-auto-update-initial-value t
helm-input-idle-delay 0.1
helm-idle-delay 0.1)
:bind (("C-x r l" . helm-bookmarks)
("C-x C-m" . helm-M-x)
("C-h i" . helm-google-suggest)
("M-y" . helm-show-kill-ring)
("C-h a" . helm-apropos)
("C-x C-f" . helm-find-files)
("C-x p" . helm-top)
("C-x C-b" . helm-buffers-list)))
Company for autocomplete functionality.
(use-package company
:config
(setq company-idle-delay 0.3
company-minimum-prefix-length 1
company-show-numbers t)
:hook
(after-init . global-company-mode))
(use-package company-lsp)
(use-package company-tabnine)
Syntax checking.
(use-package flycheck
:config
(setq-default flycheck-disabled-checkers '(emacs-lisp emacs-lisp-checkdoc))
(global-flycheck-mode))
For lisps
(use-package aggressive-indent
:hook ((clojure-mode . aggressive-indent-mode)
(emacs-lisp-mode . aggressive-indent-mode)
(lisp-mode . aggressive-indent-mode)
(scheme-mode . aggressive-indent-mode)))
Emacs support for the Language Server Protocol.
(use-package lsp-mode
:hook
((lsp-mode . lsp-enable-which-key-integration)
(before-save . lsp-format-buffer)
(before-save . lsp-organize-imports))
:commands lsp-mode lsp)
(use-package lsp-ui
:after (lsp-mode))
(use-package helm-lsp
:commands helm-lsp-workspace-symbol)
(use-package emmet-mode)
LSP support for css requires vscode-html-languageserver.
(use-package web-mode
:mode (("\\.html\\'" . web-mode)
("\\.htm\\'" . web-mode)
("\\.css\\'" . web-mode)
("\\.scss\\'" . web-mode)
("\\.sass\\'" . web-mode))
:custom ((web-mode-css-indent-offset indent-size)
(web-mode-code-indent-offset indent-size)
(web-mode-markup-indent-offset indent-size))
:hook ((web-mode . emmet-mode)
(web-mode . lsp-deferred)))
(use-package typescript-mode
:mode (("\\.js\\'" . typescript-mode)
("\\.jsx\\'" . typescript-mode)
("\\.ts\\'" . typescript-mode)
("\\.tsx\\'" . typescript-mode))
:custom (typescript-indent-level indent-size)
:hook ((typescript-mode . emmet-mode)
(typescript-mode . lsp-deferred)))
LSP support requires vscode-json-languageserver.
(use-package json-mode
:mode (("\\.json\\'" . json-mode))
:custom (js-indent-level indent-size)
:hook (json-mode . lsp-deferred))
(straight-use-package 'yaml-mode)
(use-package yaml-mode
:mode (("\\.yml\\'" . yaml-mode)
("\\.yaml\\'" . yaml-mode)))
PHP support requires vscode-intelephense.
(use-package php-mode
:mode (("\\.php\\'" . php-mode))
:hook (php-mode . lsp-deferred))
LSP support - requires go-langserver.
(use-package go-mode
:mode ("\\.go\\'" . go-mode)
:hook (go-mode . lsp-deferred))
LSP support - requires ccls. Installed via `brew install ccls`
(use-package ccls
:ensure
:config
'(ccls-initialization-options (quote (compilationDatabaseDirectory :build)))
:hook ((c-mode c++-mode objc-mode) .
(lambda () (require 'ccls) (lsp))))
(use-package ispell
:init (defun ispell-line()
(interactive)
(ispell-region (line-beginning-position) (line-end-position)))
:bind (("C-c sr" . ispell-region)
("C-c sb" . ispell-buffer)
("C-c sw" . ispell-word)
("C-c sl" . ispell-line)))
(setq ispell-program-name "/usr/local/bin/aspell")
I have used the Hemingway editor just to sanity check my writings, but leaving the comforts of Emacs was a knock. Giving writegood a spin.
(use-package writegood-mode)
Olivetti is a minor mode for a nice writing environment.
(use-package olivetti
:config
(setq-default olivetti-body-width 100)
(setq olivetti-body-width 100)
:commands olivetti-mode)