From 40fd4964068d0b7628b6f699dab4aec200eadb0a Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Tue, 8 Oct 2019 21:40:33 +0200 Subject: Emacs: use single configuration file, compiled by home-manager --- user/emacs/.emacs.d/init.el | 848 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 832 insertions(+), 16 deletions(-) (limited to 'user/emacs/.emacs.d/init.el') diff --git a/user/emacs/.emacs.d/init.el b/user/emacs/.emacs.d/init.el index 48fc30a3..d4470242 100644 --- a/user/emacs/.emacs.d/init.el +++ b/user/emacs/.emacs.d/init.el @@ -1,26 +1,842 @@ -;;; init --- user init file -*- no-byte-compile: t -*- -;;; Commentary: -;; Entry point for Emacs init. -;; Ensures that main init code is up-to-date by loading the newest version. -;; -;;; Code: +;;; init --- user init file (setq inhibit-startup-echo-area-message "alan") -(setq load-prefer-newer t - package-user-dir (concat "~/.emacs.d/packages/" emacs-version "/elpa") - package-enable-at-startup nil - package-archives nil) +(setq inhibit-startup-screen t + initial-scratch-message "" + initial-major-mode 'text-mode + package-enable-at-startup nil) (package-initialize) -(require 'auto-compile nil :noerror) (defun reload-user-init-file () "Reload init file." (interactive) (load-file user-init-file)) -(when (featurep 'auto-compile) - (auto-compile-on-load-mode)) +(eval-when-compile + (require 'use-package) + (setq use-package-expand-minimally t)) +(setq use-package-always-demand (daemonp)) -(let ((gc-cons-threshold most-positive-fixnum)) - (load (expand-file-name "main.el" user-emacs-directory) :nomessage t)) -;;; init ends here +;;; Customize + +(setq custom-file "~/.emacs.d/custom.el") +(load custom-file :noerror :nomessage) + +(use-package crux + :defer 1 + :custom ((crux-reopen-as-root-mode nil))) + +;;; Styles + +(custom-set-variables + ;; I prefer an always-visible cursor. Feels less distracting. + '(blink-cursor-mode nil) + ;; Disable all the bars, unless on OSX, in which case, keep the menu bar. + '(menu-bar-mode nil) + '(scroll-bar-mode nil) + '(tool-bar-mode nil)) +(set-fringe-mode '(4 . 4)) + +;; Ring the bell sometimes, but not so often +(setq ring-bell-function + (lambda () + (unless (memq this-command + '(isearch-abort abort-recursive-edit exit-minibuffer keyboard-quit minibuffer-keyboard-quit undo-tree-undo)) + (ding)))) + +(when (or (daemonp) + window-system) + (load-theme 'almost-mono-white t) + (if (eq window-system 'x) + (setq-default line-spacing 0.2)) + (setq frame-background-mode 'light) + (mapc 'frame-set-background-mode (frame-list))) + (let ((line (face-attribute 'mode-line :underline))) + (set-face-attribute 'mode-line nil :overline line) + (set-face-attribute 'mode-line-inactive nil :overline line) + (set-face-attribute 'mode-line-inactive nil :underline line) + (set-face-attribute 'mode-line nil :box nil) + (set-face-attribute 'mode-line-inactive nil :box nil)) + +;;; Chrome +(use-package minions + :custom ((minions-mode-line-lighter "#") + (minions-mode-line-delimiters nil) + (minions-mode t))) + +(setq-default mode-line-position nil + mode-line-mule-info nil + mode-line-client nil + mode-line-remote nil) + +(use-package moody + :config (progn + (setq x-underline-at-descent-line t) + (moody-replace-mode-line-buffer-identification) + (moody-replace-vc-mode) + (with-eval-after-load 'eyebrowse + (defvar eyebrowse-lighter-default + '(:eval (eyebrowse-mode-line-indicator))) + (defvar moody-replace-eyebrowse-lighter + '(:eval (moody-tab (eyebrowse-mode-line-indicator) 1 'up))) + (defun moody-replace-eyebrowse (&optional reverse) + (interactive "P") + (if (assoc 'eyebrowse-mode mode-line-misc-info) + (setcdr (assoc 'eyebrowse-mode mode-line-misc-info) + (list (if reverse + eyebrowse-lighter-default + moody-replace-eyebrowse-lighter))) + (push (list 'eyebrowse-mode moody-replace-eyebrowse-lighter) + (cdr (last mode-line-misc-info))))) + (moody-replace-eyebrowse nil)))) + +(when (eq system-type 'darwin) + (add-to-list 'default-frame-alist '(ns-transparent-titlebar . t)) + (add-to-list 'default-frame-alist '(ns-appearance . 'light))) + +(add-to-list 'default-frame-alist '(width . 100)) +(add-to-list 'default-frame-alist '(height . 40)) + +;;; Dates & Times + +(custom-set-variables + '(calendar-week-start-day 1) + '(calendar-date-style 'iso)) + +(defun insert-date (prefix) + "Insert the current date. +With PREFIX, use British format. +With two prefix arguments, write out the day and month name." + (interactive "P") + (let ((format (cond + ((not prefix) "%Y-%m-%d") + ((equal prefix '(4)) "%d/%m/%Y") + ((equal prefix '(16)) "%A, %d %B %Y")))) + (insert (format-time-string format)))) + +(defun insert-datetime (prefix) + "Insert current date and time. With PREFIX, use ISO8601 format." + (interactive "P") + (let ((format (cond + ((not prefix) "%Y-%m-%d %H:%M:%S") + ((equal prefix '(4)) "%Y-%m-%dT%H:%M:%SZ")))) + (insert (format-time-string format)))) + +;;; Keybindings + +;; I think =set-keyboard-coding-system= stops OS X from doing something +;; annoying to add accents. The modifier setup is to match my +;; re-arrangement of modifiers on OSX: Cmd on the outside, then +;; Option/alt, then Control. + +(when (eq system-type 'darwin) + (custom-set-variables + '(mac-option-modifier 'meta) + '(mac-right-option-modifier 'none) + '(mac-control-modifier 'control) + '(mac-right-control-modifier 'left) + '(mac-command-modifier 'super) + '(mac-right-command-modifier 'left) + '(mac-function-modifier 'hyper))) + +(use-package general + :functions (general-unbind general-define-key) + :config (progn + (general-override-mode +1) + (when (eq system-type 'darwin) + (general-unbind "s-x")))) + +(use-package avy + :custom ((avy-all-windows nil))) +(use-package ace-link + :after avy + :commands (ace-link-setup-default) + :config (ace-link-setup-default)) + +;; Popup keybindings following a prefix automatically. + +(use-package which-key + :defer 5 + :custom ((which-key-mode +1)) + :config (progn + (which-key-setup-side-window-right-bottom))) + +;;; Modeline + +(use-package relative-buffers + :defer 2 + :custom ((global-relative-buffers-mode t))) + +;;; Minibuffer + +(setq enable-recursive-minibuffers t) +(minibuffer-depth-indicate-mode t) + +(use-package hydra + :defer 2) +(use-package ivy + :config (progn + (ivy-mode +1))) +(use-package ivy-hydra + :defer 2) + +(use-package smerge-mode + :after magit + :config + (defhydra unpackaged/smerge-hydra + (:color pink :hint nil :post (smerge-auto-leave)) + " +^Move^ ^Keep^ ^Diff^ ^Other^ +^^-----------^^-------------------^^---------------------^^------- +_n_ext _b_ase _<_: upper/base _C_ombine +_p_rev _u_pper _=_: upper/lower _r_esolve +^^ _l_ower _>_: base/lower _k_ill current +^^ _a_ll _R_efine +^^ _RET_: current _E_diff +" + ("n" smerge-next) + ("p" smerge-prev) + ("b" smerge-keep-base) + ("u" smerge-keep-upper) + ("l" smerge-keep-lower) + ("a" smerge-keep-all) + ("RET" smerge-keep-current) + ("\C-m" smerge-keep-current) + ("<" smerge-diff-base-upper) + ("=" smerge-diff-upper-lower) + (">" smerge-diff-base-lower) + ("R" smerge-refine) + ("E" smerge-ediff) + ("C" smerge-combine-with-next) + ("r" smerge-resolve) + ("k" smerge-kill-current) + ("w" (lambda () + (interactive) + (save-buffer) + (bury-buffer)) + "Save and bury buffer" :color blue) + ("q" nil "cancel" :color blue)) + :hook (magit-diff-visit-file . (lambda () + (when smerge-mode + (unpackaged/smerge-hydra/body))))) + +(use-package swiper + :general ([remap isearch-forward] #'swiper-isearch)) + +;; transition smex history to amx +(let ((smex-save-file (concat user-emacs-directory "smex-items"))) + (use-package amx + :custom ((amx-history-length 100)))) + +(use-package counsel + :commands (counsel-unicode-char) + :general ("M-x" #'counsel-M-x)) + +;;; Windows + +(defun split-window-properly (&optional window) + (let ((window (or window (selected-window)))) + (or (and (window-splittable-p window) + ;; Split window vertically. + (with-selected-window window + (split-window-below))) + (and (window-splittable-p window t) + ;; Split window horizontally. + (with-selected-window window + (split-window-right)))))) + +(setq split-window-preferred-function #'split-window-properly + split-height-threshold nil + split-width-threshold 160) + +(use-package eyebrowse + :after (evil) + :custom ((eyebrowse-new-workspace t) + (eyebrowse-mode t) + (eyebrowse-mode-line-left-delimiter "") + (eyebrowse-mode-line-right-delimiter "") + (eyebrowse-mode-line-separator " ") + (eyebrowse-mode-line-style 'always)) + :general (:keymaps 'evil-window-map + "0" #'eyebrowse-switch-to-window-config-0 + "1" #'eyebrowse-switch-to-window-config-1 + "2" #'eyebrowse-switch-to-window-config-2 + "3" #'eyebrowse-switch-to-window-config-3 + "4" #'eyebrowse-switch-to-window-config-4 + "5" #'eyebrowse-switch-to-window-config-5 + "6" #'eyebrowse-switch-to-window-config-6 + "7" #'eyebrowse-switch-to-window-config-7 + "8" #'eyebrowse-switch-to-window-config-8 + "9" #'eyebrowse-switch-to-window-config-9) + :ghook ('evil-after-load-hook #'eyebrowse-setup-evil-keys)) + +(use-package winner + :after evil + :defer 8 + :custom ((winner-mode t) + (winner-boring-buffers '("*Completions*" "*Help*" "*Apropos*" "*Buffer List*" "*info*" "*Compile-Log*"))) + :general (:keymaps 'evil-window-map + "u" #'winner-undo + "r" #'winner-redo + "C-r" #'winner-redo)) +;;; Evil + +(use-package evil + :demand t + :commands (evil-mode evil-delete-buffer evil-ex-define-cmd) + :init (progn + (defvar evil-want-integration) + (defvar evil-want-keybinding) + (setq evil-want-integration t + evil-want-keybinding nil)) + :custom ((evil-shift-width 2) + (evil-mode-line-format nil)) + :config (evil-mode +1) + :general + (:states 'motion + "C-;" #'evil-avy-goto-line) + (:states 'normal + ";" #'evil-ex) + (:states '(normal motion) + "g s" #'evil-avy-goto-symbol-1)) + +(use-package evil-collection + :after (evil) + :defer 3 + :demand t + :commands (evil-collection-init) + :custom ((evil-collection-company-use-tng nil)) + :config (progn + (evil-collection-init))) + +(general-create-definer my-leader-def + :keymaps 'override + :states '(normal motion) + :prefix ",") + +(use-package evil-space + :defer 1 + :after evil + :custom ((evil-space-mode t))) + +(use-package evil-surround + :after evil + :defer 2 + :custom ((global-evil-surround-mode t))) + +(use-package evil-commentary + :after evil + :defer 2 + :custom ((evil-commentary-mode t))) + +(use-package evil-magit + :after magit + :custom ((evil-magit-use-y-for-yank nil))) + +(use-package evil-quickscope + :after evil + :commands (evil-quickscope-mode) + :ghook ('(magit-mode-hook git-rebase-mode-hook) #'turn-off-evil-quickscope-mode) + :custom ((global-evil-quickscope-mode t))) + +(use-package evil-org + :after org + :commands (evil-org-set-key-theme) + :ghook ('org-mode-hook #'evil-org-mode) + :gfhook #'evil-org-set-key-theme) + +(use-package evil-org-agenda + :after org + :ghook ('org-agenda-mode-hook #'evil-org-agenda-set-keys)) + +;;; Projects + +(use-package projectile + :defer 1 + :defines projectile-command-map + :custom ((projectile-mode +1) + (projectile-completion-system 'ivy)) + :config (progn + (add-to-list 'projectile-globally-ignored-files "package-lock.json") + (add-to-list 'projectile-globally-ignored-files "pnpm-lock.yaml") + (add-to-list 'projectile-project-root-files "package.json") + (add-to-list 'projectile-project-root-files-bottom-up "pnpm-workspace.yaml") + (setq projectile-project-root-files-functions '(projectile-root-local + projectile-root-top-down + projectile-root-bottom-up + projectile-root-top-down-recurring)) + (with-eval-after-load 'evil-ex + (evil-ex-define-cmd "prg" #'projectile-ripgrep) + (evil-ex-define-cmd "pesh[ell]" #'projectile-run-eshell)))) + +(use-package counsel-projectile + :defer 1 + :commands (counsel-projectile-switch-project + counsel-projectile-rg + counsel-projectile-switch-to-buffer + counsel-projectile-mode) + :general (:keymaps 'projectile-command-map + "s s" #'counsel-projectile-rg + "s r" #'counsel-projectile-rg) + :config (progn + (assq-delete-all #'projectile-ripgrep counsel-projectile-key-bindings) + (counsel-projectile-mode +1) + (with-eval-after-load 'evil-ex + (evil-ex-define-cmd "cprg" #'counsel-projectile-rg) + (evil-ex-define-cmd "pb" #'counsel-projectile-switch-to-buffer) + (evil-ex-define-cmd "psw[itch]" #'counsel-projectile-switch-project)))) + +(use-package magit + :defer 10 + :commands (magit-status magit-dispatch) + :custom ((magit-auto-revert-mode nil) + (magit-section-visibility-indicator nil) + (magit-diff-refine-hunk 'all) + (magit-display-buffer-function #'display-buffer) + (magit-completing-read-function #'ivy-completing-read)) + :config (progn + (global-magit-file-mode +1) + (remove-hook 'magit-section-highlight-hook 'magit-section-highlight) + (remove-hook 'magit-section-highlight-hook 'magit-section-highlight-selection) + (remove-hook 'magit-section-highlight-hook 'magit-diff-highlight))) + +(eval-when-compile (require 'fringe-helper)) +(use-package git-gutter + :defer t) +(use-package git-gutter-fringe + :defer 5 + :config (progn + (global-git-gutter-mode 1) + ;; places the git gutter outside the margins. + (setq-default fringes-outside-margins nil) + ;; thin fringe bitmaps + (fringe-helper-define 'git-gutter-fr:added '(center repeated) + ".XXX....") + (fringe-helper-define 'git-gutter-fr:modified '(center repeated) + ".XXX....") + (fringe-helper-define 'git-gutter-fr:deleted '(center repeated) + ".XXX....") + (setq git-gutter-fr:side 'right-fringe))) + +(use-package git-messenger + :commands (git-messenger:popup-message) + :defer 10 + :custom ((git-messenger:use-magit-popup t))) + +(use-package git-timemachine + :commands (git-timemachine)) + +(use-package editorconfig + :defer 2 + :init (progn + (unless (executable-find "editorconfig") + (warn "Missing `editorconfig' executable."))) + :config (editorconfig-mode +1)) + +;;; Completion + +(use-package company + :defer 2 + :commands (company-explicit-action-p) + :custom ((global-company-mode +1) + (company-idle-delay 0) + (company-show-numbers t) + (company-dabbrev-downcase nil) + (company-dabbrev-ignore-case nil) + (company-begin-commands '(self-insert-command)) + (company-auto-complete #'company-explicit-action-p) + (company-auto-complete-chars '(?\ ?\( ?\) ?.))) + :general (:states 'insert + "TAB" #'company-indent-or-complete-common)) + +;; (use-package all-the-icons) + +(eval-when-compile (require 'subr-x)) +(eval-and-compile + (defun company-tabnine-load-path () + (string-trim-right (shell-command-to-string "ghq list -p company-tabnine")))) + +(use-package company-tabnine + :commands (company-tabnine) + :after (company) + :load-path (lambda () (list (company-tabnine-load-path))) + :custom ((company-tabnine-binaries-folder "~/.local/tabnine")) + :general ("" #'company-tabnine-call-other-backends + "" #'company-tabnine-call-other-backends) + :init (progn + (add-to-list 'company-backends #'company-tabnine))) + +;;; Documentation + +(use-package eldoc + :defer 5 + :custom ((global-eldoc-mode +1) + (eldoc-idle-delay 0.5))) + +(use-package eldoc-box + :after (eldoc eglot) + :custom ((eldoc-box-hover-mode +1) + (eldoc-box-hover-at-point-mode +1))) + +(use-package ehelp + :defer 15) + +(use-package helpful + :after ehelp + :general (ehelp-map + "k" #'helpful-key + "v" #'helpful-variable + "f" #'helpful-callable)) + +;;; Files + +;;;; Auto-saving + +;; Auto-save everything to a temporary directory, instead of cluttering +;; the filesystem. I don’t want emacs-specific lockfiles, either. + +(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t)) + create-lockfiles nil) + +;;;; Auto-reloading + +(use-package autorevert + :custom ((global-auto-revert-mode t) + (auto-revert-verbose t))) + +;;;; Backups + +;; I like to keep my backups out of regular folders. I tell emacs to use +;; a subfolder of its configuration directory for that. Also, use the +;; trash for deleting on OS X. +(let ((backup-dir (expand-file-name "~/.emacs.d/backups/"))) + (unless (file-directory-p backup-dir) + (make-directory backup-dir)) + (setq backup-directory-alist `((".*" . ,backup-dir)) + backup-by-copying-when-linked t + backup-by-copying-when-mismatch t)) + +(setq delete-by-moving-to-trash t) + +(use-package goto-chg + :defer 1) + +;;; Directories + +(custom-set-variables + '(dired-dwim-target t) + '(dired-recursive-copies 'top) + '(dired-listing-switches "-alh") + '(dired-recursive-deleted (if delete-by-moving-to-trash + 'always + 'top))) + +(add-hook 'dired-mode-hook + (lambda () + (dired-hide-details-mode))) + +(use-package dired-git-info + :general (:keymaps 'dired-mode-map + :states 'normal + ")" #'dired-git-info-mode)) + +;;; Shells + +(use-package eshell + :defer 5 + :commands (eshell) + :functions (eshell/pwd) + :init (progn + (with-eval-after-load 'evil-ex + (evil-ex-define-cmd "esh[ell]" #'eshell))) + :custom ((eshell-prompt-function (lambda () + (concat (eshell/pwd) "\n$ "))) + (eshell-prompt-regexp "^[$][[:blank:]]") + (eshell-cmpl-cycle-completions nil))) + +(use-package eshell-toggle + :after projectile + :commands (eshell-toggle) + :custom ((eshell-toggle-use-projectile-root t))) + +(use-package esh-autosuggest + :after eshell + :ghook ('eshell-mode-hook)) + +(declare-function eshell-push-command "esh-buf-stack" (CMD)) +(defun my-bind-esh-push () + (general-define-key + :states '(normal insert) + :keymaps 'local + "M-q" #'eshell-push-command)) + +(use-package esh-buf-stack + :after (eshell) + :ghook ('eshell-mode-hook #'my-bind-esh-push) + :config (setup-eshell-buf-stack)) + +(use-package bash-completion + :after (eshell)) + +(use-package fish-completion + :when (executable-find "fish") + :after (bash-completion) + :custom ((fish-completion-fallback-on-bash-p t)) + :commands (global-fish-completion-mode) + :config (global-fish-completion-mode)) + +(use-package esh-help + :after (eshell) + :config (setup-esh-help-eldoc)) + +(use-package eshell-fringe-status + :after eshell + :ghook '(eshell-mode-hook)) + +(use-package eshell-up + :after (eshell)) + +(use-package shell + :defer t + :general (:keymaps 'shell-mode-map + "C-d" #'comint-delchar-or-maybe-eof)) + +(use-package comint + :defer t + :general (:keymaps 'comint-mode-map + "C-c C-l" #'counsel-shell-history)) + +;;; Editing + +(setq-default indent-tabs-mode nil + tab-always-indent 'complete) + +(use-package ws-butler + :ghook ('prog-mode-hook)) + +;;; Major modes + +;;;; js +(custom-set-variables '(js-indent-level 2) + '(js-enabled-frameworks '(javascript))) + +;;;; typescript +(custom-set-variables '(typescript-indent-level 2)) +(autoload 'ansi-color-apply-on-region "ansi-color") +(defun colorise-compilation-buffer () + (ansi-color-apply-on-region compilation-filter-start (point-max))) +(add-hook 'compilation-filter-hook #'colorise-compilation-buffer) + +;;;; shell +(general-add-hook 'sh-mode-hook + (lambda () + (general-add-hook 'after-save-hook + #'executable-make-buffer-file-executable-if-script-p :append :local))) + +(add-to-list 'auto-mode-alist '("\\.env\\'" . conf-unix-mode)) +(use-package sh-script + :mode (("\\.zsh\\'" . shell-script-mode) + ("zshenv\\'" . shell-script-mode) + ("zshrc\\'" . shell-script-mode)) + :config (setq sh-shell-file "/usr/bin/env zsh" + sh-basic-offset 2)) + +(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) + +;;;; make +(general-add-hook 'makefile-mode-hook + (lambda () + (setq-local indent-tabs-mode t))) + +;;;; nix +(custom-set-variables '(nix-indent-function #'nix-indent-line)) + +(use-package nix-update + :commands (nix-update-fetch)) + +;;;; gitlab-ci.yml +(with-eval-after-load 'git-gutter-fringe + (fringe-helper-define 'flycheck-fringe-bitmap-double-arrow '(center repeated) + "XXX.....")) + +(custom-set-variables '(gitlab-ci-url "https://gitlab.satoshipay.tech")) +(use-package gitlab-ci-mode-flycheck + :ghook ('gitlab-ci-mode-hook (list #'gitlab-ci-mode-flycheck-enable + #'flycheck-mode))) + +;;;; *ignore +(use-package gitignore-mode + :mode ((".dockerignore\\'" . gitignore-mode))) + +;;;; kubernetes +(custom-set-variables '(k8s-site-docs-version "v1.13")) + +;;;; beancount + +(use-package beancount + :load-path "~/projects/bitbucket.org/blais/beancount/editors/emacs") + +;;;; org + +(custom-set-variables '(org-ellipsis "…") + `(org-directory "~/Documents/org")) + +(use-package org-journal + :commands (org-journal-new-date-entry + org-journal-new-entry + org-journal-new-scheduled-entry) + :gfhook (#'variable-pitch-mode) + :custom ((org-journal-date-format "%A, %d %B %Y") + (org-journal-dir "~/Documents/journal"))) + +;;;; web modes (tsx, html) + +(use-package web-mode + :mode (("\\.tsx" . web-mode)) + :custom ((web-mode-enable-auto-pairing nil) + (web-mode-code-indent-offset 2) + (web-mode-markup-indent-offset 2) + (web-mode-css-indent-offset 2) + (web-mode-style-padding 0) + (web-mode-script-padding 0))) + +;;; IDE features + +(fringe-helper-define 'left-vertical-bar '(center repeated) + "XXX.....") +(use-package flymake + :custom ((flymake-error-bitmap '(left-vertical-bar compilation-error)) + (flymake-warning-bitmap '(left-vertical-bar compilation-warning)))) +(use-package flymake-diagnostic-at-point + :custom ((flymake-diagnostic-at-point-diagnostic-function #'flymake-diagnostic-at-point-display-minibuffer)) + :ghook '(flymake-mode-hook)) + +(use-package lsp-mode + :ghook ('(typescript-mode-hook + dockerfile-mode-hook + yaml-mode-hook + js-mode-hook + css-mode-hook + scss-mode-hook + html-mode-hook + haskell-mode-hook) + #'lsp) + :functions (lsp--flymake-setup) + :gfhook 'lsp--flymake-setup + :custom ((lsp-auto-guess-root t) + (lsp-auto-configure nil) + (lsp-prefer-flymake t) + (lsp-enable-symbol-highlighting nil)) + :config (progn + (add-to-list 'lsp-language-id-configuration '(js-mode . "javascript")))) + +(use-package lsp-clients + :after (lsp-mode)) + +(use-package lsp-ui + :after lsp-mode + :ghook ('lsp-mode-hook) + :custom ((lsp-ui-sideline-enable nil) + (lsp-ui-doc-mode nil) + (lsp-enable-snippet nil))) + +(use-package lsp-haskell + :after lsp-mode) + +;; Inside a javascript project, it's common to install tools locally to +;; the project. This will allows emacs to find their executables. + +(use-package add-node-modules-path + :ghook ('(js2-mode-hook typescript-mode-hook) #'add-node-modules-path)) + +;;;; Reformat on save + +(use-package prettier-js + :custom ((prettier-js-show-errors 'echo)) + :ghook ('(typescript-mode-hook) #'prettier-js-mode t) + :config (progn + (if-let ((prettier_d (executable-find "prettier_d"))) + (setq prettier-js-command prettier_d + prettier-js-args '("--pkg-conf" "--parser" "typescript")) + (message "prettier_d is not available")))) + +;;; E-mail + +(declare-function sendmail-send-it "sendmail") +(setq send-mail-function #'sendmail-send-it) + +(use-package mu4e + :if (executable-find "mu") + :commands (mu4e) + :init (setq mail-user-agent #'mu4e-user-agent) + :custom ((mu4e-completing-read-function #'ivy-completing-read) + (mu4e-maildir "~/mail") + (mu4e-context-policy 'pick-first) + (mu4e-update-interval 600) + (mu4e-change-filenames-when-moving t) + (mu4e-index-lazy-check t) + (mu4e-hide-index-messages t) + (mu4e-compose-format-flowed t)) + :init (progn + (with-eval-after-load 'evil-ex + (evil-ex-define-cmd "mu[4e]" #'mu4e))) + :config (progn + (setq mu4e-contexts (list + (make-mu4e-context + :name "SatoshiPay" + :match-func (lambda (msg) + (if msg + (mu4e-message-contact-field-matches + msg :to ".*@satoshipay.io") + (string-equal (system-name) "satoshipad"))) + :vars '((user-mail-address . "alan@satoshipay.io") + (mu4e-sent-messages-behavior . delete) + (mu4e-drafts-folder . "/satoshipay/Drafts") + (mu4e-sent-folder . "/satoshipay/Sent Mail") + (mu4e-refile-folder . "/satoshipay/All Mail") + (mu4e-trash-folder . "/satoshipay/Bin") + (mu4e-maildir-shortcuts . (("/satoshipay/INBOX" . ?i) + ("/satoshipay/All Mail" . ?a) + ("/satoshipay/Sent Mail" . ?s) + ("/satoshipay/Spam" . ?p))))))))) + +;;; Take me to my leader + +(my-leader-def + "" nil + "`" #'eshell-toggle + "h" '(:keymap ehelp-map :package ehelp) + "w" '(:keymap evil-window-map :package evil) + "x" '(:keymap ctl-x-map) + "q" #'evil-delete-buffer + "p" projectile-command-map + "v" #'split-window-right + "o" #'other-window + "u" #'universal-argument + ";" #'counsel-M-x + "bb" #'ivy-switch-buffer + "bx" #'kill-this-buffer + "br" #'revert-buffer + "bk" #'kill-buffer + "dd" #'dired + "fs" #'save-buffer + "ff" #'find-file + "fw" #'write-file + "fd" #'crux-delete-file-and-buffer + "fr" #'crux-rename-file-and-buffer + "gs" #'magit-status + "gm" #'git-messenger:popup-message + "gg" #'magit-dispatch + "gn" #'git-gutter:next-hunk + "gp" #'git-gutter:previous-hunk + "gi" #'git-gutter:popup-hunk + "gs" #'git-gutter:stage-hunk + "go" #'git-gutter:revert-hunk + "gt" #'git-timemachine + "bi" #'ibuffer + "bz" #'bury-buffer + "iu" #'counsel-unicode-char) + +;; # Local Variables: +;; # flycheck-disabled-checkers: 'emacs-lisp-checkdoc +;; # End: -- cgit 1.4.1