# emacs-config **Repository Path**: mirrors_akheron/emacs-config ## Basic Information - **Project Name**: emacs-config - **Description**: My emacs configuration - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-09-24 - **Last Updated**: 2026-05-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README * My emacs config Many ideas taken from https://github.com/Kaali/vj-emacs-0x12 ** Usage #+BEGIN_EXAMPLE cd $HOME git clone https://github.com/akheron/emacs-config .emacs-config ln -s .emacs-config/emacs .emacs #+END_EXAMPLE ** Bootstrap *** Enable lexical binding #+BEGIN_SRC emacs-lisp ;;; -*- lexical-binding: t; -*- #+END_SRC *** Paths #+BEGIN_SRC emacs-lisp (eval-and-compile (defvar akheron--config-root "~/.emacs-config" "Root path of emacs config") (defun akheron--config-path (path) (expand-file-name (concat (file-name-as-directory akheron--config-root) path))) (setq default-directory (expand-file-name "~/")) (add-to-list 'load-path (akheron--config-path "lib"))) #+END_SRC Find executables also in =~/local/bin=. #+BEGIN_SRC emacs-lisp (setq exec-path (cons "~/local/bin" exec-path)) #+END_SRC *** Customize Save Customize variables to a separate file. #+BEGIN_SRC emacs-lisp (setq custom-file (akheron--config-path "custom.el")) (load custom-file t) #+END_SRC *** Package management #+BEGIN_SRC emacs-lisp (require 'package) (setq package-archives '(("melpa" . "http://melpa.org/packages/") ("gnu" . "https://elpa.gnu.org/packages/"))) (package-initialize) (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (eval-when-compile (require 'use-package)) (require 'diminish) (require 'bind-key) (setq use-package-always-ensure t) #+END_SRC ** Global configuration Based on "Effective emacs": http://steve.yegge.googlepages.com/effective-emacs #+BEGIN_SRC emacs-lisp (setq inhibit-startup-message 1) (setq make-backup-files nil) (setq confirm-kill-emacs 'y-or-n-p) (setq tab-width 8) (global-font-lock-mode 1) (line-number-mode 1) (column-number-mode 1) (and (functionp 'tool-bar-mode) (tool-bar-mode -1)) (and (functionp 'scroll-bar-mode) (scroll-bar-mode -1)) (menu-bar-mode -1) (transient-mark-mode -1) (mouse-avoidance-mode 'jump) (subword-mode) #+END_SRC Disable abbrev-mode #+BEGIN_SRC emacs-lisp (setq-default abbrev-mode nil) #+END_SRC Fix dead keys #+BEGIN_SRC emacs-lisp (require 'iso-transl) #+END_SRC Global key bindings #+BEGIN_SRC emacs-lisp (bind-key "C-w" 'backward-kill-word) (bind-key "C-x C-k" 'kill-region) (bind-key "M-r" 'isearch-backward-regexp) (bind-key "M-s" 'isearch-forward-regexp) (bind-key "" 'call-last-kbd-macro) (bind-key "M-n" 'forward-paragraph) (bind-key "M-p" 'backward-paragraph) (bind-key "C-M-n" (lambda () (interactive) (forward-line 12))) (bind-key "C-M-p" (lambda () (interactive) (forward-line -12))) (bind-key "C-x C-g" 'goto-line) (bind-key "M--" 'dabbrev-expand) (bind-key "C-M-y" 'clipboard-yank) ; Disable compose-mail (bind-key "C-x m" nil) (if window-system ;; Window system present (progn ;; Disable iconifying with C-x C-z (bind-key "C-x C-z" nil)) ;; Running in console (progn ;; Bind backward-delete-char to ^H (bind-key "C-h" 'backward-delete-char))) (bind-key "C-x p" (lambda () (interactive) (other-window -1))) (bind-key "C-z" nil) ; Copy to clipboard (bind-key "C-x M-w" 'clipboard-kill-ring-save) ; Unset harmful keys (bind-key "M-DEL" nil) (bind-key "C-" nil) (bind-key "C-" nil) (bind-key "C-" nil) (bind-key "C-" nil) ; Imitate US keyboard layout (bind-key "M-;" 'beginning-of-buffer) (bind-key "M-:" 'end-of-buffer) ; Open links browser (bind-key "C-c C-o" 'browse-url-at-point) ; see 50-buffers.el (bind-key "C-x 4 t" 'transpose-buffers) ; Always display the result of C-x 4 f (find-file-in-other-window) et ; al. in an existing window (setq display-buffer-overriding-action '(display-buffer-use-some-window . ())) #+END_SRC ** Autorevert #+BEGIN_SRC emacs-lisp (global-auto-revert-mode 1) (diminish 'auto-revert-mode) #+END_SRC ** Themes Cobalt 2 theme, Fira Code font #+BEGIN_SRC emacs-lisp (load "~/.emacs.d/cobalt2-theme") (load-theme 'cobalt2 t) (set-face-attribute 'default nil :font "Fira Code" :height 120) #+END_SRC ** Don't rant about disabled functions #+BEGIN_SRC emacs-lisp (put 'downcase-region 'disabled nil) (put 'narrow-to-region 'disabled nil) #+END_SRC ** One space ends sentence #+BEGIN_SRC emacs-lisp (setq sentence-end-double-space nil) #+END_SRC ** Use the X primary selection for cutting & pasting #+BEGIN_SRC emacs-lisp (setq x-select-enable-primary t) (setq x-select-enable-clipboard nil) #+END_SRC ** Never indent with tabs #+BEGIN_SRC emacs-lisp (setq-default indent-tabs-mode nil) #+END_SRC ** Show trailing whitespace #+BEGIN_SRC emacs-lisp (setq-default show-trailing-whitespace t) #+END_SRC ** Server Start server after initialization #+BEGIN_SRC emacs-lisp (add-hook 'after-init-hook 'server-start) #+END_SRC ** Smarter move-beginning-of-line #+BEGIN_SRC emacs-lisp (defun smarter-move-beginning-of-line (arg) "Move point back to indentation of beginning of line. Move point to the first non-whitespace character on this line. If point is already there, move to the beginning of the line. Effectively toggle between the first non-whitespace character and the beginning of the line. If ARG is not nil or 1, move forward ARG - 1 lines first. If point reaches the beginning or end of the buffer, stop there." (interactive "^p") (setq arg (or arg 1)) ;; Move lines first (when (/= arg 1) (let ((line-move-visual nil)) (forward-line (1- arg)))) (let ((orig-point (point))) (back-to-indentation) (when (= orig-point (point)) (move-beginning-of-line 1)))) ;; remap C-a to `smarter-move-beginning-of-line' (global-set-key [remap move-beginning-of-line] 'smarter-move-beginning-of-line) #+END_SRC ** Buffers #+BEGIN_SRC emacs-lisp ;; For buffer list: show the current line's buffer in other window and ;; hide the buffer list (defun show-buffer-in-other-window-and-close () (interactive) (Buffer-menu-switch-other-window) (quit-window) (other-window 1)) (defun my-buffer-menu-mode-hook () (define-key Buffer-menu-mode-map "c" 'show-buffer-in-other-window-and-close)) (add-hook 'Buffer-menu-mode-hook 'my-buffer-menu-mode-hook) (defun transpose-buffers (arg) "Transpose the buffers shown in two windows." (interactive "p") (let ((selector (if (>= arg 0) 'next-window 'previous-window))) (while (/= arg 0) (let ((this-win (window-buffer)) (next-win (window-buffer (funcall selector)))) (set-window-buffer (selected-window) next-win) (set-window-buffer (funcall selector) this-win) (select-window (funcall selector))) (setq arg (if (plusp arg) (1- arg) (1+ arg)))))) #+END_SRC ** Ivy #+BEGIN_SRC emacs-lisp (defun akheron--ag-at-point () "Start `counsel-ag' with the symbol at point" (interactive) (counsel-ag (thing-at-point 'symbol t))) (use-package el-patch) ; Make counsel-find-file open the file in the window at point by ; patching find-file. ; ; From https://emacs.stackexchange.com/questions/46327/migrated-from-emacs-25-to-26-1-cannot-force-find-file-counsel-projectile-find-f ; (el-patch-defun find-file (filename &optional wildcards) (interactive (find-file-read-args "Find file: " (confirm-nonexistent-file-or-buffer))) (let ((value (find-file-noselect filename nil nil wildcards))) (if (listp value) (mapcar (el-patch-swap 'pop-to-buffer-same-window 'switch-to-buffer) (nreverse value)) ((el-patch-swap pop-to-buffer-same-window switch-to-buffer) value)))) (use-package counsel :diminish ivy-mode :init (setq ivy-re-builders-alist '((t . ivy--regex-ignore-order))) (setq ivy-use-virtual-buffers t) (setq ivy-count-format "(%d/%d) ") (setq ivy-height 25) :config (ivy-mode 1) (bind-key "C-s" 'swiper) (bind-key "M-x" 'counsel-M-x) (bind-key "C-x C-f" 'counsel-find-file) (bind-key "C-c g" 'counsel-git-grep) (bind-key "C-c k" 'akheron--ag-at-point) (bind-key "C-c C-k" 'counsel-ag)) #+END_SRC ** Projectile #+BEGIN_SRC emacs-lisp (use-package ag :defer t) (use-package projectile :defer 2 :diminish "" :commands (projectile-mode projectile-register-project-type) :preface (setq projectile-keymap-prefix (kbd "C-c p")) :config (setq projectile-completion-system 'ivy projectile-enable-caching nil projectile-indexing-method 'alien) (projectile-mode)) #+END_SRC ** Try Try packages without installing them. #+BEGIN_SRC emacs-lisp (use-package try :defer 3) #+END_SRC ** C/C++ #+BEGIN_SRC emacs-lisp (setq-default c-basic-offset 4) (setq c-offsets-alist '((substatement-open . 0) (case-label . +) (brace-list-open . 0) (statement-case-open . 0))) #+END_SRC ** Clojure #+BEGIN_SRC emacs-lisp (use-package cider) #+END_SRC ** CoffeeScript #+BEGIN_SRC emacs-lisp (use-package coffee-mode :mode "\\.coffee\\'" :config (setq coffee-tab-width 2) (add-hook 'coffee-mode-hook #'(lambda () (define-key coffee-mode-map (kbd "C-c C-;") 'coffee-indent-shift-left) (define-key coffee-mode-map (kbd "C-c C-:") 'coffee-indent-shift-right) (define-key coffee-mode-map (kbd "C-c C-c") 'comment-region) (define-key coffee-mode-map (kbd "C-c C-u") 'uncomment-region) (subword-mode) (which-function-mode)))) #+END_SRC ** Company #+BEGIN_SRC emacs-lisp (use-package company :commands company-mode :diminish company-mode) #+END_SRC ** Diff #+BEGIN_SRC emacs-lisp (add-hook 'diff-mode-hook #'(lambda () (define-key diff-mode-map "\M-q" 'fill-paragraph))) #+END_SRC ** Django templates #+BEGIN_SRC emacs-lisp (use-package django-html-mode :ensure f ; In lib/ :commands django-html-mode :config (add-hook 'django-html-mode-hook #'(lambda () (local-set-key (kbd "C-c %") 'django-close-tag)))) #+END_SRC ** Dockerfile #+BEGIN_SRC emacs-lisp (use-package dockerfile-mode :mode "Dockerfile$") #+END_SRC ** Elm #+BEGIN_SRC emacs-lisp (defun akheron--elm-mode-hook () (setq elm-indent-offset 4) (setq elm-format-elm-version "0.19") (setq elm-format-on-save t) (subword-mode)) (use-package elm-mode :config (add-hook 'elm-mode-hook #'akheron--elm-mode-hook)) #+END_SRC ** eshell Don't highlight trailing whitespace in eshell buffers. #+BEGIN_SRC emacs-lisp (defun akheron--eshell-mode-hook () (setq show-trailing-whitespace nil)) (add-hook 'eshell-mode-hook #'akheron--eshell-mode-hook) #+END_SRC ** eww - Don't highlight trailing whitespace - Use fixed-pitch font for ~~ tags #+BEGIN_SRC emacs-lisp (defun akheron--eww-tag-code (dom) (let ((start (point)) (text (dom-text dom))) (insert text) (add-face-text-property start (point) 'fixed-pitch) (insert " "))) (defun akheron--eww-mode-hook () (setq show-trailing-whitespace nil) (add-to-list 'shr-external-rendering-functions '(code . akheron--eww-tag-code))) (use-package eww :config (add-hook 'eww-mode-hook #'akheron--eww-mode-hook)) #+END_SRC ** Frame title #+BEGIN_SRC emacs-lisp (setq frame-title-format '((:eval (if (buffer-file-name) (abbreviate-file-name (buffer-file-name)) "%b")))) #+END_SRC ** git-gutter #+BEGIN_SRC emacs-lisp (use-package git-gutter :diminish "" :config (global-git-gutter-mode t) (setq git-gutter:always-show-gutter t) (bind-key "C-x v =" 'git-gutter:popup-diff) (bind-key "C-x v n" 'git-gutter:next-hunk) (bind-key "C-x v p" 'git-gutter:previous-hunk)) #+END_SRC ** Haskell #+BEGIN_SRC emacs-lisp (use-package haskell-mode :mode "\\.hs$" :config (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)) (use-package intero :config (add-hook 'haskell-model-hook 'intero-mode)) #+END_SRC ** integers Increment/decrement integer at point #+BEGIN_SRC emacs-lisp (use-package integers :ensure f ; In lib/ :bind (("C-c +" . increment-integer-at-point) ("C-c -" . decrement-integer-at-point))) #+END_SRC ** Prettier #+BEGIN_SRC emacs-lisp ;; Adapted from https://github.com/lunaryorn/old-emacs-configuration/blob/c854f4dd4555581f36665b844cd7c45034cf36a3/lisp/lunaryorn-flycheck.el#L62-L75 (defun akheron--node-modules-executable (parent-dir executable-name) (expand-file-name (concat "node_modules/.bin/" executable-name) parent-dir)) (defun akheron--node-modules-has-executable (parent-dir executable-name) (let ((executable-path (akheron--node-modules-executable parent-dir executable-name))) (and (file-regular-p executable-path) (file-executable-p executable-path)))) (defun akheron--find-node-modules-executable (executable-name) (-when-let* ((file-name (buffer-file-name)) (root (locate-dominating-file file-name #'(lambda (dir) (akheron--node-modules-has-executable dir executable-name))))) (akheron--node-modules-executable root executable-name))) (defun akheron--maybe-use-prettier () (when-let ((prettier-executable (akheron--find-node-modules-executable "prettier"))) (set (make-local-variable 'prettier-js-command) prettier-executable) (prettier-js-mode))) (use-package prettier-js :diminish "") #+END_SRC ** JavaScript #+BEGIN_SRC emacs-lisp (defun akheron--maybe-use-tide () (let ((tsconfig (locate-dominating-file (buffer-file-name) "tsconfig.json")) (jsconfig (locate-dominating-file (buffer-file-name) "jsconfig.json"))) (when (or tsconfig jsconfig) (tide-setup) (eldoc-mode +1) (diminish 'eldoc-mode) (tide-hl-identifier-mode +1) (company-mode +1)))) (defun akheron--js-enable-outline (map) ;; Use outline-minor-mode to see an overview of tests (outline-minor-mode +1) (set (make-local-variable 'outline-regexp) " *\\(describe\\|it\\)\\(\\.skip\\|\\.only\\)?(") (set (make-local-variable 'outline-level) #'(lambda () (let ((matched-heading (match-string 0))) (if (string-match " *" matched-heading) ;; consider every 2 spaces in the beginning of a line ;; a level of outline (+ 1 (/ (length (match-string 0 matched-heading)) 2)) 0)))) (bind-key "C-c C-o" outline-mode-prefix-map map) (diminish 'outline-minor-mode)) (defun akheron--js2-mode-hook () (akheron--maybe-use-prettier) (akheron--maybe-use-tide) (setq js2-basic-offset 2) (subword-mode +1) (diminish 'subword-mode) (akheron--js-enable-outline js2-mode-map)) (use-package js2-mode :mode ("\\.jsx?\\'" . js2-jsx-mode) :bind (:map js2-mode-map ("C-m" . newline-and-indent) ("C-c C-c" . comment-region) ("C-c C-u" . uncomment-region) ("C-c C-n" . flycheck-next-error) ("C-c C-p" . flycheck-previous-error)) ;("<" . nil) ;(">" . nil) ;("C-d" . nil)) :config (setq-default js2-mode-show-parse-errors nil) (setq-default js2-mode-show-strict-warnings nil) (add-hook 'js2-mode-hook #'akheron--js2-mode-hook)) #+END_SRC ** JSON js-mode is used for JSON #+BEGIN_SRC emacs-lisp (setq-default js-indent-level 2) #+END_SRC ** PureScript #+BEGIN_SRC emacs-lisp (use-package psc-ide) (use-package purescript-mode :mode "\\.purs$" :after (psc-ide) :config (defun akheron--purescript-mode-hook () (psc-ide-mode) (company-mode) (bind-key "C-c C-n" 'flycheck-next-error) (bind-key "C-c C-p" 'flycheck-previous-error) (turn-on-purescript-indentation)) (add-hook 'purescript-mode-hook #'akheron--purescript-mode-hook)) #+END_SRC ** Jinja2 #+BEGIN_SRC emacs-lisp (use-package jinja2-mode :mode "\\.\\(jinja\\|j2\\)$") #+END_SRC ** LaTeX #+BEGIN_SRC emacs-lisp (add-hook 'latex-mode-hook #'(lambda () (turn-on-auto-fill) (setq tex-open-quote "''") (setq tex-close-quote "''"))) #+END_SRC ** Lilypond #+BEGIN_SRC emacs-lisp (use-package lilypond-mode :mode ("\\.ly\\'" . LilyPond-mode) :commands LilyPond-mode :ensure f) #+END_SRC ** magit #+BEGIN_SRC emacs-lisp (use-package magit :bind ("C-x g" . magit-status) :config (setq ediff-window-setup-function 'ediff-setup-windows-plain) ;; Open browser for PR url in magit-process window (bind-key "C-c C-o" 'browse-url-at-point magit-mode-map)) (use-package forge) #+END_SRC ** Markdown #+BEGIN_SRC emacs-lisp (use-package markdown-mode :mode "\\.md$" :config (setq markdown-command "markdown -f fencedcode")) #+END_SRC ** Modeline #+BEGIN_SRC emacs-lisp ; Simpler modeline (setq-default mode-line-format (list " " ; Encoding 'mode-line-mule-info ; */% indicators if the file has been modified 'mode-line-modified " " ; line, column, file % 'mode-line-position " " ; the name of the buffer (i.e. filename) ; note this gets automatically highlighted 'mode-line-buffer-identification " " ; major and minor modes in effect 'mode-line-modes ; if which-func-mode is in effect, display which ; function we are currently in. '(which-func-mode ("" which-func-format "--")) "-%-" ) ) #+END_SRC ** macrostep #+BEGIN_SRC emacs-lisp (use-package macrostep :bind (:map emacs-lisp-mode-map ("C-c e" . macrostep-expand))) #+END_SRC ** Email #+BEGIN_SRC emacs-lisp (use-package sendmail :mode ("/tmp/mutt" . mail-mode) :hook (mail-mode . turn-on-auto-fill)) #+END_SRC ** org-mode #+BEGIN_SRC emacs-lisp (defun akheron--evaluate-time-range () (save-excursion (unless (org-at-date-range-p t) (goto-char (point-at-bol)) (re-search-forward org-tr-regexp-both (point-at-eol) t)) (unless (org-at-date-range-p t) (user-error "Not at a time-stamp range, and none found in current line"))) (let* ((ts1 (match-string 1)) (ts2 (match-string 2)) (havetime (or (> (length ts1) 15) (> (length ts2) 15))) (match-end (match-end 0)) (time1 (org-time-string-to-time ts1)) (time2 (org-time-string-to-time ts2)) (t1 (float-time time1)) (t2 (float-time time2)) (diff (abs (- t2 t1))) (negative (< (- t2 t1) 0)) ;; (ys (floor (* 365 24 60 60))) (ds (* 24 60 60)) (hs (* 60 60)) (fy "%dy %dd %02d:%02d") (fy1 "%dy %dd") (fd "%dd %02d:%02d") (fd1 "%dd") (fh "%02d:%02d") y d h m align) (if havetime (setq ; y (floor (/ diff ys)) diff (mod diff ys) y 0 d (floor (/ diff ds)) diff (mod diff ds) h (floor (/ diff hs)) diff (mod diff hs) m (floor (/ diff 60))) (setq ; y (floor (/ diff ys)) diff (mod diff ys) y 0 d (floor (+ (/ diff ds) 0.5)) h 0 m 0)) (list y d h m))) (defun akheron--add-times (time1 time2) (apply (lambda (y1 d1 h1 m1 y2 d2 h2 m2) (let ((y (+ y1 y2)) (d (+ d1 d2)) (h (+ h1 h2)) (m (+ m1 m2))) (when (> m 60) (setq h (+ h 1) m (- m 60))) (when (> h 24) (setq d (+ d 1) h (- h 24))) (when (> d 365) (setq y (+ y 1) d (- d 365))) (list y d h m))) (append time1 time2))) (defun akheron--make-working-hours-string (time) (apply (lambda (y d h m) (if (or (> y 0) (> d 0)) "Too long time range (over a day)" (let ((hrs (- (+ (float h) (/ (float m) 60)) 0.5))) (format "%.2f" hrs)))) time)) (defun akheron--working-hours-at-point () (interactive) (message (akheron--make-working-hours-string (akheron--evaluate-time-range)))) (defun akheron--working-hours-at-line () (interactive) (save-excursion (let ((cumulative-time '(0 0 0 0)) (time-ranges 0)) (goto-char (point-at-bol)) (re-search-forward org-tr-regexp-both (point-at-eol) t) (catch 'break (while (org-at-date-range-p t) (setq time-ranges (+ time-ranges 1) cumulative-time (akheron--add-times cumulative-time (akheron--evaluate-time-range))) (when (eolp) (throw 'break nil)) (re-search-forward org-tr-regexp-both (point-at-eol) t))) (if (equal cumulative-time '(0 0 0 0)) (message "No time range!") (message "%s%s" (akheron--make-working-hours-string cumulative-time) (if (> time-ranges 1) (format " (%d time ranges)" time-ranges) "")))))) (use-package org :mode ("\\.org$" . org-mode) :config (setq org-src-fontify-natively t) (bind-key "C-c y" 'akheron--working-hours-at-line org-mode-map) (bind-key "C-c C-y" 'akheron--working-hours-at-point org-mode-map)) #+END_SRC ** Python #+BEGIN_SRC emacs-lisp (use-package blacken) (use-package py-isort) (use-package flycheck-mypy) (use-package python :mode ("\\.py$" . python-mode) :config (add-hook 'python-mode-hook #'(lambda () (define-key python-mode-map "\C-m" 'newline-and-indent) (define-key python-mode-map (kbd "C-c C-;") 'python-indent-shift-left) (define-key python-mode-map (kbd "C-c C-:") 'python-indent-shift-right) (define-key python-mode-map (kbd "C-c C-c") 'comment-region) (define-key python-mode-map (kbd "C-c C-u") 'uncomment-region) (define-key python-mode-map (kbd "C-c C-n") 'flycheck-next-error) (define-key python-mode-map (kbd "C-c C-p") 'flycheck-previous-error) (electric-indent-local-mode -1) (subword-mode) (blacken-mode))) (add-hook 'before-save-hook 'py-isort-before-save)) #+END_SRC ** ReStructured text #+BEGIN_SRC emacs-lisp (use-package rst-mode :ensure f ; In lib/ :mode "\\.rst$" :config (add-hook 'rst-mode-hook 'turn-on-auto-fill) (cond ((equal font-lock-global-modes t) (setq font-lock-global-modes '(not rst-mode))) ((and (listp font-lock-global-modes) (equal (car font-lock-global-modes) 'not)) (append-to-list font-lock-global-modes 'rst-mode)))) #+END_SRC ** Rust #+BEGIN_SRC emacs-lisp (use-package cargo :commands cargo-minor-mode) (use-package racer :commands racer-mode) (defun akheron--rust-mode-hook () (rust-enable-format-on-save) (cargo-minor-mode) (racer-mode) (company-mode)) (use-package rust-mode :mode "\\.rs$" :config (add-hook 'rust-mode-hook #'akheron--rust-mode-hook)) #+END_SRC ** Scheme #+BEGIN_SRC emacs-lisp (use-package paredit :commands paredit-mode :diminish paredit-mode :config (bind-key "M-;" 'beginning-of-buffer paredit-mode-map) (bind-key "M-:" 'end-of-buffer paredit-mode-map)) (use-package geiser :commands turn-on-geiser-mode) (defun akheron--scheme-mode-hook () (enable-paredit-mode) (turn-on-geiser-mode)) (add-hook 'scheme-mode-hook #'akheron--scheme-mode-hook) #+END_SRC ** SCSS #+BEGIN_SRC emacs-lisp (defun akheron--scss-hook () (when (equal (file-name-extension buffer-file-name) "scss") (setq-local css-indent-offset 2))) (use-package scss-mode :mode "\\.scss$" :config (add-hook 'css-mode-hook #'akheron--scss-hook)) #+END_SRC ** TypeScript #+BEGIN_SRC emacs-lisp (use-package tide :commands tide-setup) (use-package typescript-mode :mode "\\.tsx?\\'" :config (add-hook 'typescript-mode-hook #'akheron--typescript-mode-hook)) (defun akheron--typescript-mode-hook () (setq typescript-indent-level 2) (tide-setup) (eldoc-mode +1) (tide-hl-identifier-mode +1) (company-mode +1) (akheron--maybe-use-prettier) (akheron--js-enable-outline typescript-mode-map)) #+END_SRC ** unfill #+BEGIN_SRC emacs-lisp (use-package unfill :commands unfill-paragraph :bind ("C-M-q" . unfill-paragraph)) #+END_SRC ** uniquiry Use 'foo|bar', 'foo|baz' style buffer naming #+BEGIN_SRC emacs-lisp (use-package uniquify :ensure f ; In lib/ :config (setq uniquify-buffer-name-style 'post-forward)) #+END_SRC ** wgrep #+BEGIN_SRC emacs-lisp (use-package wgrep :defer 5) #+END_SRC ** which-func #+BEGIN_SRC emacs-lisp (use-package which-func :config (set-face-attribute 'which-func nil :foreground "white")) #+END_SRC ** whitespace #+BEGIN_SRC emacs-lisp (use-package whitespace :diminish "" :config (setq whitespace-line-column 78) (setq whitespace-style '(face lines-tail)) (add-hook 'prog-mode-hook 'whitespace-mode)) #+END_SRC ** YAML #+BEGIN_SRC emacs-lisp (use-package yaml-mode :mode "\\.yml$") #+END_SRC ** sudoedit (via tramp) #+BEGIN_SRC emacs-lisp (defun akheron--sudo-edit (&optional arg) "Edit currently visited file as root. With a prefix ARG prompt for a file to visit. Will also prompt for a file to visit if current buffer is not visiting a file." (interactive "P") (if (or arg (not buffer-file-name)) (find-file (concat "/sudo:root@localhost:" (ido-read-file-name "Find file(as root): "))) (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))) (bind-key "C-x C-r" #'akheron--sudo-edit) #+END_SRC ** Flycheck #+BEGIN_SRC emacs-lisp (use-package grizzl ; Will be loaded by flycheck :defer t) (use-package flycheck-rust :commands flycheck-rust-setup) (defun akheron--use-js-executables-from-node-modules () "Set executables of JS checkers from local node modules." (pcase-dolist (`(,checker . ,module) '((javascript-jshint . "jshint") (javascript-eslint . "eslint") (javascript-jscs . "jscs") (scss-stylelint . "stylelint"))) (when-let ((lint-executable (akheron--find-node-modules-executable module)) (executable-var (flycheck-checker-executable-variable checker))) (set (make-local-variable executable-var) lint-executable)))) (defun akheron--flycheck-mode-hook () (akheron--use-js-executables-from-node-modules) (flycheck-rust-setup)) (use-package flycheck :config (let ((virtualenv-dir "~/.virtualenvs/emacs")) ;; Only have flycheck bitching in left-fringe (setq flycheck-highlighting-mode 'lines) ;; Use grizzl instead of ido for completion (setq flycheck-completion-system 'grizzl) (setq-default flycheck-flake8rc (expand-file-name "~/.emacs-config/conf/flake8rc")) ;; Disable elisp checker. (setq flycheck-checkers (delq 'emacs-lisp-checkdoc flycheck-checkers)) (setq flycheck-display-errors-delay 0.1) (add-hook 'flycheck-mode-hook #'akheron--flycheck-mode-hook) (add-hook 'after-init-hook #'global-flycheck-mode))) #+END_SRC ** Final things Clear the echo area #+BEGIN_SRC emacs-lisp (princ "" t) #+END_SRC