Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
;; (require 'emacs-load-time)
(defconst emacs-start-time (current-time))
(defvar file-name-handler-alist-old file-name-handler-alist)
(setq package-enable-at-startup nil
file-name-handler-alist nil
message-log-max 16384
gc-cons-threshold 402653184
gc-cons-percentage 0.6
auto-window-vscroll nil)
(add-hook 'after-init-hook
`(lambda ()
(setq file-name-handler-alist file-name-handler-alist-old
gc-cons-threshold 800000
gc-cons-percentage 0.1)
(garbage-collect)) t)
;;; Functions
(defun emacs-path (path)
(expand-file-name path user-emacs-directory))
(defun lookup-password (host user port)
(require 'auth-source)
(require 'auth-source-pass)
(let ((auth (auth-source-search :host host :user user :port port)))
(if auth
(let ((secretf (plist-get (car auth) :secret)))
(if secretf
(funcall secretf)
(error "Auth entry for %s@%s:%s has no secret!"
user host port)))
(error "No auth entry found for %s@%s:%s" user host port))))
(defvar saved-window-configuration nil)
(defun push-window-configuration ()
(push (current-window-configuration) saved-window-configuration))
(defun pop-window-configuration ()
(let ((config (pop saved-window-configuration)))
(if config
(set-window-configuration config)
(if (> (length (window-list)) 1)
;;; Environment
(defconst emacs-environment (getenv "NIX_MYENV_NAME"))
(setq load-path
(append '("~/.emacs.d")
(delete-dups load-path)
(defun filter (f args)
(let (result)
(dolist (arg args)
(when (funcall f arg)
(setq result (cons arg result))))
(nreverse result)))
(defun nix-read-environment (name)
(executable-find (concat "load-env-" name)))
(and (re-search-forward "^source \\(.+\\)$" nil t)
(match-string 1))))
(and (or (re-search-forward "^ nativeBuildInputs=\"\\(.+?\\)\"" nil t)
(re-search-forward "^ buildInputs=\"\\(.+?\\)\"" nil t))
(split-string (match-string 1))))))
(require 'use-package)
(defconst load-path-reject-re "/\\.emacs\\.d/\\(lib\\|site-lisp\\)/"
"Regexp matching `:load-path' values to be rejected.")
(defun load-path-handler-override (orig-func name keyword args rest state)
(if (cl-some (apply-partially #'string-match load-path-reject-re) args)
(use-package-process-keywords name rest state)
(let ((body (use-package-process-keywords name rest state)))
(mapcar #'(lambda (path)
`(eval-and-compile (add-to-list 'load-path ,path t)))
(advice-add 'use-package-handler/:load-path
:around #'load-path-handler-override)
(if init-file-debug
(setq use-package-verbose t
use-package-expand-minimally nil
use-package-compute-statistics t
debug-on-error t)
(setq use-package-verbose nil
use-package-expand-minimally t)))
;;; Settings
(defconst emacs-data-suffix
(cond ((string= "emacsERC" emacs-environment) "alt")
((string-match "emacs2[67]\\(.+\\)$" emacs-environment)
(match-string 1 emacs-environment))))
(defconst alternate-emacs (string= emacs-data-suffix "alt"))
(defconst user-data-directory
(emacs-path (if emacs-data-suffix
(format "data-%s" emacs-data-suffix)
(load (emacs-path "settings"))
;; Note that deferred loading may override some of these changed values.
;; This can happen with `savehist', for example.
(when emacs-data-suffix
(let ((settings (with-temp-buffer
(insert-file-contents (emacs-path "settings.el"))
(read (current-buffer)))))
(pcase-dolist (`(quote (,var ,value . ,_)) (cdr settings))
(when (and (stringp value)
(string-match "/\\.emacs\\.d/data" value))
(set var (replace-regexp-in-string
(format "/.emacs.d/data-%s" emacs-data-suffix)
(defvar Info-directory-list
(mapcar 'expand-file-name
(mapcar (apply-partially #'expand-file-name "share/info")
(nix-read-environment emacs-environment))
(setq disabled-command-function nil) ;; enable all commands
;; Disable all warnings about obsolete functions here.
(dolist (sym '(flet lisp-complete-symbol))
(setplist sym (use-package-plist-delete (symbol-plist sym)
;;; Libraries
(use-package alert :defer t :load-path "lisp/alert")
(use-package anaphora :defer t)
(use-package apiwrap :defer t)
(use-package asoc :defer t)
(use-package async :defer t :load-path "lisp/async")
(use-package button-lock :defer t)
(use-package ctable :defer t)
(use-package dash :defer t)
(use-package deferred :defer t)
(use-package diminish :demand t)
(use-package el-mock :defer t)
(use-package elisp-refs :defer t)
(use-package epc :defer t)
(use-package epl :defer t)
(use-package esxml :defer t)
(use-package f :defer t)
(use-package fn :defer t)
(use-package fringe-helper :defer t)
(use-package fuzzy :defer t)
(use-package ghub
:defer t
(require 'auth-source-pass)
(defvar my-ghub-token-cache nil)
'ghub--token :around
#'(lambda (orig-func host username package &optional nocreate forge)
(or my-ghub-token-cache
(setq my-ghub-token-cache
(funcall orig-func host username package nocreate forge))))))
(use-package ghub+ :defer t)
(use-package ht :defer t)
(use-package kv :defer t)
(use-package list-utils :defer t)
(use-package logito :defer t)
(use-package loop :defer t)
(use-package m-buffer :defer t)
(use-package makey :defer t)
(use-package marshal :defer t)
(use-package names :defer t)
(use-package noflet :defer t)
(use-package oauth2 :defer t)
(use-package ov :defer t)
(use-package packed :defer t)
(use-package parent-mode :defer t)
(use-package parsebib :defer t)
(use-package parsec :defer t)
(use-package peval :defer t)
(use-package pfuture :defer t)
(use-package pkg-info :defer t)
(use-package popup :defer t)
(use-package popup-pos-tip :defer t)
(use-package popwin :defer t)
(use-package pos-tip :defer t)
(use-package request :defer t)
(use-package rich-minority :defer t)
(use-package s :defer t)
(use-package simple-httpd :defer t)
(use-package spinner :defer t)
(use-package tablist :defer t)
(use-package uuidgen :defer t)
(use-package web :defer t)
(use-package web-server :defer t)
(use-package websocket :defer t)
(use-package with-editor :defer t)
(use-package xml-rpc :defer t)
(use-package zoutline :defer t)
;;; Keymaps
(define-key input-decode-map [?\C-m] [C-m])
(mapc #'(lambda (entry)
(define-prefix-command (cdr entry))
(bind-key (car entry) (cdr entry)))
'(("C-," . my-ctrl-comma-map)
("<C-m>" . my-ctrl-m-map)
("C-h e" . my-ctrl-h-e-map)
("C-h x" . my-ctrl-h-x-map)
("C-c b" . my-ctrl-c-b-map)
("C-c e" . my-ctrl-c-e-map)
("C-c m" . my-ctrl-c-m-map)
("C-c w" . my-ctrl-c-w-map)
("C-c y" . my-ctrl-c-y-map)
("C-c H" . my-ctrl-c-H-map)
("C-c N" . my-ctrl-c-N-map)
("C-c (" . my-ctrl-c-open-paren-map)
("C-c -" . my-ctrl-c-minus-map)
("C-c =" . my-ctrl-c-equals-map)
("C-c ." . my-ctrl-c-r-map)
;;; Packages
(use-package abbrev
:defer 5
((text-mode prog-mode erc-mode LaTeX-mode) . abbrev-mode)
. (lambda ()
(add-hook 'expand-expand-hook #'indent-according-to-mode)
(add-hook 'expand-jump-hook #'indent-according-to-mode)))
(if (file-exists-p abbrev-file-name)
(use-package ace-jump-mode
:defer t)
(use-package ace-link
:disabled t
:defer 10
:bind ("C-c M-o" . ace-link-addr)
(add-hook 'org-mode-hook
#'(lambda () (bind-key "C-c C-o" #'ace-link-org org-mode-map)))
(add-hook 'gnus-summary-mode-hook
#'(lambda () (bind-key "M-o" #'ace-link-gnus gnus-summary-mode-map)))
(add-hook 'gnus-article-mode-hook
#'(lambda () (bind-key "M-o" #'ace-link-gnus gnus-article-mode-map)))
(add-hook 'ert-results-mode-hook
#'(lambda () (bind-key "o" #'ace-link-help ert-results-mode-map)))
(add-hook 'eww-mode-hook
#'(lambda () (bind-key "f" #'ace-link-eww eww-mode-map))))
(use-package ace-mc
:bind (("<C-m> h" . ace-mc-add-multiple-cursors)
("<C-m> M-h" . ace-mc-add-single-cursor)))
(use-package ace-window
:bind* ("<C-return>" . ace-window))
(use-package adoc-mode
:mode "\\.adoc\\'"
(add-hook 'adoc-mode-hook
#'(lambda ()
(auto-fill-mode 1)
;; (visual-line-mode 1)
;; (visual-fill-column-mode 1)
(use-package agda-input
:demand t
(setq-default default-input-method "Agda")
;; (dolist (hook '(minibuffer-setup-hook
;; fundamental-mode-hook
;; text-mode-hook
;; prog-mode-hook))
;; (add-hook hook #'(lambda () (set-input-method "Agda"))))
(use-package agda2-mode
;; This declaration depends on the load-path established by agda-input.
:mode ("\\.agda\\'" "\\\\'")
:bind (:map agda2-mode-map
("C-c C-i" . agda2-insert-helper-function))
(defun agda2-insert-helper-function (&optional prefix)
(interactive "P")
(let ((func-def (with-current-buffer "*Agda information*"
(let ((name (car (split-string func-def " "))))
(insert " where\n " func-def " " name " x = ?\n")))))
(advice-add 'agda2-mode
:before #'direnv-update-directory-environment))
(use-package aggressive-indent
:hook (emacs-lisp-mode . aggressive-indent-mode))
(use-package align
:bind (("M-[" . align-code)
("C-c [" . align-regexp))
:commands align
(defun align-code (beg end &optional arg)
(interactive "rP")
(if (null arg)
(align beg end)
(let ((end-mark (copy-marker end)))
(indent-region beg end-mark nil)
(align beg end-mark)))))
(use-package anki-editor
:commands anki-editor-submit)
(use-package aria2
:commands aria2-downloads-list)
(use-package ascii
:bind ("C-c e A" . ascii-toggle)
:commands (ascii-on ascii-off)
(defun ascii-toggle ()
(if ascii-display
(use-package auctex
:demand t
:no-require t
:mode ("\\.tex\\'" . TeX-latex-mode)
(defun latex-help-get-cmd-alist () ;corrected version:
"Scoop up the commands in the index of the latex info manual.
The values are saved in `latex-help-cmd-alist' for speed."
;; mm, does it contain any cached entries
(if (not (assoc "\\begin" latex-help-cmd-alist))
(setq latex-help-cmd-alist nil)
(Info-goto-node (concat latex-help-file "Command Index"))
(goto-char (point-max))
(while (re-search-backward "^\\* \\(.+\\): *\\(.+\\)\\." nil t)
(let ((key (buffer-substring (match-beginning 1) (match-end 1)))
(value (buffer-substring (match-beginning 2)
(match-end 2))))
(add-to-list 'latex-help-cmd-alist (cons key value))))))
(add-hook 'TeX-after-compilation-finished-functions
(use-package auth-source-pass
(defvar auth-source-pass--cache (make-hash-table :test #'equal))
(defun auth-source-pass--reset-cache ()
(setq auth-source-pass--cache (make-hash-table :test #'equal)))
(defun auth-source-pass--read-entry (entry)
"Return a string with the file content of ENTRY."
(run-at-time 45 nil #'auth-source-pass--reset-cache)
(let ((cached (gethash entry auth-source-pass--cache)))
(or cached
(insert-file-contents (expand-file-name
(format "%s.gpg" entry)
(buffer-substring-no-properties (point-min) (point-max)))
(defun auth-source-pass-entries ()
"Return a list of all password store entries."
(let ((store-dir (getenv "PASSWORD_STORE_DIR")))
(lambda (file) (file-name-sans-extension (file-relative-name file store-dir)))
(directory-files-recursively store-dir "\.gpg$")))))
(use-package auto-yasnippet
:after yasnippet
:bind (("C-c y a" . aya-create)
("C-c y e" . aya-expand)
("C-c y o" . aya-open-line)))
(use-package avy
:bind* ("C-." . avy-goto-char-timer)
(use-package avy-zap
:bind (("M-z" . avy-zap-to-char-dwim)
("M-Z" . avy-zap-up-to-char-dwim)))
(use-package backup-each-save
:commands backup-each-save
(defun my-make-backup-file-name (file)
(make-backup-file-name-1 (expand-file-name (file-truename file))))
(defun backup-each-save-filter (filename)
(not (string-match
(concat "\\(^/tmp\\|\\.emacs\\.d/data\\(-alt\\)?/"
(defun my-dont-backup-files-p (filename)
(unless (string-match filename "\\(archive/sent/\\|recentf\\`\\)")
(normal-backup-enable-predicate filename)))
:hook after-save
(setq backup-each-save-filter-function 'backup-each-save-filter
backup-enable-predicate 'my-dont-backup-files-p))
(use-package backup-walker
:commands backup-walker-start)
(use-package beacon
:commands beacon-mode)
(use-package biblio
:commands biblio-lookup)
(use-package bm
:unless alternate-emacs
:bind (("C-c b b" . bm-toggle)
("C-c b n" . bm-next)
("C-c b p" . bm-previous))
:commands (bm-repository-load
(add-hook 'after-init-hook #'bm-repository-load)
(add-hook 'find-file-hooks #'bm-buffer-restore)
(add-hook 'after-revert-hook #'bm-buffer-restore)
(add-hook 'kill-buffer-hook #'bm-buffer-save)
(add-hook 'after-save-hook #'bm-buffer-save)
(add-hook 'vc-before-checkin-hook #'bm-buffer-save)
(add-hook 'kill-emacs-hook #'(lambda nil
(use-package bookmark+
:after bookmark
:bind ("M-B" . bookmark-bmenu-list)
:commands bmkp-jump-dired)
(use-package browse-at-remote
:bind ("C-c B" . browse-at-remote))
(use-package browse-kill-ring
:defer 5
:commands browse-kill-ring)
(use-package browse-kill-ring+
:after browse-kill-ring
:config (browse-kill-ring-default-keybindings))
(use-package bytecomp-simplify
:defer 15)
(use-package c-includes
:disabled t
:commands c-includes
:after cc-mode
:bind (:map c-mode-base-map
("C-c C-i" . c-includes-current-file)))
(use-package calc
:defer t
'((GiB "1024 * MiB" "Giga Byte")
(MiB "1024 * KiB" "Mega Byte")
(KiB "1024 * B" "Kilo Byte")
(B nil "Byte")
(Gib "1024 * Mib" "Giga Bit")
(Mib "1024 * Kib" "Mega Bit")
(Kib "1024 * b" "Kilo Bit")
(b "B / 8" "Bit")))
(setq math-units-table nil))
(use-package cargo
:commands cargo-minor-mode
:bind (:map cargo-mode-map
("C-c C-c C-y" . cargo-process-clippy))
(defadvice cargo-process-clippy
(around my-cargo-process-clippy activate)
(let ((cargo-process--command-flags
(concat cargo-process--command-flags
" --tests -- -D clippy::all -D clippy::cognitive_complexity")))
(defun cargo-fix ()
(concat "cargo fix -Z unstable-options"
" --clippy --tests --benches --allow-dirty --allow-staged"))))
(use-package cc-mode
:mode (("\\.h\\(h?\\|xx\\|pp\\)\\'" . c++-mode)
("\\.m\\'" . c-mode)
("\\.mm\\'" . c++-mode))
:bind (:map c++-mode-map
("<" . self-insert-command)
(">" . self-insert-command))
:bind (:map c-mode-base-map
("#" . self-insert-command)
("{" . self-insert-command)
("}" . self-insert-command)
("/" . self-insert-command)
("*" . self-insert-command)
(";" . self-insert-command)
("," . self-insert-command)
(":" . self-insert-command)
("(" . self-insert-command)
(")" . self-insert-command)
("<return>" . newline-and-indent)
("M-q" . c-fill-paragraph)
(defun my-c-mode-common-hook ()
(require 'flycheck)
;; (flycheck-define-checker
;; c++-ledger
;; "A C++ syntax checker for the Ledger project specifically."
;; :command ("ninja"
;; "-C"
;; (eval (expand-file-name "~/Products/ledger"))
;; (eval (concat "src/CMakeFiles/libledger.dir/"
;; (file-name-nondirectory (buffer-file-name))
;; ".o")))
;; :error-patterns
;; ((error line-start
;; (message "In file included from") " " (or "<stdin>" (file-name))
;; ":" line ":" line-end)
;; (info line-start (or "<stdin>" (file-name)) ":" line ":" column
;; ": note: " (optional (message)) line-end)
;; (warning line-start (or "<stdin>" (file-name)) ":" line ":" column
;; ": warning: " (optional (message)) line-end)
;; (error line-start (or "<stdin>" (file-name)) ":" line ":" column
;; ": " (or "fatal error" "error") ": " (optional (message)) line-end))
;; :error-filter
;; (lambda (errors)
;; (let ((errors (flycheck-sanitize-errors errors)))
;; (dolist (err errors)
;; ;; Clang will output empty messages for #error/#warning pragmas
;; ;; without messages. We fill these empty errors with a dummy message
;; ;; to get them past our error filtering
;; (setf (flycheck-error-message err)
;; (or (flycheck-error-message err) "no message")))
;; (flycheck-fold-include-levels errors "In file included from")))
;; :modes c++-mode
;; :next-checkers ((warning . c/c++-cppcheck)))
(flycheck-mode 1)
;; (flycheck-select-checker 'c++-ledger)
(setq-local flycheck-check-syntax-automatically nil)
(setq-local flycheck-highlighting-mode nil)
(set (make-local-variable 'parens-require-spaces) nil)
(let ((bufname (buffer-file-name)))
(when bufname
((string-match "/ledger/" bufname)
(c-set-style "ledger"))
((string-match "/edg/" bufname)
(c-set-style "edg"))
(c-set-style "clang")))))
'c++-mode '(("\\<\\(assert\\|DEBUG\\)(" 1 font-lock-warning-face t))))
:hook (c-mode-common . my-c-mode-common-hook)
(indent-tabs-mode . nil)
(c-basic-offset . 2)
(c-comment-only-line-offset . (0 . 0))
. ((substatement-open before after)
. ((statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . 0)
(substatement-label . 0)
(label . 0)
(case-label . +)
(statement-case-open . 0)
(statement-cont . +)
(arglist-intro . +)
(arglist-close . +)
(inline-open . 0)
(brace-list-open . 0)
. (first c-lineup-topmost-intro-cont
(c-special-indent-hook . c-gnu-impose-minimum)
(c-block-comment-prefix . "")))
(indent-tabs-mode . nil)
(c-basic-offset . 2)
(c-comment-only-line-offset . (0 . 0))
. ((substatement-open before after)
. ((statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . 0)
(substatement-label . 0)
(label . 0)
(case-label . 0)
(statement-case-open . 0)
(statement-cont . +)
(arglist-intro . +)
(arglist-close . +)
(inline-open . 0)
(brace-list-open . 0)
. (first c-lineup-topmost-intro-cont
(c-special-indent-hook . c-gnu-impose-minimum)
(c-block-comment-prefix . "")))
(indent-tabs-mode . nil)
(c-basic-offset . 2)
(c-comment-only-line-offset . (0 . 0))
. ((substatement-open before after)
. ((statement-block-intro . +)
(knr-argdecl-intro . 5)
(substatement-open . 0)
(substatement-label . 0)
(label . 0)
(case-label . 0)
(statement-case-open . 0)
(statement-cont . +)
(arglist-intro . +)
(arglist-close . +)
(inline-open . 0)
(brace-list-open . 0)
. (first c-lineup-topmost-intro-cont
(c-special-indent-hook . c-gnu-impose-minimum)
(c-block-comment-prefix . ""))))
(use-package centered-cursor-mode
:commands centered-cursor-mode)
(use-package change-inner
:bind (("M-i" . change-inner)
("M-o M-o" . change-outer)))
(use-package chess
:load-path "lisp/chess"
:commands chess)
(use-package chess-ics
:after chess
:commands chess-ics
(defun chess ()
(chess-ics "" 5000 "jwiegley"
(lookup-password "" "jwiegley" 80))))
(use-package circe
:if alternate-emacs
:defer t)
(use-package cl-info
;; jww (2017-12-10): Need to configure.
:disabled t)
;; (use-package clipmon
;; :bind ("<f2>" . clipmon-autoinsert-toggle)
;; :hook (after-init . clipmon-mode-start))
(use-package cmake-font-lock
:hook (cmake-mode . cmake-font-lock-activate))
(use-package cmake-mode
:mode ("CMakeLists.txt" "\\.cmake\\'"))
(use-package col-highlight
:commands col-highlight-mode)
(use-package color-moccur
:commands (isearch-moccur isearch-all isearch-moccur-all)
:bind (("M-s O" . moccur)
:map isearch-mode-map
("M-o" . isearch-moccur)
("M-O" . isearch-moccur-all)))
(use-package command-log-mode
:bind (("C-c e M" . command-log-mode)
("C-c e L" . clm/open-command-log-buffer)))
(use-package company
:defer 5
:commands (company-mode company-indent-or-complete-common)
(dolist (hook '(emacs-lisp-mode-hook
(add-hook hook
#'(lambda ()
(local-set-key (kbd "<tab>")
;; From
;; See also
(defadvice company-pseudo-tooltip-unless-just-one-frontend
(around only-show-tooltip-when-invoked activate)
(when (company-explicit-action-p)
;; See
(defun ora-company-number ()
"Forward to `company-complete-number'.
Unless the number is potentially part of the candidate.
In that case, insert the number."
(let* ((k (this-command-keys))
(re (concat "^" company-prefix k)))
(if (cl-find-if (lambda (s) (string-match re s))
(self-insert-command 1)
(company-complete-number (string-to-number k)))))
(let ((map company-active-map))
(lambda (x)
(define-key map (format "%d" x) 'ora-company-number))
(number-sequence 0 9))
(define-key map " " (lambda ()
(self-insert-command 1))))
(defun check-expansion ()
(if (outline-on-heading-p t)
(if (looking-at "\\_>") t
(backward-char 1)
(if (looking-at "\\.") t
(backward-char 1)
(if (looking-at "->") t nil))))))
(define-key company-mode-map [tab]
'(menu-item "maybe-company-expand" nil
:filter (lambda (&optional _)
(when (check-expansion)
(eval-after-load "coq"
(defun company-mode/backend-with-yas (backend)
(if (and (listp backend) (member 'company-yasnippet backend))
(append (if (consp backend) backend (list backend))
'(:with company-yasnippet))))
(setq company-backends
(mapcar #'company-mode/backend-with-yas company-backends))))
(global-company-mode 1))
(use-package company-auctex
:after (company latex))
(use-package company-cabal
:after (company haskell-cabal))
(use-package company-coq
:disabled t
:after coq
:commands company-coq-mode
:bind (:map company-coq-map
:bind (:map coq-mode-map
("C-M-h" . company-coq-toggle-definition-overlay)))
(use-package company-elisp
:after company
(push 'company-elisp company-backends))
(setq-local company-backend '(company-elisp))
(use-package company-ghc
:disabled t
:after (company ghc)
(push 'company-ghc company-backends))
(use-package company-lsp
:after lsp-mode
(require 'lsp-clients)
(push 'company-lsp company-backends))
(use-package company-math
:defer t)
(use-package company-quickhelp
:after company
:bind (:map company-active-map
("C-c ?" . company-quickhelp-manual-begin)))
(use-package company-restclient
:after (company restclient))
(use-package company-rtags
:disabled t
:load-path "~/.nix-profile/share/emacs/site-lisp/rtags"
:after (company rtags)
(push 'company-rtags company-backends))
(use-package company-terraform
:after (company terraform-mode))
(use-package compile
:bind (("C-c c" . compile)
("M-O" . show-compilation))
:bind (:map compilation-mode-map
("z" . delete-window))
(defun show-compilation ()
(let ((it
(catch 'found
(dolist (buf (buffer-list))
(when (string-match "\\*compilation\\*" (buffer-name buf))
(throw 'found buf))))))
(if it
(display-buffer it)
(call-interactively 'compile))))
(defun compilation-ansi-color-process-output ()
(ansi-color-process-output nil)
(set (make-local-variable 'comint-last-output-start)
:hook (compilation-filter . compilation-ansi-color-process-output))
(use-package copy-as-format
:bind (("C-c w m" . copy-as-format-markdown)
("C-c w g" . copy-as-format-slack)
("C-c w o" . copy-as-format-org-mode)
("C-c w r" . copy-as-format-rst)
("C-c w s" . copy-as-format-github)
("C-c w w" . copy-as-format))
(setq copy-as-format-default "github"))
(use-package coq-lookup
:bind ("C-h q" . coq-lookup))
(use-package counsel
:after ivy
:demand t
:custom (counsel-find-file-ignore-regexp
(concat "\\(\\`\\.[^.]\\|"
(regexp-opt completion-ignored-extensions)
:bind (("C-*" . counsel-org-agenda-headlines)
("C-x C-f" . counsel-find-file)
("C-c e l" . counsel-find-library)
("C-c e q" . counsel-set-variable)
("C-h e l" . counsel-find-library)
("C-h e u" . counsel-unicode-char)
("C-h f" . counsel-describe-function)
("C-x r b" . counsel-bookmark)
("M-x" . counsel-M-x)
;; ("M-y" . counsel-yank-pop)
("M-s f" . counsel-file-jump)
;; ("M-s g" . counsel-rg)
("M-s j" . counsel-dired-jump))
:commands counsel-minibuffer-history
(bind-key "M-r" #'counsel-minibuffer-history minibuffer-local-map)
(add-to-list 'ivy-sort-matches-functions-alist
'(counsel-find-file . ivy--sort-files-by-date))
(defun counsel-recoll-function (string)
"Run recoll for STRING."
(if (< (length string) 3)
(counsel-more-chars 3)
(format "recollq -t -b %s"
(shell-quote-argument string)))
(defun counsel-recoll (&optional initial-input)
"Search for a string in the recoll database.
You'll be given a list of files that match.
Selecting a file will launch `swiper' for that file.
INITIAL-INPUT can be given as the initial minibuffer input."
(counsel-require-program "recollq")
(ivy-read "recoll: " 'counsel-recoll-function
:initial-input initial-input
:dynamic-collection t
:history 'counsel-git-grep-history
:action (lambda (x)
(when (string-match "file://\\(.*\\)\\'" x)
(let ((file-name (match-string 1 x)))
(find-file file-name)
(unless (string-match "pdf$" x)
(swiper ivy-text)))))
:unwind #'counsel-delete-process
:caller 'counsel-recoll)))
(use-package counsel-gtags
;; jww (2017-12-10): Need to configure.
:disabled t
:after counsel)
(use-package counsel-osx-app
:bind* ("S-M-SPC" . counsel-osx-app)
:commands counsel-osx-app
(setq counsel-osx-app-location
(list "/Applications"
(expand-file-name "~/Applications")
(expand-file-name "~/.nix-profile/Applications")
(use-package counsel-projectile
:after (counsel projectile)
(counsel-projectile-mode 1))
(use-package counsel-tramp
:commands counsel-tramp)
(use-package crosshairs
:bind ("M-o c" . crosshairs-mode))
(use-package crux
:bind ("C-c e i" . crux-find-user-init-file))
(use-package css-mode
:mode "\\.css\\'")
(use-package csv-mode
:mode "\\.csv\\'"
(defun csv-remove-commas ()
(goto-char (point-min))
(while (re-search-forward "\"\\([^\"]+\\)\"" nil t)
(replace-match (replace-regexp-in-string "," "" (match-string 1)))))
(defun maybe-add (x y)
(if (equal x "")
(if (equal y "")
(if (equal y "")
(format "%0.2f" (+ (string-to-number x) (string-to-number y))))))
(defun parse-desc (desc)
((string-match "\\(BOT \\+\\|SOLD -\\)\\([0-9]+\\) \\(.+\\) @\\([0-9.]+\\)\\( .+\\)?" desc)
(list (match-string 1 desc)
(match-string 2 desc)
(match-string 3 desc)
(match-string 4 desc)
(match-string 5 desc)))))
(defun maybe-add-descs (x y)
(let ((x-info (parse-desc x))
(y-info (parse-desc y)))
(and (string= (nth 0 x-info) (nth 0 y-info))
(string= (nth 2 x-info) (nth 2 y-info))
(string= (nth 3 x-info) (nth 3 y-info))
(format "%s%d %s @%s%s"
(nth 0 y-info)
(+ (string-to-number (nth 1 x-info))
(string-to-number (nth 1 y-info)))
(nth 2 y-info)
(nth 3 y-info)
(or (nth 4 y-info) "")))))
(defun csv-merge-lines ()
(goto-char (line-beginning-position))
(let ((start (point-marker))
(fields-a (csv--collect-fields (line-end-position))))
(forward-line 1)
(let ((fields-b (csv--collect-fields (line-end-position))))
(when (string= (nth 3 fields-a) (nth 3 fields-b))
(let ((desc (maybe-add-descs (nth 4 fields-a) (nth 4 fields-b))))
(when desc
(delete-region start (line-end-position))
(setcar (nthcdr 4 fields-b) desc)
(setcar (nthcdr 5 fields-b)
(maybe-add (nth 5 fields-a) (nth 5 fields-b)))
(setcar (nthcdr 6 fields-b)
(maybe-add (nth 6 fields-a) (nth 6 fields-b)))
(setcar (nthcdr 7 fields-b)
(maybe-add (nth 7 fields-a) (nth 7 fields-b)))
(insert (mapconcat #'identity fields-b ","))
(forward-char 1)
(forward-line -1))))))))
(use-package cursor-chg
:commands change-cursor-mode
(change-cursor-mode 1)
(toggle-cursor-type-when-idle 1))
(use-package cus-edit
:bind (("C-c o" . customize-option)
("C-c O" . customize-group)
("C-c F" . customize-face)))
(use-package debbugs-gnu
:commands (debbugs-gnu debbugs-gnu-search)
:bind ("C-c #" . gnus-read-ephemeral-emacs-bug-group))
(use-package deadgrep
:bind ("M-s g" . deadgrep))
(use-package dedicated
:bind ("C-c W" . dedicated-mode))
(use-package deft
:bind ("C-, C-," . deft))
(use-package diff-hl
:commands (diff-hl-mode diff-hl-dired-mode)
:hook (magit-post-refresh . diff-hl-magit-post-refresh))
(use-package diff-hl-flydiff
:commands diff-hl-flydiff-mode)
(use-package diff-mode
:commands diff-mode)
(use-package diffview
:commands (diffview-current diffview-region diffview-message))
(use-package dired
:bind ("C-c j" . dired-two-pane)
:bind (:map dired-mode-map
("j" . dired)
("z" . pop-window-configuration)
("e" . ora-ediff-files)
("l" . dired-up-directory)
("q" . pop-window-configuration)
("Y" . ora-dired-rsync)
("M-!" . async-shell-command)
("<tab>" . dired-next-window)
("M-s f"))
:diminish dired-omit-mode
:hook (dired-mode . dired-hide-details-mode)
:hook (dired-mode . dired-omit-mode)
(defun dired-two-pane ()
(let ((here default-directory))
(dired "~/dl")
(dired here)))
(defun dired-next-window ()
(let ((next (car (cl-remove-if-not #'(lambda (wind)
(with-current-buffer (window-buffer wind)
(eq major-mode 'dired-mode)))
(cdr (window-list))))))
(when next
(select-window next))))
(defvar mark-files-cache (make-hash-table :test #'equal))
(defun mark-similar-versions (name)
(let ((pat name))
(if (string-match "^\\(.+?\\)-[0-9._-]+$" pat)
(setq pat (match-string 1 pat)))
(or (gethash pat mark-files-cache)
(ignore (puthash pat t mark-files-cache)))))
(defun dired-mark-similar-version ()
(setq mark-files-cache (make-hash-table :test #'equal))
(dired-mark-sexp '(mark-similar-versions name)))
(defun ora-dired-rsync (dest)
(read-file-name "Rsync to: " (dired-dwim-target-directory)))))
(let ((files (dired-get-marked-files
nil current-prefix-arg))
(tmtxt/rsync-command "rsync -aP "))
(dolist (file files)
(setq tmtxt/rsync-command
(concat tmtxt/rsync-command
(shell-quote-argument file)
" ")))
(setq tmtxt/rsync-command
(concat tmtxt/rsync-command
(shell-quote-argument dest)))
(async-shell-command tmtxt/rsync-command "*rsync*")
(other-window 1)))
(defun ora-ediff-files ()
(let ((files (dired-get-marked-files))
(wnd (current-window-configuration)))
(if (<= (length files) 2)
(let ((file1 (car files))
(file2 (if (cdr files)
(cadr files)
"file: "
(if (file-newer-than-file-p file1 file2)
(ediff-files file2 file1)
(ediff-files file1 file2))
(add-hook 'ediff-after-quit-hook-internal
`(lambda ()
(setq ediff-after-quit-hook-internal nil)
(set-window-configuration ,wnd))))
(error "no more than 2 files should be marked"))))
(add-hook 'dired-mode-hook
#'(lambda () (bind-key "M-G" #'switch-to-gnus dired-mode-map))))
(use-package dired-toggle
:bind ("C-c ~" . dired-toggle)
(defun my-dired-toggle-mode-hook ()
(visual-line-mode 1)
(setq-local visual-line-fringe-indicators '(nil right-curly-arrow))
(setq-local word-wrap nil))
:hook (dired-toggle-mode . my-dired-toggle-mode-hook))
(use-package dired-x
:after dired
(defvar dired-omit-regexp-orig (symbol-function 'dired-omit-regexp))
;; Omit files that Git would ignore
(defun dired-omit-regexp ()
(let ((file (expand-file-name ".git"))
(while (and (not (file-exists-p file))
(setq parent-dir
(file-name-directory file))))
;; Give up if we are already at the root dir.
(not (string= (file-name-directory file)
;; Move up to the parent dir and try again.
(setq file (expand-file-name ".git" parent-dir)))
;; If we found a change log in a parent, use that.
(if (file-exists-p file)
(let ((regexp (funcall dired-omit-regexp-orig))
(shell-command-to-string "git clean -d -x -n")))
(if (= 0 (length omitted-files))
(if (> (length regexp) 0)
"\\|" "")
#'(lambda (str)
(substring str 13
(if (= ?/ (aref str (1- (length str))))
(1- (length str))
(split-string omitted-files "\n" t)
(funcall dired-omit-regexp-orig)))))
(use-package dired+
:after dired-x
(defun dired-do-delete (&optional arg) ; Bound to `D'
"Delete all marked (or next ARG) files.
NOTE: This deletes marked, not flagged, files.
`dired-recursive-deletes' controls whether deletion of
non-empty directories is allowed."
(interactive "P")
;; This is more consistent with the file-marking feature than
;; `dired-do-flagged-delete'. But it can be confusing to the user,
;; especially since this is usually bound to `D', which is also the
;; `dired-del-marker'. So offer this warning message:
(unless arg
(message "NOTE: Deletion of files marked `%c' (not those flagged `%c')."
dired-marker-char dired-del-marker))
;; This can move point if ARG is an integer.
(dired-map-over-marks (cons (dired-get-filename) (point)) arg)
(defun dired-do-flagged-delete (&optional no-msg) ; Bound to `x'
"In Dired, delete the files flagged for deletion.
NOTE: This deletes flagged, not marked, files.
If arg NO-MSG is non-nil, no message is displayed.
User option `dired-recursive-deletes' controls whether deletion of
non-empty directories is allowed."
(unless no-msg
(message "NOTE: Deletion of files flagged `%c' (not those marked `%c')"
dired-del-marker dired-marker-char)
;; Too slow/annoying, but without it the message is never seen: (sit-for 2)
(let* ((dired-marker-char dired-del-marker)
(regexp (dired-marker-regexp))
(case-fold-search nil))
(if (save-excursion (goto-char (point-min)) (re-search-forward regexp nil t))
;; This cannot move point since last arg is nil.
(dired-map-over-marks (cons (dired-get-filename) (point)) nil)
'USE-TRASH-CAN) ; This arg is for Emacs 24+ only.
(unless no-msg (message "(No deletions requested.)"))))))
(use-package direnv
:demand t
(defun patch-direnv-environment (&rest _args)
(setenv "PATH" (concat emacs-binary-path ":" (getenv "PATH")))
(setq exec-path (cons (file-name-as-directory emacs-binary-path)
(defconst emacs-binary-path (directory-file-name
(executable-find "emacsclient"))))
(defvar flycheck-executable-for-buffer (make-hash-table :test #'equal))
(defun locate-flycheck-executable (cmd)
;; (add-hook 'post-command-hook #'direnv--maybe-update-environment)
(let ((exe (gethash (cons cmd (buffer-name))
(if exe
(direnv-update-environment default-directory)
(let ((exe (executable-find cmd)))
(puthash (cons cmd (buffer-name)) exe
(eval-after-load 'flycheck
'(setq flycheck-executable-find #'locate-flycheck-executable))
(add-hook 'coq-mode-hook
#'(lambda ()
;; (add-hook 'post-command-hook #'direnv--maybe-update-environment)
(direnv-update-environment default-directory)))
(advice-add 'direnv-update-directory-environment
:after #'patch-direnv-environment)
(add-hook 'git-commit-mode-hook #'patch-direnv-environment)
(add-hook 'magit-status-mode-hook #'patch-direnv-environment)
(defvar my-direnv-last-buffer nil)
(defun update-on-buffer-change ()
(unless (eq (current-buffer) my-direnv-last-buffer)
(setq my-direnv-last-buffer (current-buffer))
(direnv-update-environment default-directory)))
(add-hook 'post-command-hook #'update-on-buffer-change))
(use-package discover-my-major
:bind (("C-h <C-m>" . discover-my-major)
("C-h M-m" . discover-my-mode)))
(use-package docker
:bind ("C-c d" . docker)
(use-package docker-image :commands docker-images)
(use-package docker-container :commands docker-containers)
(use-package docker-volume :commands docker-volumes)
(use-package docker-network :commands docker-containers)
(use-package docker-machine :commands docker-machines)
(use-package docker-compose :commands docker-compose))
(use-package docker-compose-mode
:mode "docker-compose.*\.yml\\'")
(use-package docker-tramp
:after tramp
:defer 5)
(use-package dockerfile-mode
:mode "Dockerfile[a-zA-Z.-]*\\'")
(use-package dot-gnus
:bind (("M-G" . switch-to-gnus)
("C-x m" . compose-mail))
;; Have to set these here, because initsplit sends their customization
;; values to gnus-settings.el.
(setq gnus-init-file (emacs-path "dot-gnus")
gnus-home-directory "~/Messages/Gnus/")
(defun fetchmail-password ()
(lookup-password "" "johnw" 993)))
(use-package dot-org
:commands my-org-startup
:bind* (("M-C" . jump-to-org-agenda)
("M-m" . org-smart-capture)
("M-M" . org-inline-note)
("C-c a" . org-agenda)
("C-c S" . org-store-link)
("C-c l" . org-insert-link))
(unless alternate-emacs
(run-with-idle-timer 300 t 'jump-to-org-agenda)
(use-package doxymacs
:commands (doxymacs-mode doxymacs-font-lock)
(doxymacs-mode 1)
(use-package dumb-jump
:hook ((coq-mode haskell-mode) . dumb-jump-mode))
(use-package ebdb-com
:commands ebdb)
(use-package edbi
:commands edbi:sql-mode)
(use-package ediff
:bind (("C-c = b" . ediff-buffers)
("C-c = B" . ediff-buffers3)
("C-c = c" . compare-windows)
("C-c = =" . ediff-files)
("C-c = f" . ediff-files)
("C-c = F" . ediff-files3)
("C-c = m" . count-matches)
("C-c = r" . ediff-revision)
("C-c = p" . ediff-patch-file)
("C-c = P" . ediff-patch-buffer)
("C-c = l" . ediff-regions-linewise)
("C-c = w" . ediff-regions-wordwise))
(defun test-compare ()
(let ((here (point)))
(search-forward "got:")
(goto-char here))
(search-forward "expected:")
(call-interactively #'compare-windows)))
(use-package ediff-keep
:after ediff)
(use-package edit-env
:commands edit-env)
(use-package edit-indirect
:bind (("C-c '" . edit-indirect-region)))
(use-package edit-rectangle
:bind ("C-x r e" . edit-rectangle))
(use-package edit-server
:disabled t
:if (and window-system
(not alternate-emacs))
:defer 5
(use-package edit-var
:bind ("C-c e v" . edit-variable))
(use-package eglot
:commands eglot
;; (add-to-list 'eglot-server-programs '(rust-mode "rust-analyzer"))
(defun project-root (project)
(car (project-roots project))))
(use-package eldoc
:hook ((c-mode-common emacs-lisp-mode) . eldoc-mode))
(use-package elint
:commands (elint-initialize elint-current-buffer)
:bind ("C-c e E" . my-elint-current-buffer)
(defun my-elint-current-buffer ()
(add-to-list 'elint-standard-variables 'current-prefix-arg)
(add-to-list 'elint-standard-variables 'command-line-args-left)
(add-to-list 'elint-standard-variables 'buffer-file-coding-system)
(add-to-list 'elint-standard-variables 'emacs-major-version)
(add-to-list 'elint-standard-variables 'window-system))
(use-package elisp-depend
:commands elisp-depend-print-dependencies)
(use-package elisp-docstring-mode
:commands elisp-docstring-mode)
(use-package elisp-slime-nav
:commands (elisp-slime-nav-mode
(use-package elmacro
:bind (("C-c m e" . elmacro-mode)
("C-x C-)" . elmacro-show-last-macro)))
(use-package emamux
:commands emamux:send-command)
(use-package emojify
:after erc
:defer 15
;; (global-emojify-mode-line-mode -1)
(use-package emms-setup
:disabled t
:bind ("M-E" . emms-browser)
(use-package engine-mode
:defer 5
(defengine google ""
:keybinding "/")
(engine-mode 1))
(use-package epa
(use-package erc
:commands (erc erc-tls)
:bind (:map erc-mode-map
("C-c r" . reset-erc-track-mode))
(defun irc (&optional arg)
(interactive "P")
(if arg
(pcase-dolist (`(,server . ,nick)
'(("" . "johnw")
("" . "jwiegley")))
(erc-tls :server server :port 6697 :nick (concat nick "_")
:password (lookup-password server nick 6697)))
(let ((pass (lookup-password "" "johnw" 6697)))
(when (> (length pass) 32)
(error "Failed to read ZNC password"))
(erc :server "" :port 6697 :nick "johnw"
:password (concat "johnw/gitter:" pass))
(sleep-for 5)
(erc :server "" :port 6697 :nick "johnw"
:password (concat "johnw/libera:" pass)))))
(defun reset-erc-track-mode ()
(setq erc-modified-channels-alist nil)
(defun setup-irc-environment ()
(set (make-local-variable 'scroll-conservatively) 100)
(setq erc-timestamp-only-if-changed-flag nil
erc-timestamp-format "%H:%M "
erc-fill-prefix " "
erc-fill-column 78
erc-insert-timestamp-function 'erc-insert-timestamp-left
ivy-use-virtual-buffers nil))
(defun accept-certificate ()
(when (re-search-backward "/znc[\n ]+AddTrustedServerFingerprint[\n ]+\\(.+\\)" nil t)
(goto-char (point-max))
(erc-send-input (concat "/znc AddTrustedServerFingerprint " (match-string 1)))))
(defcustom erc-foolish-content '()
"Regular expressions to identify foolish content.
Usually what happens is that you add the bots to
`erc-ignore-list' and the bot commands to this list."
:group 'erc
:type '(repeat regexp))
(defun erc-foolish-content (msg)
"Check whether MSG is foolish."
(erc-list-match erc-foolish-content msg))
(add-hook 'erc-mode-hook #'setup-irc-environment)
(when alternate-emacs
(add-hook 'emacs-startup-hook #'irc))
(eval-after-load 'erc-identd
'(defun erc-identd-start (&optional port)
"Start an identd server listening to port 8113.
Port 113 (auth) will need to be redirected to port 8113 on your
machine -- using iptables, or a program like redir which can be
run from inetd. The idea is to provide a simple identd server
when you need one, without having to install one globally on
your system."
(interactive (list (read-string "Serve identd requests on port: " "8113")))
(unless port (setq port erc-identd-port))
(when (stringp port)
(setq port (string-to-number port)))
(when erc-identd-process
(delete-process erc-identd-process))
(setq erc-identd-process
(make-network-process :name "identd"
:buffer nil
:host 'local :service port
:server t :noquery t
:filter 'erc-identd-filter))
(set-process-query-on-exit-flag erc-identd-process nil)))
(erc-track-minor-mode 1)
(erc-track-mode 1)
(add-hook 'erc-insert-pre-hook
#'(lambda (s)
(when (erc-foolish-content s)
(setq erc-insert-this nil))))
(bind-key "<f5>" #'accept-certificate))
(use-package erc-alert
:disabled t
:after erc)
(use-package erc-highlight-nicknames
:after erc)
(use-package erc-macros
:after erc)
(use-package erc-patch
:disabled t
:after erc)
(use-package erc-question
:disabled t
:after erc)
(use-package erc-yank
:load-path "lisp/erc-yank"
:after erc
:bind (:map erc-mode-map
("C-y" . erc-yank )))
(use-package erefactor
:disabled t
:bind (:map emacs-lisp-mode-map
("C-c C-v" . erefactor-map)))
(use-package ert
:bind ("C-c e t" . ert-run-tests-interactively))
(use-package esh-toggle
:bind ("C-x C-z" . eshell-toggle))
(use-package eshell
:commands (eshell eshell-command)
(defvar eshell-isearch-map
(let ((map (copy-keymap isearch-mode-map)))
(define-key map [(control ?m)] 'eshell-isearch-return)
(define-key map [return] 'eshell-isearch-return)
(define-key map [(control ?r)] 'eshell-isearch-repeat-backward)
(define-key map [(control ?s)] 'eshell-isearch-repeat-forward)
(define-key map [(control ?g)] 'eshell-isearch-abort)
(define-key map [backspace] 'eshell-isearch-delete-char)
(define-key map [delete] 'eshell-isearch-delete-char)
"Keymap used in isearch in Eshell.")
(defun eshell-initialize ()
(defun eshell-spawn-external-command (beg end)
"Parse and expand any history references in current input."
(goto-char end)
(when (looking-back "&!" beg)
(delete-region (match-beginning 0) (match-end 0))
(goto-char beg)
(insert "spawn "))))
(add-hook 'eshell-expand-input-functions #'eshell-spawn-external-command)
(use-package em-unix
:defer t
(unintern 'eshell/su nil)
(unintern 'eshell/sudo nil)))
(add-hook 'eshell-first-time-mode-hook #'eshell-initialize))
(use-package eshell-bookmark
:hook (eshell-mode . eshell-bookmark-setup))
(use-package eshell-up
:commands eshell-up)
(use-package eshell-z
:after eshell)
(use-package etags
:bind ("M-T" . tags-search))
(use-package eval-expr
:bind ("M-:" . eval-expr)
(defun eval-expr-minibuffer-setup ()
(local-set-key (kbd "<tab>") #'lisp-complete-symbol)
(set-syntax-table emacs-lisp-mode-syntax-table)
(use-package eval-in-repl
;; jww (2017-12-10): Need to configure.
:disabled t)
(use-package evil
:commands evil-mode)
(use-package expand-region
:bind ("C-=" . er/expand-region))
(use-package eyebrowse
:bind-keymap ("C-\\" . eyebrowse-mode-map)
:bind (:map eyebrowse-mode-map
("C-\\ C-\\" . eyebrowse-last-window-config)
("A-1" . eyebrowse-switch-to-window-config-1)
("A-2" . eyebrowse-switch-to-window-config-2)
("A-3" . eyebrowse-switch-to-window-config-3)
("A-4" . eyebrowse-switch-to-window-config-4))
(eyebrowse-mode t))
(use-package fancy-narrow
:bind (("C-c N N" . fancy-narrow-to-region)
("C-c N W" . fancy-widen))
:commands (fancy-narrow-to-region fancy-widen))
(use-package fast-scroll
:disabled t
:demand t
(add-hook 'fast-scroll-start-hook #'(lambda () (flycheck-mode -1)))
(add-hook 'fast-scroll-end-hook #'(lambda () (flycheck-mode 1)))
(fast-scroll-mode 1))
(use-package feebleline
:bind (("M-o m" . feebleline-mode))
(window-divider-mode t))
(use-package fence-edit
:commands fence-edit-code-at-point)
(use-package fetchmail-mode
:commands fetchmail-mode)
(use-package ffap
:bind ("C-c v" . ffap))
(use-package flycheck
:commands (flycheck-mode
(dolist (where '((emacs-lisp-mode-hook . emacs-lisp-mode-map)
(haskell-mode-hook . haskell-mode-map)
(js2-mode-hook . js2-mode-map)
(c-mode-common-hook . c-mode-base-map)))
(add-hook (car where)
`(lambda ()
(bind-key "M-n" #'flycheck-next-error ,(cdr where))
(bind-key "M-p" #'flycheck-previous-error ,(cdr where)))))
(defalias 'show-error-at-point-soon
(defun magnars/adjust-flycheck-automatic-syntax-eagerness ()
"Adjust how often we check for errors based on if there are any.
This lets us fix any errors as quickly as possible, but in a
clean buffer we're an order of magnitude laxer about checking."
(setq flycheck-idle-change-delay
(if flycheck-current-errors 0.3 3.0)))
;; Each buffer gets its own idle-change-delay because of the
;; buffer-sensitive adjustment above.
(make-variable-buffer-local 'flycheck-idle-change-delay)
(add-hook 'flycheck-after-syntax-check-hook
;; Remove newline checks, since they would trigger an immediate check
;; when we want the idle-change-delay to be in effect while editing.
(setq-default flycheck-check-syntax-automatically '(save
(defun flycheck-handle-idle-change ()
"Handle an expired idle time since the last change.
This is an overwritten version of the original
flycheck-handle-idle-change, which removes the forced deferred.
Timers should only trigger inbetween commands in a single
threaded system and the forced deferred makes errors never show
up before you execute another command."
(flycheck-buffer-automatically 'idle-change)))
(use-package flycheck-haskell
:commands flycheck-haskell-setup)
(use-package flycheck-hdevtools
:disabled t
:after flycheck
(use-package flycheck-package
:after flycheck)
(use-package flycheck-rtags
:disabled t
:load-path "~/.nix-profile/share/emacs/site-lisp/rtags"
:after flycheck)
;; (use-package flycheck-rust
;; :config (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))
(use-package flyspell
:bind (("C-c i b" . flyspell-buffer)
("C-c i f" . flyspell-mode))
(defun my-flyspell-maybe-correct-transposition (beg end candidates)
(unless (let (case-fold-search)
(string-match "\\`[A-Z0-9]+\\'"
(buffer-substring-no-properties beg end)))
(flyspell-maybe-correct-transposition beg end candidates))))
(use-package focus
:commands focus-mode)
(use-package font-lock-studio
:commands (font-lock-studio
(use-package forge
:after magit
(defun my-quick-create-pull-request (title branch)
(interactive "sTitle: \nsBranch: ")
(setq branch (concat "johnw/" branch))
;; Split this commit to another branch.
(magit-branch-spinoff branch)
;; Push that branch to the remote.
(call-interactively #'magit-push-current-to-pushremote)
;; Create a pullreq using the same title.
(forge-create-pullreq (concat "origin/" branch) "origin/master"))
(transient-insert-suffix 'forge-dispatch "c i"
'("p" "quick-pr" my-quick-create-pull-request))
(remove-hook 'magit-status-sections-hook 'forge-insert-issues))
(use-package format-all
:commands (format-all-buffer
(defun format-all--resolve-system (choices)
"Get first choice matching `format-all--system-type' from CHOICES."
(cl-dolist (choice choices)
(cond ((atom choice)
(cl-return choice))
((eql format-all--system-type (car choice))
(cl-return (cadr choice))))))
(define-format-all-formatter ormolu
(:executable "ormolu")
(:install "stack install ormolu")
(:languages "Haskell" "Literate Haskell")
(:format (format-all--buffer-easy executable))))
(use-package free-keys
:commands free-keys)
(use-package fullframe
:defer t
(autoload #'fullframe "fullframe"))
(use-package ggtags
;; jww (2017-12-10): Need to configure.
:disabled t
:commands ggtags-mode
(use-package gist
:no-require t
:bind ("C-c G" . my-gist-region-or-buffer)
(defun my-gist-region-or-buffer (start end)
(interactive "r")
(copy-region-as-kill start end)
(let ((file-name buffer-file-name))
(if file-name
(call-process "gist" nil t nil "-f" file-name "-P")
(call-process "gist" nil t nil "-P"))
(kill-ring-save (point-min) (1- (point-max)))
(message (buffer-substring (point-min) (1- (point-max))))))))
(use-package git-annex
:load-path "lisp/git-annex"
:after dired
:defer t)
(use-package git-link
:bind ("C-c Y" . git-link)
:commands (git-link git-link-commit git-link-homepage))
(use-package git-timemachine
:commands git-timemachine)
(use-package git-undo
:load-path "lisp/git-undo"
:commands git-undo)
(use-package gitattributes-mode
:defer 5)
(use-package gitconfig-mode
:defer 5)
(use-package gitignore-mode
:defer 5)
(use-package github-review
:after forge
:commands github-review-start
(transient-insert-suffix 'forge-dispatch "c p"
'("c r" "github-review" github-review-forge-pr-at-point)))
(use-package gitpatch
:commands gitpatch-mail)
(use-package go-jira
:no-require t
(defvar jira-token nil)
(defun jira-create ()
(unless jira-token
(setq jira-token (lookup-password "" "johnw" 6697)))
(setenv "JIRA_API_TOKEN" jira-token)
(require 'with-editor)
(start-process "go-jira" (get-buffer-create " *go-jira*")
"jira" "create" "-b"
"--editor" (concat with-editor-emacsclient-executable
" -s /tmp/emacs501/server")
"-t" (expand-file-name "~/doc/tasks/jira.template"))))
(use-package google-this
:bind-keymap ("C-c /" . google-this-mode-submap)
:bind* ("M-SPC" . google-this-search)
:bind (:map google-this-mode-map
("/" . google-this-search)))
(use-package goto-last-change
:bind ("C-x C-/" . goto-last-change))
(use-package goto-line-preview
(global-set-key [remap goto-line] 'goto-line-preview))
(use-package graphviz-dot-mode
:mode "\\.dot\\'")
(use-package grep
:bind (("M-s n" . find-name-dired)
("M-s F" . find-grep)
("M-s G" . grep)
("M-s d" . find-grep-dired)))
(use-package gud
:commands gud-gdb
:bind (("<f9>" . gud-cont)
("<f10>" . gud-next)
("<f11>" . gud-step)
("S-<f11>" . gud-finish))
(defun show-debugger ()
(let ((gud-buf
(catch 'found
(dolist (buf (buffer-list))
(if (string-match "\\*gud-" (buffer-name buf))
(throw 'found buf))))))
(if gud-buf
(switch-to-buffer-other-window gud-buf)
(call-interactively 'gud-gdb)))))
(use-package gud-lldb
:commands lldb)
(use-package haskell-edit
:load-path "lisp/haskell-config"
:after haskell-mode
:bind (:map haskell-mode-map
("C-c M-q" . haskell-edit-reformat)))
(use-package haskell-mode
:mode (("\\.hs\\(c\\|-boot\\)?\\'" . haskell-mode)
("\\.lhs\\'" . literate-haskell-mode)
("\\.cabal\\'" . haskell-cabal-mode))
:bind (:map haskell-mode-map
("C-c C-h" . my-haskell-hoogle)
("C-c C-," . haskell-navigate-imports)
("C-c C-." . haskell-mode-format-imports)
("C-c C-u" . my-haskell-insert-undefined)
(defun my-haskell-insert-undefined ()
(interactive) (insert "undefined"))
(defun snippet (name)
(interactive "sName: ")
(find-file (expand-file-name (concat name ".hs") "~/src/notes"))
(goto-char (point-min))
(when (eobp)
(insert "hdr")
(defvar hoogle-server-process nil)
(defun my-haskell-hoogle (query &optional arg)
"Do a Hoogle search for QUERY."
(let ((def (haskell-ident-at-point)))
(if (and def (symbolp def)) (setq def (symbol-name def)))
(list (read-string (if def
(format "Hoogle query (default %s): " def)
"Hoogle query: ")
nil nil def)
(let ((pe process-environment)
(ep exec-path)
(default-hoo (expand-file-name
(locate-dominating-file "." "default.hoo"))))
(unless (and hoogle-server-process
(process-live-p hoogle-server-process))
(message "Starting local Hoogle server on port 8687...")
(with-current-buffer (get-buffer-create " *hoogle-web*")
(cd temporary-file-directory)
(let ((process-environment pe)
(exec-path ep))
(setq hoogle-server-process
(start-process "hoogle-web" (current-buffer)
(executable-find "hoogle")
"server" (concat "--database=" default-hoo)
"--local" "--port=8687"))))
(message "Starting local Hoogle server on port 8687...done")))
(format ""
" " "+" (replace-regexp-in-string "\\+" "%2B" query)))))
(defvar haskell-prettify-symbols-alist
'(("::" . ?∷)
("forall" . ?∀)
("exists" . ?∃)
("->" . ?→)
("<-" . ?←)
("=>" . ?⇒)
("~>" . ?⇝)
("<~" . ?⇜)
("<>" . ?⨂)
("msum" . ?⨁)
("\\" . )
("not" . )
("&&" . ?∧)
("||" . ?∨)
("/=" . ?≠)
("<=" . ?≤)
(">=" . ?≥)
("<<<" . ?⋘)
(">>>" . ?⋙)
("`elem`" . ?∈)
("`notElem`" . ?∉)
("`member`" . ?∈)
("`notMember`" . ?∉)
("`union`" . ?∪)
("`intersection`" . ?∩)
("`isSubsetOf`" . ?⊆)
("`isNotSubsetOf`" . ?⊄)
("`isSubsequenceOf`" . ?⊆)
("`isProperSubsetOf`" . ?⊂)
("undefined" . ?⊥)))
(require 'haskell)
(require 'haskell-doc)
(require 'haskell-commands)
(defun my-update-cabal-repl (&rest _args)
(aif (getenv "CABAL_REPL")
(let ((args (nthcdr 2 (split-string it))))
(setq-local haskell-process-args-cabal-repl
(append haskell-process-args-cabal-repl args))))))
(defun my-haskell-mode-hook ()
(diminish 'interactive-haskell-mode)
(when (and (boundp 'brittany-enabled)
(let ((brittany (find-brittany)))
(when brittany
(setq-local haskell-stylish-on-save t)
(setq-local haskell-mode-stylish-haskell-path brittany)
(setq-local haskell-mode-stylish-haskell-args '("-")))))
(advice-add 'direnv-update-directory-environment
:after #'my-update-cabal-repl)
(whitespace-mode 1)
(flycheck-mode 1)
(add-hook 'hack-local-variables-hook
#'(lambda ()
(when nil
(setq-local flycheck-ghc-search-path nil)
(setq-local flycheck-ghc-args nil)))
(setq-local prettify-symbols-alist haskell-prettify-symbols-alist)
(prettify-symbols-mode 1)
(bug-reference-prog-mode 1)
(when (executable-find "ormolu")
(require 'format-all)
(format-all--set-chain "Haskell" '(ormolu))
(format-all-mode 1)))
(add-hook 'haskell-mode-hook #'my-haskell-mode-hook)
(eval-after-load 'align
(mapcar #'(lambda (x)
`(,(car x)
(regexp . ,(cdr x))
(modes quote (haskell-mode literate-haskell-mode))))
'((haskell-types . "\\(\\s-+\\)\\(::\\|∷\\)\\s-+")
(haskell-assignment . "\\(\\s-+\\)=\\s-+")
(haskell-arrows . "\\(\\s-+\\)\\(->\\|→\\)\\s-+")
(haskell-left-arrows . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+")))))
(defun haskell-process-load-complete
(session process buffer reload module-buffer &optional cont)
"Handle the complete loading response. BUFFER is the string of
text being sent over the process pipe. MODULE-BUFFER is the
actual Emacs buffer of the module being loaded."
(when (get-buffer (format "*%s:splices*" (haskell-session-name session)))
(with-current-buffer (haskell-interactive-mode-splices-buffer session)
(let* ((ok (cond
"Ok, \\(?:\\([0-9]+\\|one\\)\\) modules? loaded\\.$")
"Failed, \\(?:[0-9]+\\) modules? loaded\\.$")
"Ok, modules loaded: \\(.+\\)\\.$")
"Failed, modules loaded: \\(.+\\)\\.$")
(error (message "Unexpected response from haskell process.")))))
(modules (haskell-process-extract-modules buffer))
(cursor (haskell-process-response-cursor process))
(warning-count 0))
(haskell-process-set-response-cursor process 0)
(haskell-check-remove-overlays module-buffer)
(haskell-process-errors-warnings module-buffer session process buffer)
(setq warning-count (1+ warning-count)))
(haskell-process-set-response-cursor process cursor)
(if (and (not reload)
(haskell-process-reload-with-fbytecode process module-buffer)
(haskell-process-import-modules process (car modules)))
(if ok
(haskell-mode-message-line (if reload "Reloaded OK." "OK."))
(haskell-interactive-mode-compile-error session "Compilation failed."))
(when cont
(condition-case-unless-debug e
(funcall cont ok)
(error (message "%S" e))
(quit nil))))))
(use-package hcl-mode
:mode "\.nomad\\'")
(use-package helm
:defer t
:bind (:map helm-map
("<tab>" . helm-execute-persistent-action)
("C-i" . helm-execute-persistent-action)
("C-z" . helm-select-action)
("A-v" . helm-previous-page))
(helm-autoresize-mode 1))
(use-package helm-descbinds
:bind ("C-h b" . helm-descbinds)
(fset 'describe-bindings 'helm-descbinds))
(use-package helm-describe-modes
:after helm
:bind ("C-h m" . helm-describe-modes))
(use-package helm-firefox
:bind ("A-M-b" . helm-firefox-bookmarks))
(use-package helm-font
:commands (helm-select-xfont helm-ucs))
(use-package helm-google
:commands helm-google)
(use-package helm-navi
:after (helm navi)
:commands helm-navi)
(use-package helm-sys
:commands helm-top)
(use-package helpful
:bind (("C-h e F" . helpful-function)
("C-h e C" . helpful-command)
("C-h e M" . helpful-macro)
("C-h e L" . helpful-callable)
("C-h e S" . helpful-at-point)
("C-h e V" . helpful-variable)))
(use-package hi-lock
:bind (("M-o l" . highlight-lines-matching-regexp)
("M-o r" . highlight-regexp)
("M-o w" . highlight-phrase)))
(use-package hideif
:diminish hide-ifdef-mode
:hook (c-mode-common . hide-ifdef-mode))
(use-package hideshow
:diminish hs-minor-mode
:hook (prog-mode . hs-minor-mode)
:bind (:map prog-mode-map
("C-c h" . hs-toggle-hiding)))
(use-package highlight
:bind (("C-c H H" . hlt-highlight-region)
("C-c H U" . hlt-unhighlight-region)))
(use-package highlight-cl
:hook (emacs-lisp-mode . highlight-cl-add-font-lock-keywords))
(use-package highlight-defined
:commands highlight-defined-mode)
(use-package highlight-numbers
:hook (prog-mode . highlight-numbers-mode))
(use-package hilit-chg
:bind ("M-o C" . highlight-changes-mode))
(use-package hippie-exp
:bind (("M-/" . hippie-expand)
("C-M-/" . dabbrev-completion)))
(use-package hl-line
:commands hl-line-mode
:bind ("M-o h" . hl-line-mode))
(use-package hl-line+
:after hl-line)
(use-package hydra
:defer t
(defhydra hydra-zoom (global-map "<f2>")
("g" text-scale-increase "in")
("l" text-scale-decrease "out")))
(use-package ibuffer
:bind ("C-x C-b" . ibuffer)
(add-hook 'ibuffer-mode-hook
#'(lambda ()
(ibuffer-switch-to-saved-filter-groups "default"))))
(use-package iedit
:defer t)
(use-package ielm
:commands ielm
:bind (:map ielm-map ("<return>" . my-ielm-return))
(defun my-ielm-return ()
(let ((end-of-sexp (save-excursion
(goto-char (point-max))
(skip-chars-backward " \t\n\r")
(if (>= (point) end-of-sexp)
(goto-char (point-max))
(skip-chars-backward " \t\n\r")
(delete-region (point) (point-max))
(call-interactively #'ielm-return))
(call-interactively #'paredit-newline)))))
(use-package iflipb
:disabled t
:bind* ("<S-return>" . my-iflipb-next-buffer)
:commands (iflipb-next-buffer iflipb-previous-buffer)
(defvar my-iflipb-auto-off-timeout-sec 1)
(defvar my-iflipb-auto-off-timer nil)
(defvar my-iflipb-auto-off-timer-canceler-internal nil)
(defvar my-iflipb-ing-internal nil)
(defun my-iflipb-auto-off ()
(setq my-iflipb-auto-off-timer-canceler-internal nil
my-iflipb-ing-internal nil)
(when my-iflipb-auto-off-timer
(message nil)
(cancel-timer my-iflipb-auto-off-timer)
(setq my-iflipb-auto-off-timer nil)))
(defun my-iflipb-next-buffer (arg)
(interactive "P")
(iflipb-next-buffer arg)
(if my-iflipb-auto-off-timer-canceler-internal
(cancel-timer my-iflipb-auto-off-timer-canceler-internal))
(setq my-iflipb-auto-off-timer
(run-with-idle-timer my-iflipb-auto-off-timeout-sec 0
my-iflipb-ing-internal t))
(defun my-iflipb-previous-buffer ()
(if my-iflipb-auto-off-timer-canceler-internal
(cancel-timer my-iflipb-auto-off-timer-canceler-internal))
(setq my-iflipb-auto-off-timer
(run-with-idle-timer my-iflipb-auto-off-timeout-sec 0
my-iflipb-ing-internal t))
(setq iflipb-always-ignore-buffers
"\\`\\( \\|diary\\|ipa\\|\\.newsrc-dribble\\'\\)"
iflipb-wrap-around t)
(defun iflipb-first-iflipb-buffer-switch-command ()
(not (and (or (eq last-command 'my-iflipb-next-buffer)
(eq last-command 'my-iflipb-previous-buffer))
(use-package image-file
:defer 5
(auto-image-file-mode 1)
(add-hook 'image-mode-hook #'image-transform-reset))
(use-package imenu-list
:commands imenu-list-minor-mode)
(use-package indent
:commands indent-according-to-mode)
(use-package indent-shift
:bind (("C-c <" . indent-shift-left)
("C-c >" . indent-shift-right)))
(use-package info
:bind ("C-h C-i" . info-lookup-symbol)
(add-hook 'Info-mode-hook
#'(lambda ()
(setq buffer-face-mode-face '(:family "Bookerly"))
(text-scale-adjust 1))))
(use-package info-look
:defer t
(autoload 'info-lookup-add-help "info-look"))
(use-package info-lookmore
:after info-look
(use-package initsplit
:demand t
:load-path "lisp/initsplit")
(use-package ialign
:bind ("C-c {" . ialign-interactive-align))
(use-package inventory
:commands (inventory sort-package-declarations))
(use-package ipcalc
:commands ipcalc)
(use-package isearch
:no-require t
:bind (("C-M-r" . isearch-backward-other-window)
("C-M-s" . isearch-forward-other-window))
:bind (:map isearch-mode-map
("C-c" . isearch-toggle-case-fold)
("C-t" . isearch-toggle-regexp)
("C-^" . isearch-edit-string)
("C-i" . isearch-complete))
(defun isearch-backward-other-window ()
(other-window 1)
(call-interactively 'isearch-backward))
(defun isearch-forward-other-window ()
(other-window 1)
(call-interactively 'isearch-forward)))
(use-package ispell
:no-require t
:bind (("C-c i c" . ispell-comments-and-strings)
("C-c i d" . ispell-change-dictionary)
("C-c i k" . ispell-kill-ispell)
("C-c i m" . ispell-message)
("C-c i r" . ispell-region)))
(use-package ivy
:demand t
:bind (("C-x b" . ivy-switch-buffer)
("C-x B" . ivy-switch-buffer-other-window)
("M-H" . ivy-resume))
:bind (:map ivy-minibuffer-map
("<tab>" . ivy-alt-done)
("SPC" . ivy-alt-done-or-space)
("C-d" . ivy-done-or-delete-char)
("C-i" . ivy-partial-or-done)
("C-r" . ivy-previous-line-or-history)
("M-r" . ivy-reverse-i-search))
:bind (:map ivy-switch-buffer-map
("C-k" . ivy-switch-buffer-kill))
(ivy-dynamic-exhibit-delay-ms 200)
(ivy-height 10)
(ivy-initial-inputs-alist nil t)
(ivy-magic-tilde nil)
(ivy-re-builders-alist '((t . ivy--regex-ignore-order)))
(ivy-use-virtual-buffers t)
(ivy-wrap t)
(defun ivy-done-or-delete-char ()
(if (eolp)
(defun ivy-alt-done-or-space ()
(if (= ivy--length 1)
(defun ivy-switch-buffer-kill ()
(let ((bn (ivy-state-current ivy-last)))
(when (get-buffer bn)
(kill-buffer bn))
(unless (buffer-live-p (ivy-state-buffer ivy-last))
(setf (ivy-state-buffer ivy-last)
(with-ivy-window (current-buffer))))
(setq ivy--all-candidates (delete bn ivy--all-candidates))
;; This is the value of `magit-completing-read-function', so that we see
;; Magit's own sorting choices.
(defun my-ivy-completing-read (&rest args)
(let ((ivy-sort-functions-alist '((t . nil))))
(apply 'ivy-completing-read args)))
(ivy-mode 1)
(ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur)
(defun ivy--switch-buffer-matcher (regexp candidates)
"Return REGEXP matching CANDIDATES.
Skip buffers that match `ivy-ignore-buffers'."
(let ((res (ivy--re-filter regexp candidates)))
(if (or (null ivy-use-ignore)
(null ivy-ignore-buffers))
(or (cl-remove-if
(lambda (buf)
(lambda (f-or-r)
(if (functionp f-or-r)
(funcall f-or-r buf)
(string-match-p f-or-r buf)))
(and (eq ivy-use-ignore t)
(use-package ivy-bibtex
:commands ivy-bibtex)
(use-package ivy-hydra
:after (ivy hydra)
:defer t)
(use-package ivy-pass
:commands ivy-pass)
(use-package ivy-rich
:after ivy
:demand t
(ivy-rich-mode 1)
(setq ivy-virtual-abbreviate 'full
ivy-rich-switch-buffer-align-virtual-buffer t
ivy-rich-path-style 'abbrev))
(use-package ivy-rtags
:disabled t
:load-path "~/.nix-profile/share/emacs/site-lisp/rtags"
:after (ivy rtags))
(use-package jq-mode
:mode "\\.jq\\'")
(use-package js2-mode
:mode "\\.js\\'"
(add-to-list 'flycheck-disabled-checkers #'javascript-jshint)
(flycheck-add-mode 'javascript-eslint 'js2-mode)
(flycheck-mode 1))
(use-package js3-mode
;; jww (2017-12-10): Need to configure.
:disabled t)
(use-package json-mode
:mode "\\.json\\'")
(use-package json-reformat
:after json-mode)
(use-package json-snatcher
:after json-mode)
(use-package key-chord
:commands key-chord-mode)
(use-package keypression
:commands key-chord-mode)
(use-package know-your-http-well
:commands (http-header
(use-package kotl-mode
:mode "\\.kotl\\'")
(use-package langtool
:disabled t
:bind ("C-c K" . langtool-check))
(use-package latex
(require 'preview)
;; (load (emacs-path "site-lisp/auctex/style/minted"))
(info-lookup-add-help :mode 'LaTeX-mode
:regexp ".*"
:parse-rule "\\\\?[a-zA-Z]+\\|\\\\[^a-zA-Z]"
:doc-spec '(("(latex2e)Concept Index")
("(latex2e)Command Index")))
(defvar latex-prettify-symbols-alist
'(("\N{THIN SPACE}" . ?\⟷)))
(bind-key "C-x SPC"
#'(lambda ()
(insert "\N{THIN SPACE}"))
(bind-key "C-x A"
#'(lambda ()
(insert "ٰ"))
(bind-key "A-َ"
#'(lambda ()
(insert "ٰ"))
(bind-key "A-ه"
#'(lambda ()
(insert "ۀ"))
(bind-key "A-د"
#'(lambda ()
(insert "ذ"))
(add-hook 'LaTeX-mode-hook
(setq-local prettify-symbols-alist latex-prettify-symbols-alist)
(prettify-symbols-mode 1))))
(use-package ledger-mode
:mode "\\.ledger\\'"
:load-path "~/src/ledger/lisp"
:commands ledger-mode
:bind ("C-c L" . my-ledger-start-entry)
(defun my-ledger-start-entry (&optional arg)
(interactive "p")
(find-file-other-window "/Volumes/Files/Accounts/ledger.dat")
(goto-char (point-max))
(skip-syntax-backward " ")
(if (looking-at "\n\n")
(goto-char (point-max))
(delete-region (point) (point-max))
(insert ?\n)
(insert ?\n))
(insert (format-time-string "%Y/%m/%d ")))
(defun ledger-matchup ()
(while (re-search-forward "\\(\\S-+Unknown\\)\\s-+\\$\\([-,0-9.]+\\)"
nil t)
(let ((account-beg (match-beginning 1))
(account-end (match-end 1))
(amount (match-string 2))
account answer)
(goto-char account-beg)
(set-window-point (get-buffer-window) (point))
(with-current-buffer (get-buffer "nrl-mastercard-old.dat")
(goto-char (point-min))
(when (re-search-forward (concat "\\(\\S-+\\)\\s-+\\$" amount)
nil t)
(setq account (match-string 1))
(goto-char (match-beginning 1))
(set-window-point (get-buffer-window) (point))
(setq answer
(read-char (format "Is this a match for %s (y/n)? "
(when (eq answer ?y)
(goto-char account-beg)
(delete-region account-beg account-end)
(insert account))
(defun my-ledger-add-symbols ()
(while (re-search-forward " \\(BOT\\|SOLD\\) [+-][0-9,]+ \\(\\S-+\\) " nil t)
(forward-line 2)
(goto-char (line-beginning-position))
(insert " ; Symbol: " (match-string 2) ?\n)))
(add-hook 'ledger-mode-hook
#'(lambda ()
(auto-fill-mode -1))))
(use-package lentic-mode
:disabled t
:commands global-lentic-mode)
(use-package link-hint
:defer 10
:bind ("C-c C-o" . link-hint-open-link)
(add-hook 'eww-mode-hook
#'(lambda () (bind-key "f" #'link-hint-open-link eww-mode-map)))
(add-hook 'w3m-mode-hook
#'(lambda () (bind-key "f" #'link-hint-open-link w3m-mode-map))))
(use-package lively
:bind ("C-x C-E" . lively))
(use-package lisp-mode
:defer t
:hook ((emacs-lisp-mode lisp-mode)
. (lambda () (add-hook 'after-save-hook #'check-parens nil t)))
(dolist (mode '(ielm-mode
(0 (ignore
(compose-region (match-beginning 1)
(match-end 1) ))))
("(\\(ert-deftest\\)\\>[ '(]*\\(setf[ ]+\\sw+\\|\\sw+\\)?"
(1 font-lock-keyword-face)
(2 font-lock-function-name-face
nil t))))))
(use-package lispy
:commands lispy-mode
:bind (:map lispy-mode-map
:bind (:map emacs-lisp-mode-map
("C-1" . lispy-describe-inline)
("C-2" . lispy-arglist-inline)
("C-c C-j" . lispy-goto)))
(use-package llvm-mode
:disabled t
:mode "\\.ll\\'")
(use-package lsp-haskell
:disabled t
:after lsp-mode
:hook (haskell-mode . lsp-haskell-enable))
(use-package lsp-mode
:disabled t
:commands lsp)
(use-package lsp-ui
:after lsp-mode
:hook (lsp-mode . lsp-ui-mode)
(define-key lsp-ui-mode-map [remap xref-find-definitions]
(define-key lsp-ui-mode-map [remap xref-find-references]
(use-package lua-mode
:mode "\\.lua\\'"
:interpreter "lua")
(use-package macrostep
:bind ("C-c e m" . macrostep-expand))
(use-package magit
:bind (("C-x g" . magit-status)
("C-x G" . magit-status-with-prefix))
:bind (:map magit-mode-map
("U" . magit-unstage-all)
("M-h") ("M-s") ("M-m") ("M-w"))
:bind (:map magit-file-section-map ("<C-return>"))
:bind (:map magit-hunk-section-map ("<C-return>"))
;; History can be viewed with:
;; git log refs/snapshots/$(git symbolic-ref HEAD)
(defun magit-monitor (&optional no-display)
"Start git-monitor in the current directory."
(let* ((path (file-truename
(expand-file-name default-directory))))
(name (format "*git-monitor: %s*"
(file-name-nondirectory path))))
(unless (and (get-buffer name)
(with-current-buffer (get-buffer name)
(string= path (directory-file-name default-directory))))
(with-current-buffer (get-buffer-create name)
(cd path)
(start-process "*git-monitor*" (current-buffer)
"git-monitor" "-d" path))))))
(defun magit-status-with-prefix ()
(let ((current-prefix-arg '(4)))
(call-interactively 'magit-status)))
(defun endless/visit-pull-request-url ()
"Visit the current branch's PR on Github."
(format ""
"\\`.+github\\.com:\\(.+?\\)\\(\\.git\\)?\\'" "\\1"
(magit-get "remote" (magit-get-remote) "url"))
:hook (magit-mode . hl-line-mode)
(use-package magit-commit
(use-package git-commit))
(use-package magit-files
(add-hook 'magit-status-mode-hook #'(lambda () (magit-monitor t)))
(define-key magit-mode-map "G" #'endless/visit-pull-request-url)
(eval-after-load 'magit-pull
'(transient-insert-suffix 'magit-pull "p"
'("F" "default" magit-fetch-from-upstream)))
(eval-after-load 'magit-push
'(transient-insert-suffix 'magit-push "p"
'("P" "default" magit-push-current-to-upstream)))
;; (remove-hook 'magit-status-sections-hook 'magit-insert-status-headers)
;; (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header)
;; (remove-hook 'magit-status-sections-hook 'magit-insert-unpushed-to-pushremote)
;; (remove-hook 'magit-status-sections-hook 'magit-insert-unpushed-to-upstream-or-recent)
;; (remove-hook 'magit-status-sections-hook 'magit-insert-unpulled-from-pushremote)
;; (remove-hook 'magit-status-sections-hook 'magit-insert-unpulled-from-upstream)
(use-package magit-popup
:defer t)
(use-package magit-imerge
;; jww (2017-12-10): Need to configure.
:disabled t
:after magit)
(use-package makefile-runner
:bind ("C-c M" . makefile-runner))
(use-package malyon
:commands malyon
(defun replace-invisiclues ()
"^\\( +\\)\\(\\([A-Z]\\)\\. \\)?\\(.+\\)"
(quote (replace-eval-replacement
concat "\\1\\2" (replace-quote (rot13 (match-string 4)))))
nil (if (use-region-p) (region-beginning))
(if (use-region-p) (region-end)) nil nil)))
(use-package markdown-mode
:mode (("\\`README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init (setq markdown-command "multimarkdown"))
(use-package markdown-preview-mode
:after markdown-mode
(setq markdown-preview-stylesheets
(list (concat ""
(use-package math-symbol-lists
:defer t)
(use-package mc-calc
:after multiple-cursors
:bind (("<C-m> = c" . mc-calc)
("<C-m> = =" . mc-calc-eval)
("<C-m> = g" . mc-calc-grab)
("<C-m> = b" . mc-calc-copy-to-buffer)))
(use-package mc-extras
:after multiple-cursors
:bind (("<C-m> M-C-f" . mc/mark-next-sexps)
("<C-m> M-C-b" . mc/mark-previous-sexps)
("<C-m> <" . mc/mark-all-above)
("<C-m> >" . mc/mark-all-below)
("<C-m> C-d" . mc/remove-current-cursor)
("<C-m> C-k" . mc/remove-cursors-at-eol)
("<C-m> M-d" . mc/remove-duplicated-cursors)
("<C-m> |" . mc/move-to-column)
("<C-m> ~" . mc/compare-chars)))
(use-package mc-freeze
:after multiple-cursors
:bind ("<C-m> f" . mc/freeze-fake-cursors-dwim))
(use-package mc-rect
:after multiple-cursors
:bind ("<C-m> ]" . mc/rect-rectangle-to-multiple-cursors))
(use-package mediawiki
:commands mediawiki-open)
(use-package memory-usage
:commands memory-usage)
(use-package mhtml-mode
:bind (:map html-mode-map
("<return>" . newline-and-indent)))
(use-package mic-paren
:defer 5
(use-package midnight
:bind ("C-c z" . clean-buffer-list))
(use-package minibuffer
(defun my-minibuffer-setup-hook ()
(setq gc-cons-threshold most-positive-fixnum))
(defun my-minibuffer-exit-hook ()
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook))
(use-package minimap
:commands minimap-mode)
(use-package mmm-mode
:defer t)
(use-package moccur-edit
:after color-moccur)
(use-package monitor
:defer t
(autoload #'define-monitor "monitor"))
(use-package mule
:no-require t
(prefer-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))
(use-package multi-term
:bind (("C-c t" . multi-term-next)
("C-c T" . multi-term))
(defun screen ()
(let (term-buffer)
;; Set buffer.
(setq term-buffer
(let ((multi-term-program (executable-find "screen"))
(multi-term-program-switches "-DR"))
(set-buffer term-buffer)
(switch-to-buffer term-buffer)))
(require 'term)
(defalias 'my-term-send-raw-at-prompt 'term-send-raw)
(defun my-term-end-of-buffer ()
(call-interactively #'end-of-buffer)
(if (and (eobp) (bolp))
(delete-char -1)))
(defadvice term-process-pager (after term-process-rebind-keys activate)
(define-key term-pager-break-map "\177" 'term-pager-back-page)))
(use-package multifiles
:bind ("C-c m f" . mf/mirror-region-in-multifile))
(use-package multiple-cursors
:after phi-search
:defer 5
;; - Sometimes you end up with cursors outside of your view. You can scroll
;; the screen to center on each cursor with `C-v` and `M-v`.
;; - If you get out of multiple-cursors-mode and yank - it will yank only
;; from the kill-ring of main cursor. To yank from the kill-rings of every
;; cursor use yank-rectangle, normally found at C-x r y.
:bind (("<C-m> ^" . mc/edit-beginnings-of-lines)
("<C-m> `" . mc/edit-beginnings-of-lines)
("<C-m> $" . mc/edit-ends-of-lines)
("<C-m> '" . mc/edit-ends-of-lines)
("<C-m> R" . mc/reverse-regions)
("<C-m> S" . mc/sort-regions)
("<C-m> W" . mc/mark-all-words-like-this)
("<C-m> Y" . mc/mark-all-symbols-like-this)
("<C-m> a" . mc/mark-all-like-this-dwim)
("<C-m> c" . mc/mark-all-dwim)
("<C-m> l" . mc/insert-letters)
("<C-m> n" . mc/insert-numbers)
("<C-m> r" . mc/mark-all-in-region)
("<C-m> s" . set-rectangular-region-anchor)
("<C-m> %" . mc/mark-all-in-region-regexp)
("<C-m> t" . mc/mark-sgml-tag-pair)
("<C-m> w" . mc/mark-next-like-this-word)
("<C-m> x" . mc/mark-more-like-this-extended)
("<C-m> y" . mc/mark-next-like-this-symbol)
("<C-m> C-x" . reactivate-mark)
("<C-m> C-SPC" . mc/mark-pop)
("<C-m> (" . mc/mark-all-symbols-like-this-in-defun)
("<C-m> C-(" . mc/mark-all-words-like-this-in-defun)
("<C-m> M-(" . mc/mark-all-like-this-in-defun)
("<C-m> [" . mc/vertical-align-with-space)
("<C-m> {" . mc/vertical-align)
("S-<mouse-1>" . mc/add-cursor-on-click))
:bind (:map selected-keymap
("c" . mc/edit-lines)
("." . mc/mark-next-like-this)
("<" . mc/unmark-next-like-this)
("C->" . mc/skip-to-next-like-this)
("," . mc/mark-previous-like-this)
(">" . mc/unmark-previous-like-this)
("C-<" . mc/skip-to-previous-like-this)
("y" . mc/mark-next-symbol-like-this)
("Y" . mc/mark-previous-symbol-like-this)
("w" . mc/mark-next-word-like-this)
("W" . mc/mark-previous-word-like-this))
(defun reactivate-mark ()
(use-package navi-mode
:after outshine
:bind ("M-s s" . navi-search-and-switch))
(use-package nf-procmail-mode
:commands nf-procmail-mode)
(use-package nginx-mode
:commands nginx-mode)
(use-package nix-shell
:no-require t
(defun nix-shell ()
(let ((explicit-shell-file-name "shell")
(explicit-shell-args nil))
(call-interactively 'shell))))
(use-package nix-mode
:mode "\\.nix\\'")
(use-package nix-update
:load-path "lisp/nix-update"
:bind ("C-c U" . nix-update-fetch))
(use-package nov
:mode ("\\.epub\\'" . nov-mode))
(use-package nroff-mode
:commands nroff-mode
(defun update-nroff-timestamp ()
(goto-char (point-min))
(when (re-search-forward "^\\.Dd " nil t)
(let ((stamp (format-time-string "%B %e, %Y")))
(unless (looking-at stamp)
(delete-region (point) (line-end-position))
(insert stamp)
(let (after-save-hook)
(add-hook 'nroff-mode-hook
#'(lambda () (add-hook 'after-save-hook #'update-nroff-timestamp nil t))))
(use-package nxml-mode
:commands nxml-mode
:bind (:map nxml-mode-map
("<return>" . newline-and-indent)
("C-c M-h" . tidy-xml-buffer))
(defun tidy-xml-buffer ()
(call-process-region (point-min) (point-max) "tidy" t t nil
"-xml" "-i" "-wrap" "0" "-omit" "-q" "-utf8")))
(defalias 'xml-mode 'nxml-mode)
(autoload 'sgml-skip-tag-forward "sgml-mode")
(add-to-list 'hs-special-modes-alist
(use-package olivetti
:commands olivetti-mode)
(use-package operate-on-number
:bind ("C-c N" . operate-on-number-at-point))
(use-package origami
:hook (rust-mode . origami-mode)
:bind (:map origami-mode-map
("C-, C-h" . origami-toggle-node))
;; We need to tell origami how to work under rust mode
(with-eval-after-load "origami"
(add-to-list 'origami-parser-alist '(rust-mode . origami-c-style-parser)))
;; Highlights the line the fold starts on
(origami-show-fold-header t)
(defun origami-header-overlay-range (fold-overlay)
"Given a `fold-overlay', return the range that the corresponding
header overlay should cover. Result is a cons cell of (begin . end)."
(with-current-buffer (overlay-buffer fold-overlay)
(let ((fold-begin
(goto-char (overlay-start fold-overlay))
;; Find the end of the folded region -- include the following
;; newline if possible. The header will span the entire fold.
(goto-char (overlay-end fold-overlay))
(when (looking-at ".")
(forward-char 1)
(when (looking-at "\n")
(forward-char 1)))
(cons fold-begin fold-end)))))
(use-package outline
:diminish outline-minor-mode
:hook ((emacs-lisp-mode LaTeX-mode) . outline-minor-mode))
(use-package outorg
:after outshine)
(use-package outshine
:disabled t
:after (:or outline org-mode)
:hook (outline-minor-mode . outshine-hook-function))
(use-package ovpn-mode
:commands ovpn
'ovpn-mode-pull-authinfo :around
#'(lambda (ad-do-it config)
(if (string= config "OpenVPN_PoC_2019_johnwiegley.ovpn")
(list "johnwiegley"
(concat (lookup-password "demonet OpenVPN" "johnwiegley" 80)
(password-store--run "otp" "DFINITY/demonet OpenVPN")))
(funcall ad-do-it config)))))
(use-package package-lint
:commands package-lint-current-buffer)
(use-package pandoc-mode
:hook (markdown-mode
(pandoc-mode . pandoc-load-default-settings)))
(use-package paradox
:commands paradox-list-packages)
(use-package paredit
:hook ((lisp-mode emacs-lisp-mode) . paredit-mode)
:bind (:map paredit-mode-map
("M-k" . paredit-raise-sexp)
("M-I" . paredit-splice-sexp)
("C-M-l" . paredit-recentre-on-sexp)
("C-c ( n" . paredit-add-to-next-list)
("C-c ( p" . paredit-add-to-previous-list)
("C-c ( j" . paredit-join-with-next-list)
("C-c ( J" . paredit-join-with-previous-list))
:bind (:map lisp-mode-map ("<return>" . paredit-newline))
:bind (:map emacs-lisp-mode-map ("<return>" . paredit-newline))
:hook (paredit-mode
. (lambda ()
(unbind-key "M-r" paredit-mode-map)
(unbind-key "M-s" paredit-mode-map)))
(require 'eldoc)
(eldoc-add-command 'paredit-backward-delete
(use-package paredit-ext
:after paredit)
(use-package pass
:commands (pass pass-view-mode)
:mode ("\\.passwords/.*\\.gpg\\'" . pass-view-mode)
(defun insert-password ()
(shell-command "apg -m24 -x24 -a1 -n1" t))
(add-hook 'pass-view-mode-hook #'pass-view--prepare-otp))
(use-package password-store
:defer 5
:commands (password-store-insert
(defun password-store--run-edit (entry)
(require 'pass)
(find-file (concat (expand-file-name entry (password-store-dir)) ".gpg")))
(defun password-store-insert (entry login password)
"Insert a new ENTRY containing PASSWORD."
(interactive (list (read-string "Password entry: ")
(read-string "Login: ")
(read-passwd "Password: " t)))
(message "%s" (shell-command-to-string
(if (string= "" login)
(format "echo %s | %s insert -m -f %s"
(shell-quote-argument password)
(shell-quote-argument entry))
(format "echo -e '%s\nlogin: %s' | %s insert -m -f %s"
password login password-store-executable
(shell-quote-argument entry)))))))
(use-package password-store-otp
:defer t
(defun password-store-otp-append-from-image (entry)
"Check clipboard for an image and scan it to get an OTP URI,
append it to ENTRY."
(interactive (list (read-string "Password entry: ")))
(let ((qr-image-filename (password-store-otp--get-qr-image-filename entry)))
(when (not (zerop (call-process "screencapture" nil nil nil
"-T5" qr-image-filename)))
(error "Couldn't get image from clipboard"))
(condition-case nil
(call-process "zbarimg" nil t nil "-q" "--raw"
(error "It seems you don't have `zbar-tools' installed")))
(buffer-substring (point-min) (point-max))))
(when (not password-store-otp-screenshots-path)
(delete-file qr-image-filename)))))
(use-package pcre2el
:commands (rxt-mode rxt-global-mode))
(use-package pdf-tools
:magic ("%PDF" . pdf-view-mode)
'(pdf-annot pdf-cache pdf-dev pdf-history pdf-info pdf-isearch
pdf-links pdf-misc pdf-occur pdf-outline pdf-sync
pdf-util pdf-view pdf-virtual))
(require pkg))
(use-package per-window-point
:defer 5
:commands pwp-mode
(pwp-mode 1))
(use-package persistent-scratch
:unless (or (null window-system)
:defer 5
(with-demoted-errors "Error: %S"
:commands persistent-scratch-setup-default)
(use-package personal
(define-key key-translation-map (kbd "A-TAB") (kbd "C-TAB"))
:commands unfill-region
:bind (("M-L" . mark-line)
("M-S" . mark-sentence)
("M-j" . delete-indentation-forward)
("M-D" . my-open-Messages)
("M-R" . my-open-PathFinder)
("M-K" . my-open-KeyboardMaestro)
("C-c )" . close-all-parentheses)
("C-c 0" . recursive-edit-preserving-window-config-pop)
("C-c 1" . recursive-edit-preserving-window-config)
("C-c C-0" . copy-current-buffer-name)
("C-c C-z" . delete-to-end-of-buffer)
("C-c M-q" . unfill-paragraph)
("C-c e P" . check-papers)
("C-c e b" . do-eval-buffer)
("C-c e r" . do-eval-region)
("C-c e s" . scratch)
("C-c n" . insert-user-timestamp)
("C-x C-d" . duplicate-line)
("C-x C-v" . find-alternate-file-with-sudo)
("C-x K" . delete-current-buffer-file)
("C-x M-q" . refill-paragraph)
("C-x C-n" . next-line)
("C-x C-p" . previous-line))
(defun my-open-Messages ()
(call-process "/usr/bin/open" nil nil nil
(defun my-open-PathFinder ()
(call-process "/usr/bin/open" nil nil nil
(defun my-open-KeyboardMaestro ()
(call-process "/usr/bin/open" nil nil nil
(bind-keys* ("M-!" . async-shell-command))
(bind-keys ("<C-M-backspace>" . backward-kill-sexp)
("M-'" . insert-pair)
("M-J" . delete-indentation)
("M-\"" . insert-pair)
("M-`" . other-frame)
("M-g c" . goto-char)
("C-c SPC" . just-one-space)
("C-c M-;" . comment-and-copy)
("C-c e c" . cancel-debug-on-entry)
("C-c e d" . debug-on-entry)
("C-c e e" . toggle-debug-on-error)
("C-c e f" . emacs-lisp-byte-compile-and-load)
("C-c e j" . emacs-lisp-mode)