My Emacs settings
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

905 lines
27 KiB

;;; init.el --- user-init-file -*- lexical-binding: t -*-
;; Bootstrap quelpa
;; (package-initialize)
;; (unless (require 'quelpa nil t)
;; (with-temp-buffer
;; (url-insert-file-contents "")
;; (eval-buffer)))
(progn ; startup
(add-to-list 'package-archives '("org" . "") t)
(defvar before-user-init-time (current-time)
"Value of `current-time' when Emacs begins loading `user-init-file'.")
(message "Loading Emacs...done (%.3fs)"
(float-time (time-subtract before-user-init-time
(setq user-init-file (or load-file-name buffer-file-name))
(setq user-emacs-directory (file-name-directory user-init-file))
(message "Loading %s..." user-init-file)
(setq inhibit-startup-buffer-menu t)
(setq inhibit-startup-screen t)
(setq inhibit-startup-echo-area-message "locutus")
(setq initial-buffer-choice t)
(setq initial-scratch-message "")
(setq load-prefer-newer t)
(defalias 'yes-or-no-p 'y-or-n-p)
(scroll-bar-mode 0)
(tool-bar-mode 0)
(menu-bar-mode 0)
(delete-selection-mode 1)
(column-number-mode 1))
(progn ; `use-package'
(require 'use-package)
(setq use-package-verbose t)
(setq use-package-always-defer t)
(setq use-package-enable-imenu-support t))
(use-package auto-compile
:demand t
(setq auto-compile-display-buffer nil)
(setq auto-compile-mode-line-counter t)
(setq auto-compile-source-recreate-deletes-dest t)
(setq auto-compile-toggle-deletes-nonlib-dest t)
(setq auto-compile-update-autoloads t)
(add-hook 'auto-compile-inhibit-compile-hook
(use-package bash-completion
:demand t
:config (progn
(use-package custom
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file)))
(use-package server
:config (or (server-running-p) (server-mode)))
(progn ; startup
(message "Loading early birds...done (%.3fs)"
(float-time (time-subtract (current-time)
;;; Long tail
(use-package abbrev
(setq save-abbrevs 'silently)
(setq-default abbrev-mode t))
(use-package auth-source-pass
:demand t
:after auth-source
(setq auth-sources '(password-store))))
(use-package autorevert
(global-auto-revert-mode 1)
;; auto-update dired buffers
(setq global-auto-revert-non-file-buffers t
auto-revert-verbose nil))
(use-package avy
:bind (("C-c C-j" . avy-goto-char-2)
("M-g g" . avy-goto-line))
;; Home row
(setq avy-keys '(?a ?r ?s ?t ?d ?h ?n ?e ?i ?o))
(setq avy-style 'at-full)
(setq avy-all-windows t)))
(use-package beginend
:demand t
(use-package browse-url
(setq browse-url-generic-program (executable-find "nightly")))
(use-package buffer-move
:bind (("<s-up>" . buf-move-up)
("<s-down>" . buf-move-down)
("<s-left>" . buf-move-left)
("<s-right>" . buf-move-right)))
(use-package buffer-watcher
:demand t)
(use-package clojure-mode
:mode "\\.clj\\'")
(use-package cider
:after clojure-mode
:init (progn
(defun setup-clojure-buffer ()
(clj-refactor-mode 1)
(paredit-mode 1)
(setq indent-tabs-mode nil))
(add-hook 'clojure-mode-hook #'setup-clojure-buffer)
(add-hook 'cider-mode-hook #'cider-turn-on-eldoc-mode))
:config (progn
(setq cider-repl-use-clojure-font-lock t
cider-repl-use-pretty-printing t
cider-repl-wrap-history t
cider-repl-history-size 3000)))
(use-package clj-refactor
:after clojure-mode
:config (cljr-add-keybindings-with-prefix "C-c C-r"))
(use-package company
:init (progn
(add-hook 'prog-mode-hook 'company-mode))
:config (progn
(setq company-idle-delay 0.5)
(setq company-tooltip-limit 10)
(setq company-minimum-prefix-length 2)
(setq company-tooltip-flip-when-above t)))
(use-package company-dabbrev
:config (progn
(setq company-dabbrev-ignore-case t)
(setq company-dabbrev-downcase nil)))
(use-package company-go
:after go-mode
:config (progn
(add-to-list 'company-backends #'company-go)
(setq company-go-show-annotation t)))
(use-package compile
:hook (compilation-filter . my/colorize-compilation-buffer)
(defun my/colorize-compilation-buffer ()
(require 'ansi-color)
(let ((inhibit-read-only t))
(ansi-color-apply-on-region compilation-filter-start (point))))))
(use-package counsel
:demand t
:bind (("M-x" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("M-i" . counsel-imenu)
("M-y" . counsel-yank-pop))
:init (progn
(setq counsel-linux-app-format-function
(use-package dabbrev
:bind (("S-SPC" . dabbrev-expand)))
(use-package dash
:config (dash-enable-font-lock))
(use-package diff-hl
:hook ((prog-mode . diff-hl-mode)
(magit-post-refresh . diff-hl-magit-post-refresh)))
(use-package dired
:bind (:map dired-mode-map
("M-s" . find-name-dired)
("C-k" . dired-kill-subdir))
:init (progn
(add-hook 'dired-mode-hook #'dired-hide-details-mode))
:config (progn
(setq dired-listing-switches "-alh")
(setq dired-dwim-target t)
(put 'dired-find-alternate-file 'disabled nil)))
(use-package dired-du
:after dired)
(use-package dired-x
:demand t
:after dired
:init (progn
(add-hook 'dired-mode-hook #'dired-omit-mode))
:config (progn
(setq dired-omit-files "^\\...+$")))
(use-package drag-stuff
:demand t
:config (progn
(drag-stuff-global-mode t)
(add-to-list 'drag-stuff-except-modes 'org-mode)
(add-to-list 'drag-stuff-except-modes 'rebase-mode)
(add-to-list 'drag-stuff-except-modes 'emacs-lisp-mode)))
(use-package duplicate-thing
:bind ("M-D" . duplicate-thing))
(use-package ediff
:config (progn
;; window positioning & frame setup
(setq ediff-window-setup-function 'ediff-setup-windows-plain
ediff-split-window-function 'split-window-horizontally)))
(use-package editorconfig
:demand t
:init (editorconfig-mode 1))
(use-package elbank)
(use-package eldoc
:config (global-eldoc-mode))
(use-package elec-pair
:demand t
:config (electric-pair-mode t))
(use-package electric
:demand t
:config (electric-indent-mode t))
(use-package elisp-mode
:hook (emacs-lisp-mode . (lambda () (setq indent-tabs-mode nil))))
(use-package embrace
:bind (("C-c e" . embrace-commander))
:hook (emacs-lisp-mode . embrace-emacs-lisp-mode-hook))
(use-package erc
:init (progn
(setq erc-nick "NicolasPetton"
erc-autojoin-channels-alist '(("" . ("#emacs"))))))
(use-package esh-mode
:hook (eshell-mode . my/configure-esh-mode)
;; We can't use use-package's :bind here as eshell insists on
;; recreating a fresh eshell-mode-map for each new eshell buffer.
(defun my/configure-esh-mode ()
(bind-key "M-p" #'counsel-esh-history eshell-mode-map))))
(use-package em-cmpl
:hook (eshell-mode . eshell-cmpl-initialize))
(use-package em-smart
:hook (eshell-mode . eshell-smart-initialize)
(add-to-list 'eshell-smart-display-navigate-list #'counsel-esh-history)))
(use-package em-term
(nconc eshell-visual-subcommands
'(("docker" "build")
("git" "log" "diff" "show")
("npm" "init" "install")
("yarn" "init" "install")))
(add-to-list 'eshell-command-completions-alist
'("gunzip" "gz\\'"))
(add-to-list 'eshell-command-completions-alist
'("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'"))
(setenv "PAGER" "cat")
(setenv "SUDO_ASKPASS" (executable-find ""))))
(use-package pcomplete
:config (progn
(defvar pcomplete-man-user-commands
"apropos -s 1 .|while read -r a b; do echo \" $a\";done;"))
"p-completion candidates for `man' command")
(defun pcomplete/man ()
"Completion rules for the `man' command."
(pcomplete-here pcomplete-man-user-commands))))
(use-package pcmpl-git
:after pcomplete)
(use-package expand-region
:bind (("C-=" . er/expand-region)))
(use-package flycheck
:commands (flycheck-mode)
:init (add-hook 'prog-mode-hook #'flycheck-mode))
(use-package flyspell
:bind (:map flyspell-mode-map
("C-;" . nil))
:init (progn
;; (add-hook 'prog-mode-hook #'flyspell-prog-mode)
(dolist (mode-hook '(text-mode-hook org-mode-hook LaTeX-mode-hook))
(add-hook mode-hook #'flyspell-mode))))
(use-package flyspell-correct-ivy
:bind* (("C-." . flyspell-correct-word-generic)))
(use-package go-eldoc
:after go-mode
:hook (go-mode . setup-go-mode)
:config (progn
(defun setup-go-mode ()
(add-hook 'before-save-hook #'gofmt nil t)
(use-package go-mode
:bind (:map go-mode-map
("M-." . godef-jump)
("C-c d" . godoc-at-point))
:init (progn
(add-to-list 'exec-path (format "%s/.local/share/go/bin" (getenv "HOME")))
(setenv "GOPATH" (format "%s/.local/share/go" (getenv "HOME")))))
(use-package gnus-dired
:bind (:map gnus-dired-mode-map
("C-x C-a" . gnus-dired-attach))
:config (add-hook 'dired-mode-hook #'turn-on-gnus-dired-mode))
(use-package help
:config (temp-buffer-resize-mode))
(use-package helpful
:bind (("C-h ." . helpful-at-point)
("C-h k" . helpful-key)
("C-h v" . helpful-variable)
("C-h f" . helpful-callable)))
(use-package ibuffer
:bind (("C-x C-b" . ibuffer)))
;; Fix dead characters
(use-package iso-transl
:demand t)
(use-package ispell
(defun ispell-word-then-abbrev (p)
"Call `ispell-word', then create an abbrev for it.
With prefix P, create local abbrev. Otherwise it will
be global."
(interactive "P")
(let (bef aft)
(while (progn
(and (setq bef (thing-at-point 'word))
(not (ispell-word nil 'quiet)))))
(setq aft (thing-at-point 'word)))
(when (and aft bef (not (equal aft bef)))
(setq aft (downcase aft))
(setq bef (downcase bef))
(if p local-abbrev-table global-abbrev-table)
bef aft)
(message "\"%s\" now expands to \"%s\" %sally"
bef aft (if p "loc" "glob")))))
(define-key ctl-x-map "\C-i" #'ispell-word-then-abbrev))
(use-package ivy
:demand t
:bind (("C-c r" . ivy-resume))
:config (progn
(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(setq ivy-count-format "(%d/%d) ")
(setq ivy-use-selectable-prompt t)))
(progn ; `isearch'
(setq isearch-allow-scroll t))
(use-package js2-mode
:mode "\\.js\\'"
:config (progn
(define-key js2-mode-map (kbd "C-c C-o") nil))
(defun js2-show-node-at-point ()
(js2-show-node (js2-node-at-point)))
(defun js2-show-node-parent-at-point ()
(js2-show-node (js2-node-parent (js2-node-at-point))))
(defun js2-show-node (node)
(let* ((buf (get-buffer-create "*js2-node-at-point*"))
(node-contents (buffer-substring (js2-node-abs-pos node) (js2-node-abs-end node))))
(set-buffer buf)
(delete-region (point-min) (point-max))
(insert node-contents)))))
(use-package emacs-js
:commands (setup-js-buffer)
(add-hook 'js-mode-hook #'setup-js-buffer)))
(use-package finsit-bugref
:demand t
(use-package finsit-prodigy
:demand t
:after prodigy
:config (progn
(use-package finsit-elcouch
:demand t
:after elcouch
(use-package finsit-basecamp
:demand t
(use-package finsit-magit
:demand t
:after magit
(use-package finsit-prodigy
:demand t
:after prodigy)
(use-package finsit-yasnippet
:demand t
:after yasnippet
(use-package klassified
:init (add-hook 'js2-mode-hook #'klassified-interaction-js-mode))
(use-package less-css-mode)
(use-package lisp-mode
(add-hook 'emacs-lisp-mode-hook 'outline-minor-mode)
(defun indent-spaces-mode ()
(setq indent-tabs-mode nil))
(add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode))
(use-package magit
:bind (("C-x g" . magit-status)
("C-x M-g" . magit-dispatch-popup)
:map magit-mode-map
("C" . magit-commit-add-log))
:config (progn
;; (magit-add-section-hook 'magit-status-sections-hook
;; 'magit-insert-modules
;; 'magit-insert-unpulled-from-upstream)
(magit-define-popup-action 'magit-commit-popup
?x "Absorb" #'magit-commit-absorb-popup)
(setq magit-branch-prefer-remote-upstream '("master"))
(setq magit-branch-adjust-remote-upstream-alist '(("origin/master" "master")))
(setq magit-branch-arguments nil)))
(use-package man
:config (setq Man-width 80))
(use-package multiple-cursors
:bind (("M-RET" . mc/edit-lines)
("C-<" . mc/mark-previous-like-this)
("C->" . mc/mark-next-like-this)
("C-M-<" . mc/unmark-next-like-this)
("C-M->" . mc/unmark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)))
(use-package no-littering
:demand t
:config (progn
(require 'recentf)
(add-to-list 'recentf-exclude no-littering-var-directory)
(add-to-list 'recentf-exclude no-littering-etc-directory)
(setq delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
(setq backup-directory-alist
`((".*" . ,(no-littering-expand-var-file-name "backup/"))))
(setq auto-save-file-name-transforms
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
(setq create-lockfiles nil)))
(use-package nov
:mode ("\\.epub\\'" . nov-mode)
:config (progn
(defun my-nov-font-setup ()
(face-remap-add-relative 'variable-pitch
:family "Gentium Book Basic"
:height 1.5))
(add-hook 'nov-mode-hook 'my-nov-font-setup)
(require 'justify-kp)
(setq nov-text-width 62)
(defun my-nov-window-configuration-change-hook ()
(remove-hook 'window-configuration-change-hook
(defun my-nov-post-html-render-hook ()
(if (get-buffer-window)
(let ((max-width (pj-line-width))
(goto-char (point-min))
(while (not (eobp))
(when (not (looking-at "^[[:space:]]*$"))
(goto-char (line-end-position))
(when (> (shr-pixel-column) max-width)
(goto-char (line-beginning-position))
(forward-line 1))))
(add-hook 'window-configuration-change-hook
nil t)))
(add-hook 'nov-post-html-render-hook 'my-nov-post-html-render-hook)))
(use-package omnisharp
:after csharp-mode
:bind (:map omnisharp-mode-map
("C-c r" . omnisharp-run-code-action-refactoring)
("M-." . omnisharp-go-to-definition)
;; ("M-." . omnisharp-find-implementations)
("M-?" . omnisharp-find-usages))
:hook ((omnisharp-mode . configure-omnisharp)
(csharp-mode . omnisharp-mode))
(add-to-list 'company-backends #'company-omnisharp)
(setq omnisharp-imenu-support t)
(defun configure-omnisharp ()
(local-set-key (kbd "C-c C-c") #'recompile))))
(use-package csharp-mode
:hook ((csharp-mode . configure-csharp))
:config (progn
(defun configure-csharp ()
(setq indent-tabs-mode nil)
(setq c-syntactic-indentation t)
(c-set-style "ellemtel")
(setq c-basic-offset 4)
(setq truncate-lines t)
(setq tab-width 4))))
(use-package open-url-at-point
:bind ("C-c C-o" . open-url-at-point))
(use-package ox-twbs
:demand t
:after org)
(use-package paredit
:demand t
:bind (:map paredit-mode-map
("M-s" . nil))
(add-hook 'emacs-lisp-mode-hook #'paredit-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode))
(use-package paren
:demand t
:config (show-paren-mode))
(use-package pass
:mode ("org/reference/password-store/" . pass-view-mode)
:bind ("C-x p" . pass)
:config (progn
(add-to-list 'auto-mode-alist '("\\<password-store\\>/.*\\.gpg\\'" . pass-view-mode))))
(use-package pdf-tools
:demand t
:bind (:map pdf-view-mode-map
("C-s" . isearch-forward))
:config (progn
(use-package counsel-projectile
:demand t
:after projectile
:config (progn
(define-key projectile-mode-map
[remap projectile-ag]
(use-package projectile
:demand t
:bind (:map projectile-mode-map
("C-c p" . projectile-command-map))
:config (progn
:compile "cd ~/work/ftgp/monitor/monitor/Monitor.Web.Ui/Client && gulp lint"
:test "cd ~/work/ftgp/monitor/monitor/Monitor.Web.Ui/Client && gulp karma"
:test-suffix "-tests")))
(use-package prog-mode
:config (progn
(defun indicate-buffer-boundaries-left ()
(setq indicate-buffer-boundaries 'left))
(add-hook 'prog-mode-hook #'indicate-buffer-boundaries-left)))
(use-package quelpa
:config (progn
(setq quelpa-upgrade-p nil)
(add-to-list 'quelpa-melpa-recipe-stores "~/.emacs.d/etc/quelpa/recipes/")))
(use-package rainbow-mode
:init (progn
(add-hook 'css-mode-hook 'rainbow-mode)
(add-hook 'less-mode-hook 'rainbow-mode)))
(use-package recentf
:demand t
(setq recentf-auto-cleanup 300)
(setq recentf-max-saved-items 4000))
(add-to-list 'recentf-exclude "^/\\(?:ssh\\|su\\|sudo\\)?:")
(use-package company-restclient
:after restclient
:config (progn
(add-to-list 'company-backend 'company-restclient)
(add-hook 'restclient-mode-hook #'company-mode-on)))
(use-package savehist
:config (savehist-mode))
(use-package saveplace
:config (save-place-mode))
(use-package shell-switcher
:bind (("C-'" . shell-switcher-switch-buffer)
("C-M-'" . shell-switcher-new-shell))
:config (progn
(setq shell-switcher-new-shell-function #'vterm)))
(use-package simple
:config (column-number-mode))
(use-package subword
:init (global-subword-mode))
(use-package swiper
:bind (("C-s" . swiper-isearch)))
(use-package tabify
(defun tabify-buffer ()
(tabify (point-min) (point-max)))
(defun untabify-buffer ()
(untabify (point-min) (point-max))))
(use-package term
:bind (
:map term-mode-map
("C-c C-t" . my/term-toggle-line-mode)
:map term-raw-map
("C-c C-t" . my/term-toggle-line-mode))
:init (progn
(defun my/term-toggle-line-mode ()
"Toggle between char and line modes."
(if (term-in-char-mode)
(progn ; `text-mode'
(add-hook 'text-mode-hook #'indicate-buffer-boundaries-left))
(use-package time-stamp
:init (progn
(defvar-local time-stamp-target nil
"File in which time-stamps should be written.")
(put 'time-stamp-target 'safe-local-variable 'string-or-null-p)
(defun time-stamp-target ()
"Update the time-stamp in `time-stamp-target' if non-nil."
(when (and time-stamp-target
(file-exists-p time-stamp-target))
(with-current-buffer (find-file-noselect time-stamp-target)
(use-package tramp
:config (progn
(add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:"))
(add-to-list 'tramp-default-proxies-alist '("localhost" nil nil))
(add-to-list 'tramp-default-proxies-alist
(list (regexp-quote (system-name)) nil nil))))
(use-package transmission
:config (progn
(defun transmission-add-magnet (url)
"Like `transmission-add', but with no file completion."
(interactive "sMagnet url: ")
(transmission-add url))))
(use-package uniquify
(setq uniquify-buffer-name-style 'forward))
(use-package url-vars
(setq url-privacy-level 'high)))
(use-package web-mode
:init (progn
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.htm\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode)))
(setq web-mode-css-indent-offset 2))
(use-package whitespace
(setq whitespace-display-mappings
(space-mark 32 [183] [46]) ; normal space, ·
(space-mark 160 [164] [95])
(space-mark 2208 [2212] [95])
(space-mark 2336 [2340] [95])
(space-mark 3616 [3620] [95])
(space-mark 3872 [3876] [95])
(newline-mark 10 [182 10]) ; newlne, ¶
(tab-mark 9 [9655 9] [92 9]) ; tab, ▷
(progn ;; `window'
(bind-key "C-;" #'other-window))
(use-package winner
:bind (("C-|". winner-undo)))
(use-package workflow
:commands (work-clock-out
(use-package ws-butler
(add-hook 'prog-mode-hook #'ws-butler-mode))
(use-package yasnippet
:demand t
:init (progn
(use-package zerodark-theme
:demand t
(defun set-selected-frame-dark ()
(let ((frame-name (cdr (assq 'name (frame-parameters (selected-frame))))))
"xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT 'dark' -name '%s'"
(when (window-system)
(load-theme 'zerodark t)
(setq frame-title-format '(buffer-file-name "%f" ("%b"))))))
(use-package minions
:demand t
:config (unless minions-mode
(use-package zoom-frm
:bind (("C-+" . zoom-frm-in)
("C--" . zoom-frm-out)))
(progn ; startup
(message "Loading %s...done (%.3fs)" user-init-file
(float-time (time-subtract (current-time)
(add-hook 'after-init-hook
(lambda ()
"Loading %s...done (%.3fs) [after-init]" user-init-file
(float-time (time-subtract (current-time)
(progn ; local packages
(let ((dir (expand-file-name "local" user-emacs-directory)))
(when (file-exists-p dir)
(add-to-list 'load-path dir))))
(progn ; personalize
(let ((file (expand-file-name (concat (user-real-login-name) ".el")
(when (file-exists-p file)
(load file))))
(progn ; host-specific setup
(let* ((host (substring (shell-command-to-string "hostname") 0 -1))
(host-dir (concat "~/.emacs.d/hosts/" host))
(host-file (expand-file-name "init.el" host-dir)))
(when (file-exists-p host-dir)
(let ((default-directory host-dir))
(add-to-list 'load-path host-dir)
(when (file-exists-p host-file)
(load host-file))))
(progn ; private modules
(let ((private-dir "~/.priv/elisp"))
(when (file-exists-p private-dir)
(add-to-list 'load-path private-dir)
(require 'private-modules nil t))))
;; display line numbers in buffers visiting a file
;; (dolist (mode-hook '(prog-mode-hook text-mode-hook))
;; (add-hook mode-hook (lambda ()
;; (when buffer-file-name
;; (setq display-line-numbers t)))))
(defun goto-line-with-line-numbers ()
(let ((display-line-numbers t))
(call-interactively #'goto-line)))
(global-set-key [remap goto-line] #'goto-line-with-line-numbers)
;; Local Variables:
;; indent-tabs-mode: nil
;; eval: (flycheck-mode -1)
;; no-byte-compile: t
;; End:
;;; init.el ends here