minor config update
[dot-emacs] / init.el
diff --git a/init.el b/init.el
index 6cfc1d6fb036b72cb75bfae42ecc7408fd0cf4bb..e91121ded3628786f3166f302634219a3e0688e7 100644 (file)
--- a/init.el
+++ b/init.el
@@ -1,4 +1,4 @@
-;; Copyright (C) 2019 Ian Kelling
+;; Copyright (C) 2020 Ian Kelling
 
 ;; This program is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 ;; do m-x benchmark-init to see some benchmark stats
-;;(add-to-list 'load-path "~/.emacs.d/src/benchmark-init-el/")
+;;(add-to-list 'load-path (concat user-emacs-directory "src/benchmark-init-el/")
 ;;(require 'benchmark-init-loaddefs)
 ;;(benchmark-init/activate)
 
 ;;; init.el --- the start of customization
 
-;; (toggle-debug-on-error) ;uncomment to help debug
+;;(toggle-debug-on-error) ;uncomment to help debug
+
 
 
 ;; stop from minimizing & freezing the gui
 (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)
+                   ;; 100 mb
+                   gc-cons-threshold 100000000))
+          ;; taken from wiegley, dunno why the t is there.
+          t)
+
+;; stuff to allow an alternate location for ~/.emacs.d
+(setq user-emacs-directory (file-name-directory user-init-file))
+(when (getenv "EHOME")
+  (setenv "HOME" (getenv "EHOME")))
 
 ;; 2019-6-26, 1.26s
 ;; ; to profile init:
 ;; ; uncomment the following block
-;; (require 'benchmark-init)
-;; (add-hook 'after-init-hook 'benchmark-init/deactivate)
+;;(require 'benchmark-init)
+;;(add-hook 'after-init-hook 'benchmark-init/deactivate)
 ;; ; Then run:
 ;; ; emacs -f benchmark-init/show-durations-tabulated
 ;; ; emacs -f benchmark-init/show-durations-tree
 
 ;; these need to be done before the hook in order to satisfy the byte compiler or batch mode
 
-;; this is the builtin org mode
-;;(add-to-list 'load-path "~/.emacs.d/emacs/site-lisp/org")
-
-(add-to-list 'load-path "~/.emacs.d/src/readline-complete")
+(add-to-list 'load-path (concat user-emacs-directory "src/readline-complete"))
 
 ;; disabled since not used.
-;;(add-to-list 'load-path "~/.emacs.d/src/bbdb-csv-import")
-;;(add-to-list 'load-path "~/.emacs.d/src/ghci-completion")
-;;(add-to-list 'load-path "~/.emacs.d/src/mediawiki-el")
-;;(add-to-list 'load-path "~/.emacs.d/src/spray")
+;;(add-to-list 'load-path (concat user-emacs-directory "src/bbdb-csv-import"))
+;;(add-to-list 'load-path (concat user-emacs-directory "src/spray"))
 
-(add-to-list 'load-path "~/.emacs.d/src/visible-mark")
+(add-to-list 'load-path (concat user-emacs-directory "src/visible-mark"))
 
 
 
 ;; from its README.md
 (eval-when-compile
   (require 'use-package))
-
+(use-package use-package-ensure-system-package
+  :ensure t)
 
 ;; Ubiquitous Packages. these could go anywhere actually
-(use-package saveplace
-  :unless noninteractive
-  :config
-  (save-place-mode 1))
+
 ;; find file at point
 (use-package ffap)
 
 
+
+
 (setq package-archives
       (quote
        (("gnu" . "https://elpa.gnu.org/packages/")
 
 
 ;; keep our init.el clean, by moving customization elisp to it's own file
-(setq custom-file "~/.emacs.d/custom.el")
-(load custom-file 'noerror)
+(setq custom-file (concat user-emacs-directory "custom.el"))
+;; empty atm
+;;(load custom-file 'noerror)
 
 
 ;;; auto-complete
 ;; disabled while I look for another alternative
 ;;(icomplete-mode)
 
+(unless (string= (daemonp) "server")
+  (setq ac-use-comphist nil))
 (require 'auto-complete-config)
 (ac-config-default)
 
 
 ;; complete after 1 char instead of default 2
-(setq ac-auto-start 1)
-(setq ac-delay 0.001)
+(setq ac-auto-start 1
+      ac-delay 0.001)
 
 (add-to-list 'ac-modes 'org-mode 'sql-mode)
 
          (list (format "LC_INSIDE_EMACS=%s,comint" emacs-version))
          process-environment))
        (default-directory
-         (if (file-accessible-directory-p default-directory)
-             default-directory
-           "/"))
+        (if (file-accessible-directory-p default-directory)
+            default-directory
+          "/"))
        proc decoding encoding changed)
     (let ((exec-path (if (and command (file-name-directory command))
                         ;; If the command has slashes, make sure we
 
 ;; avoid window config hook saving too much, it can
 ;; get into loops in some random situations
-(setq my-auto-save-last nil)
+(defvar my-auto-save-last nil)
+(defvar my-as nil)
+(defvar my-auto-save-last nil)
 (defun my-auto-save-win ()
   (unless (eq (current-buffer) my-auto-save-last)
     (my-auto-save (current-buffer))))
 
 (defun my-as-on-local (&rest ignore)
   (interactive)
-  (setq-local my-as on))
+  (setq-local my-as t))
 
 ;; based on suggestion in the emacs docs, redefine these 2 functions
 ;; to avoid prompt spamming the user when we do auto-save
@@ -503,13 +510,15 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
       ;; assume hard linked files are done on purpose, don't screw them up
       backup-by-copying-when-linked t)
 
+(defvar last-backup-time 0)
 ;; todo, the time needs to be an integer, not a vector type thing
 (defun constant-backup ()
   "Backup conditioned on some time passing since last one.
   Hooked into 'before-save-hook."
   (cl-flet ((b-time (minutes)
-                    (< last-backup-time
-                       (- (current-time) (* 60 minutes)))))
+              (< last-backup-time
+                 ;; current-time is seconds, so convert minutes to seconds.
+                 (- (current-time) (* 60 minutes)))))
     (when (or (not (boundp 'last-backup-time)) (and (< (buffer-size) 10000000) (b-time 5)) (b-time 30))
       (setq buffer-backed-up nil)
       (setq-local last-backup-time (current-time)))))
@@ -547,18 +556,6 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
 ;; lowest bound of functionality is actually about 15 input events
 ;; (setq auto-save-interval ...)
 
-;;; c-like settings
-;; change last thing from gnu.
-;; notably this avoids brace indent after if, and 4 space indent
-(setq c-default-style '((java-mode . "java")
-                        (awk-mode . "awk")
-                        (other . "stroustrup")))
-;; for emacs itself, use
-;; (setq c-default-style '((java-mode . "java")
-;;                         (awk-mode . "awk")
-;;                         (other . "gnu")))
-;; (setq-default c-basic-offset 2)
-
 ;;; color theme
 
 ;; A Theme builder is available at http://elpa.gnu.org/themes/ along with
@@ -571,24 +568,45 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
   (while custom-enabled-themes
     (disable-theme (car custom-enabled-themes)))
   (load-theme arg t))
-(setq color-theme-is-global t)
+
+;; not a real var? remove when I see this again
+;;(setq color-theme-is-global t)
 
 ;; temporary, make night be default
 
 (defun toggle-night ()
   (interactive)
   (cond  ((equal (car custom-enabled-themes) 'naquadah)
-          (override-theme 'leuven))
+          (override-theme 'ef-light))
          (t
           (override-theme 'naquadah))))
 
+(setq ef-themes-mixed-fonts t
+      ef-themes-variable-pitch-ui t)
+
 
 ;; in the leuven theme file, i made this change. will need to remake it
 ;; on package updates. I could fork, but its a pretty simple change
 ;; < `(default ((,class (:foreground "#333333" :background "#FFFFFF"))))
 ;; > `(default ((,class (:foreground "#333333" :background "#F6F6F0"))))
-(override-theme 'leuven)
+;;
+;; <   `(font-lock-comment-face ((,class (:slant italic :foreground "#8D8D84")))) ; #696969
+;; >   `(font-lock-comment-face ((,class (:slant italic :foreground "#484848")))) ; #696969
 
+;;(override-theme 'leuven)
+
+;; based on ef-themes README.org
+(mapc #'disable-theme custom-enabled-themes)
+;; the default blue is too dark and messes with erc colors
+(setq ef-light-palette-overrides
+      '((bg-mode-line "#efefef")))
+(ef-themes-select 'ef-light)
+;;(load-theme 'ef-light)
+
+
+;; for learning about faces, see
+;; useful snippet
+;; (byte-recompile-file "/home/iank/.emacs.d/elpa/leuven-theme-20220203.947/leuven-theme.el" nil 0)
 
 ;; disable color thing with this:
 ;;(disable-theme (car custom-enabled-themes))
@@ -625,12 +643,14 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
 
 
 
-
 ;;; cross session settings
 
+
+
 (use-package recentf
   ;; defer & commands from jwiegley
   :defer 10
+  :if (string= (daemonp) "server")
   :commands (recentf-mode
              recentf-add-file
              recentf-apply-filename-handlers)
@@ -640,24 +660,30 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
         recentf-max-menu-items 15)
   )
 
+(when (string= (daemonp) "server")
+  ;; save it every 5 minutes. https://www.emacswiki.org/emacs/RecentFiles
+  (run-at-time nil (* 5 60) 'recentf-save-list))
+
+;; less strong conditional: :unless noninteractive
 (use-package saveplace
-  :unless noninteractive
+  :if (string= (daemonp) "server")
   :config
-  save-place-version-control 'nospecial
-  save-place-limit 4000
-  save-place-file "~/.emacs.d/places"
+  (setq
+   save-place-version-control 'nospecial
+   save-place-limit 4000
+   save-place-file (concat user-emacs-directory "places"))
   (save-place-mode 1))
 
 
 ;; savehist keeps track of some history search entries
 (use-package savehist
-  :unless noninteractive
+  :if (string= (daemonp) "server")
   :config
   (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring)
         ;; save every minute
         savehist-autosave-interval 60
         ;; keep the home clean
-        savehist-file "~/.emacs.d/.savehist")
+        savehist-file (concat user-emacs-directory ".savehist"))
   (savehist-mode 1))
 
 ;;; dired
@@ -665,191 +691,29 @@ A non-nil CURRENT-ONLY argument means save only current buffer."
 ;; dired - reuse current buffer by pressing 'a'
 (put 'dired-find-alternate-file 'disabled nil)
 
-;;; mu4e
-
-;; alsot tried notmuch, it had some glitches, and it's config has a list
-;; of folders which i'd rather not publish, so it's config is archived.
-
-;;(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e")
-;;(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")
-;;  (require 'mu4e)
-
-;; (setq mu4e-headers-results-limit 2000)
-
-
-
-(defun my-mu4e-init ()
-  (setq mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields))
-  ;; it's implemented in mu4e, but not in the actions list for
-  ;; some reason.
-  (add-to-list 'mu4e-view-actions
-               '("browser view" . mu4e-action-view-in-browser) t)
-
-  (add-to-list 'mu4e-headers-actions
-               '("from this sender" . mu4e-action-msgs-by-this-sender) t)
-  (add-to-list 'mu4e-view-actions
-               '("from this sender" . mu4e-action-msgs-by-this-sender) t)
-  ;; normally, you would add to this, but we want to
-  ;; modify unread messages. the first 4 are defined by default.
-  (setq mu4e-bookmarks
-        `( ,(make-mu4e-bookmark
-             :name  "Unread messages"
-             ;; old less restrictive unread, for adapting in the future:
-             ;; flag:unread AND NOT flag:trashed AND NOT maildir:/Junk AND NOT maildir:/fwfw AND NOT maildir:/log
-             :query "flag:unread maildir:/INBOX"
-             :key ?u)
-           ,(make-mu4e-bookmark
-             :name "Today's messages"
-             :query "date:today..now"
-             :key ?t)
-           ,(make-mu4e-bookmark
-             :name "Last 7 days"
-             :query "date:7d..now"
-             :key ?w)
-           ,(make-mu4e-bookmark
-             :name "Messages with images"
-             :query "mime:image/*"
-             :key ?p))
-        )
-  )
-
-(eval-after-load "mu4e" '(my-mu4e-init))
-
-(setq
- ;; message mode prompted me on first message.
- ;; a function which describes options then sets this
- ;; the other options were to use smtp directly or pass to another mail client
- ;; here we use the standard sendmail interface. This applies for gnus too.
- send-mail-function (quote sendmail-send-it)
- ;; https://github.com/djcb/mu/issues/1025
- mail-user-agent 'mu4e-user-agent
- ;; common to gnus. default sendmail-query-once asks us, then sets this via customize.
- send-mail-function (quote sendmail-send-it)
- ;; use the standard imap folders
- mu4e-sent-folder   "/Sent"
- mu4e-drafts-folder "/Drafts"
- mu4e-trash-folder  "/Trash"
- ;; reindex new mail this often in seconds
- ;; show addresses instead of just names
- mu4e-view-show-addresses t
- mu4e-use-fancy-chars t
- mu4e-confirm-quit nil
- mu4e-headers-leave-behavior 'apply ;; dont ask, do whatever was marked
- ;; default 500.
- mu4e-headers-results-limit 1000
- ;; tell exim to use from: as envelope from.
- ;; exim's default is use outgoing_msg_localpart@hostname.
- mail-specify-envelope-from t
-
- ;; looking up the list of maildirs when doing jo from summary
- ;; can take a few seconds if we have a ton of messages.
- ;; Only take that time for the first lookup.
- ;; if we add a new maildir, just restart mu4e for it to be in that list.
- mu4e-cache-maildir-list t
- ;; default is 8, way too small for my big monitors
- mu4e-headers-visible-lines 50
- message-sendmail-envelope-from 'header
- ;; trying this out
- ;;mu4e-view-use-gnus t
- ;; had problems where mu4e and gnus would hang verifying signatures, gnus man
- ;; said this should help, but it didnt work. they still got verified.
- ;; mm-verify-option 'never
- )
-
-;; fucks up reading unread bookmark. when that is fixed, enable it
-;; (setq mu4e-update-interval 60)
-
-
-;; this file includes setting up my email addresses, which are not public,
-;; including
-;; mu4e-user-mail-address-list
-;; and a function
-;; inspired by mu4e info manual, search for mu4e-compose-pre-hook.
-(when (file-exists-p "/p/c/mymu4e.el")
-  (load "/p/c/mymu4e.el"))
-
-(defun my-decrypt ()
-  ;; use for decrypting in mu4e
-  (interactive)
-  (beginning-of-buffer)
-  (when (search-forward "-----BEGIN PGP MESSAGE-----" nil t)
-    (read-only-mode 0)
-    (let ((start (match-beginning 0))
-          (end (search-forward "-----END PGP MESSAGE-----" nil t)))
-      (shell-command-on-region start end "gpg2 -dq" nil t shell-command-default-error-buffer t)
-      )))
-(add-hook 'mu4e-view-mode-hook 'my-decrypt)
-
-(defun iank-set-from-name (regexes)
-  "If we find an address matching regex, then set that address as the to,
-and whatever was used"
-  (when mu4e-compose-parent-message
-    (let ((found nil))
-      (while (and regexes (not found))
-        (setq re (car regexes)
-              regexes (cdr regexes)
-              found (mu4e-message-contact-field-matches
-                     mu4e-compose-parent-message :to re)))
-      (when found
-        (setq user-full-name (car found))
-        ;; we get an error unless we do this. that is a bug. I could
-        ;; send a patch...  also a bug: setting message-from-style nil
-        ;; doesnt work in mu4e unless user-full-name is also nil.
-        (unless user-full-name
-          (setq message-from-style nil))
-        (setq user-mail-address (cdr found)
-              mail-signature nil))
-      found)))
-(defun iank-set-from (regexes)
-  "If we find an address matching regex, then set that address as the to,
-and Ian Kelling as the name"
-  (when mu4e-compose-parent-message
-    (let ((found nil))
-      (while (and regexes (not found))
-        (setq re (car regexes)
-              sig (cadr regexes)
-              regexes (cddr regexes)
-              found (cdr (mu4e-message-contact-field-matches
-                          mu4e-compose-parent-message :to re))))
-      (when found (setq user-mail-address found
-                        user-full-name "Ian Kelling"))
-      found)))
-
-
-(defun mu-exit-wait ()
-  (interactive)
-  ;; taken from the mu source
-  (let* ((buf (get-buffer mu4e~proc-name))
-        (proc (and (buffer-live-p buf) (get-buffer-process buf))))
-    (mu4e-quit)
-    ;; without sleep, we get database locked by another process error when hitting u
-    ;; if another mu was running.
-    (if proc (sleep-for 0 1000))))
-
-(defun fsf-mu4e ()
-  (interactive)
-  (my-mu4e-commmon)
-  (setq
-   user-mail-address "iank@fsf.org"
-   iank-user-mail-address user-mail-address
-   ;; WARNING: be careful editing this, there needs to be a space after --, and my editor
-   ;; and git will automatically remove it unless i manually disable it.
-   mail-signature fsf-sig
-   ) ;; end setq
-  (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to)
-  (mu4e))
 
+;; copied from dired-x info manual
+(with-eval-after-load 'dired
+  (require 'dired-x)
+  ;; use e instead for find file. i would like
+  ;; dired-do-async-shell-command, except it pops open some async
+  ;; shell buffer. i should figure out how to get rid of that.
+  (define-key dired-mode-map "f" 'dired-do-shell-command)
+  ;; Set dired-x global variables here.  For example:
+  ;; (setq dired-guess-shell-gnutar "gtar")
+  ;; (setq dired-x-hands-off-my-keys nil)
+  )
+(add-hook 'dired-mode-hook
+          (lambda ()
+            ;; Set dired-x buffer-local variables here.  For example:
+            ;; (dired-omit-mode 1)
+            ))
 
-
-
-(defun mu4e-action-msgs-by-this-sender (msg)
-  "In header view, view messages by the sender of the message under point."
-  (let ((from (mu4e-message-field msg :from)))
-    (unless from
-      (mu4e-error "No from header for this message"))
-    ;; from is structured like: (("Anacron" . "root@x2.lan"))
-    (mu4e-headers-search (concat "f:" (cdar from)))))
-
+;; the defaults are just some weird predefined list, like xpdf for pdf.
+(setq dired-guess-shell-alist-user
+      (list
+       (list ".*" "xdg-open")
+       ))
 
 
 ;;; elisp settings
@@ -857,10 +721,6 @@ and Ian Kelling as the name"
 (setq eval-expression-debug-on-error t)
 
 
-(eval-after-load "python-mode"
-  '(progn
-     (define-key python-mode-map (kbd "C-j") nil)))
-
 ;;; isearch
 (setq
  isearch-allow-scroll t
@@ -949,11 +809,11 @@ and Ian Kelling as the name"
 
 ;; Activate occur easily inside isearch
 (define-key isearch-mode-map (kbd "C-o")
-  (lambda () (interactive)
-    (let ((case-fold-search isearch-case-fold-search))
-      (occur (if isearch-regexp
-                 isearch-string
-               (regexp-quote isearch-string))))))
+            (lambda () (interactive)
+              (let ((case-fold-search isearch-case-fold-search))
+                (occur (if isearch-regexp
+                           isearch-string
+                         (regexp-quote isearch-string))))))
 ;;; lisp / elisp mode setings
 
 (add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save)
@@ -985,50 +845,67 @@ and Ian Kelling as the name"
 ;; interactive modes don't need whitespace checks
 (defun interactive-lisp-coding-defaults ()
   (whitespace-mode -1))
-(setq prelude-interactive-lisp-coding-hook 'prelude-interactive-lisp-coding-defaults)
 
+;;; modes with little configuration needed
 
-;; ielm is an interactive Emacs Lisp shell
-(defun ielm-mode-defaults ()
-  (run-hooks 'prelude-interactive-lisp-coding-hook)
-  (turn-on-eldoc-mode))
-(add-hook 'ielm-mode-hook 'ielm-mode-defaults)
 
-;;; modes with little configuration needed
 
-(setq outline-minor-mode-prefix "\ 3\ 1"
-      css-indent-offset 2
-      ;; auto indent shell script comments
-      sh-indent-comment t
-      sh-here-document-word "'EOF'"
-      tramp-default-method "ssh"
-      ;; ediff-buffers is the main command to use
-      ;; don't start another frame for the control panel
-      ;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers
-      ;; so disable this temporarily with the next line if you want that
-      ;; sometime I should setup 2 functions to explicitly do each type
-      ediff-window-setup-function 'ediff-setup-windows-plain
-      ;;(setq ediff-window-setup-function 'ediff-setup-windows-default)
-      ;; do side by side diffs
-      ediff-split-window-function 'split-window-horizontally
-      ;; ediff things I tried which didn't work, which intuitively I think should
-      ;; work better: I can open the second diff buffer in a new frame, and
-      ;; close it's window in the first frame after starting ediff, but when I
-      ;; hit n to go to the next diff, it restores the window in the first
-      ;; frame. Another thing I tried is to open 2 new frames and set them up
-      ;; as I want. However, if I try to open the *Ediff Control Panel* buffer
-      ;; in a different window from its original one, my mouse jumps to one of
-      ;; the diff frames, or if that isn't visible, the buffer just hangs
-      ;; until I select the original ediff control panel window. This seems
-      ;; like a bug to me. I am using a very recent development version of
-      ;; emacs.
-
-      )
+(custom-set-variables
+ '(css-indent-offset 2)
+ '(sh-here-document-word "'EOF'")
+ '(outline-minor-mode-prefix "\ 3\ 1")
+ '(tramp-default-method "ssh")
+ ;; change last thing from gnu.
+ ;; notably this avoids brace indent after if, and 4 space indent
+ ;; for emacs itself, use
+ ;; (setq c-default-style '((java-mode . "java")
+ ;;                         (awk-mode . "awk")
+ ;;                         (other . "gnu")))
+ ;; (setq-default c-basic-offset 2)
+ '(c-default-style '((java-mode . "java")
+                     (awk-mode . "awk")
+                     (other . "stroustrup")))
+ )
+
+
+(setq
+ ;; ediff-buffers is the main command to use
+ ;; don't start another frame for the control panel
+ ;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers
+ ;; so disable this temporarily with the next line if you want that
+ ;; sometime I should setup 2 functions to explicitly do each type
+ ediff-window-setup-function 'ediff-setup-windows-plain
+ ;;(setq ediff-window-setup-function 'ediff-setup-windows-default)
+ ;; do side by side diffs
+ ediff-split-window-function 'split-window-horizontally
+ ;; ediff things I tried which didn't work, which intuitively I think should
+ ;; work better: I can open the second diff buffer in a new frame, and
+ ;; close it's window in the first frame after starting ediff, but when I
+ ;; hit n to go to the next diff, it restores the window in the first
+ ;; frame. Another thing I tried is to open 2 new frames and set them up
+ ;; as I want. However, if I try to open the *Ediff Control Panel* buffer
+ ;; in a different window from its original one, my mouse jumps to one of
+ ;; the diff frames, or if that isn't visible, the buffer just hangs
+ ;; until I select the original ediff control panel window. This seems
+ ;; like a bug to me. I am using a very recent development version of
+ ;; emacs.
+
+ )
 
 ;; disabled temporarily. todo, look into it
 ;;(add-hook 'outline-minor-mode-hook 'outshine-mode)
 
 
+
+;; this file includes setting up my email addresses, which are not public,
+;; including
+;; mu4e-user-mail-address-list
+;; and a function
+;; inspired by mu4e info manual, search for mu4e-compose-pre-hook.
+(when (file-exists-p "/p/c/mymu4e.el")
+  (load "/p/c/mymu4e"))
+
+
 (when (file-exists-p "/a/h/iank-mod.el")
   (load-file "/a/h/iank-mod.el"))
 
@@ -1044,29 +921,40 @@ and Ian Kelling as the name"
 ;; be pasting whitespace significant things in here, so
 ;; just don't do anything.
 ;; todo: propose this upstream
+;; fundamental mode for files like .asc
 (add-to-list 'ws-butler-global-exempt-modes 'message-mode)
+(add-to-list 'ws-butler-global-exempt-modes 'dns-mode)
+(add-to-list 'ws-butler-global-exempt-modes 'fundamental-mode)
 
 (ws-butler-global-mode)
 
-(require 'nginx-mode)
+;; disabled because i dont edit nginx files enough
+;; to have this loaded at startup
+;;(use-package nginx-mode)
 ;;The mode should automatically activate for files called nginx.conf and files under /etc/nginx - if not, you can add something like this to your init file:
 ;;(add-to-list 'auto-mode-alist '("/etc/nginx/sites-available/.*" . nginx-mode))
 
 ;; todo, put this on a hook with prog mode
 ;;(highlight-indentation-mode 1)
 
-(add-hook 'auto-revert-tail-mode-hook
-          (lambda ()
-            (when (string=
-                   buffer-file-name
-                   "/var/log/cloudman/development/cm-service.log")
-              (setq-local prev-auto-revert-max 0)
-              ;; set buffer-local hook
-              (add-hook 'after-revert-hook 'tail-colorize nil t))))
-(defun tail-colorize ()
-  (ansi-color-apply-on-region prev-auto-revert-max (point-max))
-  (setq-local prev-auto-revert-max (point-max)))
 
+;; example of a syntax highlighted tail
+(use-package autorevert
+  :defer t
+  :config
+  (defvar prev-auto-revert-max)
+  (defun tail-colorize ()
+    (ansi-color-apply-on-region prev-auto-revert-max (point-max))
+    (setq-local prev-auto-revert-max (point-max)))
+  (add-hook 'auto-revert-tail-mode-hook
+            (lambda ()
+              (when (string=
+                     buffer-file-name
+                     "/var/log/cloudman/development/cm-service.log")
+                (setq-local prev-auto-revert-max 0)
+                ;; set buffer-local hook
+                (add-hook 'after-revert-hook 'tail-colorize nil t))))
+  )
 
 ;; delete active selection with self-insert commands
 (delete-selection-mode t)
@@ -1076,7 +964,7 @@ and Ian Kelling as the name"
 
 ;; dot mode, repeats last action
 (require 'dot-mode)
-(add-hook 'find-file-hooks 'dot-mode-on)
+(add-hook 'find-file-hook 'dot-mode-on)
 
 ;; clean up obsolete buffers automatically at midnight
 (require 'midnight)
@@ -1087,7 +975,6 @@ and Ian Kelling as the name"
 
 
 ;; show the name of the current function definition in the modeline
-(setq which-func-modes t)
 (which-function-mode 1)
 
 ;; enable winner-mode to manage window configurations
@@ -1117,7 +1004,6 @@ and Ian Kelling as the name"
 
 ;; todo, turn on auto-fill just for txt files
 ;;(add-hook 'text-mode-hook 'turn-on-auto-fill)
-(add-hook 'text-mode-hook 'turn-on-flyspell)
 
 ;; random extra highlights
 (require 'volatile-highlights)
@@ -1140,11 +1026,31 @@ and Ian Kelling as the name"
 
 ;;; misc general settings
 
+
+;; I tried to look for a function that would set this that is
+;; not part of the emacs interactive customize stuff, but didn't see one
+;; in the faces documentation.
+
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil))))
+ '(region ((t nil))))
+
+
 ;; from tramp manual, use the same ssh controlmaster. I was having problems with
 ;; tramp prompting me for a username and pass.
 (customize-set-variable 'tramp-use-ssh-controlmaster-options nil)
 
 (setq
+ ;; avoid this stupid prompt when doing sudo-edit
+ ;; Save auth info to file ~/.authinfo? [y/n/N/e/?]
+ ;; which doesn't actually use the default N by pressing enter,
+ ;; and doesn't actually save the 'never' setting like it claims.
+ ;; todo: file a bug.
+ auth-source-save-behavior nil
  auto-revert-interval 2
  ;; fix eof end of file newline
  mode-require-final-newline t
@@ -1160,8 +1066,18 @@ and Ian Kelling as the name"
  paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] "
  sh-basic-offset 2
  vc-follow-symlinks t
+ dired-confirm-shell-command nil
+ dired-deletion-confirmer '(lambda (x) t)
+ dired-listing-switches "-alh"
+ dired-recursive-deletes 'always
+ dired-clean-confirm-killing-deleted-buffers nil
+ undo-outer-limit 100000000 ; per undo command
+ undo-limit 500000000 ; undo history limit
+ undo-strong-limit 600000000 ; undo history limit plus some extra
  )
 
+
+
 (ivy-mode 1)
 (add-hook 'text-mode-hook (lambda () (auto-fill-mode t)))
 (setq counsel-find-file-at-point t)
@@ -1211,11 +1127,10 @@ and Ian Kelling as the name"
 (setq font-lock-maximum-decoration t
       inhibit-startup-message t
       transient-mark-mode t
-      delete-by-moving-to-trash t
       shift-select-mode nil
       truncate-partial-width-windows nil
       uniquify-buffer-name-style 'forward
-      oddmuse-directory "~/.emacs.d/oddmuse"
+      oddmuse-directory (concat user-emacs-directory "oddmuse")
       echo-keystrokes 0.1
       mark-ring-max 160
       sort-fold-case t  ; case insensitive line sorting
@@ -1227,9 +1142,6 @@ and Ian Kelling as the name"
       ring-bell-function 'ignore
       case-replace nil
       revert-without-query '(".*")
-      ;; don't pause display code on input.
-      ;; smoother display performance at slight cost of input performance
-      redisplay-dont-pause t
       font-lock-maximum-decoration t) ; probably default and not necesary
 
 
@@ -1242,20 +1154,8 @@ and Ian Kelling as the name"
               imenu-auto-rescan t
               indicate-empty-lines t) ; mark end of buffer
 
-(require 'smooth-scroll)
-;; long gnus summary buffers lags too much with this,
-;; but I like it enough to leave it enabled by default
-;; and crank up the step size to be faster
-;; and it doesn't have a way to enable it only for certain modes etc.
-;; todo sometime, make it work for certain modes only
-(smooth-scroll-mode t)
-;; its too slow with the default of 2
-(setq smooth-scroll/vscroll-step-size 6)
-;; sublimity doesn't work as good going fast by default
-;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location
 
-
-(blink-cursor-mode '(-4))
+(blink-cursor-mode 0)
 (menu-bar-mode -1)
 (tool-bar-mode -1)
 
@@ -1323,7 +1223,7 @@ and Ian Kelling as the name"
 (defun fill-buffer ()
   (interactive)
   (save-mark-and-excursion
-    (beginning-of-buffer)
+    (goto-char (point-min))
     (while (= (forward-line) 0)
       (fill-paragraph))))
 
@@ -1416,72 +1316,6 @@ Go to the next directory based on where the cursor is."
 ;; make window title be the buffer name
 (setq frame-title-format "%b")
 
-;; -----------------------------
-;; fixing up the mode line
-;; modified from mastering emacs blog
-;; ----------------------------
-
-(defvar mode-line-cleaner-alist
-  `((auto-complete-mode . "")
-    (yas/minor-mode . "")
-    (paredit-mode . "")
-    (auto-fill-function . "")
-    (eldoc-mode . "")
-    (abbrev-mode . "")
-    (flyspell-mode . "")
-    (glasses-mode . "")
-    (dot-mode . "")
-    (yas-global-mode . "")
-    (yas-minor-mode . "")
-    (undo-tree-mode . "")
-    (volatile-highlights-mode . "")
-    (highlight-symbol-mode . "")
-    ;; Major modes
-    (lisp-interaction-mode . "λ")
-    (hi-lock-mode . "")
-    (python-mode . "Py")
-    (emacs-lisp-mode . "EL")
-    (nxhtml-mode . "nx"))
-  "Alist for `clean-mode-line'.
-
-  When you add a new element to the alist, keep in mind that you
-  must pass the correct minor/major mode symbol and a string you
-  want to use in the modeline *in lieu of* the original.")
-
-
-(defun clean-mode-line ()
-  (interactive)
-  (loop for cleaner in mode-line-cleaner-alist
-        do (let* ((mode (car cleaner))
-                  (mode-str (cdr cleaner))
-                  (old-mode-str (cdr (assq mode minor-mode-alist))))
-             (when old-mode-str
-               (setcar old-mode-str mode-str))
-             ;; major mode
-             (when (eq mode major-mode)
-               (setq mode-name mode-str)))))
-
-                                        ; disabled
-                                        ;  (add-hook 'after-change-major-mode-hook 'clean-mode-line)
-
-
-;; alias the new `flymake-report-status-slim' to
-;; `flymake-report-status'
-(defalias 'flymake-report-status 'flymake-report-status-slim)
-(defun flymake-report-status-slim (e-w &optional status)
-  "Show \"slim\" flymake status in mode line."
-  (when e-w
-    (setq flymake-mode-line-e-w e-w))
-  (when status
-    (setq flymake-mode-line-status status))
-  (let* ((mode-line " Î¦"))
-    (when (> (length flymake-mode-line-e-w) 0)
-      (setq mode-line (concat mode-line ":" flymake-mode-line-e-w)))
-    (setq mode-line (concat mode-line flymake-mode-line-status))
-    (setq flymake-mode-line mode-line)
-    (force-mode-line-update)))
-
-
 (defun my-after-change-major-mode-hook ()
   (setq mode-line-mule-info nil
         minor-mode-alist nil
@@ -1505,7 +1339,7 @@ Go to the next directory based on where the cursor is."
 
 ;;; org mode
 
-;; todo work on org-cycle-emulate-tab
+
 
 ;; todo, this doesn't work for a non-standard keybind
 ;;(setq org-special-ctrl-k t)
@@ -1555,6 +1389,8 @@ Go to the next directory based on where the cursor is."
       org-global-properties (quote (("STYLE_ALL" . "habit")))
       org-special-ctrl-a/e t  ;; home and end work special in headlines
       org-completion-use-ido t
+      ;; i had some problem with this in the past, but don't know what, so whatever.
+      org-cycle-emulate-tab nil
       org-catch-invisible-edits 'smart)
 
 (setq
@@ -1595,8 +1431,8 @@ Go to the next directory based on where the cursor is."
 (defun variable-pitch-off ()
   (variable-pitch-mode 0))
 (add-hook 'yaml-mode-hook 'variable-pitch-off)
+(add-hook 'dns-mode-hook 'variable-pitch-off)
 
-(eval-after-load "org" '(my-org-face-init))
 
 (defun my-org-face-init()
   (set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family))
@@ -1607,6 +1443,8 @@ Go to the next directory based on where the cursor is."
   (set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family))
   )
 
+(eval-after-load "org" '(my-org-face-init))
+
 (defun remove-org-binds ()
   (define-key org-mode-map (kbd "<M-return>") nil)
   (define-key org-mode-map (kbd "C-'") nil)
@@ -1643,6 +1481,8 @@ Go to the next directory based on where the cursor is."
   ;; so that I can do completion before the dialog pops up
   ;;(local-set-key (kbd "<tab>") 'auto-complete)
   (local-set-key (kbd "TAB") 'auto-complete)
+  (define-key emacs-lisp-mode-map (kbd "M-q") nil)
+
   ;; todo, this is causing error message on loading file, prolly not working
   ;;(flycheck-mode +1)
   (setq ac-sources (delq 'ac-source-dictionary ac-sources))
@@ -1651,7 +1491,8 @@ Go to the next directory based on where the cursor is."
   ;; this says do autofilling using newcomment.el. The "only" is a misnomer.
   (set (make-local-variable 'comment-auto-fill-only-comments) t)
   (column-number-mode t)
-  (turn-on-smartparens-mode)
+  ;; trying without
+  ;; (turn-on-smartparens-mode)
 
   ;; prettify lambdas
   (font-lock-add-keywords
@@ -1661,8 +1502,6 @@ Go to the next directory based on where the cursor is."
                     nil))))))
 (add-hook 'prog-mode-hook 'prog-mode-defaults)
 
-;; enable flyspell in prog mode. text mode is handled
-(add-hook 'prog-mode-hook 'flyspell-prog-mode)
 
 
 ;;; yank auto-indent
@@ -1711,6 +1550,23 @@ indent yanked text (with prefix arg don't indent)."
 ;;  # eval: (outline-minor-mode)
 ;; # outline-regexp: "\\( *\\)# [*]\\{1,8\\} "
 
+(defun outline-level ()
+  "Return the depth to which a statement is nested in the outline.
+Point must be at the beginning of a header line.
+This is actually either the level specified in `outline-heading-alist'
+or else the number of characters matched by `outline-regexp'."
+  (or (cdr (assoc (match-string 0) outline-heading-alist))
+      (let ((whitespace-end (match-end 1))
+            (match-begin (match-beginning 0)))
+        (if (= whitespace-end match-begin)
+            (- (match-end 0) match-begin)
+          (- (match-end 0) whitespace-end)
+          ))))
+;; originally:
+;;(or (cdr (assoc (match-string 0) outline-heading-alist))
+;;    (- (match-end 0) (match-beginning 0))))
+
+
 
 ;; avoid stupid git crap like "warning, terminal not fully functional"
 (setenv "PAGER" "cat")
@@ -1750,64 +1606,19 @@ indent yanked text (with prefix arg don't indent)."
     (shell)))
 
 (add-hook 'shell-mode-hook 'track-shell-directory/procfs)
-;;; smartparens
-;; the melpa git version had a catastrophic bug I reported.
-;; downgraded to marmalade version and everything is working fine.
-(require 'smartparens-config)
-(show-smartparens-global-mode t)
-
-
-(defun gp/sp/pair-on-newline-and-indent (id action context)
-  "Open a new brace or bracket expression, with relevant newlines and indent. "
-  (save-excursion
-    (newline)
-    (indent-according-to-mode))
-  (indent-according-to-mode))
-
-;; when opening a pair, and then inserting a newline, push the closing pair to another newline
-(sp-pair "{" nil :post-handlers
-         '(:add ((lambda (id action context)
-                   (gp/sp/pair-on-newline-and-indent id action context)) (kbd "RET"))))
-(sp-pair "[" nil :post-handlers
-         '(:add ((lambda (id action context)
-                   (gp/sp/pair-on-newline-and-indent id action context)) (kbd "RET"))))
-
-
-;; in my version, this is not a pairing.
-;; not sure if it is in a future version since I reverted to marmalade
-;; Don't need c-comments in strings -- they frustrate filename globs
-;; (sp-pair "/*" nil :unless '(sp-in-string-p))
-
-;; Don't need quotes to pair next to words
-(sp-pair "\"" nil :unless '(sp-point-before-word-p sp-point-after-word-p))
-(sp-pair "'" nil :unless '(sp-point-before-word-p sp-point-after-word-p))
-
-
-;; todo, testout these mode specific settings from graphene.
-;; Ruby-specific pairs and handlers
-
-(eval-after-load "ruby"
-  '(require 'smartparens-ruby))
-
-;; Markdown
-(sp-local-pair '(markdown-mode gfm-mode) "*" "*"
-               :unless '(sp-in-string-p)
-               :actions '(insert wrap))
-
-;; Except in HTML
-(sp-local-pair 'html-mode "\"" nil :unless '(:rem sp-point-after-word-p))
-
-
-
-
 ;;; spell correction
 (setq
  ispell-program-name "hunspell"
  ispell-silently-savep t) ; don't prompt to save personal dictionary
 
-(require 'rw-hunspell)
+(use-package rw-hunspell
+  :defer t)
 ;; rw-hunspell sets up hunspell dictionary automagically.
 
+(use-package flyspell
+  :ensure-system-package hunspell
+  :hook ((prog-mode . flyspell-prog-mode)
+         (text-mode . turn-on-flyspell)))
 
 ;; Rant: Hunspell SHOULD be standard. its used by firefox and openoffice and
 ;; osx. In contrast, the first few words I added to aspell dictionary were
@@ -1819,15 +1630,19 @@ indent yanked text (with prefix arg don't indent)."
 
 
 ;;; tex
-(setq-default TeX-PDF-mode t) ; use pdf
-;; more sensible defaults based on info manual quickstart
-(setq TeX-auto-save t
-      TeX-parse-self t
-      ;; not documented, but looking at the source, I find this
-      ;; stops me from being asked what command on every C-c-c
-      ;; when doing a latex document.
-      TeX-command-force "LaTeX"
-      )
+
+(use-package latex-mode
+  :no-require t
+  :config
+  (setq-default TeX-PDF-mode t) ; use pdf
+  ;; more sensible defaults based on info manual quickstart
+  (setq TeX-auto-save t
+        TeX-parse-self t
+        ;; not documented, but looking at the source, I find this
+        ;; stops me from being asked what command on every C-c-c
+        ;; when doing a latex document.
+        TeX-command-force "LaTeX"
+        ))
 
 ;;; visible mark mode
 
@@ -1860,20 +1675,48 @@ indent yanked text (with prefix arg don't indent)."
 ;; if I could define overlay faces to use inverse foreground color
 
 
+;; (setq comment-start "<br align=\"left\"")
+;;
+
+;; (setq comment-start "#" comment-padding " ")
+
+
+;; graphviz fill, for html left aligned labels
+(defun grfil()
+  (interactive)
+  (setq comment-start "<br align=\"left\"/>&nbsp;")
+  (setq comment-padding " ")
+  (setq fill-column 50)
+  ;; (setq fill-column 30)
+  (mark-paragraph)
+  ;; (call-interactively 'uncomment-region)
+  (fill-paragraph)
+  (call-interactively 'comment-region)
+  (deactivate-mark)
+  (save-excursion
+    (goto-char (region-beginning))
+    (next-line)
+    (comment-line 1)
+    )
+  )
+
+;; (chirp)
+(defun chirp()
+  (message "chirp nothing"))
 ;;; znc/erc
 (defun chirp()
   (interactive)
-  (setq vol 50)
-  (when (string= (system-name) "kd") (setq vol 80))
+  (setq vol 80)
+  (when (string= (system-name) "kd") (setq vol 60))
   ;; speed is there so i can adjust and make it go slow so it plays long enough to adjust in pavucontrol
-  (start-process-shell-command "ignoreme" nil (format "mpv --speed=1 --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
+  (start-process-shell-command "ignoreme" nil (format "mpv --speed=1 --no-terminal --vo=null --volume=%d /a/bin/data/d20.wav" vol)))
 ;; from https://www.emacswiki.org/emacs/ErcSound
 (defun chirp-slow()
   (interactive)
   (setq vol 50)
   (when (string= (system-name) "tp") (setq vol 80))
   ;; speed is there so i can adjust and make it go slow so it plays long enough to adjust in pavucontrol
-  (start-process-shell-command "ignoreme" nil (format "mpv --speed=.2 --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
+  (start-process-shell-command "ignoreme" nil (format "mpv --speed=.2 --no-terminal --vo=null --volume=%d /a/bin/data/d20.wav" vol)))
 
 (defun erc-my-privmsg-sound (proc parsed)
   (let* ((tgt (car (erc-response.command-args parsed)))
@@ -1887,8 +1730,18 @@ indent yanked text (with prefix arg don't indent)."
   (unless (string-match "Server:[0-9]+" nickuserhost)
     (chirp)))
 
+(defun erc-sound-if-not-server (match-type nickuserhost msg)
+  ;; (message "d1 %s" nickuserhost)
+  (unless (or (string-match-p "Server:[0-9]+" nickuserhost) (string-match-p "leah" nickuserhost))
+    (chirp)))
+
 (use-package erc
+  :defer t
+  :custom-face
+  (erc-current-nick-face ((t :weight bold :foreground "red")))
   :init
+  (which-function-mode 0)
+  ;; fuck that default turquoise
   (setq erc-fill-prefix ""
         ;; consider invisible frames to be unseen. seems like an obvious default
         erc-track-visibility 'visible
@@ -1896,13 +1749,78 @@ indent yanked text (with prefix arg don't indent)."
         erc-track-switch-direction 'importance
         ;; defaults minus fill. todo: modify the list instead of specifying it explicitly in case the defaults change
         erc-modules
-        '(autojoin button completion irccontrols list match menu move-to-prompt netsplit networks noncommands readonly ring stamp track)
-        ) ; end setq
-  :config
-  (add-hook 'erc-server-PRIVMSG-functions
-            'erc-my-privmsg-sound)
-  (add-hook 'erc-text-matched-hook 'erc-sound-if-not-server)
-  (erc-track-mode 1))
+        '(autojoin button completion imenu irccontrols list match menu move-to-prompt netsplit networks noncommands readonly ring stamp track)
+        ;; expanded from https://www.emacswiki.org/emacs/ErcChannelTracking,
+        ;; ignore various messages
+        erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE"
+                                  "324" "329" "332" "333" "353")
+        ;; seems good, i don't care about the server buffer generally
+        erc-track-exclude-server-buffer t
+        ;; dont highlight channels just cuz of new messages, except for pms or some new channel I haven't listed in my config.
+
+        erc-track-shorten-cutoff 40
+        ;; sed -rn 's/.*(#[^>]*).*/"\1"/p' /p/c/machine_specific/li/filesystem/var/lib/znc/configs/znc.conf
+        erc-track-priority-faces-only (list
+                                        "#conservancy"
+                                        "#fosdem"
+                                        "#fsf"
+                                        "#fsf-licensing"
+                                        "#fsfe"
+                                        "#fsfsys"
+                                        "#gnu"
+                                        "#librecmc"
+                                        "#libreplanet"
+                                        "#mnt-reform"
+                                        "#nouveau"
+                                        "#pump.io"
+                                        "#savannah"
+                                        "#seagl"
+                                        "#social"
+                                        "#spamassassin"
+                                        "#talos-workstation"
+                                        "#trisquel"
+                                        "#trisquel-dev"
+                                        "#overseers"
+                                        "#gdb"
+                                        "#gcc"
+                                        "#glibc"
+                                        "#binutils"
+                                        "#gnu-linux-libre"
+                                        "#parabola"
+                                        "#guix"
+                                        "#gnu-ops"
+                                        "#gcc"
+                                        )
+  ;; so that we don't show channels where i havent been mmentioned
+  erc-track-faces-priority-list '(erc-current-nick-face
+                                  erc-keyword-face
+                                  erc-pal-face
+                                  erc-nick-msg-face
+                                  erc-direct-msg-face
+                                  erc-fool-face)
+
+
+  ) ; end setq
+
+:config
+(add-hook 'erc-server-PRIVMSG-functions
+          'erc-my-privmsg-sound)
+(add-hook 'erc-text-matched-hook 'erc-sound-if-not-server)
+(erc-track-mode 1)
+(defun erc-track--switch-buffer (fun arg)
+  (if (not erc-track-mode)
+      (message (concat "Enable the ERC track module if you want to use the"
+                      " tracking minor mode"))
+    (cond (erc-modified-channels-alist
+          ;; if we're not in erc-mode, set this buffer to return to
+           (if-let ((buf (erc-track-get-active-buffer arg))
+                    ((buffer-live-p buf)))
+               (funcall fun buf)
+             (erc-modified-channels-update)
+             (erc-track--switch-buffer fun arg)))
+         ;; if no active channels, switch back to what we were doing before
+         (t (switch-to-buffer "#fsfsys")))))
+)
 ;;; named commands
 (defun rm-file-and-buffer ()
   "Removes file connected to current buffer and kills buffer."
@@ -1925,8 +1843,8 @@ indent yanked text (with prefix arg don't indent)."
 ;; worth the benefit of only having one concept in my mind.
 (dolist
     (r `(
-         (?i (file . ,"~/.emacs.d/init.el"))
-         (?o (file . ,"/a/work.org"))
+         (?i (file . ,(concat user-emacs-directory "init.el")))
+         (?o (file . ,"/b/w/work.org"))
          (?t (file . ,"/a/t.org"))
          (?s (file . ,"/usr/share/doc/exim4-base/spec.txt.gz"))
          (?w (file . ,"/p/w.org"))
@@ -1940,26 +1858,29 @@ indent yanked text (with prefix arg don't indent)."
       undo-strong-limit 600000000) ; undo history limit plus some extra
 
 
-;;; undo tree mode
+;;; undo-fu mode
+
+;; thank god i'm done with undo-tree and the bug where my auto-saveing
+;; would cause it to lose all undo history, strangely especially in
+;; email buffers. it would claim the undo was outside the visible
+;; buffer.
 
-;; note, this has weird errors when it was before recentf-mode
+(use-package undo-fu
+  :config
+  (global-unset-key (kbd "C-z")))
 
-(use-package undo-tree
+(use-package undo-fu-session
+  :if (string= (daemonp) "server")
   :config
-  ;; more resilient undo-tree-history if we have its location set up front.
-  (setq undo-tree-history-directory-alist '(("." . "~/.undo-tree-history"))
-        undo-outer-limit 100000000 ; per undo command
-        undo-limit 500000000 ; undo history limit
-        undo-strong-limit 600000000 ; undo history limit plus some extra
-        ;; Undo in region just happens accidentally, and throws me off
-        undo-tree-enable-undo-in-region nil)
-  ;; disabled due to bug, something like unknown entry in undo tree canary
-  ;; (setq undo-tree-auto-save-history t)
-
-  ;; todo, send patch undo-tree-visualize should scroll with the scroll key, instead of just pgup pgdn (aka next/prior)
-  (global-undo-tree-mode)
-  ;; simple way to fix that enable undo-tree starts out disabled in org-mode
-  (defun undo-tree-overridden-undo-bindings-p() nil))
+  (setq undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'")))
+
+(when (string= (daemonp) "server")
+  (unless (equal (user-uid) 0) ; don't make root owned files
+    (global-undo-fu-session-mode)
+    (when (file-exists-p "/p/c/undo-fu-session")
+      (setq undo-fu-session-directory "/p/c/undo-fu-session"))
+    ))
+
 
 ;;; keybinds
 
@@ -1976,11 +1897,11 @@ indent yanked text (with prefix arg don't indent)."
 ;; from starter-kit
 
 (define-key isearch-mode-map (kbd "C-o")
-  (lambda () (interactive)
-    (let ((case-fold-search isearch-case-fold-search))
-      (occur (if isearch-regexp
-                 isearch-string
-               (regexp-quote isearch-string))))))
+            (lambda () (interactive)
+              (let ((case-fold-search isearch-case-fold-search))
+                (occur (if isearch-regexp
+                           isearch-string
+                         (regexp-quote isearch-string))))))
 
 
 (defun my-isearch-toggle-regexp ()
@@ -2054,10 +1975,16 @@ indent yanked text (with prefix arg don't indent)."
 (global-set-key (kbd "<home>") 'back-to-indentation-or-beginning)
 
 ;;;;; s-tab - indent-buffer
-;; graphical
-(global-set-key (kbd "<S-iso-lefttab>") 'indent-buffer)
-;; terminal
+;; This is translated from S-<iso-lefttab> in graphicsal mode. previously, I had
+;; also set (kbd "<S-iso-lefttab>"),
+;; But I stopped because it overrides minor mode mappings, and i don't want to do that, at least not only in graphical mode.
+;;
 (global-set-key (kbd "<backtab>") 'indent-buffer)
+
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "<backtab>") nil)))
+
 ;;;;; s-delete - send-shell
 
 (global-set-key (kbd "<S-delete>") 'send-shell)
@@ -2381,7 +2308,7 @@ modes like org-mode which have their own yank function."
 
 (global-set-key (kbd "C-M-3") 'recenter-top-bottom)
 
-;;;;; C-q org-cycle, comint previous arg
+;;;;; C-q org/bicycle-cycle, comint previous arg
 
 (global-set-key (kbd "C-q") 'bicycle-cycle)
 (add-hook 'org-mode-hook
@@ -2390,7 +2317,13 @@ modes like org-mode which have their own yank function."
 (add-hook 'comint-mode-hook
           (lambda () (define-key comint-mode-map (kbd "C-q") 'comint-insert-previous-argument)))
 
-;;;;; M-q ?? unused
+;;;;; M-q org/bicycle-cycle global
+
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "M-q") 'org-shifttab)))
+(global-set-key (kbd "M-q") 'bicycle-cycle-global)
+
 ;;;;; C-M-q quoted-insert
 
 (global-set-key (kbd "C-M-q") 'quoted-insert)
@@ -2440,6 +2373,8 @@ modes like org-mode which have their own yank function."
             (define-key comint-mode-map (kbd "C-r") 'comint-history-isearch-backward-regexp)))
 
 ;;;;; M-r ?? unused
+
+
 ;;;;; C-a copy buffer
 
 (defun copy-all ()
@@ -2503,34 +2438,10 @@ modes like org-mode which have their own yank function."
 
 (global-set-key (kbd "M-d") 'run)
 
-;;;;; C-M-d - swap buffer across windows
-;; from http://www.emacswiki.org/emacs/TransposeWindows
+;;;;; C-M-d - split-window-horizontally
+
+(global-set-key (kbd "C-M-d") 'split-window-horizontally)
 
-(setq swapping-buffer nil)
-(setq swapping-window nil)
-(defun swap-buffers-in-windows ()
-  "Swap buffers between two windows"
-  (interactive)
-  (if (and swapping-window
-           swapping-buffer)
-      (let ((this-buffer (current-buffer))
-            (this-window (selected-window)))
-        (if (and (window-live-p swapping-window)
-                 (buffer-live-p swapping-buffer))
-            (progn (switch-to-buffer swapping-buffer)
-                   (select-window swapping-window)
-                   (switch-to-buffer this-buffer)
-                   (select-window this-window)
-                   (message "Swapped buffers."))
-          (message "Old buffer/window killed.  Aborting."))
-        (setq swapping-buffer nil)
-        (setq swapping-window nil))
-    (progn
-      (setq swapping-buffer (current-buffer))
-      (setq swapping-window (selected-window))
-      (message "Buffer and window marked for swapping."))))
-
-(global-set-key (kbd "C-M-d") 'swap-buffers-in-windows)
 
 ;;;;; C-f - kill-whole-line
 
@@ -2566,12 +2477,13 @@ modes like org-mode which have their own yank function."
 
 (global-set-key (kbd "M-g") 'abort-recursive-edit)
 
-;;;;; C-M-g - gnus
+;;;;; C-M-g - mu4e
 
 (global-set-key (kbd "C-M-g") 'mu4e)
 
 ;;;;; C-z - undo-only
-(global-set-key (kbd "C-z") 'undo-tree-undo)
+;;(global-set-key (kbd "C-z") 'undo-tree-undo)
+(global-set-key (kbd "C-z") 'undo-fu-only-undo)
 ;;;;; C-M-z - suspend-frame
 (global-set-key (kbd "C-M-z") 'suspend-frame)
 ;; this is never good in a gui
@@ -2588,7 +2500,7 @@ modes like org-mode which have their own yank function."
 ;;  todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings.
 ;; this must be before smex-initialize
 (setq
- smex-save-file "~/.emacs.d/.smex-items")
+ smex-save-file (concat user-emacs-directory ".smex-items"))
 
 ;; this uses smex
 (global-set-key (kbd "M-x") 'counsel-M-x)
@@ -2609,8 +2521,10 @@ modes like org-mode which have their own yank function."
 ;;;;; C-c - copy
 
 (global-set-key (kbd "C-d") 'kill-ring-save)
-(add-hook 'c-mode-hook
-          (lambda () (define-key c-mode-map (kbd "C-d") nil)))
+(add-hook 'c-mode-common-hook
+          (lambda ()
+            (define-key c-mode-map (kbd "C-d") nil)
+            (define-key c++-mode-map (kbd "C-d") nil)))
 (add-hook 'comint-mode-hook
           (lambda ()
             (define-key comint-mode-map (kbd "C-d") nil)))
@@ -2633,6 +2547,10 @@ modes like org-mode which have their own yank function."
 
 (global-set-key (kbd "C-v") 'yank-better)
 
+(add-hook 'ivy-mode-hook
+          (lambda ()
+            (define-key ivy-minibuffer-map (kbd "C-v") nil)))
+
 
 
 (defun yank-better (arg)
@@ -2753,8 +2671,7 @@ modes like org-mode which have their own yank function."
           (progn (basic-save-buffer) (delete-frame))
         (save-buffers-kill-terminal t))))
 
-;;;;; C-* - split-window-horizontally
-(global-set-key (kbd "C-*") 'split-window-horizontally)
+;;;;; C-* - --- terminal
 ;;;;; C-M-* - calc-dispatch
 
 (global-set-key (kbd "C-M-*") 'calc-dispatch)
@@ -2935,8 +2852,10 @@ modes like org-mode which have their own yank function."
 (defun vim-style-join-line ()
   (interactive)
   (join-line '(4)))
+;; terminal
+(global-set-key (kbd "C-_") 'vim-style-join-line)
+;; gui
 (global-set-key (kbd "C-/") 'vim-style-join-line)
-(define-key undo-tree-map (kbd "C-/") nil)
 
 ;;;;; C-M-/ - copy-buffer-file-name
 
@@ -3085,6 +3004,8 @@ modes like org-mode which have their own yank function."
           (lambda ()
             (define-key org-mode-map (kbd "C-t") 'org-todo)))
 
+
+
 (defun my-comint-previous-input (arg)
   (interactive "*p")
   (if (comint-after-pmark-p)
@@ -3131,7 +3052,7 @@ modes like org-mode which have their own yank function."
 ;;;;; C-home - start of buffer
 ;;;;; C-end - end of buffer
 ;;;; right secondary
-;;;;; C-^ - save-buffers-kill-emacs
+;;;;; C-^ - save-buffers-kill-emacs exit quit
 
 (global-set-key (kbd "C-^") 'save-buffers-kill-emacs)
 
@@ -3208,7 +3129,8 @@ modes like org-mode which have their own yank function."
 ;;;;; C-M-- - org-edit-src-exit
 ;;;;; C-y - undo
 
-(global-set-key (kbd "C-y") 'undo-tree-redo)
+;;(global-set-key (kbd "C-y") 'undo-tree-redo)
+(global-set-key (kbd "C-y") 'undo-fu-only-redo)
 (add-hook 'org-mode-hook
           (lambda () (define-key org-mode-map (kbd "C-y") nil)))