consolidate
authorIan Kelling <iank@fsf.org>
Mon, 24 Jun 2019 02:47:33 +0000 (22:47 -0400)
committerIan Kelling <iank@fsf.org>
Mon, 24 Jun 2019 02:47:33 +0000 (22:47 -0400)
.gitignore
ian-notes.org
init.el
myinit.el [deleted file]

index ae7be910b3f9b37663785955006a6c49f4a7e64f..edb646b324b633a2e6e436517559ceac311c59ad 100644 (file)
@@ -27,6 +27,7 @@
 /session.*
 *.elc
 /games
+/transient
 
 # artifacts I create
 /my-init.el
index e976bacc0fb9717e6f5dbf465687773729c22766..347b3db1ea823de515c8cc1f640d8572f9807712 100644 (file)
@@ -1249,6 +1249,25 @@ clicking on info links
 speedbar-hide-button-brackets-flag nil)
       #+end_src
 
+* TODO investigate modes i had installed, but removed due to not using:
+inf-ruby
+jedi
+key-chord
+paredit
+python-info
+rust-mode
+python-mode
+tabulated-list
+python-environment
+popup
+transient
+lv
+outorg
+ac-haskell-process
+ghc
+
+* TODO in init.el, use (expand-file-name "myinit.el" init-dir) instead of ~/.emacs.d
+so it could be relocated
 * TODO fix auto save to be reliable and not rely on idle time
 sometimes emacs or computer stays busy and idle never comes
 * TODO try out which key mode
diff --git a/init.el b/init.el
index 43384feba908a79acb6320103794c12cfd88e708..f6f68de64601216e94fa34119284dbfd3a19e5a6 100644 (file)
--- a/init.el
+++ b/init.el
@@ -1,4 +1,4 @@
-;; Copyright (C) 2014 Ian Kelling
+;; Copyright (C) 2019 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
 ;; seems its changed now. no harm in keeping this though.
 (global-unset-key (kbd "C-z"))
 
+;; speed up init https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/
+(setq gc-cons-threshold 100000000)
+
+
 ;; these need to be done before the hook in order to satisfy the byte compiler or batch mode
-(add-to-list 'load-path "~/.emacs.d/emacs/site-lisp/org")
+
+;; 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 "~/.emacs.d/src/bbdb-csv-import")
+
+;; 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")
 ;;(require 'bbdb-loaddefs "~/.emacs.d/src/bbdb/lisp/bbdb-loaddefs.el")
 ;;(setq bbdb-print-tex-path "~/.emacs.d/src/bbdb/tex")
 
+
+;; iank: dunno what this was about
 ;;(add-hook 'server-visit-hook 'raise-frame)
 
+(setq init-dir (file-name-directory load-file-name))
+;; previously, i was doing byte-recompile-directory, but
+;; now i just have one init file
+(unless (equal (user-uid) 0) ; don't make root owned files
+  (byte-recompile-file (expand-file-name "init.el" init-dir)))
 
-;; load init in `after-init-hook' so all packages are loaded
+;; load init in `after-init-hook' so all packages are loaded. However, disabled because
+;; there seems to be no need.
 ;; todo, learn about the weird evaluation order of this hook that requires the quoting.
 ;; adapted from starter-kit
-(add-hook 'after-init-hook
-          `(lambda ()
-             ;; todo, set this var in my-init.org and use it instead
-             ;; of .emacs.d
-             (setq init-dir ,(file-name-directory load-file-name))
-             ;; previously, i was doing byte-recompile-directory, but
-             ;; now i just have one init file
-             (unless (equal (user-uid) 0) ; don't make root owned files
-               (byte-recompile-file (concat init-dir "myinit.el")))
+;; (add-hook 'after-init-hook
+;;           `(lambda ()
+;;              (load-file (expand-file-name "myinit.el" init-dir))
+;;              ))
+
+
+;;; Weird package bug workaround
+
+
+;; without this, when installing a package, this message happens
+;;
+;; custom-handle-keyword: Unknown keyword :group
+;;
+;; but when i lookup the function, i get the following, and if
+;; I evaluate it, the error goes away. so I think the real
+;; definition is happening somewhere else
+
+(defun custom-handle-keyword (symbol keyword value type)
+  "For customization option SYMBOL, handle KEYWORD with VALUE.
+Fourth argument TYPE is the custom option type."
+  (if purify-flag
+      (setq value (purecopy value)))
+  (cond ((eq keyword :group)
+        (custom-add-to-group value symbol type))
+       ((eq keyword :version)
+        (custom-add-version symbol value))
+       ((eq keyword :package-version)
+        (custom-add-package-version symbol value))
+       ((eq keyword :link)
+        (custom-add-link symbol value))
+       ((eq keyword :load)
+        (custom-add-load symbol value))
+       ((eq keyword :tag)
+        (put symbol 'custom-tag value))
+       ((eq keyword :set-after)
+        (custom-add-dependencies symbol value))
+       (t
+        (error "Unknown keyword %s" keyword))))
+
+
+;;; misc emacs documentation
+
+;;;; how to find auto-saved files that need recovering
+;; find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it.
+;; #file# is an auto-save file. It may or may not be different than the file is corresponds to.
+;; If it is different, emacs will give a message about recovering it when you open it.
+
+;;;; misc org functions
+
+;; ;; these are usefull with (goto-char)
+;; ;; find named entity, other than headline
+;; (org-find-entry-with-id "string-number-or-symbol")
+
+;; (org-find-exact-headline-in-buffer "heading" nil t)
+
+;; ;; remove any indent level which is throughout the buffer
+;; (org-do-remove-indentation)
+
+
+;;;; gnus
+
+;; good info http://www.emacswiki.org/emacs/GnusTutorial
+;; good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm
+
+
+;; After downloading mailing list archives, once you have an mbox file,
+;; there are rather straightforward ways to get it into any mail program,
+;; but I will cover gnus, which I use and is a bit tricky.
+
+;; gnus has a native search (limited, too slow for body text searches), and external search engine integration.
+;; gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus
+;; takes 10+ minutes, so scratch that option. it suggests 2 alternate options
+;; mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox
+;; and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise
+;; works great.
+
+;; local imap server which will use the mbox and provide search.
+;; dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its
+;; description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the
+;; module we need.
+;; pi dovecot-imapd
+
+;; dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/<username>
+;; those locations are adjustable and well documented via the var mail_location in
+;; /etc/dovecot/conf.d/10-mail.conf
+;; I forward my local mail, didn't see immediately how to turn off the inbox, but it will always be empty, so I left as
+;; is. you could make the var be empty, which apparently has the same effect.
+
+;; Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems
+;; other things like postfix use that location
+
+;; based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html
+;; other links that poped up contained outdated, innacurate information
+;; http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/
+;; http://www.emacswiki.org/emacs/JamesFerguson
+;; http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/
+
+;; Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility.
+
+
+
+;; doc group for mbox:
+;; in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file
+
+;; info about groups created within gnus is stored in ~/.newsrc.eld
+;; also stored is a duplication of what email messages are read/unread,
+;; what newsgroups are subsribed to and read/unread,
+;; probably more stuff, everything that gnus saves.
+
+
+;; searching the body of the messages, i cut off after a few minutes.
+;; i can grep the file in just a couple seconds
+
+
+;; random side note
+;; we can also get mbox from gmane
+;; http://notmuchmail.org/howto/#index7h2
+
+
+;; gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command
+;; line, but not from within gnus, but from mairix.el, which can then open the results in gnus
+
+;; mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the
+;; headers and generates a nov file for each.
+
+;; nnfolder-generate-active-file
+
+;; to reset things, when changing mail group. I duno all the proper way, but it works to delete
+;; ~/Mail ~/.newsrc.eld ~/.dribble (or something)
+
+
+;;;;; mail sources vs select methods background
+;; I found this very confusing when first reading through the manual.  "mail sources" is a term that does not simply mean
+;; sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail
+;; sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use
+;; "mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their
+;; location, but use them in their native format. This is what I want to do, and I can simply ignore mail
+;; sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it
+;; means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail.
+
+
+
+;;;;; caching background
+
+;; caching:
+;; there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why.
+;; Grepped for caching in the manual, found 2 main things.
+;; cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence
+;; gnus-use-cache, which puts things if they are
+;; gnus-cache-enter-articles
+;; things go in cache when they are marked certain ways by default, ticked and dormant
+;; and read articles are moved out of the cache
+;; still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached
+;; I'm gonna delete the cache, and check on it later see what exactly is going in there
+;; And of course, I moved ~/News to my encrypted drive and symlinked it
+
+
+
+;;; things that should be at the beginning
+;; todo, evaluating this manually disables debug on error instead of toggling it
+(toggle-debug-on-error) ;uncomment to help debug and catch errors
+
+;; packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade.
+
+;; package-activated-list:
+;; ac-dabbrev ac-haskell-process ack-and-a-half alect-themes auctex bash-completion bbdb csv-mode cyberpunk-theme dot-mode expand-region f find-file-in-project flycheck foreign-regexp ggtags ghc gnuplot-mode goto-chg haskell-mode heroku-theme highlight-indentation highlight-symbol htmlize inf-ruby info+ inkpot-theme jedi auto-complete jedi-core epc ctable concurrent key-chord leuven-theme logstash-conf magit git-commit magit-popup misc-fns mouse+ naquadah-theme nginx-mode occidental-theme org paredit pcsv php-mode pkg-info epl popup py-autopep8 python-environment deferred python-info python-mode rainbow-mode rust-mode rw-hunspell s smartparens smex smooth-scroll sr-speedbar strings swiper ivy tabulated-list tangotango-theme thingatpt+ undo-tree vimrc-mode volatile-highlights web-mode with-editor dash async ws-butler yasnippet
+
+;;;; alternate keyboards
+;; todo, figure out an easy way to disable this when using external keyboard
+(if (display-graphic-p)
+    (setq
+     enter-key (kbd "<return>")
+     s-enter-key (kbd "<S-return>")
+     c-m-enter-key (kbd "<C-M-return>")
+     m-enter (kbd "<M-return>")
+     c-enter (kbd "<C-return>"))
+  (setq
+   enter-key (kbd "C-m")
+   s-enter-key (kbd "C-8")
+   c-m-enter-key (kbd "C-M-8")
+   m-enter (kbd "M-m")
+   c-enter (kbd "C-8")))
+
+(setq tp (string= (system-name) "tp"))
+(setq x200 (string= (system-name) "x2"))
+(setq laptop-keyboard (or tp x200))
+
+;; Ubiquitous Packages which should be loaded on startup rather than
+;;   autoloaded on demand since they are likely to be used in every
+;;   session.
+(require 'saveplace)
+(require 'ffap)
+(require 'uniquify)
+(require 'ansi-color)
+(require 'recentf)
+
+;; Better to have a list of packages in here vs installed manually.
+;;   However, I install manually because sometimes there are two
+;;   versions and it is not necessarily easy to reconcile that.
+;; based on marmalage website front page.
+(require 'package)
+
+;; little kit to help remove a down server
+;; (setq package-archives nil)
+
+;;(add-to-list 'package-archives
+;;             '("marmalade" .
+;;               "http://marmalade-repo.org/packages/"))
+
+(add-to-list 'package-archives
+             '("melpa" . "http://melpa.milkbox.net/packages/") t)
+(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
+
+
+;; 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)
+
+
+
+;;; abreviations
+;; turn on abbrev mode globally
+(setq-default abbrev-mode t)
+
+;; default abbreviation mode file is .emacs.d/abbrev_defs.
+;; add-global-abbrev, add-mode-abbrev for expansion at point
+;; if all else fails, edit the abbrev file
+
+
+
+
+;;; auto-complete
+
+;; auto-completion in minibuffer
+;; disabled while I look for another alternative
+;;(icomplete-mode)
+
+(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)
+
+(add-to-list 'ac-modes 'org-mode 'sql-mode)
+
+(defun ac-common-setup ()
+  (add-to-list 'ac-sources 'ac-source-yasnippet))
+
+;; for org mode completion source taken from wiki.
+;; it did not work. no idea why. todo, investigate
+;; the ac-sources code is at http://www.emacswiki.org/emacs/AutoCompleteSources
+;; i've deleted it here so as to save space and not spam this file
+;;(defun my-ac-org-mode ()
+;;  (setq ac-sources (append ac-sources '(ac-source-org))))
+
+
+;; this makes the org-self-insert command not do a flyspell spell check.
+;; low priority thing to look into sometime
+(ac-flyspell-workaround)
+
+
+(define-key ac-completing-map (kbd "<up>") nil)
+(define-key ac-completing-map (kbd "<down>") nil)
+(define-key ac-completing-map (kbd "<S-return>") 'ac-expand)
+(define-key ac-completing-map "\t" 'ac-complete)
+(define-key ac-completing-map (kbd "<tab>") 'ac-complete)
+
+
+
+;;; auto-complete readline-complete
+
+(require 'readline-complete)
+;; not sure how I made these, but I deleted, and
+;; it would be nice to make them again sometime
+;;(require 'src-loaddefs)
+
+;; disabled cuz broken
+;; redefining function in readline-complete so ac-complete only uses readline as a source
+(defun ac-rlc-setup-sources ()
+  "Add me to shell-mode-hook!"
+  (setq ac-sources '(ac-source-shell)))
+(add-hook 'shell-mode-hook 'ac-rlc-setup-sources)
+
+;; generally unnecessary, but why not
+(setq explicit-shell-file-name "bash")
+
+;; readline-complete says to add this line.
+;; however, it  up my procfs directory tracking hook
+;; because get-process doesn't notice the child shell.
+;; instead, I've removed export EMACS=t from
+;;  comint-exec-1 (the function which initially sets it)
+;; by finding it in emacs sources and redefinind it here
+;; and done stty echo in my bashrc
+;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash"))
+
+(setenv "EMACS" "")
+(setq explicit-bash-args nil)
+(setq comint-process-echoes t)
+;; default of 30 is way too slow. todo, consider pushing this upstream
+(setq rlc-attempts 5)
+
+(add-to-list 'ac-modes 'shell-mode)
+
+;; readline-complete recommends this (i assume this format),
+;; but greping finds no reference in emacs or my .emacs.d
+;; so I'm assuming it is for an older emacs
+;;(setq explicit-ssh-args '("-t"))
+
+(add-hook 'shell-mode-hook
+          (lambda ()
+            (define-key shell-mode-map (kbd "<tab>") 'auto-complete)))
+
+
+;;; readline complete fix
+
+;; I need this function here, where INSIDE_EMACS is replaced with RLC_INSIDE_EMACS.
+;; ian: last update 2017-1-7. update this periodically from upstream
+;; like when we do a major emacs update
+(defun comint-exec-1 (name buffer command switches)
+  (let ((process-environment
+        (nconc
+         ;; If using termcap, we specify `emacs' as the terminal type
+         ;; because that lets us specify a width.
+         ;; If using terminfo, we specify `dumb' because that is
+         ;; a defined terminal type.  `emacs' is not a defined terminal type
+         ;; and there is no way for us to define it here.
+         ;; Some programs that use terminfo get very confused
+         ;; if TERM is not a valid terminal type.
+         ;; ;; There is similar code in compile.el.
+         (if (and (boundp 'system-uses-terminfo) system-uses-terminfo)
+             (list "TERM=dumb" "TERMCAP="
+                   (format "COLUMNS=%d" (window-width)))
+           (list "TERM=emacs"
+                 (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))
+         (list (format "RLC_INSIDE_EMACS=%s,comint" emacs-version))
+         process-environment))
+       (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
+                        ;; first look relative to the current directory.
+                        (cons default-directory exec-path) exec-path)))
+      (setq proc (apply 'start-file-process name buffer command switches)))
+    ;; Some file name handler cannot start a process, fe ange-ftp.
+    (unless (processp proc) (error "No process started"))
+    (let ((coding-systems (process-coding-system proc)))
+      (setq decoding (car coding-systems)
+           encoding (cdr coding-systems)))
+    ;; Even if start-file-process left the coding system for encoding data
+    ;; sent from the process undecided, we had better use the same one
+    ;; as what we use for decoding.  But, we should suppress EOL
+    ;; conversion.
+    (if (and decoding (not encoding))
+       (setq encoding (coding-system-change-eol-conversion decoding 'unix)
+             changed t))
+    (if changed
+       (set-process-coding-system proc decoding encoding))
+    proc))
+
+;;; auto save & backup
+(setq auto-save-timeout 1) ; idle time before auto-save.
+
+;; main hook for my auto save
+(add-hook 'auto-save-hook 'my-auto-save)
+;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active
+(add-hook 'window-configuration-change-hook 'my-auto-save-win)
+
+;; this function from mu4e really does not like buffer saving
+(advice-add 'message-send-and-exit :before 'my-as-off)
+(advice-add 'message-send-and-exit :after 'my-as-on)
+
+;; avoid window config hook saving too much, it can
+;; get into loops in some random situations
+(setq 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-auto-save (&optional last)
+  (when (and
+         my-as
+         (buffer-file-name)
+         ;; mu4e has a bug right now, undo breaks when saving drafts
+         (not (string= (buffer-file-name) "*draft*"))
+         (buffer-modified-p)
+         (not (org-src-edit-buffer-p)))
+    ;; serial is incremented on each save, so let's do a bit less of them
+    (not (derived-mode-p 'dns-mode))
+    (setq my-auto-save-last last)
+    (let (message-log-max)
+      ;; a bit of a hack to partially suppress the constant saving in the echo area
+      (with-temp-message ""
+        (basic-save-buffer)))))
+
+;; in the message-send-and-exit advice, got an error because it passed an arg.
+;; didn't look into why, just add ignored args.
+(defun my-as-off (&rest ignore)
+  (interactive)
+  (setq my-as nil))
+
+(defun my-as-off-local (&rest ignore)
+  (interactive)
+  (setq-local my-as nil))
+
+(defun my-as-on (&rest ignore)
+  (interactive)
+  (setq my-as t))
+
+(defun my-as-on-local (&rest ignore)
+  (interactive)
+  (setq-local my-as on))
+
+;; based on suggestion in the emacs docs, redefine these 2 functions
+;; to avoid prompt spamming the user when we do auto-save
+(defun ask-user-about-supersession-threat (fn)
+  (discard-input)
+  (message
+   "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however
+a backup is being created in case that is not what you intended." buffer-file-name)
+  (setq buffer-backed-up nil))
+
+(defadvice ask-user-about-lock (before lock-deactivate-as activate)
+  (make-local-variable 'my-as)
+  (setq my-as nil)
+  (message "proper autosave has been turned off for this buffer because of lock file problem.
+  In this buffer, do M-x my-as-on to reenable"))
+
+;; todo, this doesn't work consistently to override the auto-save message
+(defalias 'do-auto-save-original (symbol-function 'do-auto-save))
+(defun do-auto-save (&optional no-message current-only)
+  "This function has been modified to wrap the original so that NO-MESSAGE
+is  always set to t, since we auto-save a lot, it spams otherwise.
+The original doc string is as follows:
+
+Auto-save all buffers that need it.
+This is all buffers that have auto-saving enabled
+and are changed since last auto-saved.
+Auto-saving writes the buffer into a file
+so that your editing is not lost if the system crashes.
+This file is not the file you visited; that changes only when you save.
+Normally we run the normal hook `auto-save-hook' before saving.
+
+
+A non-nil NO-MESSAGE argument means do not print any message if successful.
+A non-nil CURRENT-ONLY argument means save only current buffer."
+  (interactive)
+  (do-auto-save-original t current-only))
+
+;; enable MY auto-save
+(my-as-on)
+
+;;; backups, separate from auto-save
+
+
+;; set backup file location
+(setq backup-directory-alist '(("." . "~/.editor-backups")))
+(setq auto-save-file-name-transforms
+      '((".*" "~/.editor-backups/" t)))
+
+(setq version-control t ;; Use version numbers for backups
+      kept-new-versions 100
+      kept-old-versions 2
+      delete-old-versions t ;; delete old versions silently
+      ;; assume hard linked files are done on purpose, don't screw them up
+      backup-by-copying-when-linked t)
+
+;; 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)))))
+    (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)))))
+
+;; make a backup on auto-save, because the backup feature is not
+;; utilized with my-auto-save, only normal interactive save.
+;; todo, enable when fixed
+;;(add-hook 'before-save-hook 'constant-backup)
+
+(add-hook 'auto-save-hook 'auto-save-size-limit)
+
+(defun auto-save-size-limit ()
+  (when (and (not backup-inhibited) (> (buffer-size) 2000000))
+    (message "Backups disabled for this buffer due to size > 2 megs")
+    (make-local-variable 'backup-inhibited)
+    (setq backup-inhibited t)))
+
+
+;; ;; background:
+;; ;;      the faq suggests to auto-save using
+;; (setq auto-save-visited-file-name t)
+;;         and to toggle auto-saving in the current buffer, type `M-x auto-save-mode'
+
+;;         however, this is  buggy.
+;;         it leaves around lock files, which can be disabled with
+;;         (setq create-lockfiles nil)
+;;         but it is also buggy on other things that appear to hook onto file saving
+;;         so i created my own function, which originally had bugs,
+;;         but new emacs version fixed all that, yay!.
+
+
+                                        ; not using, but here for documentation,
+                                        ; alternate way to enable and specify how long between autosaves.
+                                        ; number of input events between autosave.
+                                        ; lowest bound of functionality is actually about 15 input events
+                                        ;(setq auto-save-interval
+
+;;; bbdb
+;; based on bbdb manual
+;; also has instructions to integrate with gnus,
+
+(bbdb-initialize 'message)
+
+;; recommended by gnus,
+;; but seems like it could be good to have set for other stuff
+(setq user-full-name "Ian Kelling")
+;; general email setting? recommended by mu4e
+(setq message-kill-buffer-on-exit t)
+
+
+
+;; use d instead
+(add-hook 'bbdb-mode-hook
+          (lambda () (define-key bbdb-mode-map (kbd "C-k") nil))
+          ;; based on emacs24-starter-kit
+          (setq bbdb-offer-save 'auto
+                bbdb-notice-auto-save-file t
+                bbdb-expand-mail-aliases t
+                bbdb-canonicalize-redundant-nets-p t
+                bbdb-complete-name-allow-cycling t)
+          )
+
+;;(require 'bbdb-csv-import)
+
+;;; bookmark settings
+                                        ; save bookmarks whenever they are changed instead of just when emacs quits
+(setq bookmark-save-flag 1)
+                                        ; increase bookmark context size for better functionality
+(setq bookmark-search-size 2000)
+
+;;; 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
+;; a list of pre-built themes at http://elpa.gnu.org/themes/view.html and
+;; themes are available through ELPA.
+
+
+;; interesting light themes
+
+
+(defun override-theme (arg)
+  (interactive)
+  (while custom-enabled-themes
+    (disable-theme (car custom-enabled-themes)))
+  (load-theme arg t))
+(setq color-theme-is-global t)
+
+(defun toggle-night ()
+  (interactive)
+  (cond  ((equal (car custom-enabled-themes) 'naquadah)
+          (override-theme 'leuven))
+         (t
+          (override-theme 'naquadah))))
+
+
+;; 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)
+
+
+;; disable color thing with this:
+;;(disable-theme (car custom-enabled-themes))
+
+;; decent dark themes
+
+;;(override-theme 'tangotango)
+;;(override-theme 'deeper-blue)
+;;(override-theme 'tango-dark)
+;;(override-theme 'tsdh-dark)
+
+;;(override-theme 'heroku)
+;;(override-theme 'inkpot)  ;; part of inkpot-theme package
+;;(override-theme 'naquadah) ; org mode features, part of  naquadah-theme package
+;;(override-theme 'spolsky) ;; part of sublime-themes package
+;;(override-theme 'twilight-anti-bright)  ;; from twilight-anti-bright-theme package
+
+;; interesting but not usable colors
+;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package
+;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which
+;;(override-theme 'misterioso) ; cursor not visible enough
+
+
+
+;;decent light themes
+;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package
+;;(override-theme 'occidental) ; from occidental-theme package
+
+
+;;color-theme is deprecated in emacs 24.
+
+;; theme packages i tried then removed:
+;; ignored ones that didn't use the new theme engine
+
+;;66 packages (zenburn-theme-2.1, zen-and-art-theme-1.0.1, waher-theme-20130917.7, ujelly-theme-1.0.35, twilight-theme-1.0.0, twilight-bright-theme-20130605.143, twilight-anti-bright-theme-20120713.316, tronesque-theme-1.3, tron-theme-12, toxi-theme-0.1.0, tommyh-theme-1.2, tango-2-theme-1.0.0, sunny-day-theme-20131203.1250, sublime-themes-20140117.323, subatomic-theme-20131011.1048, soothe-theme-0.3.16, soft-morning-theme-20131211.1342, soft-charcoal-theme-20130924.1206, sea-before-storm-theme-0.3, purple-haze-theme-20130929.1751, phoenix-dark-pink-theme-20130905.941, phoenix-dark-mono-theme-20130306.1215, pastels-on-dark-theme-0.3, obsidian-theme-20130920.937, nzenburn-theme-20130513, noctilux-theme-20131019.31, mustang-theme-20130920.939, monokai-theme-0.0.10, molokai-theme-20130828.0, late-night-theme-0.0, jujube-theme-0.1, ir-black-theme-20130302.2355, gruvbox-theme-20131229.1458, gruber-darker-theme-0.6, grandshell-theme-20140118.1003, github-theme-0.0.3, gandalf-theme-0.1, flatland-theme-20131204.858, django-theme-20131022.202, deep-thought-theme-0.1.1, dakrone-theme-20131212.1159, colorsarenice-theme-20131128.1106, color-theme-wombat+-0.0.2, color-theme-wombat-0.0.1, color-theme-twilight-0.1, color-theme-tango-0.0.2, color-theme-solarized-20120301, color-theme-sanityinc-solarized-2.25, color-theme-railscasts-0.0.2, color-theme-monokai-0.0.5, color-theme-molokai-0.1, color-theme-ir-black-1.0.1, color-theme-heroku-1.0.0, color-theme-github-0.0.3, color-theme-eclipse-0.0.2, color-theme-dpaste-0.0.1, color-theme-dawn-night-1.0, color-theme-colorful-obsolescence-0.0.1, color-theme-cobalt-0.0.2, color-theme-20080305.34, clues-theme-20130908.801, busybee-theme-20130920.942, bubbleberry-theme-0.1.2, mblage-theme-20130715.621, anti-zenburn-theme-20140104.1542, ample-zen-theme-0.2)
+
+
+
+
+;;; yasnippet
+
+;; cd ~/.emacs.d/src
+;; git clone --recursive https://github.com/capitaomorte/yasnippet
+;; touch snippets/.yas-make-groups
+
+;;   This all makes it so I can look through the default snippets
+;;   in the menu bar, but they don't show up elsewhere, because they are
+;;   mostly things I don't want.
+
+
+(require 'yasnippet)
+;; this needs to be before yas-global-mode
+(setq yas-snippet-dirs (list "~/.emacs.d/snippets"))
+(yas-global-mode 1)
+
+(setq
+ yas-also-auto-indent-first-line t
+ yas-choose-tables-first t
+ yas-use-menu (quote full)
+ ;; this sets ido-prompt as first function
+ yas-prompt-functions
+ '(yas-ido-prompt yas-dropdown-prompt yas-x-prompt yas-completing-prompt yas-no-prompt))
+
+;; todo, explore this option for wrapping region
+;; '(yas/wrap-around-region t))
+
+;;; cross session settings
+
+;; Save a list of recent files visited.
+(recentf-mode 1)
+(setq recentf-max-saved-items 200
+      recentf-max-menu-items 15)
+
+
+(setq save-place t
+      save-place-version-control 'nospecial
+      save-place-limit 40000
+      save-place-file "~/.emacs.d/places")
+
+
+
+;; savehist keeps track of some history
+;; search entries
+(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-mode 1)
+
+
+;;; ediff
+;; ediff-buffers is the main command to use
+
+;; ediff - 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
+(setq ediff-window-setup-function 'ediff-setup-windows-plain)
+;;(setq ediff-window-setup-function 'ediff-setup-windows-default)
+
+;; do side by side diffs
+(setq ediff-split-window-function 'split-window-horizontally)
+
+
+
+;; 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.
+
+;;; dired
+
+;; 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)
+
+(setq
+ ;; 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
+ mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields)
+ ;; 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
+ )
+
+;; 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.
+(load "/p/c/mu4e.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 mu-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-mail-address (cdr found)
+                        user-full-name (car found)))
+      found)))
+(defun mu-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)
+              regexes (cdr 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 my-mu4e-to-fsf ()
+  "inspired by mu4e info manual, search for mu4e-compose-pre-hook."
+  (cond
+   ((mu-set-from '("iank@fsf.org"
+                   "iank@gnu.org")))
+   ((setq user-mail-address "iank@fsf.org"
+          user-full-name "Ian Kelling"))))
+
+
+;; on first run   mkdir -p /nocow/user/.mufsf; mu index --maildir=/nocow/user/fsfmd
+(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)
+  (unless (equal mu4e-maildir "/nocow/user/fsfmd") (mu-exit-wait))
+  (setq
+   ;; fsf monitor is smaller
+   mu4e-headers-visible-lines 15
+   mu4e-maildir "/nocow/user/fsfmd"
+   mu4e-refile-folder "/Spam"
+   mu4e-index-lazy-check nil
+   mu4e-get-mail-command "true"
+   user-mail-address "iank@fsf.org"
+   ;; 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 "
+
+--
+Ian Kelling | Senior Systems Administrator, Free Software Foundation
+GPG Key: B125 F60B 7B28 7FF6 A2B7  DF8F 170A F0E2 9542 95DF
+https://fsf.org | https://gnu.org
+"
+
+   mu4e-user-mail-address-list '("iank@fsf.org"
+                                 "iank@gnu.org")
+   mu4e-maildir-shortcuts
+   '( ("/INBOX"     . ?i)
+      ("/sysadmin" . ?a)
+      ("/sec"  . ?x)
+      ("/rtcc"  . ?c)
+      ("/Drafts"     . ?d)
+      ("/Sent"     . ?s)
+      )
+   ) ;; end setq
+  (call-process "/a/exe/lnf" nil nil nil "-T" "/nocow/user/.mufsf" (concat (getenv "HOME") "/.mu"))
+  (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to-fsf)
+  (remove-hook 'mu4e-compose-pre-hook 'my-mu4e-to)
+  (mu4e)) ;; end defun fsf-mu4e
+
+
+;; 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)
+
+;; 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))
+      )
+
+
+(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)))))
+
+(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)
+
+
+;;; elisp settings
+                                        ; when manually evaluating lisp, go into debugger on error
+(setq eval-expression-debug-on-error t)
+                                        ;reminder of useful var: debug-on-error
+
+
+;;; haskell
+
+;; useful comint-shell mode commands. If not prefaced with *, it means it is not in the haskell custom repl
+;; *todo: setup haskell c-t toggle arrow keys
+;; tab completion
+;; C-q insert prev arg
+;; C-( history search
+;; c-m-left/right move to next/prev prompts
+;; *c-enter, multi-line input
+;; *s-delete, send input across windows. (i can implement this)
+;; *c-m-l clear screen
+;; *haskell-process-interrupt, c-cc terminate job (i can implement this maybe)
+
+;; nice bash/readline functions missing in comint:
+;; yank-nth-arg
+;; operate-get-next
+;; menu-complete
+
+;; usefull comint commands:
+;; c-cl : list historic command in temp buffer
+;; C-c C-o comint-delete-output
+;; comint-restore-input, todo: put this on a randomish c-c key
+
+
+
+;; todo:
+;; checkout haskell repl functions:
+;; c-cv haskell-check, hlint
+;; C-M-q           prog-indent-sexp
+;; c-c.  haskell-mode-format-imports
+;; C-c M-/         haskell-doc-check-active
+;; haskell-process-generate-tags
+;; haskell-process-cabal-build
+;; haskell-cabal-command.. or something
+;; haskell-process-restart
+;; C-h v haskell-process-log
+;; C-h v haskell-process-show-debug-tips
+
+;; various not immediately useful functions:
+;; haskell-process-add-dependency
+;; haskell-process-touch-buffer
+;; haskell-process-cd
+;; haskell-process-unignore
+;; haskell-process-reload-devel-main
+
+
+;; rebind
+;; home: C-a             haskell-interactive-mode-beginning
+;; c-return: C-j             haskell-interactive-mode-newline-indent
+;; up/down: <C-down>        haskell-interactive-mode-history-next
+
+;; todo haskell mode better binds for:
+;; 'haskell-process-load-file
+;; 'haskell-process-do-type
+;; 'haskell-process-do-info
+;; 'inferior-haskell-send-decl
+
+
+;; commands which don't work in haskell-interactive-mode(hi) vs inferior-haskell-mode(ih, default)
+;; functions not in hi:
+;; inferior-haskell-find-definition, use tags instead
+;; inferior-haskell-find-haddock, todo, test if this works
+
+;; redefined ih to hi
+;; switch-to-haskell -> 'haskell-interactive-switch
+;; haskell-process-load-file -> inferior-haskell-load-file
+;; haskell-process-do-type -> inferior-haskell-type
+;; switch-to-haskell -> haskell-interactive-switch
+;; inferior-haskell-load-file -> 'haskell-process-load-file
+
+
+;; haskell-mode installation from source, based on its readme
+;; in the git directory,
+;; make all
+
+
+
+
+;; remove default option to not link the file
+(setq haskell-compile-command "ghc -Wall -ferror-spans -fforce-recomp %s")
+(add-hook 'haskell-indentation-mode-hook
+          (lambda ()
+            (define-key haskell-indentation-mode-map [?\C-d] nil)
+            (define-key haskell-indentation-mode-map
+              (kbd "<deletechar>")
+              'haskell-indentation-delete-char)))
+
+;;copied from haskell-mode docs in order to use the new, better, nondefault
+;;interactive mode.
+(eval-after-load "haskell-mode"
+  '(progn
+     (define-key haskell-mode-map (kbd "C-x C-d") nil)
+     (define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch)
+     (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file)
+     (define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch)
+     (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type)
+     (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info)
+     (define-key haskell-mode-map (kbd "C-c M-.") nil)
+     (define-key haskell-mode-map (kbd "C-c C-d") nil)))
+
+;; ghc-mod install http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html
+;; todo, try this out
+;; (autoload 'ghc-init "ghc" nil t)
+;;(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode)))
+
+
+
+;; from the package readme for ghci-completion
+(require 'ghci-completion)
+(add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion)
+
+
+;; disable some rebinds. they are set to appropriate keys in the keybinds section
+(eval-after-load "haskell-mode"
+  '(progn
+     (define-key haskell-mode-map (kbd "C-a") 'nil)
+     (define-key haskell-mode-map (kbd "C-j") 'nil)))
+
+(eval-after-load "python-mode"
+  '(progn
+     (define-key python-mode-map (kbd "C-j") nil)))
+
+(defun pretty-lambdas-haskell ()
+  (font-lock-add-keywords
+   nil `((,(concat "(?\\(" (regexp-quote "\\") "\\)")
+          (0 (progn (compose-region (match-beginning 1) (match-end 1)
+                                    ,(make-char 'greek-iso8859-7 107))
+                    nil))))))
+;; from haskell-mode manual
+(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
+(when (window-system)
+  (add-hook 'haskell-mode-hook 'pretty-lambdas-haskell))
+
+;; added from haskell-mode website install instructions
+                                        ;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file")
+(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
+;;the three indentation modules are mutually exclusive - add at most one. Trying out the "most advanced"
+(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
+;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
+;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
+
+
+;; todo, set this to some other key
+;;    (local-set-key (kbd "C-e") 'my-haskell-load-and-run)
+
+(defun my-haskell-load-and-run ()
+  "Loads and runs the current Haskell file."
+  (interactive)
+  (let ((start-buffer (current-buffer)))
+    (inferior-haskell-load-and-run inferior-haskell-run-command)
+    (sleep-for 0 100)
+    (end-of-buffer)
+    (pop-to-buffer start-buffer)))
+
+;; show haskell function in mode line
+;; todo, this broke after updating emacs
+;;(eval-after-load "which-func"
+;;  '(add-to-list 'which-func-modes 'haskell-mode))
+
+
+
+(add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup)
+(add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup)
+(eval-after-load "auto-complete"
+  '(add-to-list 'ac-modes 'haskell-interactive-mode))
+
+(add-hook 'haskell-mode-hook
+          (lambda () (define-key haskell-mode-map (kbd "C-(")
+                       (lambda () (interactive)
+                         (basic-save-buffer)
+                         (haskell-compile)
+                         (run-with-timer .3 nil 'repeat-shell)))))
+(add-hook 'haskell-cabal-mode-hook
+          (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile)))
+
+
+
+(add-hook 'haskell-interactive-mode-hook
+          (lambda ()
+            (define-key haskell-interactive-mode-map "\r" nil)
+            (define-key haskell-interactive-mode-map (kbd "<return>") 'haskell-interactive-mode-return)))
+(add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map "\r" nil)))
+
+
+
+(add-hook 'haskell-interactive-mode-hook
+          (lambda ()
+            (define-key haskell-interactive-mode-map (kbd "<C-M-return>") 'haskell-interactive-mode-newline-indent)))
+
+;;; isearch
+(setq
+ isearch-allow-scroll t
+ search-ring-update t) ;; dont start an edit when going to previous search
+
+(defun isearch-yank-regexp (regexp)
+  "Pull REGEXP into search regexp."
+  (let ((isearch-regexp nil)) ;; Dynamic binding of global.
+    (isearch-yank-string regexp))
+  (isearch-search-and-update))
+
+(defun isearch-yank-symbol (&optional partialp backward)
+  "Put symbol at current point into search string.
+
+     If PARTIALP is non-nil, find all partial matches."
+  (interactive "P")
+
+  (let (from to bound sym)
+    (setq sym
+                                        ; this block taken directly from find-tag-default
+                                        ; we couldn't use the function because we need the internal from and to values
+          (when (or (progn
+                      ;; Look at text around `point'.
+                      (save-excursion
+                        (skip-syntax-backward "w_") (setq from (point)))
+                      (save-excursion
+                        (skip-syntax-forward "w_") (setq to (point)))
+                      (> to from))
+                    ;; Look between `line-beginning-position' and `point'.
+                    (save-excursion
+                      (and (setq bound (line-beginning-position))
+                           (skip-syntax-backward "^w_" bound)
+                           (> (setq to (point)) bound)
+                           (skip-syntax-backward "w_")
+                           (setq from (point))))
+                    ;; Look between `point' and `line-end-position'.
+                    (save-excursion
+                      (and (setq bound (line-end-position))
+                           (skip-syntax-forward "^w_" bound)
+                           (< (setq from (point)) bound)
+                           (skip-syntax-forward "w_")
+                           (setq to (point)))))
+            (buffer-substring-no-properties from to)))
+    (cond ((null sym)
+           (message "No symbol at point"))
+          ((null backward)
+           (goto-char (1+ from)))
+          (t
+           (goto-char (1- to))))
+    (isearch-search)
+    (if partialp
+        (isearch-yank-string sym)
+      (isearch-yank-regexp
+       (concat "\\_<" (regexp-quote sym) "\\_>")))))
+
+(defun isearch-current-symbol (&optional partialp)
+  "Incremental search forward with symbol under point.
+
+     Prefixed with \\[universal-argument] will find all partial
+     matches."
+  (interactive "P")
+  (let ((start (point)))
+    (isearch-forward-regexp nil 1)
+    (isearch-yank-symbol partialp)))
+;; todo, make this
+
+(defun isearch-backward-current-symbol (&optional partialp)
+  "Incremental search backward with symbol under point.
+
+     Prefixed with \\[universal-argument] will find all partial
+     matches."
+  (interactive "P")
+  (let ((start (point)))
+    (isearch-backward-regexp nil 1)
+    (isearch-yank-symbol partialp)))
+
+
+
+                                        ; lets look through emacs starter kit before we throw this out.
+
+
+                                        ;   automatically wrap to the top of the buffer when isearch fails
+(defadvice isearch-search (after isearch-no-fail activate)
+  (unless isearch-success
+    (ad-disable-advice 'isearch-search 'after 'isearch-no-fail)
+    (ad-activate 'isearch-search)
+    (isearch-repeat (if isearch-forward 'forward))
+    (ad-enable-advice 'isearch-search 'after 'isearch-no-fail)
+    (ad-activate 'isearch-search)))
+
+;; 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))))))
+;;; lisp / elisp mode setings
+
+(add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save)
+(defun starter-kit-remove-elc-on-save ()
+  "If you're saving an elisp file, likely the .elc is no longer valid."
+  (make-local-variable 'after-save-hook)
+  (add-hook 'after-save-hook
+            (lambda ()
+              (if (file-exists-p (concat buffer-file-name "c"))
+                  (delete-file (concat buffer-file-name "c"))))))
+
+
+(defun emacs-lisp-mode-defaults ()
+  ;; checkdoc has an annoying feature that wants a header and footer
+  ;; in every elisp buffer as if they all were packages
+  ;; todo, see if there is a way
+  ;; to make checkdoc usable instead of just disabling it as I do here
+  (if (boundp 'flycheck-checkers)
+      (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers)))
+  (eldoc-mode 1))
+(add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults)
+
+(define-key lisp-mode-map (kbd "<M-up>") 'backward-up-list)
+(define-key lisp-mode-map (kbd "<M-down>") 'down-list)
+(define-key emacs-lisp-mode-map (kbd "<M-up>") 'backward-up-list)
+(define-key emacs-lisp-mode-map (kbd "<M-down>") 'down-list)
+(define-key emacs-lisp-mode-map (kbd "<M-escape>") 'find-function-at-point)
+
+;; 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)
+
+
+;; 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)
+
+;;; mediawiki
+
+(eval-after-load "mediawiki"
+  '(progn
+     (remove-hook 'outline-minor-mode-hook 'mediawiki-outline-magic-keys)
+     (add-hook 'mediawiki-mode-hook
+               (lambda () (define-key mediawiki-mode-map (kbd "C-(") 'mediawiki-save-reload)))
+
+     ;; mediawiki mode has a bug that it will claim an edit conflict unless you reload after saving.
+     ;; I also like to save with no edit summary for previewing on my local mw instance
+     (defun mediawiki-save-reload ()
+       (interactive)
+       (and (mediawiki-save "") (mediawiki-reload)))))
+;;; modes with little configuration needed
+;; busted:
+;;(require 'csv-mode)
+;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
+
+(require 'outshine)
+(add-hook 'outline-minor-mode-hook 'outshine-mode)
+(add-hook 'emacs-lisp-mode-hook 'outline-minor-mode)
+(add-hook 'sh-mode-hook 'outline-minor-mode)
+
+
+
+(setq org-caldav-url "https://cal.iankelling.org"
+      org-caldav-calendar-id "ian"
+      org-caldav-inbox "/p/cal.org")
+;;(org-caldav-sync)
+
+
+;;(require 'dtrt-indent)
+;;(setq dtrt-indent-mode t)
+
+(setq css-indent-offset 2)
+
+(load-file "/a/h/iank-mod.el")
+
+;; from when i was running my own patches
+;;(add-to-list 'load-path "/a/opt/ws-butler")
+
+(require 'ws-butler)
+;; todo: I think this is broken, it keeps collapsing the last line
+;; for empty messages.
+
+;; the main problem is when it deletes the blank line at the end
+;; of a message with an empty body. but I might also
+;; be pasting whitespace significant things in here, so
+;; just don't do anything.
+;; todo: propose this upstream
+(add-to-list 'ws-butler-global-exempt-modes 'message-mode)
+
+(ws-butler-global-mode)
+
+
+
+(require '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)))
+
+
+;; gnu global
+(require 'ggtags)
+(add-hook 'c-mode-common-hook
+          (lambda () (ggtags-mode 1)
+            (setq c-label-minimum-indentation 0)))
+
+;; specific to my unusual keybind setup, you may want to
+;; pick different keys
+(define-key ggtags-mode-map (kbd "C-M-o") 'ggtags-find-tag-dwim)
+(define-key ggtags-mode-map (kbd "C-M-m") 'ggtags-grep)
+
+(defun gtags-update-single(filename)
+  "Update Gtags database for changes in a single file"
+  (interactive)
+  (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " ggtags-project-root " ; gtags --single-update " filename )))
+
+(defun gtags-update-current-file()
+  (interactive)
+  (let ((rel-filename (replace-regexp-in-string
+                       ggtags-project-root "."
+                       (buffer-file-name (current-buffer)))))
+    (gtags-update-single rel-filename)))
+
+(defun gtags-update-hook()
+  "Update GTAGS file incrementally upon saving a file"
+  (when (and ggtags-mode ggtags-project-root)
+    (gtags-update-current-file)))
+
+(add-hook 'after-save-hook 'gtags-update-hook)
+
+;; i'd like to make some elisp which modifies a keymap to remove
+;; all binds which don't match a predicate.
+;; I tried setting a keymap to a new keymap,
+;; but that didn't register as functional.
+;; so I'd need to modify the list in place.
+
+(require 'magit)
+
+
+;; colorize hex colors: use rainbow mode
+
+
+;; 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, which I use postfix for
+(setq send-mail-function (quote sendmail-send-it))
+
+(require 'spray)
+(global-set-key (kbd "C-M-w") 'spray-mode)
+;; remember, h/l = move. f/s = faster/slower, space = pause, all others quit
+
+;; delete active selection with self-insert commands
+(delete-selection-mode t)
+
+;; Transparently open compressed files
+(auto-compression-mode t)
+
+;; Highlight matching parenthesesq when the pointq is on them.
+;; not needed since smart paren mode?
+;;  (show-paren-mode 1)
+
+
+;; 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.
+(setq TeX-command-force "LaTeX")
+
+;; dot mode, repeats last action
+(require 'dot-mode)
+(add-hook 'find-file-hooks 'dot-mode-on)
+
+
+;; clean up obsolete buffers automatically at midnight
+(require 'midnight)
+
+
+;; disabled because it takes 400ms on startup
+;; ;; emacs regexes are too limited.
+;; (require 'foreign-regexp)
+;; ;; perl is most powerful, but javascript is pretty close and
+;; ;; I'd rather know javascript stuff than perl
+;; (custom-set-variables
+;;  '(foreign-regexp/regexp-type 'javascript) ;; Choose by your preference.
+;;  '(reb-re-syntax 'foreign-regexp)) ;; Tell re-builder to use foreign regexp.
+;; ;; it would be nice to add documentation to do this for more commands to that package
+;; ;; disabled because it's too slow. but I'd still m-x it for advanced replacements
+;; ;;(define-key global-map [remap isearch-forward-regexp] 'foreign-regexp/isearch-forward)
+
+
+;; saner regex syntax
+(require 're-builder)
+(setq reb-re-syntax 'string)
+
+
+;; use shift + arrow keys to switch between visible buffers
+;; todo, set these keys to something else
+(require 'windmove)
+(windmove-default-keybindings)
+
+
+;; show the name of the current function definition in the modeline
+(require 'which-func)
+(setq which-func-modes t)
+(which-function-mode 1)
+
+
+;; enable winner-mode to manage window configurations
+(winner-mode +1)
+
+;; meaningful names for buffers with the same name
+(require 'uniquify)
+(setq uniquify-buffer-name-style 'forward
+      uniquify-separator "/"
+      ;; for sdx work. until I figure out a better way.
+      ;; maybe something like projectile can do it,
+      ;; or hacking around the status bar
+      uniquify-min-dir-content 2
+      uniquify-after-kill-buffer-p t ; rename after killing uniquified
+      uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
+
+
+;; makefiles require tabs
+;; todo: find a makefile indent function that works,
+;; best I could find is this one which means don't indent at all
+;;
+(add-hook 'makefile-mode-hook
+          (lambda ()
+            (setq indent-tabs-mode t)
+            (setq indent-line-function (lambda () 'no-indent))))
+
+
+;; 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)
+
+
+;; auto indent shell script comments
+(setq sh-indent-comment t)
+
+;; random extra highlights
+(require 'volatile-highlights)
+(volatile-highlights-mode t)
+
+
+;; make help buffers smaller when it makes sense
+(temp-buffer-resize-mode 1)
+
+
+(require 'info+)
+;; based on suggestions in info+.el, I also installed  misc-fns, strings, and thingatpt+
+;; remove some bad keybinds from info+
+(define-key Info-mode-map [mouse-4]         nil)
+(define-key Info-mode-map [mouse-5]         nil)
+
+
+(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 7)
+;; sublimity doesn't work as good going fast by default
+;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location
+
+
+(setq sh-here-document-word "'EOF'")
+
+(setq tramp-default-method "ssh")
+;;; misc general settings
+
+(ivy-mode 1)
+(add-hook 'text-mode-hook (lambda () (auto-fill-mode t)))
+(setq counsel-find-file-at-point t)
+
+;; easier to read with just spaces as separator
+(setf (nth 2 ido-decorations) "   ")
+
+
+;; https://www.emacswiki.org/emacs/FillParagraph
+;; make list items start paragraphs.
+(setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ")
+
+(setq sh-basic-offset 2)
+(setq vc-follow-symlinks t)
+
+;; give us a shell to start instead of scratch
+;;(setq initial-buffer-choice (lambda () (new-shell)))
+
+;; disable this nasty function, as I always use a gui
+(defun suspend-frame() (interactive))
+
+;; Seed the random-number generator
+(random t)
+
+;; easier to remember than keybinds
+(defalias 'scrypt 'mml-secure-message-encrypt-pgpmime)
+(defalias 'sign 'mml-secure-message-sign-pgpmime)
+(defun encrypt ()
+  (interactive)
+  (mml-secure-message-encrypt-pgpmime 'dontsign))
+
+;; don't highlight the region.
+(set-face-background 'region nil)
+
+;; this fixes save error for python example code
+(define-coding-system-alias 'UTF-8 'utf-8)
+
+;; i don't use frame titles, but if I ever do
+;; this starter kit setting is probably good
+(if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b"))))
+
+
+;;(prefer-coding-system 'utf-8-unix)
+
+;; remove ugly 3d box feature
+(set-face-attribute 'mode-line nil :box nil)
+
+(add-to-list 'default-frame-alist
+             '(font . "DejaVu Sans Mono-11"))
+                                        ; the default will jump 2 sizes.
+(setq text-scale-mode-step 1.1)
+(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"
+      echo-keystrokes 0.1
+      mark-ring-max 160
+      sort-fold-case t  ; case insensitive line sorting
+      global-mark-ring-max 1000
+      ;; the visible bell seems to lag the ui
+      ;;visible-bell t
+      ;; turn off audible bell
+      ;; https://www.emacswiki.org/emacs/AlarmBell
+      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
+
+
+(setq-default indent-tabs-mode nil ;; don't use tabs to indent
+              cursor-type 'box
+              fill-column 72
+
+              ;; wrap at word boundaries instead of mid-word
+              word-wrap t
+              imenu-auto-rescan t
+              indicate-empty-lines t) ; mark end of buffer
+
+
+(blink-cursor-mode '(-4))
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+
+
+;; enable various commands
+(put 'narrow-to-region 'disabled nil)
+(put 'narrow-to-page 'disabled nil)
+(put 'narrow-to-defun 'disabled nil)
+(put 'upcase-region 'disabled nil)
+(put 'downcase-region 'disabled nil)
+(put 'scroll-left 'disabled nil)
+;; these from graphene, haven't read about them yet
+(put 'ido-complete 'disabled nil)
+(put 'ido-exit-minibuffer 'disabled nil)
+(put 'dired-find-alternate-file 'disabled nil)
+(put 'autopair-newline 'disabled nil)
+
+
+
+;;disable and minimize various prompts/messages
+(fset 'yes-or-no-p 'y-or-n-p)
+(setq confirm-nonexistent-file-or-buffer nil
+      inhibit-startup-message t
+      inhibit-startup-echo-area-message t
+      inhibit-startup-screen t
+      compilation-read-command nil ;; just don't compile with unsafe file local vars
+      kill-buffer-query-functions (remq 'process-kill-buffer-query-function
+                                        kill-buffer-query-functions))
+
+
+;; exit without bothering me
+;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042
+(add-hook 'comint-exec-hook
+          (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil)))
+;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting
+;; apparently this would need to be in some later hook. dunno where is best, but this works
+(defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate)
+  (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions)))
+
+
+
+;; (custom-set-faces
+;;  ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin
+;;  '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil))))
+;;  ;; don't highlight the region
+;;  '(region ((t nil))))
+(setq-default header-line-format " ")
+
+
+(setq initial-scratch-message nil)
+
+
+;; vertical margin background.
+;; google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html
+;; the xresource doesn't work for me, probably an xmonad thing.
+
+;; figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search
+;; info,
+;; then M-x customize-face
+;; header-line
+;; unchecked some stuff so that it inherits from default.
+
+;;; misc function definitions
+
+
+(defun fill-buffer ()
+  (interactive)
+  (save-mark-and-excursion
+    (beginning-of-buffer)
+    (while (= (forward-line) 0)
+      (fill-paragraph))))
+
+
+(defun next-backup-dir ()
+  "In a directory listing from rsync -n,
+Go to the next directory based on where the cursor is."
+  (interactive)
+  (let* ((start-col (current-column))
+         (end-col (progn (skip-chars-forward "^/\n") (current-column)))
+         (dir (progn
+                (beginning-of-line 1)
+                (buffer-substring-no-properties (point) (+ (point) end-col)))))
+    (message dir)
+    (forward-line 1)
+    (while (and (not (eobp))
+                (string= dir (buffer-substring-no-properties (point) (+ (point) end-col))))
+      (forward-line 1))
+    (forward-char-same-line start-col)))
+;; copy paste this for fast keybind
+;;(local-set-key (kbd "<kp-enter>"))
+
+
+(defun goto-buffer-or-find-file (file-name)
+  "If buffer is with FILE-NAME exists, go to it, else open the file using full path."
+  (interactive)
+  (let ((b (get-buffer (file-name-nondirectory file-name))))
+    (if b
+        (switch-to-buffer b)
+      (find-file file-name))))
+
+
+
+
+;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something
+(defun unpop-global-mark ()
+  "Unpop off global mark ring. Does nothing if mark ring is empty."
+  (interactive)
+  (when global-mark-ring
+    (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
+    (let ((lm (car (last global-mark-ring))))
+      (set-marker (mark-marker) (marker-position lm) (marker-buffer lm)))
+    (when (null (mark t)) (ding))
+    (setq global-mark-ring (nbutlast global-mark-ring))
+    (goto-char (marker-position (mark-marker)))))
+
+(defun indent-buffer ()
+  "Indents the entire buffer."
+  (interactive)
+  (cond ((derived-mode-p 'org-mode)
+         (org-indent-region (point-min) (point-max)))
+        ((derived-mode-p 'python-mode)
+         (py-autopep8))
+        (t
+         (indent-region (point-min) (point-max)))))
+
+
+;; TODO doesn't work with uniquify
+(defun rename-file-and-buffer ()
+  "Renames current buffer and file it is visiting."
+  (interactive)
+  (let ((name (buffer-name))
+        (filename (buffer-file-name)))
+    (if (not (and filename (file-exists-p filename)))
+        (message "Buffer '%s' is not visiting a file!" name)
+      (let ((new-name (read-file-name "New name: " filename)))
+        (cond ((get-buffer new-name)
+               (message "A buffer named '%s' already exists!" new-name))
+              (t
+               (rename-file name new-name 1)
+               (rename-buffer new-name)
+               (set-visited-file-name new-name)
+               (set-buffer-modified-p nil)))))))
+
+
+
+(defun sudo-edit (&optional arg)
+  (interactive "P")
+  (if (or arg (not buffer-file-name))
+      (find-file (concat "/sudo::" (ido-read-file-name "File: ")))
+    (find-alternate-file (concat "/sudo::" buffer-file-name))))
+
+
+
+(defun backward-symbol (arg)
+  (interactive "p")
+  (forward-symbol (- arg)))
+
+;;; mode line
+;; 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 . "")
+    (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
+        mode-line-position nil)) ; todo, make only flymake status show up
+
+(add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook)
+
+;;; mouse related
+;;;; settings
+(setq focus-follows-mouse t
+      mouse-autoselect-window t
+      xterm-mouse-mode t)
+;;;; move-mouse-to-point
+;; todo, this is buggy with multiple windows open.
+(defun move-mouse-to-point ()
+  (interactive)
+  (let* ((pos (posn-col-row (posn-at-point)))
+         (x (+ (car pos) 2)) ; no idea why this is off by 1-2
+         (y (cdr pos)))
+    (set-mouse-position (selected-frame) x y)))
+
+;;;; keybinds for wow mouse
+
+(global-set-key (kbd "<mouse-6>") 'move-mouse-to-point)
+(global-set-key (kbd "<kp-left>") 'indent-region)
+(global-set-key (kbd "<kp-begin>") 'mark-defun)
+(global-set-key (kbd "<kp-right>") 'ibuffer)
+(global-set-key (kbd "<kp-prior>") 'delete-horizontal-space)
+
+;;; 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)
+
+;; todo, generally fix org mode keys
+;; todo, org-mark-element, unbdind from M-h, bind to mark defun key
+
+                                        ;(org-babel-do-load-languages
+                                        ; 'org-babel-load-languages
+                                        ; '((emacs-lisp . t)
+                                        ;   (sh . t)))
+
+
+
+;; make shell work like interactive bash shell
+(setq org-babel-default-header-args:sh
+      '((:results . "output") (:shebang . "#!/bin/bash -l")))
+
+;; my patch to output stderr
+(setq org-babel-use-error-buffer nil)
+
+                                        ;
+;; org-mode manual suggests these, but I haven't used them.
+;;(global-set-key "\C-cl" 'org-store-link)
+;;(global-set-key "\C-ca" 'org-agenda)
+;; this got in the way of a haskell mode command
+;;(global-set-key "\C-cb" 'org-iswitchb)
+
+
+
+;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix
+
+(setq org-src-fontify-natively t ; make babel blocks nice
+      org-adapt-indentation nil
+      org-src-preserve-indentation t
+      ;; The most basic logging is to keep track of when a TODO item was finished.
+      org-log-done 'time
+      ;; use a drawer to keep the logs tidy
+      org-log-into-drawer t
+      org-extend-today-until 0
+      org-startup-truncated nil
+      org-clock-persist t
+      org-clock-mode-line-total 'today
+      ;; global STYLE property values for completion
+      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
+      org-catch-invisible-edits 'smart)
+
+;; non universally recommended settings
+(setq
+ org-default-notes-file (concat org-directory "/a/t.org")
+ org-agenda-files (quote ("/a/t.org"))
+ org-mobile-directory "/p/org-mobile"
+ org-mobile-inbox-for-pull "/p/from-mobile.org"
+ org-directory "/p")
+
+;; modeilne populated from (org-clock-get-clocked-time)
+;; which is populated from the var org-clock-total-time
+;; which is populated by a function which starts from (org-clock-get-sum-start)
+;;
+
+(org-clock-persistence-insinuate)
+
+
+(defun time-to-org-day (time)
+  (round (time-to-number-of-days
+          (time-subtract time (list 0 (* 3600 org-extend-today-until) 0)))))
+
+
+(defun my-org-confirm-babel-evaluate (lang body)
+  (not (or (string= (buffer-file-name) "/a/t.org")
+           (string= (buffer-file-name) "/home/iank/.emacs.d/my-init.org")
+           )))
+(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
+
+
+(defun org-time-stamp-with-time (arg)
+  (interactive "P")
+  ;; '(4) is the argument passed by universal prefix
+  (org-time-stamp (if arg arg '(4)) t))
+
+(defun ian-org-work-time ()
+  (interactive)
+  (save-excursion
+    (set-buffer "t.org")
+    (goto-char (org-find-entry-with-id "ian-identifier-1"))
+    (org-clock-in)))
+
+(defun ian-org-idle-time ()
+  (interactive)
+  (save-excursion
+    (goto-char (org-find-entry-with-id "ian-identifier-2"))
+    (set-buffer "t.org")
+    (org-clock-in)))
+
+
+
+;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables
+;; keywords: proportional font, monospace
+
+(defun variable-pitch-on ()
+  (variable-pitch-mode 1))
+(add-hook 'fundamental-mode-hook 'variable-pitch-on)
+(add-hook 'org-mode-hook 'variable-pitch-on)
+(add-hook 'text-mode-hook 'variable-pitch-on)
+(defun variable-pitch-off ()
+  (variable-pitch-mode 0))
+(add-hook 'yaml-mode-hook 'variable-pitch-off)
+
+
+(set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family))
+(set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family))
+(set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family))
+(set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family))
+(set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family))
+(set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family))
+
+
+(defun remove-org-binds ()
+  (define-key org-mode-map (kbd "<M-return>") nil)
+  (define-key org-mode-map (kbd "C-'") nil)
+  (define-key org-mode-map (kbd "C-y") nil)
+  (define-key org-mode-map (kbd "<C-return>") nil)
+  (define-key org-mode-map (kbd "<C-M-kp-enter>") nil)
+  (define-key org-mode-map (kbd "C-,") nil)
+  (define-key org-mode-map (kbd "C-M-m") nil)
+  (define-key org-mode-map (kbd "C-k") nil)
+  (define-key org-mode-map (kbd "C-j") nil)
+  (define-key org-mode-map (kbd "C-M-i") nil)
+  (define-key org-mode-map (kbd "C-M-t") nil)
+  (define-key org-mode-map (kbd "M-a") 'nil)
+  (define-key org-mode-map (kbd "C-a") nil)
+  (define-key org-mode-map (kbd "M-e") nil)
+  (define-key org-mode-map (kbd "C-e") nil)
+  (define-key org-mode-map (kbd "C-3") nil)
+  (define-key org-mode-map (kbd "<M-left>") nil)
+  (define-key org-mode-map (kbd "<M-right>") nil)
+  (define-key org-mode-map (kbd "<S-return>") nil)
+  (define-key org-mode-map (kbd "<tab>") nil)
+  (define-key org-mode-map (kbd "<C-S-down>") nil)
+  (define-key org-mode-map (kbd "<C-S-up>") nil)
+  (define-key org-mode-map (kbd "<S-down>") nil)
+  (define-key org-mode-map (kbd "<S-up>") nil)
+  (define-key org-mode-map "\t" nil))
+(add-hook 'org-mode-hook 'remove-org-binds)
+
+;;; prog-mode-defaults
+
+
+(defun prog-mode-defaults ()
+  "Default coding hook, useful with any programming language."
+  ;; so that I can do completion before the dialog pops up
+  (local-set-key (kbd "<tab>") 'auto-complete)
+  ;; todo, this is causing error message on loading file, prolly not working
+  ;;(flycheck-mode +1)
+  (setq ac-sources (delq 'ac-source-dictionary ac-sources))
+  (highlight-symbol-mode)
+  (make-local-variable 'column-number-mode)
+  ;; 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)
+
+  ;; prettify lambdas
+  (font-lock-add-keywords
+   nil `(("(\\(lambda\\>\\)"
+          (0 (progn (compose-region (match-beginning 1) (match-end 1)
+                                    ,(make-char 'greek-iso8859-7 107))
+                    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
+;; automatically indenting yanked text if in programming-modes
+(defvar yank-indent-modes
+  '(LaTeX-mode TeX-mode)
+  "Modes in which to indent regions that are yanked (or yank-popped).
+Only modes that don't derive from `prog-mode' should be listed here.")
+
+(defvar yank-indent-blacklisted-modes
+  '(python-mode slim-mode haml-mode)
+  "Modes for which auto-indenting is suppressed.")
+
+(defvar yank-advised-indent-threshold 2000
+  "Threshold (# chars) over which indentation does not automatically occur.")
+
+(defun yank-advised-indent-function (beg end)
+  "Do indentation, as long as the region isn't too large."
+  (if (<= (- end beg) yank-advised-indent-threshold)
+      (indent-region beg end nil)))
+
+(defadvice yank (after yank-indent activate)
+  "If current mode is one of 'yank-indent-modes,
+indent yanked text (with prefix arg don't indent)."
+  (if (and (not (ad-get-arg 0))
+           (not (member major-mode yank-indent-blacklisted-modes))
+           (or (derived-mode-p 'prog-mode)
+               (member major-mode yank-indent-modes)))
+      (let ((transient-mark-mode nil))
+        (yank-advised-indent-function (region-beginning) (region-end)))))
+
+(defadvice yank-pop (after yank-pop-indent activate)
+  "If current mode is one of 'yank-indent-modes,
+indent yanked text (with prefix arg don't indent)."
+  (if (and (not (ad-get-arg 0))
+           (not (member major-mode yank-indent-blacklisted-modes))
+           (or (derived-mode-p 'prog-mode)
+               (member major-mode yank-indent-modes)))
+      (let ((transient-mark-mode nil))
+        (yank-advised-indent-function (region-beginning) (region-end)))))
+
+
+;;; shell mode
+;; avoid stupid git crap like "warning, terminal not fully functional"
+(setenv "PAGER" "cat")
+;; don't store successive duplicates in comint command history
+(setq comint-input-ignoredups t)
+
+(defun add-mode-line-dirtrack ()
+  (add-to-list 'mode-line-buffer-identification
+               '(:propertize (" " default-directory " ") face dired-directory)))
+(add-hook 'shell-mode-hook 'add-mode-line-dirtrack)
+
+
+;; don't fully understand it, but it works.
+;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs
+(defun track-shell-directory/procfs ()
+  (shell-dirtrack-mode 0)
+  (add-hook 'comint-preoutput-filter-functions
+            (lambda (str)
+              (prog1 str
+                (when (string-match comint-prompt-regexp str)
+                  (cd (file-symlink-p
+                       (format "/proc/%s/cwd" (process-id
+                                               (get-buffer-process
+                                                (current-buffer)))))))))
+            nil t))
+(setq comint-buffer-maximum-size 100000)
+(add-to-list 'comint-output-filter-functions 'comint-truncate-buffer)
+(defun new-shell ()
+  (interactive)
+  (shell (generate-new-buffer-name "*shell*")))
+;;
+(defun shell-wrap (prefix)
+  "wrap the shell function, automatically generate a new name for a prefix arg"
+  (interactive "P")
+  (if prefix
+      (new-shell)
+    (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 "<return>"))))
+(sp-pair "[" nil :post-handlers
+         '(:add ((lambda (id action context)
+                   (gp/sp/pair-on-newline-and-indent id action context)) (kbd "<return>"))))
+
+
+;; 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
+(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))
+
+
+;;; smex
+;;  todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings.
+                                        ; these must be before smex-initialize
+(setq
+ smex-save-file "~/.emacs.d/.smex-items")
+
+(smex-initialize)
+;;; spell correction
+(setq
+ ispell-program-name "hunspell"
+ ispell-silently-savep t) ; don't prompt to save personal dictionary
+
+(require 'rw-hunspell)
+;; rw-hunspell sets up hunspell dictionary automagically.
+
+
+;; 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
+;; "emacs" "customizable" and "timestamp". Hunspell already has those,
+;; thank god.
+
+;; ispell-personal-dictionary does not document where the hunspell
+;; dictionary goes by default, but it is ~/.hunspell_en_US for me
+
+
+;;; tex
+(setq-default TeX-PDF-mode t) ; use pdf
+
+                                        ; more sensible defaults based on info manual quickstart
+(setq TeX-auto-save t)
+(setq TeX-parse-self t)
+
+
+
+;;; visible mark mode
+
+;; since it is not easy to change the mark overlay priority, I change this one.
+(setq show-paren-priority 999)
+
+
+(defface visible-mark-active
+  '((((type tty) (class mono)))
+    (t (:background "magenta"))) "")
+
+
+
+(defface mouse-cursor-face
+  '((((type tty) (class mono)))
+    (t (:background "DeepPink1"))) "")
+
+
+(require 'visible-mark)
+
+(setq visible-mark-faces '(visible-mark-face1 visible-mark-face2))
+(setq visible-mark-forward-faces '(visible-mark-forward-face1))
+
+
+                                        ; highlight the last 2 marks
+(setq visible-mark-max 2)
+                                        ; highlight 1 forward mark
+(setq visible-mark-forward-max 1)
+                                        ; globally activate visible-mark-mode
+(global-visible-mark-mode +1)
+
+
+;; todo, it doesn't seem to be exposed in elisp, but it would be nice
+;; if I could define overlay faces to use inverse foreground color
+
+
+;;; zrc
+(require 'znc)
+(setq erc-fill-prefix "")
+(defun chirp()
+  (interactive)
+  (setq vol 50)
+  (when (string= (system-name) "tp") (setq vol 40))
+  (start-process-shell-command "ignoreme" nil (format "mpv --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
+;; from https://www.emacswiki.org/emacs/ErcSound
+
+(defun erc-my-privmsg-sound (proc parsed)
+  (let* ((tgt (car (erc-response.command-args parsed)))
+         (privp (erc-current-nick-p tgt)))
+    (and
+     privp (chirp)
+     ;; We must return nil. See help for `erc-server-PRIVMSG-functions'
+     nil)))
+
+(add-hook 'erc-server-PRIVMSG-functions
+          'erc-my-privmsg-sound)
+
+(defun erc-sound-if-not-server (match-type nickuserhost msg)
+  (unless (string-match "Server:[0-9]+" nickuserhost)
+    (chirp)))
+(add-hook 'erc-text-matched-hook 'erc-sound-if-not-server)
+
+(erc-track-mode 1)
+(setq
+ ;; consider invisible frames to be unseen. seems like an obvious default
+ erc-track-visibility 'visible
+ ;; switch to buffer where i've been mentioned, etc instead of oldest
+ erc-track-switch-direction 'importance)
+
+
+;;; named commands
+(defun rm-file-and-buffer ()
+  "Removes file connected to current buffer and kills buffer."
+  (interactive)
+  (let ((filename (buffer-file-name))
+        (buffer (current-buffer))
+        (name (buffer-name)))
+    (if (not (and filename (file-exists-p filename)))
+        (error "Buffer '%s' is not visiting a file!" name)
+      (delete-file filename)
+      (kill-buffer buffer)
+      (message "File '%s' successfully removed" filename))))
+
+;;; persistent registers
+;; This needs to be at the end, because I visit a file, thus setting a
+;; mode, and the mode hook needs to be setup before that.
+
+;; I'm using persistent registers instead of bookmarks. I dun use them
+;; much, so the added hassle of having to set it within this file is
+;; worth the benefit of only having one concept in my mind.
+(dolist
+    (r `(
+         (?i (file . ,"~/.emacs.d/my-init.org"))
+         (?t (file . ,"/a/t.org"))
+         (?x (file . ,"/a/x.txt"))
+         ))
+  (set-register (car r) (cadr r)))
+
+(setq undo-outer-limit 100000000 ; per undo command
+      undo-limit 500000000 ; undo history limit
+      undo-strong-limit 600000000) ; undo history limit plus some extra
+
+;;; keybinds
+
+;;;; misc
+(global-set-key (kbd "C-x C-b") 'ibuffer)
+
+
+;; isearch-occur
+;; Activate occur easily inside isearch
+;; 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))))))
+
+
+(defun my-isearch-toggle-regexp ()
+  (interactive)
+  (isearch-toggle-regexp)
+  (cond (isearch-regexp
+         (global-set-key (kbd "C-r") 'isearch-backward-regexp)
+         (define-key global-map (kbd "<f12>") 'isearch-forward-regexp))
+        (t
+         (global-set-key (kbd "C-r") 'isearch-backward)
+         (define-key global-map (kbd "<f12>") 'isearch-forward))))
+(define-key isearch-mode-map (kbd "M-r") 'my-isearch-toggle-regexp)
+
+
+(define-key Info-mode-map "x" 'Info-follow-nearest-node)
+
+
+;;;; single/special keys
+;;;;; tab - isearch
+(define-key isearch-mode-map (kbd "<tab>") 'isearch-query-replace)
+
+;;;;; f12 - isearch-forward
+;; explained in http://stackoverflow.com/questions/7411920/how-to-bind-search-and-search-repeat-to-c-f-in-emacs
+(global-set-key (kbd "<kp-add>") 'isearch-forward)
+(global-set-key (kbd "<f12>") 'isearch-forward)
+(define-key isearch-mode-map "\t" nil)
+(define-key isearch-mode-map (kbd "<kp-add>") 'isearch-repeat-forward)
+(define-key isearch-mode-map (kbd "<f12>") 'isearch-repeat-forward)
+;; get rid of the standard completion binding, always use auto-complete
+;; this didn't work very well
+;;(global-set-key (kbd "TAB") 'auto-complete)
+(define-key global-map [remap completion-at-point] 'auto-complete)
+
+;;;;; end - move-end-of-line
+;; taken from emacs wiki, along with home function
+;; http://www.emacswiki.org/emacs/BackToIndentationOrBeginning
+(defun point-in-comment ()
+  "Determine if the point is inside a comment"
+  (interactive)
+  (let ((syn (syntax-ppss)))
+    (and (nth 8 syn)
+         (not (nth 3 syn)))))
+(defun end-of-code-or-line (arg)
+  "Move to end of line, or before start of comments depending on situation.
+ Toggle back and forth positions if we are already at one.
+ Comments are recognized in any mode that sets syntax-ppss
+ properly."
+  (interactive "P")
+  (when (catch 'bol
+          (let ((start (point))
+                (bol (save-excursion
+                       (beginning-of-line)
+                       (point)))
+                (eol (progn (move-end-of-line arg) (point))))
+            (while (point-in-comment)
+              (backward-char)
+              (when (= (point) bol)
+                (throw 'bol t)))
+            (throw 'bol (and (not (= eol start)) (>= start (point))))))
+    (move-end-of-line arg)))
+
+(global-set-key (kbd "<end>") 'end-of-code-or-line)(add-hook 'org-mode-hook (lambda () (define-key org-mode-map (kbd "<end>") 'org-end-of-line)))
+
+;;;;; home - back-to-indentation
+(defun back-to-indentation-or-beginning ()
+  (interactive)
+  (if (= (point) (progn (back-to-indentation) (point)))
+      (if (derived-mode-p 'org-mode)
+          (org-beginning-of-line)
+        (beginning-of-line))))
+(global-set-key (kbd "<home>") 'back-to-indentation-or-beginning)
+
+;;;;; s-tab - indent-buffer
+(global-set-key (kbd "<S-iso-lefttab>") 'indent-buffer)
+;;;;; s-delete - send-shell
+
+(global-set-key (kbd "<S-delete>") 'send-shell)
+
+;; optional variables used by send-shell
+(setq shell-send-yank-key nil)
+
+(defun repeat-shell ()
+  (interactive)
+  "Repeat the last command in shell-mode, displaying the window if needed."
+  (let ((shell-buffer (get-buffer "*shell*")))
+    (if shell-buffer
+        (buffer-window-show shell-buffer)
+      (let ((original-buffer (current-buffer)))
+        (funcall 'shell)
+        (setq shell-buffer (current-buffer))
+        (switch-to-buffer original-buffer)))
+    (with-current-buffer shell-buffer
+      (goto-char (point-max))
+      (call-interactively 'comint-previous-input)
+      ;; the t flag makes the buffer advance
+      (comint-send-input nil t))))
+
+(setq compilation-filenames '("Makefile" "makefile"))
+
+(defun get-nearest-compilation-file ()
+  "Search for the compilation file traversing up the directory tree."
+  (interactive)
+  (let ((dir default-directory)
+       (parent-dir (file-name-directory (directory-file-name default-directory)))
+       (nearest-compilation-file 'nil))
+    (while (and (not (string= dir parent-dir))
+               (not nearest-compilation-file))
+      (dolist (filename compilation-filenames)
+       (setq file-path (concat dir filename))
+       (when (file-readable-p file-path)
+         (setq nearest-compilation-file file-path)))
+      (setq dir parent-dir
+           parent-dir (file-name-directory (directory-file-name parent-dir))))
+    nearest-compilation-file))
+(defun run ()
+  (interactive)
+  "call run-fun if it is set, else run make if there is a makefile,
+else save and repeat last shell command.
+run-fun is meant to store file local variables, which show how to
+do the main thing we want on this file, generally compile and
+run.
+
+example of setting it in a file:
+;; Local Variables:
+;; run-fun: merge-test
+;; End: "
+  (basic-save-buffer)
+  (if (and (boundp 'run-fun) run-fun)
+      (funcall run-fun)
+    (let ((makefile (get-nearest-compilation-file)))
+      (if (and makefile (stringp mode-name) (string= mode-name "C/l"))
+          (compile (format
+                    "make -f %s" (get-nearest-compilation-file)))
+        (repeat-shell)))))
+
+
+(defun send-shell ()
+  (interactive)
+  (send-shell-buffer "*shell*" 'shell (kbd "C-v")))
+
+(defun send-python ()
+  (interactive)
+  (send-shell-buffer "*Python*" 'py-shell (kbd "C-v")))
+
+
+(defun send-shell-buffer (buffer-name &optional init shell-send-yank-key)
+  "Send current line or region to shell-mode buffer.
+When in shell-mode, copy the current line to the
+most recently visited visible window.
+
+SHELL-SEND-YANK-KEY: key to use instead
+of yank to paste into recent window. This allows compatibility with
+modes like org-mode which have their own yank function."
+  (if (string= (buffer-name) buffer-name)
+      ;; this section is copied out of comint-send-input
+      (progn
+        (let ((proc (get-buffer-process (current-buffer))))
+          (if (not proc) (user-error "Current buffer has no process")
+            (widen)
+
+            (let* ((pmark (process-mark proc))
+                   (intxt (if (>= (point) (marker-position pmark))
+                              (progn (if comint-eol-on-send (end-of-line))
+                                     (buffer-substring pmark (point)))
+                            (let ((copy (funcall comint-get-old-input)))
+                              (goto-char pmark)
+                              (insert copy)
+                              copy))))
+
+              (if (= (length intxt) 0)
+                  (kill-new (comint-previous-matching-input-string "." 1))
+                (kill-new intxt)))))
+        (kill-append "\n" nil)
+        (select-window (previous-window nil nil 'visible))
+        (if (and (boundp 'shell-send-yank-key) shell-send-yank-key)
+            (call-interactively (global-key-binding shell-send-yank-key))
+          (yank))
+        (select-window (next-window nil nil 'visible)))
+    (let (start end)
+      (if mark-active
+          (setq start (mark)
+                end (point))
+        (setq start (save-excursion (beginning-of-line) (point))
+              end (save-excursion (end-of-line) (point)))
+        (let (line-move-visual)
+          (call-interactively 'next-line)))
+      (send-comint-input buffer-name start end init))))
+
+;; supporting functions
+(defun send-comint-input (buffer-name start end &optional init)
+  "Input the region to BUFFER-NAME, assuming it is a comint-derived buffer.
+                             Show BUFFER-NAME if it is not show.
+                             Call INIT if BUFFER-NAME does not exist."
+  (let ((input (filter-buffer-substring start end)))
+    (send-comint-string buffer-name input init)))
+
+(defun send-comint-string (buffer-name string &optional init)
+  "Input the string to BUFFER-NAME, assuming it is a comint-derived buffer.
+                             Show BUFFER-NAME if it is not show.
+                             Call INIT if BUFFER-NAME does not exist."
+  (let ((buffer (get-buffer buffer-name)))
+    (unless buffer
+      (message "nobuffer")
+      ;; save-excursion etc. don't work for (shell), so I do this instead
+      (if init (let ((original-buffer (current-buffer)))
+                 (funcall init (and (boundp 'send-shell-buffer-name) send-shell-buffer-name))
+                 (switch-to-buffer original-buffer)
+                 (setq buffer (get-buffer buffer-name)))
+        (error "No existing buffer found and no init function argument. ")))
+    (buffer-window-show buffer)
+    (with-current-buffer buffer
+      (let ((proc (get-buffer-process buffer)))
+        (goto-char (process-mark proc))
+        (insert string)
+        (comint-send-input nil t)))))
+
+(defun buffer-window-show (&optional buffer action)
+  "Like temp-buffer-window-show, but removed stuff
+        relevant to it being temp or help."
+  (let (window frame)
+    (with-current-buffer buffer
+      (when (let ((window-combination-limit
+                   ;; When `window-combination-limit' equals
+                   ;; `temp-buffer' or `temp-buffer-resize' and
+                   ;; `temp-buffer-resize-mode' is enabled in this
+                   ;; buffer bind it to t so resizing steals space
+                   ;; preferably from the window that was split.
+                   (if (or (eq window-combination-limit 'temp-buffer)
+                           (and (eq window-combination-limit
+                                    'temp-buffer-resize)
+                                temp-buffer-resize-mode))
+                       t
+                     window-combination-limit)))
+              ;; debug
+              ;;(message "window-combination-limit")
+              ;;(print window-combination-limit)
+              (setq window (display-buffer buffer action)))
+        (setq frame (window-frame window))
+        (unless (eq frame (selected-frame))
+          (raise-frame frame))
+        (setq minibuffer-scroll-window window)
+        (set-window-hscroll window 0)
+        ;; Return the window.
+        window))))
+
+
+;; when poping help, etc, allow reusing a window in a different frame if it is visible
+;; figured this out after spending quite a while reading doc string for display-buffer
+;; which is the main function which uses this.
+;; it will use other vars or its arg to override this,
+;; but those things are often nil.
+;; aha moments in reading it: ACTION = (FUNCTION-or-FUNCTIONLIST ALIST)
+;; FRAME adds an association to ACTION's alist, but it's not used if ACTION arg is nil.
+(setq display-buffer-fallback-action `(,(car display-buffer-fallback-action) . '(reusable-frames . visible)))
+;; stop splitting windows verticallly when I open a buffer or shell
+(setq split-height-threshold nil)
+
+;;;;; s-left arrow - shell
+(global-set-key (kbd "<S-left>") 'shell-wrap)
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "<S-left>") nil)))
+
+;;;;; s-right arrow - keyboard-yank-primary
+(defun keyboard-yank-primary ()
+  (interactive)
+  (let ((mouse-yank-at-point t))
+    (mouse-yank-primary nil)))
+;; paste selection
+(global-set-key (kbd "<S-right>") 'keyboard-yank-primary)
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "<S-right>") nil)))
+;;;;; esc
+                                        ; todo, test out if this can be used
+;;;;; return - new line
+
+;; todo, this doesn't set the keybind for the help minibuffer
+
+
+(global-set-key (kbd "\r") 'indent-new-comment-line)
+
+;; don't use enter for autocomplete, we use tab or something
+(define-key ac-completing-map (kbd "<return>") nil)
+(define-key ac-completing-map "\r" nil)
+
+(add-hook 'org-mode-hook
+          (lambda ()
+            ;; copied from org-mode, replace org-enter with org-enter-indent
+            (org-defkey org-mode-map "\C-m"     'org-return-indent)))
+
+
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map "\r" nil)
+            (define-key comint-mode-map (kbd "<return>") 'comint-send-input)))
+
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map "\C-m" nil)
+            (define-key comint-mode-map "\C-d" nil)))
+
+;;;;; s-return - auto-correct-prev-word
+(global-set-key (kbd "<S-return>") 'flyspell-auto-correct-previous-word)
+;; kp-enter is shift return in terminal
+(global-set-key (kbd "<kp-enter>") 'flyspell-auto-correct-previous-word)
+
+;;;;; s-down arrow - my-contract-region
+(global-set-key (kbd "<S-up>") 'my-contract-region)
+;;;;; c-up/down move 8 lines
+
+;; compiling warns that next-line should be called interactively,
+;; but we would have to do something dumb, like give it a
+;; vector of keys in order to supply the 8 argument
+(defun down-fast ()
+  (interactive)
+  (next-line 8))
+(defun up-fast ()
+  (interactive)
+  (next-line -8))
+
+(global-set-key (kbd "<C-up>") 'up-fast)
+(global-set-key (kbd "<C-down>") 'down-fast)
+
+;;;;; c-scroll comint prev/next prompt
+
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map (kbd "<C-mouse-4>") 'comint-previous-prompt)
+            (define-key comint-mode-map (kbd "<C-mouse-5>") 'comint-next-prompt)))
+;;;;; m-scroll prev/next sexp
+(global-set-key (kbd "<M-mouse-4>") 'backward-sexp)
+(global-set-key (kbd "<M-mouse-5>") 'forward-sexp)
+;;;;; S-scroll expand/contract region
+(global-set-key (kbd "<S-mouse-13>") 'my-contract-region)
+(global-set-key (kbd "<S-mouse-14>") 'er/expand-region)
+(global-set-key (kbd "<S-mouse-4>") 'my-contract-region)
+(global-set-key (kbd "<S-mouse-5>") 'er/expand-region)
+
+(defun my-contract-region (arg)
+  (interactive "p")
+  (let ((current-prefix-arg '-))
+    (call-interactively 'er/expand-region)))
+
+;; todo: define c-m scroll. i manually set to normal scrolling, i dunno why
+
+
+;;;;; c-s-scroll scale text
+
+(global-set-key (kbd "<C-S-mouse-4>") 'text-scale-increase)
+(global-set-key (kbd "<C-S-mouse-5>") 'text-scale-decrease)
+(global-set-key (kbd "<C-S-mouse-13>") 'text-scale-increase)
+(global-set-key (kbd "<C-S-mouse-14>") 'text-scale-decrease)
+(global-set-key (kbd "<C-S-down>") 'text-scale-increase)
+(global-set-key (kbd "<C-S-up>") 'text-scale-decrease)
+
+
+;;;;; s-up arrow er/expand-region
+(global-set-key (kbd "<S-down>") 'er/expand-region)
+;;;;; c-left/right move symbol
+
+(global-set-key (kbd "<C-left>") 'backward-symbol)
+(global-set-key (kbd "<C-right>") 'forward-symbol)
+
+;;;; left primary
+
+;;;;; C-2 copy-symbol
+
+(global-unset-key (kbd "C-2"))
+(defun copy-symbol (&optional arg)
+  "Copy symbol at point into kill-ring"
+  (interactive "P")
+  (kill-new (thing-at-point 'symbol)))
+
+(global-set-key (kbd "C-2") 'copy-symbol)
+
+;;;;; M-2 shell-cd-to-file
+
+
+(defun shell-cd-to-file ()
+  (interactive)
+  (let ((file (buffer-file-name)))
+    (if file
+        (send-comint-string "*shell*"
+                            (concat "c " (file-name-directory file))
+                            'shell)
+      (message "%s" "shell-cd-to-file: buffer has no file name"))))
+(global-set-key (kbd "M-2") 'shell-cd-to-file)
+
+;;;;; C-M-2 ---
+                                        ; todo. whats going on here?
+(global-unset-key (kbd "C-M-2"))
+
+;;;;; C-3 dot-mode-execute
+
+(global-set-key (kbd "C-3") 'dot-mode-execute)
+
+;;;;; C-M-3 recenter-top-bottom
+
+(global-set-key (kbd "C-M-3") 'recenter-top-bottom)
+
+;;;;; C-q org-cycle, comint previous arg
+
+(global-set-key (kbd "C-q") 'bicycle-cycle)
+(add-hook 'org-mode-hook
+          (lambda () (define-key org-mode-map (kbd "C-q") 'org-cycle)))
+(define-key widget-keymap (kbd "C-q") 'widget-forward)
+(add-hook 'comint-mode-hook
+          (lambda () (define-key comint-mode-map (kbd "C-q") 'comint-insert-previous-argument)))
+
+;;;;; M-q org-archive-to-archive-sibling
+
+(global-set-key (kbd "M-q") 'org-archive-to-archive-sibling)
+
+;;;;; C-M-q quoted-insert
+
+(global-set-key (kbd "C-M-q") 'quoted-insert)
+
+;;;;; C-w ---
+;; in terminal, it's ctrl-backspace, duplicate keybind.
+;;;;; M-w org-clock-in
+
+(global-set-key (kbd "M-w") 'org-clock-in)
+
+;;;;; C-e copy-line
+
+;; todo, make repeated calls to this append the kills
+(defun copy-line (&optional arg)
+  "Copy lines (as many as prefix argument) in the kill ring.
+        Ease of use features:
+        - Move to start of next line.
+        - Appends the copy on sequential calls.
+        - Use newline as last char even on the last line of the buffer.
+        - If region is active, copy its lines."
+  (interactive "p")
+  (let ((beg (line-beginning-position))
+        (end (line-end-position (or arg 1))))
+    (when mark-active
+      (if (> (point) (mark))
+          (setq beg (save-excursion (goto-char (mark)) (line-beginning-position)))
+        (setq end (save-excursion (goto-char (mark)) (line-end-position)))))
+    (if (eq last-command 'copy-line)
+        (kill-append (buffer-substring beg end) (< end beg))
+      (kill-ring-save beg end)))
+  (kill-append "\n" nil)
+  ;; dun need cuz I have yank-better
+  ;;(beginning-of-line (or (and arg (1+ arg)) 2))
+  (if (and arg (not (= 1 arg))) (message "%d lines copied" arg)))
+
+(global-set-key (kbd "C-e") 'copy-line)
+
+;;;;; M-e org-clock-in-last
+
+(global-set-key (kbd "M-e") 'org-clock-in-last)
+
+;;;;; C-r isearch-backward
+
+(global-set-key (kbd "C-r") 'isearch-backward)
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map (kbd "C-r") 'comint-history-isearch-backward-regexp)))
+
+;;;;; M-r org-clock-out
+
+(global-set-key (kbd "M-r") 'org-clock-out)
+
+;;;;; C-a copy buffer
+
+(defun copy-all ()
+  "Copy entire buffer to clipboard"
+  (interactive)
+  (clipboard-kill-ring-save (point-min) (point-max)))
+(global-set-key (kbd "C-a") 'copy-all)
+
+;;;;; C-s - c-x prefix
+  ; prefix key binds.
+  ; good info http://www.masteringemacs.org/articles/2011/02/08/mastering-key-bindings-emacs/
+  ; rebinding the prefix keys are tricky. apparently, some modes ignore any redefinition of a prefix key and use it explicitly,
+  ; so you have to dig into their key maps and redo things.
+  ; There are 2 simpler alternatives which have their own downsides.
+  ; One is cua mode, which I do not like because it smashes 2 keybinds onto 1 and limits what you can do.
+  ; The other is keyboard-translate, which translates the key presses before anything else.
+  ; The downside is that it translates them when you aren't using them as a prefix.
+  ; Since the swaps I'm using are all very accessible, the only downside is some mental jugling when reading docs etc about these keybinds.
+
+  ; I've seen this as an another suggestion, it was a total fail. The prefix command took over both keys.
+  ; (define-key key-translation-map [f12] "\C-c")
+  ; (define-key key-translation-map "\C-c" [left])
+
+
+  ;idea to remove the hook later since it is only needed at startup.
+  ; did not work however, and there is not a real need to fix it, so I did not investigate
+  ;(defun removeSwapHook ()
+  ;  (remove-hook 'buffer-list-update-hook 'myKeySwap)
+  ;  (remove-hook 'change-major-mode-hook 'removeSwapHook))
+  ;(add-hook 'change-major-mode-hook 'removeSwapHook)
+
+
+  ; went through almost all the relevant standard hooks,
+  ; this overcomes a known bug that (keyboard-translate) does not get applied when running emacs daemon
+  (add-hook 'buffer-list-update-hook (lambda () (interactive)
+                                       (keyboard-translate ?\C-x ?\C-s)
+                                       (keyboard-translate ?\C-s ?\C-x)
+                                       (keyboard-translate ?\C-c ?\C-d)
+                                       (keyboard-translate ?\C-d ?\C-c)))
+
+
+
+  ; these all don't work
+  ; don't know why this doesn't error but reversing the keys does
+  ;(keyboard-translate ?\t ?\M-\t)
+  ;(keyboard-translate [M-tab] [tab])
+  ; from what i can tell, it wants to use a keyboard-translate-table,
+  ; which is a char table, which is a vector indexed by chars,
+  ; and mod+tab is not a char (it has too many bits), it is an integer
+  ; it actually says it can hold vectors or strings, but that it is obsolete to do so
+  ;(characterp ?\M-a)
+  ;(characterp ?\C-a)
+
+;;;;; C-M-s - split-window-vertically
+
+(global-set-key (kbd "C-M-s") 'split-window-vertically)
+
+;;;;; C-d - C-c prefix
+;;;;; C-M-d - swap buffer across windows
+;; from http://www.emacswiki.org/emacs/TransposeWindows
+
+(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
+
+(global-set-key (kbd "C-f") 'kill-whole-line-wrapper)
+(defun kill-whole-line-wrapper (&optional arg)
+  "If we are at the end of the file, kill backwards instead of doing nothing."
+  (interactive "P")
+  (if (= (point) (point-max))
+      (kill-whole-line -1)
+    (kill-whole-line arg)))
+
+;;;;; M-f - print-var-at-point
+
+(defun print-var-at-point ()
+  (interactive)
+  (let ((v (variable-at-point)))
+    (if (symbolp v)
+        (message "%s: %s" v (symbol-value v))
+      (message "no symbol found at point"))))
+(global-set-key (kbd "M-f") 'print-var-at-point)
+
+
+;;;;; C-M-f - kill rest of line
+
+
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "C-M-f") 'org-kill-line)))
+
+(global-set-key (kbd "C-M-f") 'kill-line)
+;;;;; C-g - cancel / other window
+
+(global-set-key (kbd "C-g") 'other-window)
+
+;;;;; M-g - abort-recursive-edit
+
+(global-set-key (kbd "M-g") 'abort-recursive-edit)
+
+;;;;; C-M-g - gnus
+
+(global-set-key (kbd "C-M-g") 'mu4e)
+
+;;;;; C-z - undo-only
+
+(global-set-key (kbd "C-z") 'undo-only)
+
+;;;;; C-x - kill-region
+
+(global-set-key (kbd "C-s") 'kill-region)
+
+;;;;; M-x - smex
+
+(global-set-key (kbd "M-x") 'smex)
+
+;;;;; C-M-x - cut-to-register
+
+;; same args as copy-to-register
+(defun cut-to-register (register start end &optional delete-flag region)
+  (interactive (list (register-read-with-preview "Cut to register: ")
+                     (region-beginning)
+                     (region-end)
+                     current-prefix-arg
+                     t))
+  (copy-to-register register start end t region))
+
+(global-set-key (kbd "C-M-x") 'cut-to-register)
+
+;;;;; 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 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map (kbd "C-d") nil)))
+;; the base map is shared by many c-modes, like java
+(add-hook 'c-mode-hook
+          (lambda ()
+            (define-key c-mode-base-map "\C-d" nil)
+            (define-key c-mode-base-map (kbd "<deletechar>") 'c-electric-delete-forward)))
+
+
+;;;;; M-c - org-capture
+
+(define-key global-map "\M-c" 'org-capture)
+
+;;;;; C-M-c - copy-to-register
+
+(global-set-key (kbd "C-M-c") 'copy-to-register)
+
+;;;;; C-v - yank
+
+(global-set-key (kbd "C-v") 'yank-better)
+
+
+
+(defun yank-better (arg)
+  "Paste, linewise if our kill ends with a newline.
+  I change the behavior of plain prefix. It makes it not do linewise paste,
+  because sometimes you want to yank pop and a linewise paste screws that up.
+  c-u with no number normally makes the point go before the yank.
+  That is pointless for me, as it would be just as easier and less
+  thought to pop the mark after yanking cuz it is set to before the mark."
+  (interactive "*P")
+  (if (and (not (equal arg '(4))) (string-suffix-p "\n" (current-kill 0 t)))
+      (beginning-of-line))
+  (if (and (stringp mode-name) (string= mode-name "Org"))
+      (call-interactively 'org-yank)
+    (setq this-command 'yank)
+    (call-interactively 'yank (and (not (equal arg '(4)))))))
+
+(put 'yank-better 'delete-selection 'yank)
+
+;;;;; M-v - insert-register
+
+(global-set-key (kbd "M-v") 'insert-register)
+
+;;;;; C-M-v - yank-pop
+
+(global-set-key (kbd "C-M-v") 'yank-pop)
+
+;;;;; C-b - delete-other-windows
+
+(global-set-key (kbd "C-b") 'delete-other-windows)
+
+;;;;; M-b - isearch-backward-current-symbol
+
+(global-set-key (kbd "M-b") 'isearch-backward-current-symbol)
+
+;;;;; C-M-b - isearch-current-symbol
+
+(global-set-key (kbd "C-M-b") 'isearch-current-symbol)
+
+;;;;; C-tab - ---
+;; in terminal, it's just TAB, duplicate keybind.
+;;;;; M-tab - ---
+;; in terminal it's duplicated of C-M-i
+;;;;; C-delete - kill-symbol
+
+(global-set-key (kbd "<C-delete>") 'kill-symbol)
+(defun kill-symbol (arg)
+  (interactive "p")
+  (kill-region (point) (save-excursion (forward-symbol arg) (point))))
+
+
+;;;;; C-M-delete - kill-sexp
+
+(global-set-key (kbd "<C-M-delete>") 'kill-sexp)
+
+;;;;; C-left-arrow - compile / comint search
+
+(defun set-p (var)
+  (and (bound-and-true-p var)
+       (not (eq var 'unset))))
+(global-set-key (kbd "C-(") 'run)
+
+;; make compile work from the gtags root dir
+(defadvice compile (before pre-compile-advice activate)
+  (basic-save-buffer)
+  (when (set-p ggtags-project-root)
+    (setq-local compile-saved-dir default-directory)
+    (setq default-directory ggtags-project-root)))
+(defadvice compile (after post-compile-advice activate)
+  (when (bound-and-true-p compile-saved-dir)
+    (setq default-directory compile-saved-dir)))
+
+
+(add-hook 'c-mode-hook (lambda () (define-key c-mode-map (kbd "C-(") 'compile)))
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key isearch-mode-map (kbd "C-(") 'isearch-repeat-backward)
+            (define-key comint-mode-map (kbd "C-(") 'isearch-backward)))
+
+
+;;;;; C-M-left-arrow - org-shiftup
+
+(add-hook 'org-mode-hook
+          (lambda () (define-key org-mode-map (kbd "C-M-(") 'org-shiftup)))
+
+;;;;; C-right-arrow - forward-symbol
+;;;;; C-M-right-arrow - org-shiftdown
+(add-hook 'org-mode-hook
+(lambda () (define-key org-mode-map (kbd "C-M-)") 'org-shiftdown)))
+
+;;;;; C-backspace - backward-kill-symbol
+
+(global-set-key (kbd "<C-backspace>") 'backward-kill-symbol)
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map (kbd "<C-backspace>") 'backward-kill-word)))
+(defun backward-kill-symbol (arg)
+  (interactive "p")
+  (kill-region (point) (save-excursion (backward-symbol arg) (point))))
+
+;;;;; C-M-backspace - backward-kill-sexp
+
+(global-set-key (kbd "<C-M-backspace>") 'backward-kill-sexp)
+
+;;;; right primary
+;;;;; C-* - split-window-horizontally
+
+(global-set-key (kbd "C-*") 'split-window-horizontally)
+
+;;;;; C-M-* - calc-dispatch
+
+(global-set-key (kbd "C-M-*") 'calc-dispatch)
+
+;;;;; C-9 - delete-window-or-exit
+
+(global-set-key (kbd "C-9") 'delete-window-or-exit)
+
+(defun delete-window-or-exit ()
+  "Delete window or exit emacs."
+  (interactive)
+  (if (condition-case nil (delete-window) (error t))
+      (if (or (boundp 'server-process) (> (length (frame-list)) 1))
+          (progn (basic-save-buffer) (delete-frame))
+        (save-buffers-kill-terminal t))))
+
+;;;;; M-9 - kill-buffer
+
+(defun kill-buffer-no-ido ()
+  "kill-buffer, avoid the ido remapping"
+  (interactive)
+  (kill-buffer))
+(global-set-key (kbd "M-9") 'kill-buffer-no-ido)
+
+;; strangely, in simple mode, this is overridden.
+;; I found this map to override, but it didn't work, so it seems its being bound some other way.
+;; I did a grep of the emacs sources, but couldn't find anything.
+;; (define-key universal-argument-map [?9 nil)
+
+;;;;; C-M-9 - end server edit
+;;  save & kill buffer if it was opened externally via emacsclient
+
+
+  (defun server-edit-save ()
+    (interactive)
+    (save-buffer)
+    (server-edit))
+  (global-set-key (kbd "C-M-9") 'server-edit-save)
+
+;;;;; C-u - universal-argument
+;;;;; C-M-u - search-keybind
+
+  (global-set-key (kbd "C-M-u") 'search-keybind)
+
+  (defun search-keybind (regexp &optional nlines)
+    (interactive (occur-read-primary-args))
+    (save-excursion
+      (describe-bindings)
+      (set-buffer "*Help*")
+      (occur regexp)
+      (delete-windows-on "*Help*")
+      ))
+
+;;;;; C-i - -----
+;;;;; C-M-i - query-replace-regexp
+
+  (global-set-key (kbd "C-M-i") 'query-replace-regexp)
+  (add-hook 'flyspell-mode-hook
+            (lambda () (define-key flyspell-mode-map (kbd "C-M-i") nil)))
+  (add-hook 'text-mode-hook
+            (lambda () (define-key text-mode-map (kbd "C-M-i") nil)))
+
+
+;;;;; C-o - occur
+
+  (global-set-key (kbd "C-o") 'occur)
+
+;;;;; C-M-o - counsel-imenu
+
+  (global-set-key (kbd "C-M-o") 'counsel-imenu)
+
+;;;;; C-p - move-mouse-to-point
+
+  (global-set-key (kbd "C-p") 'move-mouse-to-point)
+
+;;;;; C-M-p - delete-horizontal-space
+
+  (global-set-key (kbd "C-M-p") 'delete-horizontal-space)
+
+;;;;; C-j - pop-to-mark
+
+  (defun my-pop-to-mark-command ()
+    "Jump to mark, and pop a new position for mark off the ring.
+                     \(Does not affect global mark ring\)."
+    (interactive)
+    (pop-to-mark-command)
+    (if (and (derived-mode-p 'org-mode) (outline-invisible-p))
+        (org-show-context 'mark-goto)))
+
+  (global-set-key (kbd "C-j") 'my-pop-to-mark-command)
+  (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text)
+  (add-hook 'ido-setup-hook
+            (lambda () (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text)))
+  (add-hook 'lisp-interaction-mode-hook
+            (lambda ()
+              (define-key lisp-interaction-mode-map (kbd "C-j") nil)))
+
+
+;;;;; M-j - previous-error
+
+  (global-set-key (kbd "M-j") 'previous-error)
+
+;;;;; C-M-j - register prefix
+
+  (define-key global-map (kbd "C-M-j") ctl-x-r-map)
+  (define-key ctl-x-r-map "m" 'kmacro-to-register)
+
+
+;;;;; C-k - jump-to-register
+
+
+  (global-set-key (kbd "C-k") 'jump-to-register)
+
+;;;;; M-k - next-error
+
+  (global-set-key (kbd "M-k") 'next-error)
+
+;;;;; C-M-k - man
+
+  (global-set-key (kbd "C-M-k") 'man)
+
+;;;;; C-l - ivy-switch-buffer
+
+  (global-set-key (kbd "C-l") 'ivy-switch-buffer)
+
+;;;;; C-M-l - move cursor top bottom mid, comint clear screen
+
+  (global-set-key (kbd "C-M-l") 'move-to-window-line-top-bottom)
+
+;;;;; C-; - used in flyspell, not sure what for, otherwise unbound
+;;;;; M-; - comment-dwim
+;;;;; C-M-; - comment-current-line-dwim
+
+  (defun comment-current-line-dwim ()
+    "Comment or uncomment the current line."
+    (interactive)
+    (save-excursion
+      (push-mark (beginning-of-line) t t)
+      (end-of-line)
+      (comment-dwim nil))
+    (move-beginning-of-line 2))
+  (global-set-key (kbd "C-M-;") 'comment-current-line-dwim)
+
+;;;;; C-M-m - recursive grep
+
+  (define-key global-map (kbd "C-M-m") 'rgrep)
+
+;;;;; C-, - ounsel-find-file
+
+  (global-set-key (kbd "C-,") 'counsel-find-file)
+  (add-hook 'flyspell-mode-hook
+            (lambda () (define-key flyspell-mode-map (kbd "C-,") nil)))
+
+;;;;; C-M-, - ind-file-in-project
+
+  (global-set-key (kbd "C-M-,") 'find-file-in-project)
+
+;;;;; C-. - find recent file
+;;  Taken from starter kit.
+
+  (defun recentf-ido-find-file ()
+    "Find a recent file using Ido."
+    (interactive)
+    (let* ((file-assoc-list
+            (mapcar (lambda (x)
+                      (cons (file-name-nondirectory x)
+                            x))
+                    recentf-list))
+           (filename-list
+            (remove-duplicates (mapcar #'car file-assoc-list)
+                               :test #'string=))
+           (filename (ido-completing-read "Choose recent file: "
+                                          filename-list
+                                          nil
+                                          t)))
+      (when filename
+        (find-file (cdr (assoc filename
+                               file-assoc-list))))))
+
+  (add-hook 'flyspell-mode-hook
+            (lambda () (define-key flyspell-mode-map (kbd "C-.") nil)))
+  (define-key dot-mode-map (kbd "C-.") nil)
+  (global-set-key (kbd "C-.") 'recentf-ido-find-file)
+  (add-hook 'php-mode-hook
+            (lambda () (define-key php-mode-map (kbd "C-.") nil)))
+
+;;;;; C-M-. - -
+
+  (define-key dot-mode-map (kbd "C-M-.") nil)
+  ;;  (global-set-key (kbd "C-M-.") 'execute-extended-command)
+
+;;;;; C-/ - join lines
+
+  (defun vim-style-join-line ()
+    (interactive)
+    (join-line '(4)))
+  (global-set-key (kbd "C-/") 'vim-style-join-line)
+
+;;;;; C-M-/ - copy-buffer-file-name
+
+  ;; haven't bound this atm, todo, maybe someday?
+  (defun copy-variable (variable)
+    (interactive
+     (let ((v (variable-at-point))
+          (enable-recursive-minibuffers t)
+          val)
+       (setq val (completing-read (if (symbolp v)
+                                     (format
+                                      "Describe variable (default %s): " v)
+                                   "Describe variable: ")
+                                 obarray
+                                 (lambda (vv)
+                                    (or (get vv 'variable-documentation)
+                                        (and (boundp vv) (not (keywordp vv)))))
+                                 t nil nil
+                                 (if (symbolp v) (symbol-name v))))
+       (list (if (equal val "")
+                v (intern val)))))
+    (kill-new (symbol-value variable)))
+
+  (defun copy-buffer-file-name ()
+    (interactive)
+    (let ((name (cond
+                 ((derived-mode-p 'mu4e-view-mode) (mu4e-message-field-at-point :path))
+                 (t buffer-file-name))
+                ))
+      (kill-new name)
+      (message name)))
+
+
+  (global-set-key (kbd "C-M-/") 'copy-buffer-file-name)
+
+
+
+;;;;; C-8 - calc-embedded-word
+
+  (global-set-key (kbd "C-8") 'calc-embedded-word)
+
+;;;;; C-up-arrow - org prev headline
+
+  ;; disabled just because i don't want to accidentally hit it
+  (define-key global-map "\C-_" nil)
+  (global-set-key (kbd "<C-_>") 'beginning-of-defun)
+
+  (add-hook 'org-mode-hook
+            (lambda ()
+              (define-key org-mode-map (kbd "\C-_") 'outline-previous-visible-heading)))
+
+
+
+
+;;;;; C-S-up-arrow - winner undo
+
+  (global-set-key (kbd "<C-S-_>") 'winner-undo)
+
+;;;;; C-down-arrow - org next headline
+
+  (global-set-key (kbd "<C-kp-enter>") 'end-of-defun)
+
+  (add-hook 'org-mode-hook
+            (lambda ()
+              (define-key org-mode-map (kbd "<C-kp-enter>") 'outline-next-visible-heading)))
+
+
+
+
+;;;;; C-M-down-arrow - toggle-mark-activation
+
+  (defun toggle-mark-activation ()
+    (interactive)
+    (if mark-active
+        (deactivate-mark t)
+      (activate-mark)))
+
+  (global-set-key (kbd "<C-M-kp-enter>") 'toggle-mark-activation)
+
+;;;;; C-S-down-arrow  winner redo
+
+  (global-set-key (kbd "<C-S-kp-enter>") 'winner-redo)
+
+
+;;;;; C-S-down-arrow - m-x for major mode
+
+  (global-set-key (kbd "<C-S-kp-enter>") 'smex-major-mode-commands)
+
+;;;;; C-lbracket - ----
+;;;;; C-M-lbracket - scroll-right
+
+  (global-set-key (kbd "C-M-[") 'scroll-right)
+
+;;;;; C-rbracket - fill-paragraph
+
+  (global-set-key (kbd "C-]") 'fill-paragraph)
+
+;;;;; C-M-rbracket - scroll-left
+
+  (global-set-key (kbd "C-M-]") 'scroll-left)
+
+;;;;; C-return - newline-anywhere
+
+  (defun newline-anywhere ()
+    "Add a newline from anywhere in the line."
+    (interactive)
+    (end-of-line)
+    (newline-and-indent))
+  (global-set-key (kbd "<C-return>") 'newline-anywhere)
+
+
+;;;;; M-return - plain newline
+
+  (defun plain-newline ()
+    (interactive)
+    (insert "\n"))
+  (global-set-key (kbd "<M-return>") 'plain-newline)
+
+
+;;;;; C-M-return - newline-anywhere-previous
+(defun newline-anywhere-previous ()
+  "Add a newline from anywhere in the line."
+  (interactive)
+  (forward-line -1)
+  (end-of-line)
+  (newline-and-indent))
+(global-set-key (kbd "<C-M-return>") 'newline-anywhere-previous)
+
+;;;;; C-space - org-edit-special
+
+;; commented due to new keyboard needing ctrl-space for mark
+;; (kbd "<C-space>") does not work, (kbd "C-SPC") should work
+;; (add-hook 'org-mode-hook
+;;           (lambda ()
+;;             (define-key org-mode-map (kbd "C-SPC") 'org-edit-special)
+;;             ;; org-src-mode-map is broken in git version of emacs.
+;;             ;; temporarily use this for exiting edit-special mode.
+;;             (global-set-key (kbd "C-M--") 'org-edit-src-exit)
+;;             (define-key org-src-mode-map (kbd "C-SPC") 'org-edit-src-exit)))
+
+;;;;; C-M-space - before or under cursor
+
+(global-set-key (kbd "C-M-SPC") 'ispell-word)
+;;;; left secondary
+;;;;; C-M-4 - widen
+
+(global-set-key (kbd "C-M-4") 'widen)
+
+;;;;; C-tab-key - query-replace
+
+
+(global-set-key (kbd "<C-kp-add>") 'query-replace)
+
+;;;;; C-t - org cycle todo / toggle comint motion
+
+(add-hook 'org-mode-hook
+          (lambda ()
+            (define-key org-mode-map (kbd "C-t") 'org-todo)))
+
+(defun my-comint-previous-input (arg)
+  (interactive "*p")
+  (if (comint-after-pmark-p)
+      (comint-previous-input arg)
+    (forward-line -1)))
+
+(defun my-comint-next-input (arg)
+  (interactive "*p")
+  (if (comint-after-pmark-p)
+      (comint-next-input arg)
+    (forward-line)))
+
+(add-hook 'comint-mode-hook
+          (lambda ()
+            (define-key comint-mode-map (kbd "C-t") 'comint-toggle-arrow-keys)
+            (define-key comint-mode-map (kbd "<up>") 'my-comint-previous-input)
+            (define-key comint-mode-map (kbd "<down>") 'my-comint-next-input)))
+
+
+(defun comint-toggle-arrow-keys ()
+  (interactive)
+  (toggle-arrow-keys comint-mode-map))
+
+(setq-default comint-arrow-movement nil)
+(defun toggle-arrow-keys (map)
+  (cond ((lookup-key map (kbd "<up>"))
+         (setq-local comint-arrow-movement t)
+         (define-key map (kbd "<up>") nil)
+         (define-key map (kbd "<down>") nil))
+        (t
+         (setq-local comint-arrow-movement nil)
+         (define-key map (kbd "<up>") 'my-comint-previous-input)
+         (define-key map (kbd "<down>") 'my-comint-next-input)
+         (goto-char (point-max)))))
+
+(eval-after-load "message"
+  '(define-key message-mode-map (kbd "C-t") 'mail-signature))
+
+
+;;;;; C-M-t - org timestamp
+
+(global-set-key (kbd "C-M-t") 'org-time-stamp-with-time)
+
+;;;;; C-home - start of buffer
+;;;;; C-end - end of buffer
+;;;; right secondary
+;;;;; C-6 - save-buffers-kill-emacs
+
+(global-set-key (kbd "C-6") 'save-buffers-kill-emacs)
+
+;;;;; C-M-6 - insert-small-copyright
+
+(defun insert-small-copyright ()
+  (interactive)
+  (beginning-of-line)
+  (let ((beg (point)))
+    (insert "Copyright (C) 2017 Ian Kelling\nThis program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>")
+    (comment-region beg (point))))
+
+(global-set-key (kbd "C-M-6") 'insert-small-copyright)
+
+;;;;; C-M-7 - insert-full-copyright
+
+(defun insert-full-copyright ()
+  (interactive)
+  (beginning-of-line)
+  (let ((beg (point)))
+    (insert "Copyright (C) 2017 Ian Kelling\n")
+    (insert "\n")
+    (insert "This program is free software: you can redistribute it and/or modify\n")
+    (insert "it under the terms of the GNU General Public License as published by\n")
+    (insert "the Free Software Foundation, either version 3 of the License, or\n")
+    (insert "(at your option) any later version.\n")
+    (insert "\n")
+    (insert "This program is distributed in the hope that it will be useful,\n")
+    (insert "but WITHOUT ANY WARRANTY; without even the implied warranty of\n")
+    (insert "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n")
+    (insert "GNU General Public License for more details.\n")
+    (insert "\n")
+    (insert "You should have received a copy of the GNU General Public License\n")
+    (insert "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n")
+    (comment-region beg (point))))
+
+(global-set-key (kbd "C-M-7") 'insert-full-copyright)
+
+
+;;;;; C-0 - text-scale-reset
+
+(defun text-scale-reset ()
+  (interactive)
+  (text-scale-set 0))
+(global-set-key (kbd "C-0") 'text-scale-reset)
+
+;;;;; C-M-0 - insert-apache
+
+(defun insert-apache ()
+  (interactive)
+  (beginning-of-line)
+  (let ((beg (point)))
+    (insert "Copyright (C) 2017 Ian Kelling\n")
+    (insert "\n")
+    (insert "Licensed under the Apache License, Version 2.0 (the \"License\");\n")
+    (insert "you may not use this file except in compliance with the License.\n")
+    (insert "You may obtain a copy of the License at\n")
+    (insert "\n")
+    (insert "    http://www.apache.org/licenses/LICENSE-2.0\n")
+    (insert "\n")
+    (insert "Unless required by applicable law or agreed to in writing, software\n")
+    (insert "distributed under the License is distributed on an \"AS IS\" BASIS,\n")
+    (insert "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n")
+    (insert "See the License for the specific language governing permissions and\n")
+    (insert "limitations under the License.\n")
+    (comment-region beg (point))))
+(global-set-key (kbd "C-M-0") 'insert-apache)
+
+
+;;;;; C-M-- - org-edit-src-exit
+;;;;; C-y - undo
+
+(global-set-key (kbd "C-y") 'undo)
+(add-hook 'org-mode-hook
+          (lambda () (define-key org-mode-map (kbd "C-y") nil)))
+
+
+;;;;; C-\ - sr-speedbar-toggle
+(global-set-key (kbd "C-\\") 'sr-speedbar-toggle)
+
+;;;;; C-M-\ - mark-defun
+
+(global-set-key (kbd "C-M-\\") 'mark-defun)
+
+;;;;; C-h - help-prefix
+
+;;;;; C-' - val-expression
+
+(global-set-key (kbd "C-'") 'eval-expression)
+
+;;;;; C-n - unpop to mark
+
+(defun unpop-to-mark-command ()
+  "Unpop off mark ring. Does nothing if mark ring is empty."
+  (interactive)
+  (when mark-ring
+    (let ((pos (marker-position (car (last mark-ring)))))
+      (if (not (= (point) pos))
+          (goto-char pos)
+        (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
+        (set-marker (mark-marker) pos)
+        (setq mark-ring (nbutlast mark-ring))
+        (goto-char (marker-position (car (last mark-ring))))))))
+
+(global-set-key (kbd "C-n") 'unpop-to-mark-command)
+
+;;;;; C-M-n - narrow-to-region
 
-             (load-file (expand-file-name "myinit.el" init-dir))
+(global-set-key (kbd "C-M-n") 'narrow-to-region)
 
-             ))
+;;;;; C-escape - find-tag
 
-;;init.el ends here
+(global-set-key (kbd "<C-escape>") 'find-tag)
diff --git a/myinit.el b/myinit.el
deleted file mode 100644 (file)
index 5c5d102..0000000
--- a/myinit.el
+++ /dev/null
@@ -1,3568 +0,0 @@
-;;; copyright
-
-;; Copyright (C) 2019 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
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Weird package bug workaround
-
-
-;; without this, when installing a package, this message happens
-;;
-;; custom-handle-keyword: Unknown keyword :group
-;;
-;; but when i lookup the function, i get the following, and if
-;; I evaluate it, the error goes away. so I think the real
-;; definition is happening somewhere else
-
-(defun custom-handle-keyword (symbol keyword value type)
-  "For customization option SYMBOL, handle KEYWORD with VALUE.
-Fourth argument TYPE is the custom option type."
-  (if purify-flag
-      (setq value (purecopy value)))
-  (cond ((eq keyword :group)
-        (custom-add-to-group value symbol type))
-       ((eq keyword :version)
-        (custom-add-version symbol value))
-       ((eq keyword :package-version)
-        (custom-add-package-version symbol value))
-       ((eq keyword :link)
-        (custom-add-link symbol value))
-       ((eq keyword :load)
-        (custom-add-load symbol value))
-       ((eq keyword :tag)
-        (put symbol 'custom-tag value))
-       ((eq keyword :set-after)
-        (custom-add-dependencies symbol value))
-       (t
-        (error "Unknown keyword %s" keyword))))
-
-
-;;; misc emacs documentation
-
-;;;; how to find auto-saved files that need recovering
-;; find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it.
-;; #file# is an auto-save file. It may or may not be different than the file is corresponds to.
-;; If it is different, emacs will give a message about recovering it when you open it.
-
-;;;; misc org functions
-
-;; ;; these are usefull with (goto-char)
-;; ;; find named entity, other than headline
-;; (org-find-entry-with-id "string-number-or-symbol")
-
-;; (org-find-exact-headline-in-buffer "heading" nil t)
-
-;; ;; remove any indent level which is throughout the buffer
-;; (org-do-remove-indentation)
-
-
-;;;; gnus
-
-;; good info http://www.emacswiki.org/emacs/GnusTutorial
-;; good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm
-
-
-;; After downloading mailing list archives, once you have an mbox file,
-;; there are rather straightforward ways to get it into any mail program,
-;; but I will cover gnus, which I use and is a bit tricky.
-
-;; gnus has a native search (limited, too slow for body text searches), and external search engine integration.
-;; gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus
-;; takes 10+ minutes, so scratch that option. it suggests 2 alternate options
-;; mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox
-;; and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise
-;; works great.
-
-;; local imap server which will use the mbox and provide search.
-;; dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its
-;; description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the
-;; module we need.
-;; pi dovecot-imapd
-
-;; dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/<username>
-;; those locations are adjustable and well documented via the var mail_location in
-;; /etc/dovecot/conf.d/10-mail.conf
-;; I forward my local mail, didn't see immediately how to turn off the inbox, but it will always be empty, so I left as
-;; is. you could make the var be empty, which apparently has the same effect.
-
-;; Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems
-;; other things like postfix use that location
-
-;; based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html
-;; other links that poped up contained outdated, innacurate information
-;; http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/
-;; http://www.emacswiki.org/emacs/JamesFerguson
-;; http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/
-
-;; Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility.
-
-
-
-;; doc group for mbox:
-;; in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file
-
-;; info about groups created within gnus is stored in ~/.newsrc.eld
-;; also stored is a duplication of what email messages are read/unread,
-;; what newsgroups are subsribed to and read/unread,
-;; probably more stuff, everything that gnus saves.
-
-
-;; searching the body of the messages, i cut off after a few minutes.
-;; i can grep the file in just a couple seconds
-
-
-;; random side note
-;; we can also get mbox from gmane
-;; http://notmuchmail.org/howto/#index7h2
-
-
-;; gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command
-;; line, but not from within gnus, but from mairix.el, which can then open the results in gnus
-
-;; mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the
-;; headers and generates a nov file for each.
-
-;; nnfolder-generate-active-file
-
-;; to reset things, when changing mail group. I duno all the proper way, but it works to delete
-;; ~/Mail ~/.newsrc.eld ~/.dribble (or something)
-
-
-;;;;; mail sources vs select methods background
-;; I found this very confusing when first reading through the manual.  "mail sources" is a term that does not simply mean
-;; sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail
-;; sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use
-;; "mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their
-;; location, but use them in their native format. This is what I want to do, and I can simply ignore mail
-;; sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it
-;; means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail.
-
-
-
-;;;;; caching background
-
-;; caching:
-;; there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why.
-;; Grepped for caching in the manual, found 2 main things.
-;; cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence
-;; gnus-use-cache, which puts things if they are
-;; gnus-cache-enter-articles
-;; things go in cache when they are marked certain ways by default, ticked and dormant
-;; and read articles are moved out of the cache
-;; still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached
-;; I'm gonna delete the cache, and check on it later see what exactly is going in there
-;; And of course, I moved ~/News to my encrypted drive and symlinked it
-
-
-
-;;; things that should be at the beginning
-;; todo, evaluating this manually disables debug on error instead of toggling it
-(toggle-debug-on-error) ;uncomment to help debug and catch errors
-
-;; packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade.
-
-;; package-activated-list:
-;; ac-dabbrev ac-haskell-process ack-and-a-half alect-themes auctex bash-completion bbdb csv-mode cyberpunk-theme dot-mode expand-region f find-file-in-project flycheck foreign-regexp ggtags ghc gnuplot-mode goto-chg haskell-mode heroku-theme highlight-indentation highlight-symbol htmlize inf-ruby info+ inkpot-theme jedi auto-complete jedi-core epc ctable concurrent key-chord leuven-theme logstash-conf magit git-commit magit-popup misc-fns mouse+ naquadah-theme nginx-mode occidental-theme org paredit pcsv php-mode pkg-info epl popup py-autopep8 python-environment deferred python-info python-mode rainbow-mode rust-mode rw-hunspell s smartparens smex smooth-scroll sr-speedbar strings swiper ivy tabulated-list tangotango-theme thingatpt+ undo-tree vimrc-mode volatile-highlights web-mode with-editor dash async ws-butler yasnippet
-
-;;;; alternate keyboards
-;; todo, figure out an easy way to disable this when using external keyboard
-(if (display-graphic-p)
-    (setq
-     enter-key (kbd "<return>")
-     s-enter-key (kbd "<S-return>")
-     c-m-enter-key (kbd "<C-M-return>")
-     m-enter (kbd "<M-return>")
-     c-enter (kbd "<C-return>"))
-  (setq
-   enter-key (kbd "C-m")
-   s-enter-key (kbd "C-8")
-   c-m-enter-key (kbd "C-M-8")
-   m-enter (kbd "M-m")
-   c-enter (kbd "C-8")))
-
-(setq tp (string= (system-name) "tp"))
-(setq x200 (string= (system-name) "x2"))
-(setq laptop-keyboard (or tp x200))
-
-;; Ubiquitous Packages which should be loaded on startup rather than
-;;   autoloaded on demand since they are likely to be used in every
-;;   session.
-(require 'saveplace)
-(require 'ffap)
-(require 'uniquify)
-(require 'ansi-color)
-(require 'recentf)
-
-;; Better to have a list of packages in here vs installed manually.
-;;   However, I install manually because sometimes there are two
-;;   versions and it is not necessarily easy to reconcile that.
-;; based on marmalage website front page.
-(require 'package)
-
-;; little kit to help remove a down server
-;; (setq package-archives nil)
-
-;;(add-to-list 'package-archives
-;;             '("marmalade" .
-;;               "http://marmalade-repo.org/packages/"))
-
-(add-to-list 'package-archives
-             '("melpa" . "http://melpa.milkbox.net/packages/") t)
-(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
-
-
-;; 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)
-
-
-
-;;; abreviations
-;; turn on abbrev mode globally
-(setq-default abbrev-mode t)
-
-;; default abbreviation mode file is .emacs.d/abbrev_defs.
-;; add-global-abbrev, add-mode-abbrev for expansion at point
-;; if all else fails, edit the abbrev file
-
-
-
-
-;;; auto-complete
-
-;; auto-completion in minibuffer
-;; disabled while I look for another alternative
-;;(icomplete-mode)
-
-(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)
-
-(add-to-list 'ac-modes 'org-mode 'sql-mode)
-
-(defun ac-common-setup ()
-  (add-to-list 'ac-sources 'ac-source-yasnippet))
-
-;; for org mode completion source taken from wiki.
-;; it did not work. no idea why. todo, investigate
-;; the ac-sources code is at http://www.emacswiki.org/emacs/AutoCompleteSources
-;; i've deleted it here so as to save space and not spam this file
-;;(defun my-ac-org-mode ()
-;;  (setq ac-sources (append ac-sources '(ac-source-org))))
-
-
-;; this makes the org-self-insert command not do a flyspell spell check.
-;; low priority thing to look into sometime
-(ac-flyspell-workaround)
-
-
-(define-key ac-completing-map (kbd "<up>") nil)
-(define-key ac-completing-map (kbd "<down>") nil)
-(define-key ac-completing-map (kbd "<S-return>") 'ac-expand)
-(define-key ac-completing-map "\t" 'ac-complete)
-(define-key ac-completing-map (kbd "<tab>") 'ac-complete)
-
-
-
-;;; auto-complete readline-complete
-
-(require 'readline-complete)
-;; not sure how I made these, but I deleted, and
-;; it would be nice to make them again sometime
-;;(require 'src-loaddefs)
-
-;; disabled cuz broken
-;; redefining function in readline-complete so ac-complete only uses readline as a source
-(defun ac-rlc-setup-sources ()
-  "Add me to shell-mode-hook!"
-  (setq ac-sources '(ac-source-shell)))
-(add-hook 'shell-mode-hook 'ac-rlc-setup-sources)
-
-;; generally unnecessary, but why not
-(setq explicit-shell-file-name "bash")
-
-;; readline-complete says to add this line.
-;; however, it  up my procfs directory tracking hook
-;; because get-process doesn't notice the child shell.
-;; instead, I've removed export EMACS=t from
-;;  comint-exec-1 (the function which initially sets it)
-;; by finding it in emacs sources and redefinind it here
-;; and done stty echo in my bashrc
-;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash"))
-
-(setenv "EMACS" "")
-(setq explicit-bash-args nil)
-(setq comint-process-echoes t)
-;; default of 30 is way too slow. todo, consider pushing this upstream
-(setq rlc-attempts 5)
-
-(add-to-list 'ac-modes 'shell-mode)
-
-;; readline-complete recommends this (i assume this format),
-;; but greping finds no reference in emacs or my .emacs.d
-;; so I'm assuming it is for an older emacs
-;;(setq explicit-ssh-args '("-t"))
-
-(add-hook 'shell-mode-hook
-          (lambda ()
-            (define-key shell-mode-map (kbd "<tab>") 'auto-complete)))
-
-
-;;; readline complete fix
-
-;; I need this function here, where INSIDE_EMACS is replaced with RLC_INSIDE_EMACS.
-;; ian: last update 2017-1-7. update this periodically from upstream
-;; like when we do a major emacs update
-(defun comint-exec-1 (name buffer command switches)
-  (let ((process-environment
-        (nconc
-         ;; If using termcap, we specify `emacs' as the terminal type
-         ;; because that lets us specify a width.
-         ;; If using terminfo, we specify `dumb' because that is
-         ;; a defined terminal type.  `emacs' is not a defined terminal type
-         ;; and there is no way for us to define it here.
-         ;; Some programs that use terminfo get very confused
-         ;; if TERM is not a valid terminal type.
-         ;; ;; There is similar code in compile.el.
-         (if (and (boundp 'system-uses-terminfo) system-uses-terminfo)
-             (list "TERM=dumb" "TERMCAP="
-                   (format "COLUMNS=%d" (window-width)))
-           (list "TERM=emacs"
-                 (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))
-         (list (format "RLC_INSIDE_EMACS=%s,comint" emacs-version))
-         process-environment))
-       (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
-                        ;; first look relative to the current directory.
-                        (cons default-directory exec-path) exec-path)))
-      (setq proc (apply 'start-file-process name buffer command switches)))
-    ;; Some file name handler cannot start a process, fe ange-ftp.
-    (unless (processp proc) (error "No process started"))
-    (let ((coding-systems (process-coding-system proc)))
-      (setq decoding (car coding-systems)
-           encoding (cdr coding-systems)))
-    ;; Even if start-file-process left the coding system for encoding data
-    ;; sent from the process undecided, we had better use the same one
-    ;; as what we use for decoding.  But, we should suppress EOL
-    ;; conversion.
-    (if (and decoding (not encoding))
-       (setq encoding (coding-system-change-eol-conversion decoding 'unix)
-             changed t))
-    (if changed
-       (set-process-coding-system proc decoding encoding))
-    proc))
-
-;;; auto save & backup
-(setq auto-save-timeout 1) ; idle time before auto-save.
-
-;; main hook for my auto save
-(add-hook 'auto-save-hook 'my-auto-save)
-;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active
-(add-hook 'window-configuration-change-hook 'my-auto-save-win)
-
-;; this function from mu4e really does not like buffer saving
-(advice-add 'message-send-and-exit :before 'my-as-off)
-(advice-add 'message-send-and-exit :after 'my-as-on)
-
-;; avoid window config hook saving too much, it can
-;; get into loops in some random situations
-(setq 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-auto-save (&optional last)
-  (when (and
-         my-as
-         (buffer-file-name)
-         ;; mu4e has a bug right now, undo breaks when saving drafts
-         (not (string= (buffer-file-name) "*draft*"))
-         (buffer-modified-p)
-         (not (org-src-edit-buffer-p)))
-    ;; serial is incremented on each save, so let's do a bit less of them
-    (not (derived-mode-p 'dns-mode))
-    (setq my-auto-save-last last)
-    (let (message-log-max)
-      ;; a bit of a hack to partially suppress the constant saving in the echo area
-      (with-temp-message ""
-        (basic-save-buffer)))))
-
-;; in the message-send-and-exit advice, got an error because it passed an arg.
-;; didn't look into why, just add ignored args.
-(defun my-as-off (&rest ignore)
-  (interactive)
-  (setq my-as nil))
-
-(defun my-as-off-local (&rest ignore)
-  (interactive)
-  (setq-local my-as nil))
-
-(defun my-as-on (&rest ignore)
-  (interactive)
-  (setq my-as t))
-
-(defun my-as-on-local (&rest ignore)
-  (interactive)
-  (setq-local my-as on))
-
-;; based on suggestion in the emacs docs, redefine these 2 functions
-;; to avoid prompt spamming the user when we do auto-save
-(defun ask-user-about-supersession-threat (fn)
-  (discard-input)
-  (message
-   "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however
-a backup is being created in case that is not what you intended." buffer-file-name)
-  (setq buffer-backed-up nil))
-
-(defadvice ask-user-about-lock (before lock-deactivate-as activate)
-  (make-local-variable 'my-as)
-  (setq my-as nil)
-  (message "proper autosave has been turned off for this buffer because of lock file problem.
-  In this buffer, do M-x my-as-on to reenable"))
-
-;; todo, this doesn't work consistently to override the auto-save message
-(defalias 'do-auto-save-original (symbol-function 'do-auto-save))
-(defun do-auto-save (&optional no-message current-only)
-  "This function has been modified to wrap the original so that NO-MESSAGE
-is  always set to t, since we auto-save a lot, it spams otherwise.
-The original doc string is as follows:
-
-Auto-save all buffers that need it.
-This is all buffers that have auto-saving enabled
-and are changed since last auto-saved.
-Auto-saving writes the buffer into a file
-so that your editing is not lost if the system crashes.
-This file is not the file you visited; that changes only when you save.
-Normally we run the normal hook `auto-save-hook' before saving.
-
-
-A non-nil NO-MESSAGE argument means do not print any message if successful.
-A non-nil CURRENT-ONLY argument means save only current buffer."
-  (interactive)
-  (do-auto-save-original t current-only))
-
-;; enable MY auto-save
-(my-as-on)
-
-;;; backups, separate from auto-save
-
-
-;; set backup file location
-(setq backup-directory-alist '(("." . "~/.editor-backups")))
-(setq auto-save-file-name-transforms
-      '((".*" "~/.editor-backups/" t)))
-
-(setq version-control t ;; Use version numbers for backups
-      kept-new-versions 100
-      kept-old-versions 2
-      delete-old-versions t ;; delete old versions silently
-      ;; assume hard linked files are done on purpose, don't screw them up
-      backup-by-copying-when-linked t)
-
-;; 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)))))
-    (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)))))
-
-;; make a backup on auto-save, because the backup feature is not
-;; utilized with my-auto-save, only normal interactive save.
-;; todo, enable when fixed
-;;(add-hook 'before-save-hook 'constant-backup)
-
-(add-hook 'auto-save-hook 'auto-save-size-limit)
-
-(defun auto-save-size-limit ()
-  (when (and (not backup-inhibited) (> (buffer-size) 2000000))
-    (message "Backups disabled for this buffer due to size > 2 megs")
-    (make-local-variable 'backup-inhibited)
-    (setq backup-inhibited t)))
-
-
-;; ;; background:
-;; ;;      the faq suggests to auto-save using
-;; (setq auto-save-visited-file-name t)
-;;         and to toggle auto-saving in the current buffer, type `M-x auto-save-mode'
-
-;;         however, this is  buggy.
-;;         it leaves around lock files, which can be disabled with
-;;         (setq create-lockfiles nil)
-;;         but it is also buggy on other things that appear to hook onto file saving
-;;         so i created my own function, which originally had bugs,
-;;         but new emacs version fixed all that, yay!.
-
-
-                                        ; not using, but here for documentation,
-                                        ; alternate way to enable and specify how long between autosaves.
-                                        ; number of input events between autosave.
-                                        ; lowest bound of functionality is actually about 15 input events
-                                        ;(setq auto-save-interval
-
-;;; bbdb
-;; based on bbdb manual
-;; also has instructions to integrate with gnus,
-
-(bbdb-initialize 'message)
-
-;; recommended by gnus,
-;; but seems like it could be good to have set for other stuff
-(setq user-full-name "Ian Kelling")
-;; general email setting? recommended by mu4e
-(setq message-kill-buffer-on-exit t)
-
-
-
-;; use d instead
-(add-hook 'bbdb-mode-hook
-          (lambda () (define-key bbdb-mode-map (kbd "C-k") nil))
-          ;; based on emacs24-starter-kit
-          (setq bbdb-offer-save 'auto
-                bbdb-notice-auto-save-file t
-                bbdb-expand-mail-aliases t
-                bbdb-canonicalize-redundant-nets-p t
-                bbdb-complete-name-allow-cycling t)
-          )
-
-;;(require 'bbdb-csv-import)
-
-;;; bookmark settings
-                                        ; save bookmarks whenever they are changed instead of just when emacs quits
-(setq bookmark-save-flag 1)
-                                        ; increase bookmark context size for better functionality
-(setq bookmark-search-size 2000)
-
-;;; 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
-;; a list of pre-built themes at http://elpa.gnu.org/themes/view.html and
-;; themes are available through ELPA.
-
-
-;; interesting light themes
-
-
-(defun override-theme (arg)
-  (interactive)
-  (while custom-enabled-themes
-    (disable-theme (car custom-enabled-themes)))
-  (load-theme arg t))
-(setq color-theme-is-global t)
-
-(defun toggle-night ()
-  (interactive)
-  (cond  ((equal (car custom-enabled-themes) 'naquadah)
-          (override-theme 'leuven))
-         (t
-          (override-theme 'naquadah))))
-
-
-;; 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)
-
-
-;; disable color thing with this:
-;;(disable-theme (car custom-enabled-themes))
-
-;; decent dark themes
-
-;;(override-theme 'tangotango)
-;;(override-theme 'deeper-blue)
-;;(override-theme 'tango-dark)
-;;(override-theme 'tsdh-dark)
-
-;;(override-theme 'heroku)
-;;(override-theme 'inkpot)  ;; part of inkpot-theme package
-;;(override-theme 'naquadah) ; org mode features, part of  naquadah-theme package
-;;(override-theme 'spolsky) ;; part of sublime-themes package
-;;(override-theme 'twilight-anti-bright)  ;; from twilight-anti-bright-theme package
-
-;; interesting but not usable colors
-;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package
-;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which
-;;(override-theme 'misterioso) ; cursor not visible enough
-
-
-
-;;decent light themes
-;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package
-;;(override-theme 'occidental) ; from occidental-theme package
-
-
-;;color-theme is deprecated in emacs 24.
-
-;; theme packages i tried then removed:
-;; ignored ones that didn't use the new theme engine
-
-;;66 packages (zenburn-theme-2.1, zen-and-art-theme-1.0.1, waher-theme-20130917.7, ujelly-theme-1.0.35, twilight-theme-1.0.0, twilight-bright-theme-20130605.143, twilight-anti-bright-theme-20120713.316, tronesque-theme-1.3, tron-theme-12, toxi-theme-0.1.0, tommyh-theme-1.2, tango-2-theme-1.0.0, sunny-day-theme-20131203.1250, sublime-themes-20140117.323, subatomic-theme-20131011.1048, soothe-theme-0.3.16, soft-morning-theme-20131211.1342, soft-charcoal-theme-20130924.1206, sea-before-storm-theme-0.3, purple-haze-theme-20130929.1751, phoenix-dark-pink-theme-20130905.941, phoenix-dark-mono-theme-20130306.1215, pastels-on-dark-theme-0.3, obsidian-theme-20130920.937, nzenburn-theme-20130513, noctilux-theme-20131019.31, mustang-theme-20130920.939, monokai-theme-0.0.10, molokai-theme-20130828.0, late-night-theme-0.0, jujube-theme-0.1, ir-black-theme-20130302.2355, gruvbox-theme-20131229.1458, gruber-darker-theme-0.6, grandshell-theme-20140118.1003, github-theme-0.0.3, gandalf-theme-0.1, flatland-theme-20131204.858, django-theme-20131022.202, deep-thought-theme-0.1.1, dakrone-theme-20131212.1159, colorsarenice-theme-20131128.1106, color-theme-wombat+-0.0.2, color-theme-wombat-0.0.1, color-theme-twilight-0.1, color-theme-tango-0.0.2, color-theme-solarized-20120301, color-theme-sanityinc-solarized-2.25, color-theme-railscasts-0.0.2, color-theme-monokai-0.0.5, color-theme-molokai-0.1, color-theme-ir-black-1.0.1, color-theme-heroku-1.0.0, color-theme-github-0.0.3, color-theme-eclipse-0.0.2, color-theme-dpaste-0.0.1, color-theme-dawn-night-1.0, color-theme-colorful-obsolescence-0.0.1, color-theme-cobalt-0.0.2, color-theme-20080305.34, clues-theme-20130908.801, busybee-theme-20130920.942, bubbleberry-theme-0.1.2, mblage-theme-20130715.621, anti-zenburn-theme-20140104.1542, ample-zen-theme-0.2)
-
-
-
-
-;;; yasnippet
-
-;; cd ~/.emacs.d/src
-;; git clone --recursive https://github.com/capitaomorte/yasnippet
-;; touch snippets/.yas-make-groups
-
-;;   This all makes it so I can look through the default snippets
-;;   in the menu bar, but they don't show up elsewhere, because they are
-;;   mostly things I don't want.
-
-
-(require 'yasnippet)
-;; this needs to be before yas-global-mode
-(setq yas-snippet-dirs (list "~/.emacs.d/snippets"))
-(yas-global-mode 1)
-
-(setq
- yas-also-auto-indent-first-line t
- yas-choose-tables-first t
- yas-use-menu (quote full)
- ;; this sets ido-prompt as first function
- yas-prompt-functions
- '(yas-ido-prompt yas-dropdown-prompt yas-x-prompt yas-completing-prompt yas-no-prompt))
-
-;; todo, explore this option for wrapping region
-;; '(yas/wrap-around-region t))
-
-;;; cross session settings
-
-;; Save a list of recent files visited.
-(recentf-mode 1)
-(setq recentf-max-saved-items 200
-      recentf-max-menu-items 15)
-
-
-(setq save-place t
-      save-place-version-control 'nospecial
-      save-place-limit 40000
-      save-place-file "~/.emacs.d/places")
-
-
-
-;; savehist keeps track of some history
-;; search entries
-(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-mode 1)
-
-
-;;; ediff
-;; ediff-buffers is the main command to use
-
-;; ediff - 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
-(setq ediff-window-setup-function 'ediff-setup-windows-plain)
-;;(setq ediff-window-setup-function 'ediff-setup-windows-default)
-
-;; do side by side diffs
-(setq ediff-split-window-function 'split-window-horizontally)
-
-
-
-;; 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.
-
-;;; dired
-
-;; 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)
-
-(setq
- ;; 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
- mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields)
- ;; 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
- )
-
-;; 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.
-(load "/p/c/mu4e.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 mu-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-mail-address (cdr found)
-                        user-full-name (car found)))
-      found)))
-(defun mu-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)
-              regexes (cdr 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 my-mu4e-to-fsf ()
-  "inspired by mu4e info manual, search for mu4e-compose-pre-hook."
-  (cond
-   ((mu-set-from '("iank@fsf.org"
-                   "iank@gnu.org")))
-   ((setq user-mail-address "iank@fsf.org"
-          user-full-name "Ian Kelling"))))
-
-
-;; on first run   mkdir -p /nocow/user/.mufsf; mu index --maildir=/nocow/user/fsfmd
-(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)
-  (unless (equal mu4e-maildir "/nocow/user/fsfmd") (mu-exit-wait))
-  (setq
-   ;; fsf monitor is smaller
-   mu4e-headers-visible-lines 15
-   mu4e-maildir "/nocow/user/fsfmd"
-   mu4e-refile-folder "/Spam"
-   mu4e-index-lazy-check nil
-   mu4e-get-mail-command "true"
-   user-mail-address "iank@fsf.org"
-   ;; 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 "
-
--- 
-Ian Kelling | Senior Systems Administrator, Free Software Foundation
-GPG Key: B125 F60B 7B28 7FF6 A2B7  DF8F 170A F0E2 9542 95DF
-https://fsf.org | https://gnu.org
-"
-
-   mu4e-user-mail-address-list '("iank@fsf.org"
-                                 "iank@gnu.org")
-   mu4e-maildir-shortcuts
-   '( ("/INBOX"     . ?i)
-      ("/sysadmin" . ?a)
-      ("/sec"  . ?x)
-      ("/rtcc"  . ?c)
-      ("/Drafts"     . ?d)
-      ("/Sent"     . ?s)
-      )
-   ) ;; end setq
-  (call-process "/a/exe/lnf" nil nil nil "-T" "/nocow/user/.mufsf" (concat (getenv "HOME") "/.mu"))
-  (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to-fsf)
-  (remove-hook 'mu4e-compose-pre-hook 'my-mu4e-to)
-  (mu4e)) ;; end defun fsf-mu4e
-
-
-;; 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)
-
-;; 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))
-      )
-
-
-(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)))))
-
-(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)
-
-
-;;; elisp settings
-                                        ; when manually evaluating lisp, go into debugger on error
-(setq eval-expression-debug-on-error t)
-                                        ;reminder of useful var: debug-on-error
-
-
-;;; haskell
-
-;; useful comint-shell mode commands. If not prefaced with *, it means it is not in the haskell custom repl
-;; *todo: setup haskell c-t toggle arrow keys
-;; tab completion
-;; C-q insert prev arg
-;; C-( history search
-;; c-m-left/right move to next/prev prompts
-;; *c-enter, multi-line input
-;; *s-delete, send input across windows. (i can implement this)
-;; *c-m-l clear screen
-;; *haskell-process-interrupt, c-cc terminate job (i can implement this maybe)
-
-;; nice bash/readline functions missing in comint:
-;; yank-nth-arg
-;; operate-get-next
-;; menu-complete
-
-;; usefull comint commands:
-;; c-cl : list historic command in temp buffer
-;; C-c C-o comint-delete-output
-;; comint-restore-input, todo: put this on a randomish c-c key
-
-
-
-;; todo:
-;; checkout haskell repl functions:
-;; c-cv haskell-check, hlint
-;; C-M-q           prog-indent-sexp
-;; c-c.  haskell-mode-format-imports
-;; C-c M-/         haskell-doc-check-active
-;; haskell-process-generate-tags
-;; haskell-process-cabal-build
-;; haskell-cabal-command.. or something
-;; haskell-process-restart
-;; C-h v haskell-process-log
-;; C-h v haskell-process-show-debug-tips
-
-;; various not immediately useful functions:
-;; haskell-process-add-dependency
-;; haskell-process-touch-buffer
-;; haskell-process-cd
-;; haskell-process-unignore
-;; haskell-process-reload-devel-main
-
-
-;; rebind
-;; home: C-a             haskell-interactive-mode-beginning
-;; c-return: C-j             haskell-interactive-mode-newline-indent
-;; up/down: <C-down>        haskell-interactive-mode-history-next
-
-;; todo haskell mode better binds for:
-;; 'haskell-process-load-file
-;; 'haskell-process-do-type
-;; 'haskell-process-do-info
-;; 'inferior-haskell-send-decl
-
-
-;; commands which don't work in haskell-interactive-mode(hi) vs inferior-haskell-mode(ih, default)
-;; functions not in hi:
-;; inferior-haskell-find-definition, use tags instead
-;; inferior-haskell-find-haddock, todo, test if this works
-
-;; redefined ih to hi
-;; switch-to-haskell -> 'haskell-interactive-switch
-;; haskell-process-load-file -> inferior-haskell-load-file
-;; haskell-process-do-type -> inferior-haskell-type
-;; switch-to-haskell -> haskell-interactive-switch
-;; inferior-haskell-load-file -> 'haskell-process-load-file
-
-
-;; haskell-mode installation from source, based on its readme
-;; in the git directory,
-;; make all
-
-
-
-
-;; remove default option to not link the file
-(setq haskell-compile-command "ghc -Wall -ferror-spans -fforce-recomp %s")
-(add-hook 'haskell-indentation-mode-hook
-          (lambda ()
-            (define-key haskell-indentation-mode-map [?\C-d] nil)
-            (define-key haskell-indentation-mode-map
-              (kbd "<deletechar>")
-              'haskell-indentation-delete-char)))
-
-;;copied from haskell-mode docs in order to use the new, better, nondefault
-;;interactive mode.
-(eval-after-load "haskell-mode"
-  '(progn
-     (define-key haskell-mode-map (kbd "C-x C-d") nil)
-     (define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch)
-     (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file)
-     (define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch)
-     (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type)
-     (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info)
-     (define-key haskell-mode-map (kbd "C-c M-.") nil)
-     (define-key haskell-mode-map (kbd "C-c C-d") nil)))
-
-;; ghc-mod install http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html
-;; todo, try this out
-;; (autoload 'ghc-init "ghc" nil t)
-;;(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode)))
-
-
-
-;; from the package readme for ghci-completion
-(require 'ghci-completion)
-(add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion)
-
-
-;; disable some rebinds. they are set to appropriate keys in the keybinds section
-(eval-after-load "haskell-mode"
-  '(progn
-     (define-key haskell-mode-map (kbd "C-a") 'nil)
-     (define-key haskell-mode-map (kbd "C-j") 'nil)))
-
-(eval-after-load "python-mode"
-  '(progn
-     (define-key python-mode-map (kbd "C-j") nil)))
-
-(defun pretty-lambdas-haskell ()
-  (font-lock-add-keywords
-   nil `((,(concat "(?\\(" (regexp-quote "\\") "\\)")
-          (0 (progn (compose-region (match-beginning 1) (match-end 1)
-                                    ,(make-char 'greek-iso8859-7 107))
-                    nil))))))
-;; from haskell-mode manual
-(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
-(when (window-system)
-  (add-hook 'haskell-mode-hook 'pretty-lambdas-haskell))
-
-;; added from haskell-mode website install instructions
-                                        ;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file")
-(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
-;;the three indentation modules are mutually exclusive - add at most one. Trying out the "most advanced"
-(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
-;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
-;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
-
-
-;; todo, set this to some other key
-;;    (local-set-key (kbd "C-e") 'my-haskell-load-and-run)
-
-(defun my-haskell-load-and-run ()
-  "Loads and runs the current Haskell file."
-  (interactive)
-  (let ((start-buffer (current-buffer)))
-    (inferior-haskell-load-and-run inferior-haskell-run-command)
-    (sleep-for 0 100)
-    (end-of-buffer)
-    (pop-to-buffer start-buffer)))
-
-;; show haskell function in mode line
-;; todo, this broke after updating emacs
-;;(eval-after-load "which-func"
-;;  '(add-to-list 'which-func-modes 'haskell-mode))
-
-
-
-(add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup)
-(add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup)
-(eval-after-load "auto-complete"
-  '(add-to-list 'ac-modes 'haskell-interactive-mode))
-
-(add-hook 'haskell-mode-hook
-          (lambda () (define-key haskell-mode-map (kbd "C-(")
-                       (lambda () (interactive)
-                         (basic-save-buffer)
-                         (haskell-compile)
-                         (run-with-timer .3 nil 'repeat-shell)))))
-(add-hook 'haskell-cabal-mode-hook
-          (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile)))
-
-
-
-(add-hook 'haskell-interactive-mode-hook
-          (lambda ()
-            (define-key haskell-interactive-mode-map "\r" nil)
-            (define-key haskell-interactive-mode-map (kbd "<return>") 'haskell-interactive-mode-return)))
-(add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map "\r" nil)))
-
-
-
-(add-hook 'haskell-interactive-mode-hook
-          (lambda ()
-            (define-key haskell-interactive-mode-map (kbd "<C-M-return>") 'haskell-interactive-mode-newline-indent)))
-
-;;; isearch
-(setq
- isearch-allow-scroll t
- search-ring-update t) ;; dont start an edit when going to previous search
-
-(defun isearch-yank-regexp (regexp)
-  "Pull REGEXP into search regexp."
-  (let ((isearch-regexp nil)) ;; Dynamic binding of global.
-    (isearch-yank-string regexp))
-  (isearch-search-and-update))
-
-(defun isearch-yank-symbol (&optional partialp backward)
-  "Put symbol at current point into search string.
-
-     If PARTIALP is non-nil, find all partial matches."
-  (interactive "P")
-
-  (let (from to bound sym)
-    (setq sym
-                                        ; this block taken directly from find-tag-default
-                                        ; we couldn't use the function because we need the internal from and to values
-          (when (or (progn
-                      ;; Look at text around `point'.
-                      (save-excursion
-                        (skip-syntax-backward "w_") (setq from (point)))
-                      (save-excursion
-                        (skip-syntax-forward "w_") (setq to (point)))
-                      (> to from))
-                    ;; Look between `line-beginning-position' and `point'.
-                    (save-excursion
-                      (and (setq bound (line-beginning-position))
-                           (skip-syntax-backward "^w_" bound)
-                           (> (setq to (point)) bound)
-                           (skip-syntax-backward "w_")
-                           (setq from (point))))
-                    ;; Look between `point' and `line-end-position'.
-                    (save-excursion
-                      (and (setq bound (line-end-position))
-                           (skip-syntax-forward "^w_" bound)
-                           (< (setq from (point)) bound)
-                           (skip-syntax-forward "w_")
-                           (setq to (point)))))
-            (buffer-substring-no-properties from to)))
-    (cond ((null sym)
-           (message "No symbol at point"))
-          ((null backward)
-           (goto-char (1+ from)))
-          (t
-           (goto-char (1- to))))
-    (isearch-search)
-    (if partialp
-        (isearch-yank-string sym)
-      (isearch-yank-regexp
-       (concat "\\_<" (regexp-quote sym) "\\_>")))))
-
-(defun isearch-current-symbol (&optional partialp)
-  "Incremental search forward with symbol under point.
-
-     Prefixed with \\[universal-argument] will find all partial
-     matches."
-  (interactive "P")
-  (let ((start (point)))
-    (isearch-forward-regexp nil 1)
-    (isearch-yank-symbol partialp)))
-;; todo, make this
-
-(defun isearch-backward-current-symbol (&optional partialp)
-  "Incremental search backward with symbol under point.
-
-     Prefixed with \\[universal-argument] will find all partial
-     matches."
-  (interactive "P")
-  (let ((start (point)))
-    (isearch-backward-regexp nil 1)
-    (isearch-yank-symbol partialp)))
-
-
-
-                                        ; lets look through emacs starter kit before we throw this out.
-
-
-                                        ;   automatically wrap to the top of the buffer when isearch fails
-(defadvice isearch-search (after isearch-no-fail activate)
-  (unless isearch-success
-    (ad-disable-advice 'isearch-search 'after 'isearch-no-fail)
-    (ad-activate 'isearch-search)
-    (isearch-repeat (if isearch-forward 'forward))
-    (ad-enable-advice 'isearch-search 'after 'isearch-no-fail)
-    (ad-activate 'isearch-search)))
-
-;; 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))))))
-;;; lisp / elisp mode setings
-
-(add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save)
-(defun starter-kit-remove-elc-on-save ()
-  "If you're saving an elisp file, likely the .elc is no longer valid."
-  (make-local-variable 'after-save-hook)
-  (add-hook 'after-save-hook
-            (lambda ()
-              (if (file-exists-p (concat buffer-file-name "c"))
-                  (delete-file (concat buffer-file-name "c"))))))
-
-
-(defun emacs-lisp-mode-defaults ()
-  ;; checkdoc has an annoying feature that wants a header and footer
-  ;; in every elisp buffer as if they all were packages
-  ;; todo, see if there is a way
-  ;; to make checkdoc usable instead of just disabling it as I do here
-  (if (boundp 'flycheck-checkers)
-      (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers)))
-  (eldoc-mode 1))
-(add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults)
-
-(define-key lisp-mode-map (kbd "<M-up>") 'backward-up-list)
-(define-key lisp-mode-map (kbd "<M-down>") 'down-list)
-(define-key emacs-lisp-mode-map (kbd "<M-up>") 'backward-up-list)
-(define-key emacs-lisp-mode-map (kbd "<M-down>") 'down-list)
-(define-key emacs-lisp-mode-map (kbd "<M-escape>") 'find-function-at-point)
-
-;; 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)
-
-
-;; 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)
-
-;;; mediawiki
-
-(eval-after-load "mediawiki"
-  '(progn
-     (remove-hook 'outline-minor-mode-hook 'mediawiki-outline-magic-keys)
-     (add-hook 'mediawiki-mode-hook
-               (lambda () (define-key mediawiki-mode-map (kbd "C-(") 'mediawiki-save-reload)))
-
-     ;; mediawiki mode has a bug that it will claim an edit conflict unless you reload after saving.
-     ;; I also like to save with no edit summary for previewing on my local mw instance
-     (defun mediawiki-save-reload ()
-       (interactive)
-       (and (mediawiki-save "") (mediawiki-reload)))))
-;;; modes with little configuration needed
-;; busted:
-;;(require 'csv-mode)
-;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
-
-(require 'outshine)
-(add-hook 'outline-minor-mode-hook 'outshine-mode)
-(add-hook 'emacs-lisp-mode-hook 'outline-minor-mode)
-(add-hook 'sh-mode-hook 'outline-minor-mode)
-
-
-
-(setq org-caldav-url "https://cal.iankelling.org"
-      org-caldav-calendar-id "ian"
-      org-caldav-inbox "/p/cal.org")
-;;(org-caldav-sync)
-
-
-;;(require 'dtrt-indent)
-;;(setq dtrt-indent-mode t)
-
-(setq css-indent-offset 2)
-
-(load-file "/a/h/iank-mod.el")
-
-;; from when i was running my own patches
-;;(add-to-list 'load-path "/a/opt/ws-butler")
-
-(require 'ws-butler)
-;; todo: I think this is broken, it keeps collapsing the last line
-;; for empty messages.
-
-;; the main problem is when it deletes the blank line at the end
-;; of a message with an empty body. but I might also
-;; be pasting whitespace significant things in here, so
-;; just don't do anything.
-;; todo: propose this upstream
-(add-to-list 'ws-butler-global-exempt-modes 'message-mode)
-
-(ws-butler-global-mode)
-
-
-
-(require '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)))
-
-
-;; gnu global
-(require 'ggtags)
-(add-hook 'c-mode-common-hook
-          (lambda () (ggtags-mode 1)
-            (setq c-label-minimum-indentation 0)))
-
-;; specific to my unusual keybind setup, you may want to
-;; pick different keys
-(define-key ggtags-mode-map (kbd "C-M-o") 'ggtags-find-tag-dwim)
-(define-key ggtags-mode-map (kbd "C-M-m") 'ggtags-grep)
-
-(defun gtags-update-single(filename)
-  "Update Gtags database for changes in a single file"
-  (interactive)
-  (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " ggtags-project-root " ; gtags --single-update " filename )))
-
-(defun gtags-update-current-file()
-  (interactive)
-  (let ((rel-filename (replace-regexp-in-string
-                       ggtags-project-root "."
-                       (buffer-file-name (current-buffer)))))
-    (gtags-update-single rel-filename)))
-
-(defun gtags-update-hook()
-  "Update GTAGS file incrementally upon saving a file"
-  (when (and ggtags-mode ggtags-project-root)
-    (gtags-update-current-file)))
-
-(add-hook 'after-save-hook 'gtags-update-hook)
-
-;; i'd like to make some elisp which modifies a keymap to remove
-;; all binds which don't match a predicate.
-;; I tried setting a keymap to a new keymap,
-;; but that didn't register as functional.
-;; so I'd need to modify the list in place.
-
-(require 'magit)
-
-
-;; colorize hex colors: use rainbow mode
-
-
-;; 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, which I use postfix for
-(setq send-mail-function (quote sendmail-send-it))
-
-(require 'spray)
-(global-set-key (kbd "C-M-w") 'spray-mode)
-;; remember, h/l = move. f/s = faster/slower, space = pause, all others quit
-
-;; delete active selection with self-insert commands
-(delete-selection-mode t)
-
-;; Transparently open compressed files
-(auto-compression-mode t)
-
-;; Highlight matching parenthesesq when the pointq is on them.
-;; not needed since smart paren mode?
-;;  (show-paren-mode 1)
-
-
-;; 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.
-(setq TeX-command-force "LaTeX")
-
-;; dot mode, repeats last action
-(require 'dot-mode)
-(add-hook 'find-file-hooks 'dot-mode-on)
-
-
-;; clean up obsolete buffers automatically at midnight
-(require 'midnight)
-
-
-;; disabled because it takes 400ms on startup
-;; ;; emacs regexes are too limited.
-;; (require 'foreign-regexp)
-;; ;; perl is most powerful, but javascript is pretty close and
-;; ;; I'd rather know javascript stuff than perl
-;; (custom-set-variables
-;;  '(foreign-regexp/regexp-type 'javascript) ;; Choose by your preference.
-;;  '(reb-re-syntax 'foreign-regexp)) ;; Tell re-builder to use foreign regexp.
-;; ;; it would be nice to add documentation to do this for more commands to that package
-;; ;; disabled because it's too slow. but I'd still m-x it for advanced replacements
-;; ;;(define-key global-map [remap isearch-forward-regexp] 'foreign-regexp/isearch-forward)
-
-
-;; saner regex syntax
-(require 're-builder)
-(setq reb-re-syntax 'string)
-
-
-;; use shift + arrow keys to switch between visible buffers
-;; todo, set these keys to something else
-(require 'windmove)
-(windmove-default-keybindings)
-
-
-;; show the name of the current function definition in the modeline
-(require 'which-func)
-(setq which-func-modes t)
-(which-function-mode 1)
-
-
-;; enable winner-mode to manage window configurations
-(winner-mode +1)
-
-;; meaningful names for buffers with the same name
-(require 'uniquify)
-(setq uniquify-buffer-name-style 'forward
-      uniquify-separator "/"
-      ;; for sdx work. until I figure out a better way.
-      ;; maybe something like projectile can do it,
-      ;; or hacking around the status bar
-      uniquify-min-dir-content 2
-      uniquify-after-kill-buffer-p t ; rename after killing uniquified
-      uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
-
-
-;; makefiles require tabs
-;; todo: find a makefile indent function that works,
-;; best I could find is this one which means don't indent at all
-;;
-(add-hook 'makefile-mode-hook
-          (lambda ()
-            (setq indent-tabs-mode t)
-            (setq indent-line-function (lambda () 'no-indent))))
-
-
-;; 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)
-
-
-;; auto indent shell script comments
-(setq sh-indent-comment t)
-
-;; random extra highlights
-(require 'volatile-highlights)
-(volatile-highlights-mode t)
-
-
-;; make help buffers smaller when it makes sense
-(temp-buffer-resize-mode 1)
-
-
-(require 'info+)
-;; based on suggestions in info+.el, I also installed  misc-fns, strings, and thingatpt+
-;; remove some bad keybinds from info+
-(define-key Info-mode-map [mouse-4]         nil)
-(define-key Info-mode-map [mouse-5]         nil)
-
-
-(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 7)
-;; sublimity doesn't work as good going fast by default
-;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location
-
-
-(setq sh-here-document-word "'EOF'")
-
-(setq tramp-default-method "ssh")
-;;; misc general settings
-
-(ivy-mode 1)
-(add-hook 'text-mode-hook (lambda () (auto-fill-mode t)))
-(setq counsel-find-file-at-point t)
-
-;; easier to read with just spaces as separator
-(setf (nth 2 ido-decorations) "   ")
-
-
-;; https://www.emacswiki.org/emacs/FillParagraph
-;; make list items start paragraphs.
-(setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ")
-
-(setq sh-basic-offset 2)
-(setq vc-follow-symlinks t)
-
-;; give us a shell to start instead of scratch
-;;(setq initial-buffer-choice (lambda () (new-shell)))
-
-;; disable this nasty function, as I always use a gui
-(defun suspend-frame() (interactive))
-
-;; Seed the random-number generator
-(random t)
-
-;; easier to remember than keybinds
-(defalias 'scrypt 'mml-secure-message-encrypt-pgpmime)
-(defalias 'sign 'mml-secure-message-sign-pgpmime)
-(defun encrypt ()
-  (interactive)
-  (mml-secure-message-encrypt-pgpmime 'dontsign))
-
-;; don't highlight the region.
-(set-face-background 'region nil)
-
-;; this fixes save error for python example code
-(define-coding-system-alias 'UTF-8 'utf-8)
-
-;; i don't use frame titles, but if I ever do
-;; this starter kit setting is probably good
-(if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b"))))
-
-
-;;(prefer-coding-system 'utf-8-unix)
-
-;; remove ugly 3d box feature
-(set-face-attribute 'mode-line nil :box nil)
-
-(add-to-list 'default-frame-alist
-             '(font . "DejaVu Sans Mono-11"))
-                                        ; the default will jump 2 sizes.
-(setq text-scale-mode-step 1.1)
-(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"
-      echo-keystrokes 0.1
-      mark-ring-max 160
-      sort-fold-case t  ; case insensitive line sorting
-      global-mark-ring-max 1000
-      ;; the visible bell seems to lag the ui
-      ;;visible-bell t
-      ;; turn off audible bell
-      ;; https://www.emacswiki.org/emacs/AlarmBell
-      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
-
-
-(setq-default indent-tabs-mode nil ;; don't use tabs to indent
-              cursor-type 'box
-              fill-column 72
-
-              ;; wrap at word boundaries instead of mid-word
-              word-wrap t
-              imenu-auto-rescan t
-              indicate-empty-lines t) ; mark end of buffer
-
-
-(blink-cursor-mode '(-4))
-(menu-bar-mode -1)
-(tool-bar-mode -1)
-
-
-;; enable various commands
-(put 'narrow-to-region 'disabled nil)
-(put 'narrow-to-page 'disabled nil)
-(put 'narrow-to-defun 'disabled nil)
-(put 'upcase-region 'disabled nil)
-(put 'downcase-region 'disabled nil)
-(put 'scroll-left 'disabled nil)
-;; these from graphene, haven't read about them yet
-(put 'ido-complete 'disabled nil)
-(put 'ido-exit-minibuffer 'disabled nil)
-(put 'dired-find-alternate-file 'disabled nil)
-(put 'autopair-newline 'disabled nil)
-
-
-
-;;disable and minimize various prompts/messages
-(fset 'yes-or-no-p 'y-or-n-p)
-(setq confirm-nonexistent-file-or-buffer nil
-      inhibit-startup-message t
-      inhibit-startup-echo-area-message t
-      inhibit-startup-screen t
-      compilation-read-command nil ;; just don't compile with unsafe file local vars
-      kill-buffer-query-functions (remq 'process-kill-buffer-query-function
-                                        kill-buffer-query-functions))
-
-
-;; exit without bothering me
-;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042
-(add-hook 'comint-exec-hook
-          (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil)))
-;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting
-;; apparently this would need to be in some later hook. dunno where is best, but this works
-(defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate)
-  (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions)))
-
-
-
-;; (custom-set-faces
-;;  ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin
-;;  '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil))))
-;;  ;; don't highlight the region
-;;  '(region ((t nil))))
-(setq-default header-line-format " ")
-
-
-(setq initial-scratch-message nil)
-
-
-;; vertical margin background.
-;; google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html
-;; the xresource doesn't work for me, probably an xmonad thing.
-
-;; figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search
-;; info,
-;; then M-x customize-face
-;; header-line
-;; unchecked some stuff so that it inherits from default.
-
-;;; misc function definitions
-
-
-(defun fill-buffer ()
-  (interactive)
-  (save-mark-and-excursion
-    (beginning-of-buffer)
-    (while (= (forward-line) 0)
-      (fill-paragraph))))
-
-
-(defun next-backup-dir ()
-  "In a directory listing from rsync -n,
-Go to the next directory based on where the cursor is."
-  (interactive)
-  (let* ((start-col (current-column))
-         (end-col (progn (skip-chars-forward "^/\n") (current-column)))
-         (dir (progn
-                (beginning-of-line 1)
-                (buffer-substring-no-properties (point) (+ (point) end-col)))))
-    (message dir)
-    (forward-line 1)
-    (while (and (not (eobp))
-                (string= dir (buffer-substring-no-properties (point) (+ (point) end-col))))
-      (forward-line 1))
-    (forward-char-same-line start-col)))
-;; copy paste this for fast keybind
-;;(local-set-key (kbd "<kp-enter>"))
-
-
-(defun goto-buffer-or-find-file (file-name)
-  "If buffer is with FILE-NAME exists, go to it, else open the file using full path."
-  (interactive)
-  (let ((b (get-buffer (file-name-nondirectory file-name))))
-    (if b
-        (switch-to-buffer b)
-      (find-file file-name))))
-
-
-
-
-;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something
-(defun unpop-global-mark ()
-  "Unpop off global mark ring. Does nothing if mark ring is empty."
-  (interactive)
-  (when global-mark-ring
-    (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
-    (let ((lm (car (last global-mark-ring))))
-      (set-marker (mark-marker) (marker-position lm) (marker-buffer lm)))
-    (when (null (mark t)) (ding))
-    (setq global-mark-ring (nbutlast global-mark-ring))
-    (goto-char (marker-position (mark-marker)))))
-
-(defun indent-buffer ()
-  "Indents the entire buffer."
-  (interactive)
-  (cond ((derived-mode-p 'org-mode)
-         (org-indent-region (point-min) (point-max)))
-        ((derived-mode-p 'python-mode)
-         (py-autopep8))
-        (t
-         (indent-region (point-min) (point-max)))))
-
-
-;; TODO doesn't work with uniquify
-(defun rename-file-and-buffer ()
-  "Renames current buffer and file it is visiting."
-  (interactive)
-  (let ((name (buffer-name))
-        (filename (buffer-file-name)))
-    (if (not (and filename (file-exists-p filename)))
-        (message "Buffer '%s' is not visiting a file!" name)
-      (let ((new-name (read-file-name "New name: " filename)))
-        (cond ((get-buffer new-name)
-               (message "A buffer named '%s' already exists!" new-name))
-              (t
-               (rename-file name new-name 1)
-               (rename-buffer new-name)
-               (set-visited-file-name new-name)
-               (set-buffer-modified-p nil)))))))
-
-
-
-(defun sudo-edit (&optional arg)
-  (interactive "P")
-  (if (or arg (not buffer-file-name))
-      (find-file (concat "/sudo::" (ido-read-file-name "File: ")))
-    (find-alternate-file (concat "/sudo::" buffer-file-name))))
-
-
-
-(defun backward-symbol (arg)
-  (interactive "p")
-  (forward-symbol (- arg)))
-
-;;; mode line
-;; 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 . "")
-    (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
-        mode-line-position nil)) ; todo, make only flymake status show up
-
-(add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook)
-
-;;; mouse related
-;;;; settings
-(setq focus-follows-mouse t
-      mouse-autoselect-window t
-      xterm-mouse-mode t)
-;;;; move-mouse-to-point
-;; todo, this is buggy with multiple windows open.
-(defun move-mouse-to-point ()
-  (interactive)
-  (let* ((pos (posn-col-row (posn-at-point)))
-         (x (+ (car pos) 2)) ; no idea why this is off by 1-2
-         (y (cdr pos)))
-    (set-mouse-position (selected-frame) x y)))
-
-;;;; keybinds for wow mouse
-
-(global-set-key (kbd "<mouse-6>") 'move-mouse-to-point)
-(global-set-key (kbd "<kp-left>") 'indent-region)
-(global-set-key (kbd "<kp-begin>") 'mark-defun)
-(global-set-key (kbd "<kp-right>") 'ibuffer)
-(global-set-key (kbd "<kp-prior>") 'delete-horizontal-space)
-
-;;; 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)
-
-;; todo, generally fix org mode keys
-;; todo, org-mark-element, unbdind from M-h, bind to mark defun key
-
-                                        ;(org-babel-do-load-languages
-                                        ; 'org-babel-load-languages
-                                        ; '((emacs-lisp . t)
-                                        ;   (sh . t)))
-
-
-
-;; make shell work like interactive bash shell
-(setq org-babel-default-header-args:sh
-      '((:results . "output") (:shebang . "#!/bin/bash -l")))
-
-;; my patch to output stderr
-(setq org-babel-use-error-buffer nil)
-
-                                        ;
-;; org-mode manual suggests these, but I haven't used them.
-;;(global-set-key "\C-cl" 'org-store-link)
-;;(global-set-key "\C-ca" 'org-agenda)
-;; this got in the way of a haskell mode command
-;;(global-set-key "\C-cb" 'org-iswitchb)
-
-
-
-;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix
-
-(setq org-src-fontify-natively t ; make babel blocks nice
-      org-adapt-indentation nil
-      org-src-preserve-indentation t
-      ;; The most basic logging is to keep track of when a TODO item was finished.
-      org-log-done 'time
-      ;; use a drawer to keep the logs tidy
-      org-log-into-drawer t
-      org-extend-today-until 0
-      org-startup-truncated nil
-      org-clock-persist t
-      org-clock-mode-line-total 'today
-      ;; global STYLE property values for completion
-      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
-      org-catch-invisible-edits 'smart)
-
-;; non universally recommended settings
-(setq
- org-default-notes-file (concat org-directory "/a/t.org")
- org-agenda-files (quote ("/a/t.org"))
- org-mobile-directory "/p/org-mobile"
- org-mobile-inbox-for-pull "/p/from-mobile.org"
- org-directory "/p")
-
-;; modeilne populated from (org-clock-get-clocked-time)
-;; which is populated from the var org-clock-total-time
-;; which is populated by a function which starts from (org-clock-get-sum-start)
-;;
-
-(org-clock-persistence-insinuate)
-
-
-(defun time-to-org-day (time)
-  (round (time-to-number-of-days
-          (time-subtract time (list 0 (* 3600 org-extend-today-until) 0)))))
-
-
-(defun my-org-confirm-babel-evaluate (lang body)
-  (not (or (string= (buffer-file-name) "/a/t.org")
-           (string= (buffer-file-name) "/home/iank/.emacs.d/my-init.org")
-           )))
-(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
-
-
-(defun org-time-stamp-with-time (arg)
-  (interactive "P")
-  ;; '(4) is the argument passed by universal prefix
-  (org-time-stamp (if arg arg '(4)) t))
-
-(defun ian-org-work-time ()
-  (interactive)
-  (save-excursion
-    (set-buffer "t.org")
-    (goto-char (org-find-entry-with-id "ian-identifier-1"))
-    (org-clock-in)))
-
-(defun ian-org-idle-time ()
-  (interactive)
-  (save-excursion
-    (goto-char (org-find-entry-with-id "ian-identifier-2"))
-    (set-buffer "t.org")
-    (org-clock-in)))
-
-
-
-;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables
-;; keywords: proportional font, monospace
-
-(defun variable-pitch-on ()
-  (variable-pitch-mode 1))
-(add-hook 'fundamental-mode-hook 'variable-pitch-on)
-(add-hook 'org-mode-hook 'variable-pitch-on)
-(add-hook 'text-mode-hook 'variable-pitch-on)
-(defun variable-pitch-off ()
-  (variable-pitch-mode 0))
-(add-hook 'yaml-mode-hook 'variable-pitch-off)
-
-
-(set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family))
-(set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family))
-(set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family))
-(set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family))
-(set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family))
-(set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family))
-
-
-(defun remove-org-binds ()
-  (define-key org-mode-map (kbd "<M-return>") nil)
-  (define-key org-mode-map (kbd "C-'") nil)
-  (define-key org-mode-map (kbd "C-y") nil)
-  (define-key org-mode-map (kbd "<C-return>") nil)
-  (define-key org-mode-map (kbd "<C-M-kp-enter>") nil)
-  (define-key org-mode-map (kbd "C-,") nil)
-  (define-key org-mode-map (kbd "C-M-m") nil)
-  (define-key org-mode-map (kbd "C-k") nil)
-  (define-key org-mode-map (kbd "C-j") nil)
-  (define-key org-mode-map (kbd "C-M-i") nil)
-  (define-key org-mode-map (kbd "C-M-t") nil)
-  (define-key org-mode-map (kbd "M-a") 'nil)
-  (define-key org-mode-map (kbd "C-a") nil)
-  (define-key org-mode-map (kbd "M-e") nil)
-  (define-key org-mode-map (kbd "C-e") nil)
-  (define-key org-mode-map (kbd "C-3") nil)
-  (define-key org-mode-map (kbd "<M-left>") nil)
-  (define-key org-mode-map (kbd "<M-right>") nil)
-  (define-key org-mode-map (kbd "<S-return>") nil)
-  (define-key org-mode-map (kbd "<tab>") nil)
-  (define-key org-mode-map (kbd "<C-S-down>") nil)
-  (define-key org-mode-map (kbd "<C-S-up>") nil)
-  (define-key org-mode-map (kbd "<S-down>") nil)
-  (define-key org-mode-map (kbd "<S-up>") nil)
-  (define-key org-mode-map "\t" nil))
-(add-hook 'org-mode-hook 'remove-org-binds)
-
-;;; prog-mode-defaults
-
-
-(defun prog-mode-defaults ()
-  "Default coding hook, useful with any programming language."
-  ;; so that I can do completion before the dialog pops up
-  (local-set-key (kbd "<tab>") 'auto-complete)
-  ;; todo, this is causing error message on loading file, prolly not working
-  ;;(flycheck-mode +1)
-  (setq ac-sources (delq 'ac-source-dictionary ac-sources))
-  (highlight-symbol-mode)
-  (make-local-variable 'column-number-mode)
-  ;; 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)
-
-  ;; prettify lambdas
-  (font-lock-add-keywords
-   nil `(("(\\(lambda\\>\\)"
-          (0 (progn (compose-region (match-beginning 1) (match-end 1)
-                                    ,(make-char 'greek-iso8859-7 107))
-                    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
-;; automatically indenting yanked text if in programming-modes
-(defvar yank-indent-modes
-  '(LaTeX-mode TeX-mode)
-  "Modes in which to indent regions that are yanked (or yank-popped).
-Only modes that don't derive from `prog-mode' should be listed here.")
-
-(defvar yank-indent-blacklisted-modes
-  '(python-mode slim-mode haml-mode)
-  "Modes for which auto-indenting is suppressed.")
-
-(defvar yank-advised-indent-threshold 2000
-  "Threshold (# chars) over which indentation does not automatically occur.")
-
-(defun yank-advised-indent-function (beg end)
-  "Do indentation, as long as the region isn't too large."
-  (if (<= (- end beg) yank-advised-indent-threshold)
-      (indent-region beg end nil)))
-
-(defadvice yank (after yank-indent activate)
-  "If current mode is one of 'yank-indent-modes,
-indent yanked text (with prefix arg don't indent)."
-  (if (and (not (ad-get-arg 0))
-           (not (member major-mode yank-indent-blacklisted-modes))
-           (or (derived-mode-p 'prog-mode)
-               (member major-mode yank-indent-modes)))
-      (let ((transient-mark-mode nil))
-        (yank-advised-indent-function (region-beginning) (region-end)))))
-
-(defadvice yank-pop (after yank-pop-indent activate)
-  "If current mode is one of 'yank-indent-modes,
-indent yanked text (with prefix arg don't indent)."
-  (if (and (not (ad-get-arg 0))
-           (not (member major-mode yank-indent-blacklisted-modes))
-           (or (derived-mode-p 'prog-mode)
-               (member major-mode yank-indent-modes)))
-      (let ((transient-mark-mode nil))
-        (yank-advised-indent-function (region-beginning) (region-end)))))
-
-
-;;; shell mode
-;; avoid stupid git crap like "warning, terminal not fully functional"
-(setenv "PAGER" "cat")
-;; don't store successive duplicates in comint command history
-(setq comint-input-ignoredups t)
-
-(defun add-mode-line-dirtrack ()
-  (add-to-list 'mode-line-buffer-identification
-               '(:propertize (" " default-directory " ") face dired-directory)))
-(add-hook 'shell-mode-hook 'add-mode-line-dirtrack)
-
-
-;; don't fully understand it, but it works.
-;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs
-(defun track-shell-directory/procfs ()
-  (shell-dirtrack-mode 0)
-  (add-hook 'comint-preoutput-filter-functions
-            (lambda (str)
-              (prog1 str
-                (when (string-match comint-prompt-regexp str)
-                  (cd (file-symlink-p
-                       (format "/proc/%s/cwd" (process-id
-                                               (get-buffer-process
-                                                (current-buffer)))))))))
-            nil t))
-(setq comint-buffer-maximum-size 100000)
-(add-to-list 'comint-output-filter-functions 'comint-truncate-buffer)
-(defun new-shell ()
-  (interactive)
-  (shell (generate-new-buffer-name "*shell*")))
-;;
-(defun shell-wrap (prefix)
-  "wrap the shell function, automatically generate a new name for a prefix arg"
-  (interactive "P")
-  (if prefix
-      (new-shell)
-    (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 "<return>"))))
-(sp-pair "[" nil :post-handlers
-         '(:add ((lambda (id action context)
-                   (gp/sp/pair-on-newline-and-indent id action context)) (kbd "<return>"))))
-
-
-;; 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
-(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))
-
-
-;;; smex
-;;  todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings.
-                                        ; these must be before smex-initialize
-(setq
- smex-save-file "~/.emacs.d/.smex-items")
-
-(smex-initialize)
-;;; spell correction
-(setq
- ispell-program-name "hunspell"
- ispell-silently-savep t) ; don't prompt to save personal dictionary
-
-(require 'rw-hunspell)
-;; rw-hunspell sets up hunspell dictionary automagically.
-
-
-;; 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
-;; "emacs" "customizable" and "timestamp". Hunspell already has those,
-;; thank god.
-
-;; ispell-personal-dictionary does not document where the hunspell
-;; dictionary goes by default, but it is ~/.hunspell_en_US for me
-
-
-;;; tex
-(setq-default TeX-PDF-mode t) ; use pdf
-
-                                        ; more sensible defaults based on info manual quickstart
-(setq TeX-auto-save t)
-(setq TeX-parse-self t)
-
-
-
-;;; visible mark mode
-
-;; since it is not easy to change the mark overlay priority, I change this one.
-(setq show-paren-priority 999)
-
-
-(defface visible-mark-active
-  '((((type tty) (class mono)))
-    (t (:background "magenta"))) "")
-
-
-
-(defface mouse-cursor-face
-  '((((type tty) (class mono)))
-    (t (:background "DeepPink1"))) "")
-
-
-(require 'visible-mark)
-
-(setq visible-mark-faces '(visible-mark-face1 visible-mark-face2))
-(setq visible-mark-forward-faces '(visible-mark-forward-face1))
-
-
-                                        ; highlight the last 2 marks
-(setq visible-mark-max 2)
-                                        ; highlight 1 forward mark
-(setq visible-mark-forward-max 1)
-                                        ; globally activate visible-mark-mode
-(global-visible-mark-mode +1)
-
-
-;; todo, it doesn't seem to be exposed in elisp, but it would be nice
-;; if I could define overlay faces to use inverse foreground color
-
-
-;;; zrc
-(require 'znc)
-(setq erc-fill-prefix "")
-(defun chirp()
-  (interactive)
-  (setq vol 50)
-  (when (string= (system-name) "tp") (setq vol 40))
-  (start-process-shell-command "ignoreme" nil (format "mpv --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
-;; from https://www.emacswiki.org/emacs/ErcSound
-
-(defun erc-my-privmsg-sound (proc parsed)
-  (let* ((tgt (car (erc-response.command-args parsed)))
-         (privp (erc-current-nick-p tgt)))
-    (and
-     privp (chirp)
-     ;; We must return nil. See help for `erc-server-PRIVMSG-functions'
-     nil)))
-
-(add-hook 'erc-server-PRIVMSG-functions
-          'erc-my-privmsg-sound)
-
-(defun erc-sound-if-not-server (match-type nickuserhost msg)
-  (unless (string-match "Server:[0-9]+" nickuserhost)
-    (chirp)))
-(add-hook 'erc-text-matched-hook 'erc-sound-if-not-server)
-
-(erc-track-mode 1)
-(setq
- ;; consider invisible frames to be unseen. seems like an obvious default
- erc-track-visibility 'visible
- ;; switch to buffer where i've been mentioned, etc instead of oldest
- erc-track-switch-direction 'importance)
-
-
-;;; named commands
-(defun rm-file-and-buffer ()
-  "Removes file connected to current buffer and kills buffer."
-  (interactive)
-  (let ((filename (buffer-file-name))
-        (buffer (current-buffer))
-        (name (buffer-name)))
-    (if (not (and filename (file-exists-p filename)))
-        (error "Buffer '%s' is not visiting a file!" name)
-      (delete-file filename)
-      (kill-buffer buffer)
-      (message "File '%s' successfully removed" filename))))
-
-;;; persistent registers
-;; This needs to be at the end, because I visit a file, thus setting a
-;; mode, and the mode hook needs to be setup before that.
-
-;; I'm using persistent registers instead of bookmarks. I dun use them
-;; much, so the added hassle of having to set it within this file is
-;; worth the benefit of only having one concept in my mind.
-(dolist
-    (r `(
-         (?i (file . ,"~/.emacs.d/my-init.org"))
-         (?t (file . ,"/a/t.org"))
-         (?x (file . ,"/a/x.txt"))
-         ))
-  (set-register (car r) (cadr r)))
-
-(setq undo-outer-limit 100000000 ; per undo command
-      undo-limit 500000000 ; undo history limit
-      undo-strong-limit 600000000) ; undo history limit plus some extra
-
-;;; keybinds
-
-;;;; misc
-(global-set-key (kbd "C-x C-b") 'ibuffer)
-
-
-;; isearch-occur
-;; Activate occur easily inside isearch
-;; 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))))))
-
-
-(defun my-isearch-toggle-regexp ()
-  (interactive)
-  (isearch-toggle-regexp)
-  (cond (isearch-regexp
-         (global-set-key (kbd "C-r") 'isearch-backward-regexp)
-         (define-key global-map (kbd "<f12>") 'isearch-forward-regexp))
-        (t
-         (global-set-key (kbd "C-r") 'isearch-backward)
-         (define-key global-map (kbd "<f12>") 'isearch-forward))))
-(define-key isearch-mode-map (kbd "M-r") 'my-isearch-toggle-regexp)
-
-
-(define-key Info-mode-map "x" 'Info-follow-nearest-node)
-
-
-;;;; single/special keys
-;;;;; tab - isearch
-(define-key isearch-mode-map (kbd "<tab>") 'isearch-query-replace)
-
-;;;;; f12 - isearch-forward
-;; explained in http://stackoverflow.com/questions/7411920/how-to-bind-search-and-search-repeat-to-c-f-in-emacs
-(global-set-key (kbd "<kp-add>") 'isearch-forward)
-(global-set-key (kbd "<f12>") 'isearch-forward)
-(define-key isearch-mode-map "\t" nil)
-(define-key isearch-mode-map (kbd "<kp-add>") 'isearch-repeat-forward)
-(define-key isearch-mode-map (kbd "<f12>") 'isearch-repeat-forward)
-;; get rid of the standard completion binding, always use auto-complete
-;; this didn't work very well
-;;(global-set-key (kbd "TAB") 'auto-complete)
-(define-key global-map [remap completion-at-point] 'auto-complete)
-
-;;;;; end - move-end-of-line
-;; taken from emacs wiki, along with home function
-;; http://www.emacswiki.org/emacs/BackToIndentationOrBeginning
-(defun point-in-comment ()
-  "Determine if the point is inside a comment"
-  (interactive)
-  (let ((syn (syntax-ppss)))
-    (and (nth 8 syn)
-         (not (nth 3 syn)))))
-(defun end-of-code-or-line (arg)
-  "Move to end of line, or before start of comments depending on situation.
- Toggle back and forth positions if we are already at one.
- Comments are recognized in any mode that sets syntax-ppss
- properly."
-  (interactive "P")
-  (when (catch 'bol
-          (let ((start (point))
-                (bol (save-excursion
-                       (beginning-of-line)
-                       (point)))
-                (eol (progn (move-end-of-line arg) (point))))
-            (while (point-in-comment)
-              (backward-char)
-              (when (= (point) bol)
-                (throw 'bol t)))
-            (throw 'bol (and (not (= eol start)) (>= start (point))))))
-    (move-end-of-line arg)))
-
-(global-set-key (kbd "<end>") 'end-of-code-or-line)(add-hook 'org-mode-hook (lambda () (define-key org-mode-map (kbd "<end>") 'org-end-of-line)))
-
-;;;;; home - back-to-indentation
-(defun back-to-indentation-or-beginning ()
-  (interactive)
-  (if (= (point) (progn (back-to-indentation) (point)))
-      (if (derived-mode-p 'org-mode)
-          (org-beginning-of-line)
-        (beginning-of-line))))
-(global-set-key (kbd "<home>") 'back-to-indentation-or-beginning)
-
-;;;;; s-tab - indent-buffer
-(global-set-key (kbd "<S-iso-lefttab>") 'indent-buffer)
-;;;;; s-delete - send-shell
-
-(global-set-key (kbd "<S-delete>") 'send-shell)
-
-;; optional variables used by send-shell
-(setq shell-send-yank-key nil)
-
-(defun repeat-shell ()
-  (interactive)
-  "Repeat the last command in shell-mode, displaying the window if needed."
-  (let ((shell-buffer (get-buffer "*shell*")))
-    (if shell-buffer
-        (buffer-window-show shell-buffer)
-      (let ((original-buffer (current-buffer)))
-        (funcall 'shell)
-        (setq shell-buffer (current-buffer))
-        (switch-to-buffer original-buffer)))
-    (with-current-buffer shell-buffer
-      (goto-char (point-max))
-      (call-interactively 'comint-previous-input)
-      ;; the t flag makes the buffer advance
-      (comint-send-input nil t))))
-
-(setq compilation-filenames '("Makefile" "makefile"))
-
-(defun get-nearest-compilation-file ()
-  "Search for the compilation file traversing up the directory tree."
-  (interactive)
-  (let ((dir default-directory)
-       (parent-dir (file-name-directory (directory-file-name default-directory)))
-       (nearest-compilation-file 'nil))
-    (while (and (not (string= dir parent-dir))
-               (not nearest-compilation-file))
-      (dolist (filename compilation-filenames)
-       (setq file-path (concat dir filename))
-       (when (file-readable-p file-path)
-         (setq nearest-compilation-file file-path)))
-      (setq dir parent-dir
-           parent-dir (file-name-directory (directory-file-name parent-dir))))
-    nearest-compilation-file))
-(defun run ()
-  (interactive)
-  "call run-fun if it is set, else run make if there is a makefile,
-else save and repeat last shell command.
-run-fun is meant to store file local variables, which show how to
-do the main thing we want on this file, generally compile and
-run.
-
-example of setting it in a file:
-;; Local Variables:
-;; run-fun: merge-test
-;; End: "
-  (basic-save-buffer)
-  (if (and (boundp 'run-fun) run-fun)
-      (funcall run-fun)
-    (let ((makefile (get-nearest-compilation-file)))
-      (if (and makefile (stringp mode-name) (string= mode-name "C/l"))
-          (compile (format
-                    "make -f %s" (get-nearest-compilation-file)))
-        (repeat-shell)))))
-
-
-(defun send-shell ()
-  (interactive)
-  (send-shell-buffer "*shell*" 'shell (kbd "C-v")))
-
-(defun send-python ()
-  (interactive)
-  (send-shell-buffer "*Python*" 'py-shell (kbd "C-v")))
-
-
-(defun send-shell-buffer (buffer-name &optional init shell-send-yank-key)
-  "Send current line or region to shell-mode buffer.
-When in shell-mode, copy the current line to the
-most recently visited visible window.
-
-SHELL-SEND-YANK-KEY: key to use instead
-of yank to paste into recent window. This allows compatibility with
-modes like org-mode which have their own yank function."
-  (if (string= (buffer-name) buffer-name)
-      ;; this section is copied out of comint-send-input
-      (progn
-        (let ((proc (get-buffer-process (current-buffer))))
-          (if (not proc) (user-error "Current buffer has no process")
-            (widen)
-
-            (let* ((pmark (process-mark proc))
-                   (intxt (if (>= (point) (marker-position pmark))
-                              (progn (if comint-eol-on-send (end-of-line))
-                                     (buffer-substring pmark (point)))
-                            (let ((copy (funcall comint-get-old-input)))
-                              (goto-char pmark)
-                              (insert copy)
-                              copy))))
-
-              (if (= (length intxt) 0)
-                  (kill-new (comint-previous-matching-input-string "." 1))
-                (kill-new intxt)))))
-        (kill-append "\n" nil)
-        (select-window (previous-window nil nil 'visible))
-        (if (and (boundp 'shell-send-yank-key) shell-send-yank-key)
-            (call-interactively (global-key-binding shell-send-yank-key))
-          (yank))
-        (select-window (next-window nil nil 'visible)))
-    (let (start end)
-      (if mark-active
-          (setq start (mark)
-                end (point))
-        (setq start (save-excursion (beginning-of-line) (point))
-              end (save-excursion (end-of-line) (point)))
-        (let (line-move-visual)
-          (call-interactively 'next-line)))
-      (send-comint-input buffer-name start end init))))
-
-;; supporting functions
-(defun send-comint-input (buffer-name start end &optional init)
-  "Input the region to BUFFER-NAME, assuming it is a comint-derived buffer.
-                             Show BUFFER-NAME if it is not show.
-                             Call INIT if BUFFER-NAME does not exist."
-  (let ((input (filter-buffer-substring start end)))
-    (send-comint-string buffer-name input init)))
-
-(defun send-comint-string (buffer-name string &optional init)
-  "Input the string to BUFFER-NAME, assuming it is a comint-derived buffer.
-                             Show BUFFER-NAME if it is not show.
-                             Call INIT if BUFFER-NAME does not exist."
-  (let ((buffer (get-buffer buffer-name)))
-    (unless buffer
-      (message "nobuffer")
-      ;; save-excursion etc. don't work for (shell), so I do this instead
-      (if init (let ((original-buffer (current-buffer)))
-                 (funcall init (and (boundp 'send-shell-buffer-name) send-shell-buffer-name))
-                 (switch-to-buffer original-buffer)
-                 (setq buffer (get-buffer buffer-name)))
-        (error "No existing buffer found and no init function argument. ")))
-    (buffer-window-show buffer)
-    (with-current-buffer buffer
-      (let ((proc (get-buffer-process buffer)))
-        (goto-char (process-mark proc))
-        (insert string)
-        (comint-send-input nil t)))))
-
-(defun buffer-window-show (&optional buffer action)
-  "Like temp-buffer-window-show, but removed stuff
-        relevant to it being temp or help."
-  (let (window frame)
-    (with-current-buffer buffer
-      (when (let ((window-combination-limit
-                   ;; When `window-combination-limit' equals
-                   ;; `temp-buffer' or `temp-buffer-resize' and
-                   ;; `temp-buffer-resize-mode' is enabled in this
-                   ;; buffer bind it to t so resizing steals space
-                   ;; preferably from the window that was split.
-                   (if (or (eq window-combination-limit 'temp-buffer)
-                           (and (eq window-combination-limit
-                                    'temp-buffer-resize)
-                                temp-buffer-resize-mode))
-                       t
-                     window-combination-limit)))
-              ;; debug
-              ;;(message "window-combination-limit")
-              ;;(print window-combination-limit)
-              (setq window (display-buffer buffer action)))
-        (setq frame (window-frame window))
-        (unless (eq frame (selected-frame))
-          (raise-frame frame))
-        (setq minibuffer-scroll-window window)
-        (set-window-hscroll window 0)
-        ;; Return the window.
-        window))))
-
-
-;; when poping help, etc, allow reusing a window in a different frame if it is visible
-;; figured this out after spending quite a while reading doc string for display-buffer
-;; which is the main function which uses this.
-;; it will use other vars or its arg to override this,
-;; but those things are often nil.
-;; aha moments in reading it: ACTION = (FUNCTION-or-FUNCTIONLIST ALIST)
-;; FRAME adds an association to ACTION's alist, but it's not used if ACTION arg is nil.
-(setq display-buffer-fallback-action `(,(car display-buffer-fallback-action) . '(reusable-frames . visible)))
-;; stop splitting windows verticallly when I open a buffer or shell
-(setq split-height-threshold nil)
-
-;;;;; s-left arrow - shell
-(global-set-key (kbd "<S-left>") 'shell-wrap)
-(add-hook 'org-mode-hook
-          (lambda ()
-            (define-key org-mode-map (kbd "<S-left>") nil)))
-
-;;;;; s-right arrow - keyboard-yank-primary
-(defun keyboard-yank-primary ()
-  (interactive)
-  (let ((mouse-yank-at-point t))
-    (mouse-yank-primary nil)))
-;; paste selection
-(global-set-key (kbd "<S-right>") 'keyboard-yank-primary)
-(add-hook 'org-mode-hook
-          (lambda ()
-            (define-key org-mode-map (kbd "<S-right>") nil)))
-;;;;; esc
-                                        ; todo, test out if this can be used
-;;;;; return - new line
-
-;; todo, this doesn't set the keybind for the help minibuffer
-
-
-(global-set-key (kbd "\r") 'indent-new-comment-line)
-
-;; don't use enter for autocomplete, we use tab or something
-(define-key ac-completing-map (kbd "<return>") nil)
-(define-key ac-completing-map "\r" nil)
-
-(add-hook 'org-mode-hook
-          (lambda ()
-            ;; copied from org-mode, replace org-enter with org-enter-indent
-            (org-defkey org-mode-map "\C-m"     'org-return-indent)))
-
-
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map "\r" nil)
-            (define-key comint-mode-map (kbd "<return>") 'comint-send-input)))
-
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map "\C-m" nil)
-            (define-key comint-mode-map "\C-d" nil)))
-
-;;;;; s-return - auto-correct-prev-word
-(global-set-key (kbd "<S-return>") 'flyspell-auto-correct-previous-word)
-;; kp-enter is shift return in terminal
-(global-set-key (kbd "<kp-enter>") 'flyspell-auto-correct-previous-word)
-
-;;;;; s-down arrow - my-contract-region
-(global-set-key (kbd "<S-up>") 'my-contract-region)
-;;;;; c-up/down move 8 lines
-
-;; compiling warns that next-line should be called interactively,
-;; but we would have to do something dumb, like give it a
-;; vector of keys in order to supply the 8 argument
-(defun down-fast ()
-  (interactive)
-  (next-line 8))
-(defun up-fast ()
-  (interactive)
-  (next-line -8))
-
-(global-set-key (kbd "<C-up>") 'up-fast)
-(global-set-key (kbd "<C-down>") 'down-fast)
-
-;;;;; c-scroll comint prev/next prompt
-
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map (kbd "<C-mouse-4>") 'comint-previous-prompt)
-            (define-key comint-mode-map (kbd "<C-mouse-5>") 'comint-next-prompt)))
-;;;;; m-scroll prev/next sexp
-(global-set-key (kbd "<M-mouse-4>") 'backward-sexp)
-(global-set-key (kbd "<M-mouse-5>") 'forward-sexp)
-;;;;; S-scroll expand/contract region
-(global-set-key (kbd "<S-mouse-13>") 'my-contract-region)
-(global-set-key (kbd "<S-mouse-14>") 'er/expand-region)
-(global-set-key (kbd "<S-mouse-4>") 'my-contract-region)
-(global-set-key (kbd "<S-mouse-5>") 'er/expand-region)
-
-(defun my-contract-region (arg)
-  (interactive "p")
-  (let ((current-prefix-arg '-))
-    (call-interactively 'er/expand-region)))
-
-;; todo: define c-m scroll. i manually set to normal scrolling, i dunno why
-
-
-;;;;; c-s-scroll scale text
-
-(global-set-key (kbd "<C-S-mouse-4>") 'text-scale-increase)
-(global-set-key (kbd "<C-S-mouse-5>") 'text-scale-decrease)
-(global-set-key (kbd "<C-S-mouse-13>") 'text-scale-increase)
-(global-set-key (kbd "<C-S-mouse-14>") 'text-scale-decrease)
-(global-set-key (kbd "<C-S-down>") 'text-scale-increase)
-(global-set-key (kbd "<C-S-up>") 'text-scale-decrease)
-
-
-;;;;; s-up arrow er/expand-region
-(global-set-key (kbd "<S-down>") 'er/expand-region)
-;;;;; c-left/right move symbol
-
-(global-set-key (kbd "<C-left>") 'backward-symbol)
-(global-set-key (kbd "<C-right>") 'forward-symbol)
-
-;;;; left primary
-
-;;;;; C-2 copy-symbol
-
-(global-unset-key (kbd "C-2"))
-(defun copy-symbol (&optional arg)
-  "Copy symbol at point into kill-ring"
-  (interactive "P")
-  (kill-new (thing-at-point 'symbol)))
-
-(global-set-key (kbd "C-2") 'copy-symbol)
-
-;;;;; M-2 shell-cd-to-file
-
-
-(defun shell-cd-to-file ()
-  (interactive)
-  (let ((file (buffer-file-name)))
-    (if file
-        (send-comint-string "*shell*"
-                            (concat "c " (file-name-directory file))
-                            'shell)
-      (message "%s" "shell-cd-to-file: buffer has no file name"))))
-(global-set-key (kbd "M-2") 'shell-cd-to-file)
-
-;;;;; C-M-2 ---
-                                        ; todo. whats going on here?
-(global-unset-key (kbd "C-M-2"))
-
-;;;;; C-3 dot-mode-execute
-
-(global-set-key (kbd "C-3") 'dot-mode-execute)
-
-;;;;; C-M-3 recenter-top-bottom
-
-(global-set-key (kbd "C-M-3") 'recenter-top-bottom)
-
-;;;;; C-q org-cycle, comint previous arg
-
-(global-set-key (kbd "C-q") 'bicycle-cycle)
-(add-hook 'org-mode-hook
-          (lambda () (define-key org-mode-map (kbd "C-q") 'org-cycle)))
-(define-key widget-keymap (kbd "C-q") 'widget-forward)
-(add-hook 'comint-mode-hook
-          (lambda () (define-key comint-mode-map (kbd "C-q") 'comint-insert-previous-argument)))
-
-;;;;; M-q org-archive-to-archive-sibling
-
-(global-set-key (kbd "M-q") 'org-archive-to-archive-sibling)
-
-;;;;; C-M-q quoted-insert
-
-(global-set-key (kbd "C-M-q") 'quoted-insert)
-
-;;;;; C-w ---
-;; in terminal, it's ctrl-backspace, duplicate keybind.
-;;;;; M-w org-clock-in
-
-(global-set-key (kbd "M-w") 'org-clock-in)
-
-;;;;; C-e copy-line
-
-;; todo, make repeated calls to this append the kills
-(defun copy-line (&optional arg)
-  "Copy lines (as many as prefix argument) in the kill ring.
-        Ease of use features:
-        - Move to start of next line.
-        - Appends the copy on sequential calls.
-        - Use newline as last char even on the last line of the buffer.
-        - If region is active, copy its lines."
-  (interactive "p")
-  (let ((beg (line-beginning-position))
-        (end (line-end-position (or arg 1))))
-    (when mark-active
-      (if (> (point) (mark))
-          (setq beg (save-excursion (goto-char (mark)) (line-beginning-position)))
-        (setq end (save-excursion (goto-char (mark)) (line-end-position)))))
-    (if (eq last-command 'copy-line)
-        (kill-append (buffer-substring beg end) (< end beg))
-      (kill-ring-save beg end)))
-  (kill-append "\n" nil)
-  ;; dun need cuz I have yank-better
-  ;;(beginning-of-line (or (and arg (1+ arg)) 2))
-  (if (and arg (not (= 1 arg))) (message "%d lines copied" arg)))
-
-(global-set-key (kbd "C-e") 'copy-line)
-
-;;;;; M-e org-clock-in-last
-
-(global-set-key (kbd "M-e") 'org-clock-in-last)
-
-;;;;; C-r isearch-backward
-
-(global-set-key (kbd "C-r") 'isearch-backward)
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map (kbd "C-r") 'comint-history-isearch-backward-regexp)))
-
-;;;;; M-r org-clock-out
-
-(global-set-key (kbd "M-r") 'org-clock-out)
-
-;;;;; C-a copy buffer
-
-(defun copy-all ()
-  "Copy entire buffer to clipboard"
-  (interactive)
-  (clipboard-kill-ring-save (point-min) (point-max)))
-(global-set-key (kbd "C-a") 'copy-all)
-
-;;;;; C-s - c-x prefix
-  ; prefix key binds.
-  ; good info http://www.masteringemacs.org/articles/2011/02/08/mastering-key-bindings-emacs/
-  ; rebinding the prefix keys are tricky. apparently, some modes ignore any redefinition of a prefix key and use it explicitly,
-  ; so you have to dig into their key maps and redo things.
-  ; There are 2 simpler alternatives which have their own downsides.
-  ; One is cua mode, which I do not like because it smashes 2 keybinds onto 1 and limits what you can do.
-  ; The other is keyboard-translate, which translates the key presses before anything else.
-  ; The downside is that it translates them when you aren't using them as a prefix.
-  ; Since the swaps I'm using are all very accessible, the only downside is some mental jugling when reading docs etc about these keybinds.
-
-  ; I've seen this as an another suggestion, it was a total fail. The prefix command took over both keys.
-  ; (define-key key-translation-map [f12] "\C-c")
-  ; (define-key key-translation-map "\C-c" [left])
-
-
-  ;idea to remove the hook later since it is only needed at startup.
-  ; did not work however, and there is not a real need to fix it, so I did not investigate
-  ;(defun removeSwapHook ()
-  ;  (remove-hook 'buffer-list-update-hook 'myKeySwap)
-  ;  (remove-hook 'change-major-mode-hook 'removeSwapHook))
-  ;(add-hook 'change-major-mode-hook 'removeSwapHook)
-
-
-  ; went through almost all the relevant standard hooks,
-  ; this overcomes a known bug that (keyboard-translate) does not get applied when running emacs daemon
-  (add-hook 'buffer-list-update-hook (lambda () (interactive)
-                                       (keyboard-translate ?\C-x ?\C-s)
-                                       (keyboard-translate ?\C-s ?\C-x)
-                                       (keyboard-translate ?\C-c ?\C-d)
-                                       (keyboard-translate ?\C-d ?\C-c)))
-
-
-
-  ; these all don't work
-  ; don't know why this doesn't error but reversing the keys does
-  ;(keyboard-translate ?\t ?\M-\t)
-  ;(keyboard-translate [M-tab] [tab])
-  ; from what i can tell, it wants to use a keyboard-translate-table,
-  ; which is a char table, which is a vector indexed by chars,
-  ; and mod+tab is not a char (it has too many bits), it is an integer
-  ; it actually says it can hold vectors or strings, but that it is obsolete to do so
-  ;(characterp ?\M-a)
-  ;(characterp ?\C-a)
-
-;;;;; C-M-s - split-window-vertically
-
-(global-set-key (kbd "C-M-s") 'split-window-vertically)
-
-;;;;; C-d - C-c prefix
-;;;;; C-M-d - swap buffer across windows
-;; from http://www.emacswiki.org/emacs/TransposeWindows
-
-(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
-
-(global-set-key (kbd "C-f") 'kill-whole-line-wrapper)
-(defun kill-whole-line-wrapper (&optional arg)
-  "If we are at the end of the file, kill backwards instead of doing nothing."
-  (interactive "P")
-  (if (= (point) (point-max))
-      (kill-whole-line -1)
-    (kill-whole-line arg)))
-
-;;;;; M-f - print-var-at-point
-
-(defun print-var-at-point ()
-  (interactive)
-  (let ((v (variable-at-point)))
-    (if (symbolp v)
-        (message "%s: %s" v (symbol-value v))
-      (message "no symbol found at point"))))
-(global-set-key (kbd "M-f") 'print-var-at-point)
-
-
-;;;;; C-M-f - kill rest of line
-
-
-(add-hook 'org-mode-hook
-          (lambda ()
-            (define-key org-mode-map (kbd "C-M-f") 'org-kill-line)))
-
-(global-set-key (kbd "C-M-f") 'kill-line)
-;;;;; C-g - cancel / other window
-
-(global-set-key (kbd "C-g") 'other-window)
-
-;;;;; M-g - abort-recursive-edit
-
-(global-set-key (kbd "M-g") 'abort-recursive-edit)
-
-;;;;; C-M-g - gnus
-
-(global-set-key (kbd "C-M-g") 'mu4e)
-
-;;;;; C-z - undo-only
-
-(global-set-key (kbd "C-z") 'undo-only)
-
-;;;;; C-x - kill-region
-
-(global-set-key (kbd "C-s") 'kill-region)
-
-;;;;; M-x - smex
-
-(global-set-key (kbd "M-x") 'smex)
-
-;;;;; C-M-x - cut-to-register
-
-;; same args as copy-to-register
-(defun cut-to-register (register start end &optional delete-flag region)
-  (interactive (list (register-read-with-preview "Cut to register: ")
-                     (region-beginning)
-                     (region-end)
-                     current-prefix-arg
-                     t))
-  (copy-to-register register start end t region))
-
-(global-set-key (kbd "C-M-x") 'cut-to-register)
-
-;;;;; 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 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map (kbd "C-d") nil)))
-;; the base map is shared by many c-modes, like java
-(add-hook 'c-mode-hook
-          (lambda ()
-            (define-key c-mode-base-map "\C-d" nil)
-            (define-key c-mode-base-map (kbd "<deletechar>") 'c-electric-delete-forward)))
-
-
-;;;;; M-c - org-capture
-
-(define-key global-map "\M-c" 'org-capture)
-
-;;;;; C-M-c - copy-to-register
-
-(global-set-key (kbd "C-M-c") 'copy-to-register)
-
-;;;;; C-v - yank
-
-(global-set-key (kbd "C-v") 'yank-better)
-
-
-
-(defun yank-better (arg)
-  "Paste, linewise if our kill ends with a newline.
-  I change the behavior of plain prefix. It makes it not do linewise paste,
-  because sometimes you want to yank pop and a linewise paste screws that up.
-  c-u with no number normally makes the point go before the yank.
-  That is pointless for me, as it would be just as easier and less
-  thought to pop the mark after yanking cuz it is set to before the mark."
-  (interactive "*P")
-  (if (and (not (equal arg '(4))) (string-suffix-p "\n" (current-kill 0 t)))
-      (beginning-of-line))
-  (if (and (stringp mode-name) (string= mode-name "Org"))
-      (call-interactively 'org-yank)
-    (setq this-command 'yank)
-    (call-interactively 'yank (and (not (equal arg '(4)))))))
-
-(put 'yank-better 'delete-selection 'yank)
-
-;;;;; M-v - insert-register
-
-(global-set-key (kbd "M-v") 'insert-register)
-
-;;;;; C-M-v - yank-pop
-
-(global-set-key (kbd "C-M-v") 'yank-pop)
-
-;;;;; C-b - delete-other-windows
-
-(global-set-key (kbd "C-b") 'delete-other-windows)
-
-;;;;; M-b - isearch-backward-current-symbol
-
-(global-set-key (kbd "M-b") 'isearch-backward-current-symbol)
-
-;;;;; C-M-b - isearch-current-symbol
-
-(global-set-key (kbd "C-M-b") 'isearch-current-symbol)
-
-;;;;; C-tab - ---
-;; in terminal, it's just TAB, duplicate keybind.
-;;;;; M-tab - ---
-;; in terminal it's duplicated of C-M-i
-;;;;; C-delete - kill-symbol
-
-(global-set-key (kbd "<C-delete>") 'kill-symbol)
-(defun kill-symbol (arg)
-  (interactive "p")
-  (kill-region (point) (save-excursion (forward-symbol arg) (point))))
-
-
-;;;;; C-M-delete - kill-sexp
-
-(global-set-key (kbd "<C-M-delete>") 'kill-sexp)
-
-;;;;; C-left-arrow - compile / comint search
-
-(defun set-p (var)
-  (and (bound-and-true-p var)
-       (not (eq var 'unset))))
-(global-set-key (kbd "C-(") 'run)
-
-;; make compile work from the gtags root dir
-(defadvice compile (before pre-compile-advice activate)
-  (basic-save-buffer)
-  (when (set-p ggtags-project-root)
-    (setq-local compile-saved-dir default-directory)
-    (setq default-directory ggtags-project-root)))
-(defadvice compile (after post-compile-advice activate)
-  (when (bound-and-true-p compile-saved-dir)
-    (setq default-directory compile-saved-dir)))
-
-
-(add-hook 'c-mode-hook (lambda () (define-key c-mode-map (kbd "C-(") 'compile)))
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key isearch-mode-map (kbd "C-(") 'isearch-repeat-backward)
-            (define-key comint-mode-map (kbd "C-(") 'isearch-backward)))
-
-
-;;;;; C-M-left-arrow - org-shiftup
-
-(add-hook 'org-mode-hook
-          (lambda () (define-key org-mode-map (kbd "C-M-(") 'org-shiftup)))
-
-;;;;; C-right-arrow - forward-symbol
-;;;;; C-M-right-arrow - org-shiftdown
-(add-hook 'org-mode-hook
-(lambda () (define-key org-mode-map (kbd "C-M-)") 'org-shiftdown)))
-
-;;;;; C-backspace - backward-kill-symbol
-
-(global-set-key (kbd "<C-backspace>") 'backward-kill-symbol)
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map (kbd "<C-backspace>") 'backward-kill-word)))
-(defun backward-kill-symbol (arg)
-  (interactive "p")
-  (kill-region (point) (save-excursion (backward-symbol arg) (point))))
-
-;;;;; C-M-backspace - backward-kill-sexp
-
-(global-set-key (kbd "<C-M-backspace>") 'backward-kill-sexp)
-
-;;;; right primary
-;;;;; C-* - split-window-horizontally
-
-(global-set-key (kbd "C-*") 'split-window-horizontally)
-
-;;;;; C-M-* - calc-dispatch
-
-(global-set-key (kbd "C-M-*") 'calc-dispatch)
-
-;;;;; C-9 - delete-window-or-exit
-
-(global-set-key (kbd "C-9") 'delete-window-or-exit)
-
-(defun delete-window-or-exit ()
-  "Delete window or exit emacs."
-  (interactive)
-  (if (condition-case nil (delete-window) (error t))
-      (if (or (boundp 'server-process) (> (length (frame-list)) 1))
-          (progn (basic-save-buffer) (delete-frame))
-        (save-buffers-kill-terminal t))))
-
-;;;;; M-9 - kill-buffer
-
-(defun kill-buffer-no-ido ()
-  "kill-buffer, avoid the ido remapping"
-  (interactive)
-  (kill-buffer))
-(global-set-key (kbd "M-9") 'kill-buffer-no-ido)
-
-;; strangely, in simple mode, this is overridden.
-;; I found this map to override, but it didn't work, so it seems its being bound some other way.
-;; I did a grep of the emacs sources, but couldn't find anything.
-;; (define-key universal-argument-map [?9 nil)
-
-;;;;; C-M-9 - end server edit
-;;  save & kill buffer if it was opened externally via emacsclient
-
-
-  (defun server-edit-save ()
-    (interactive)
-    (save-buffer)
-    (server-edit))
-  (global-set-key (kbd "C-M-9") 'server-edit-save)
-
-;;;;; C-u - universal-argument
-;;;;; C-M-u - search-keybind
-
-  (global-set-key (kbd "C-M-u") 'search-keybind)
-
-  (defun search-keybind (regexp &optional nlines)
-    (interactive (occur-read-primary-args))
-    (save-excursion
-      (describe-bindings)
-      (set-buffer "*Help*")
-      (occur regexp)
-      (delete-windows-on "*Help*")
-      ))
-
-;;;;; C-i - -----
-;;;;; C-M-i - query-replace-regexp
-
-  (global-set-key (kbd "C-M-i") 'query-replace-regexp)
-  (add-hook 'flyspell-mode-hook
-            (lambda () (define-key flyspell-mode-map (kbd "C-M-i") nil)))
-  (add-hook 'text-mode-hook
-            (lambda () (define-key text-mode-map (kbd "C-M-i") nil)))
-
-
-;;;;; C-o - occur
-
-  (global-set-key (kbd "C-o") 'occur)
-
-;;;;; C-M-o - counsel-imenu
-
-  (global-set-key (kbd "C-M-o") 'counsel-imenu)
-
-;;;;; C-p - move-mouse-to-point
-
-  (global-set-key (kbd "C-p") 'move-mouse-to-point)
-
-;;;;; C-M-p - delete-horizontal-space
-
-  (global-set-key (kbd "C-M-p") 'delete-horizontal-space)
-
-;;;;; C-j - pop-to-mark
-
-  (defun my-pop-to-mark-command ()
-    "Jump to mark, and pop a new position for mark off the ring.
-                     \(Does not affect global mark ring\)."
-    (interactive)
-    (pop-to-mark-command)
-    (if (and (derived-mode-p 'org-mode) (outline-invisible-p))
-        (org-show-context 'mark-goto)))
-
-  (global-set-key (kbd "C-j") 'my-pop-to-mark-command)
-  (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text)
-  (add-hook 'ido-setup-hook
-            (lambda () (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text)))
-  (add-hook 'lisp-interaction-mode-hook
-            (lambda ()
-              (define-key lisp-interaction-mode-map (kbd "C-j") nil)))
-
-
-;;;;; M-j - previous-error
-
-  (global-set-key (kbd "M-j") 'previous-error)
-
-;;;;; C-M-j - register prefix
-
-  (define-key global-map (kbd "C-M-j") ctl-x-r-map)
-  (define-key ctl-x-r-map "m" 'kmacro-to-register)
-
-
-;;;;; C-k - jump-to-register
-
-
-  (global-set-key (kbd "C-k") 'jump-to-register)
-
-;;;;; M-k - next-error
-
-  (global-set-key (kbd "M-k") 'next-error)
-
-;;;;; C-M-k - man
-
-  (global-set-key (kbd "C-M-k") 'man)
-
-;;;;; C-l - ivy-switch-buffer
-
-  (global-set-key (kbd "C-l") 'ivy-switch-buffer)
-
-;;;;; C-M-l - move cursor top bottom mid, comint clear screen
-
-  (global-set-key (kbd "C-M-l") 'move-to-window-line-top-bottom)
-
-;;;;; C-; - used in flyspell, not sure what for, otherwise unbound
-;;;;; M-; - comment-dwim
-;;;;; C-M-; - comment-current-line-dwim
-
-  (defun comment-current-line-dwim ()
-    "Comment or uncomment the current line."
-    (interactive)
-    (save-excursion
-      (push-mark (beginning-of-line) t t)
-      (end-of-line)
-      (comment-dwim nil))
-    (move-beginning-of-line 2))
-  (global-set-key (kbd "C-M-;") 'comment-current-line-dwim)
-
-;;;;; C-M-m - recursive grep
-
-  (define-key global-map (kbd "C-M-m") 'rgrep)
-
-;;;;; C-, - ounsel-find-file
-
-  (global-set-key (kbd "C-,") 'counsel-find-file)
-  (add-hook 'flyspell-mode-hook
-            (lambda () (define-key flyspell-mode-map (kbd "C-,") nil)))
-
-;;;;; C-M-, - ind-file-in-project
-
-  (global-set-key (kbd "C-M-,") 'find-file-in-project)
-
-;;;;; C-. - find recent file
-;;  Taken from starter kit.
-
-  (defun recentf-ido-find-file ()
-    "Find a recent file using Ido."
-    (interactive)
-    (let* ((file-assoc-list
-            (mapcar (lambda (x)
-                      (cons (file-name-nondirectory x)
-                            x))
-                    recentf-list))
-           (filename-list
-            (remove-duplicates (mapcar #'car file-assoc-list)
-                               :test #'string=))
-           (filename (ido-completing-read "Choose recent file: "
-                                          filename-list
-                                          nil
-                                          t)))
-      (when filename
-        (find-file (cdr (assoc filename
-                               file-assoc-list))))))
-
-  (add-hook 'flyspell-mode-hook
-            (lambda () (define-key flyspell-mode-map (kbd "C-.") nil)))
-  (define-key dot-mode-map (kbd "C-.") nil)
-  (global-set-key (kbd "C-.") 'recentf-ido-find-file)
-  (add-hook 'php-mode-hook
-            (lambda () (define-key php-mode-map (kbd "C-.") nil)))
-
-;;;;; C-M-. - -
-
-  (define-key dot-mode-map (kbd "C-M-.") nil)
-  ;;  (global-set-key (kbd "C-M-.") 'execute-extended-command)
-
-;;;;; C-/ - join lines
-
-  (defun vim-style-join-line ()
-    (interactive)
-    (join-line '(4)))
-  (global-set-key (kbd "C-/") 'vim-style-join-line)
-
-;;;;; C-M-/ - copy-buffer-file-name
-
-  ;; haven't bound this atm, todo, maybe someday?
-  (defun copy-variable (variable)
-    (interactive
-     (let ((v (variable-at-point))
-          (enable-recursive-minibuffers t)
-          val)
-       (setq val (completing-read (if (symbolp v)
-                                     (format
-                                      "Describe variable (default %s): " v)
-                                   "Describe variable: ")
-                                 obarray
-                                 (lambda (vv)
-                                    (or (get vv 'variable-documentation)
-                                        (and (boundp vv) (not (keywordp vv)))))
-                                 t nil nil
-                                 (if (symbolp v) (symbol-name v))))
-       (list (if (equal val "")
-                v (intern val)))))
-    (kill-new (symbol-value variable)))
-
-  (defun copy-buffer-file-name ()
-    (interactive)
-    (let ((name (cond
-                 ((derived-mode-p 'mu4e-view-mode) (mu4e-message-field-at-point :path))
-                 (t buffer-file-name))
-                ))
-      (kill-new name)
-      (message name)))
-
-
-  (global-set-key (kbd "C-M-/") 'copy-buffer-file-name)
-
-
-
-;;;;; C-8 - calc-embedded-word
-
-  (global-set-key (kbd "C-8") 'calc-embedded-word)
-
-;;;;; C-up-arrow - org prev headline
-
-  ;; disabled just because i don't want to accidentally hit it
-  (define-key global-map "\C-_" nil)
-  (global-set-key (kbd "<C-_>") 'beginning-of-defun)
-
-  (add-hook 'org-mode-hook
-            (lambda ()
-              (define-key org-mode-map (kbd "\C-_") 'outline-previous-visible-heading)))
-
-
-
-
-;;;;; C-S-up-arrow - winner undo
-
-  (global-set-key (kbd "<C-S-_>") 'winner-undo)
-
-;;;;; C-down-arrow - org next headline
-
-  (global-set-key (kbd "<C-kp-enter>") 'end-of-defun)
-
-  (add-hook 'org-mode-hook
-            (lambda ()
-              (define-key org-mode-map (kbd "<C-kp-enter>") 'outline-next-visible-heading)))
-
-
-
-
-;;;;; C-M-down-arrow - toggle-mark-activation
-
-  (defun toggle-mark-activation ()
-    (interactive)
-    (if mark-active
-        (deactivate-mark t)
-      (activate-mark)))
-
-  (global-set-key (kbd "<C-M-kp-enter>") 'toggle-mark-activation)
-
-;;;;; C-S-down-arrow  winner redo
-
-  (global-set-key (kbd "<C-S-kp-enter>") 'winner-redo)
-
-
-;;;;; C-S-down-arrow - m-x for major mode
-
-  (global-set-key (kbd "<C-S-kp-enter>") 'smex-major-mode-commands)
-
-;;;;; C-lbracket - ----
-;;;;; C-M-lbracket - scroll-right
-
-  (global-set-key (kbd "C-M-[") 'scroll-right)
-
-;;;;; C-rbracket - fill-paragraph
-
-  (global-set-key (kbd "C-]") 'fill-paragraph)
-
-;;;;; C-M-rbracket - scroll-left
-
-  (global-set-key (kbd "C-M-]") 'scroll-left)
-
-;;;;; C-return - newline-anywhere
-
-  (defun newline-anywhere ()
-    "Add a newline from anywhere in the line."
-    (interactive)
-    (end-of-line)
-    (newline-and-indent))
-  (global-set-key (kbd "<C-return>") 'newline-anywhere)
-
-
-;;;;; M-return - plain newline
-
-  (defun plain-newline ()
-    (interactive)
-    (insert "\n"))
-  (global-set-key (kbd "<M-return>") 'plain-newline)
-
-
-;;;;; C-M-return - newline-anywhere-previous
-(defun newline-anywhere-previous ()
-  "Add a newline from anywhere in the line."
-  (interactive)
-  (forward-line -1)
-  (end-of-line)
-  (newline-and-indent))
-(global-set-key (kbd "<C-M-return>") 'newline-anywhere-previous)
-
-;;;;; C-space - org-edit-special
-
-;; commented due to new keyboard needing ctrl-space for mark
-;; (kbd "<C-space>") does not work, (kbd "C-SPC") should work
-;; (add-hook 'org-mode-hook
-;;           (lambda ()
-;;             (define-key org-mode-map (kbd "C-SPC") 'org-edit-special)
-;;             ;; org-src-mode-map is broken in git version of emacs.
-;;             ;; temporarily use this for exiting edit-special mode.
-;;             (global-set-key (kbd "C-M--") 'org-edit-src-exit)
-;;             (define-key org-src-mode-map (kbd "C-SPC") 'org-edit-src-exit)))
-
-;;;;; C-M-space - before or under cursor
-
-(global-set-key (kbd "C-M-SPC") 'ispell-word)
-;;;; left secondary
-;;;;; C-M-4 - widen
-
-(global-set-key (kbd "C-M-4") 'widen)
-
-;;;;; C-tab-key - query-replace
-
-
-(global-set-key (kbd "<C-kp-add>") 'query-replace)
-
-;;;;; C-t - org cycle todo / toggle comint motion
-
-(add-hook 'org-mode-hook
-          (lambda ()
-            (define-key org-mode-map (kbd "C-t") 'org-todo)))
-
-(defun my-comint-previous-input (arg)
-  (interactive "*p")
-  (if (comint-after-pmark-p)
-      (comint-previous-input arg)
-    (forward-line -1)))
-
-(defun my-comint-next-input (arg)
-  (interactive "*p")
-  (if (comint-after-pmark-p)
-      (comint-next-input arg)
-    (forward-line)))
-
-(add-hook 'comint-mode-hook
-          (lambda ()
-            (define-key comint-mode-map (kbd "C-t") 'comint-toggle-arrow-keys)
-            (define-key comint-mode-map (kbd "<up>") 'my-comint-previous-input)
-            (define-key comint-mode-map (kbd "<down>") 'my-comint-next-input)))
-
-
-(defun comint-toggle-arrow-keys ()
-  (interactive)
-  (toggle-arrow-keys comint-mode-map))
-
-(setq-default comint-arrow-movement nil)
-(defun toggle-arrow-keys (map)
-  (cond ((lookup-key map (kbd "<up>"))
-         (setq-local comint-arrow-movement t)
-         (define-key map (kbd "<up>") nil)
-         (define-key map (kbd "<down>") nil))
-        (t
-         (setq-local comint-arrow-movement nil)
-         (define-key map (kbd "<up>") 'my-comint-previous-input)
-         (define-key map (kbd "<down>") 'my-comint-next-input)
-         (goto-char (point-max)))))
-
-(eval-after-load "message"
-  '(define-key message-mode-map (kbd "C-t") 'mail-signature))
-
-
-;;;;; C-M-t - org timestamp
-
-(global-set-key (kbd "C-M-t") 'org-time-stamp-with-time)
-
-;;;;; C-home - start of buffer
-;;;;; C-end - end of buffer
-;;;; right secondary
-;;;;; C-6 - save-buffers-kill-emacs
-
-(global-set-key (kbd "C-6") 'save-buffers-kill-emacs)
-
-;;;;; C-M-6 - insert-small-copyright
-
-(defun insert-small-copyright ()
-  (interactive)
-  (beginning-of-line)
-  (let ((beg (point)))
-    (insert "Copyright (C) 2017 Ian Kelling\nThis program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>")
-    (comment-region beg (point))))
-
-(global-set-key (kbd "C-M-6") 'insert-small-copyright)
-
-;;;;; C-M-7 - insert-full-copyright
-
-(defun insert-full-copyright ()
-  (interactive)
-  (beginning-of-line)
-  (let ((beg (point)))
-    (insert "Copyright (C) 2017 Ian Kelling\n")
-    (insert "\n")
-    (insert "This program is free software: you can redistribute it and/or modify\n")
-    (insert "it under the terms of the GNU General Public License as published by\n")
-    (insert "the Free Software Foundation, either version 3 of the License, or\n")
-    (insert "(at your option) any later version.\n")
-    (insert "\n")
-    (insert "This program is distributed in the hope that it will be useful,\n")
-    (insert "but WITHOUT ANY WARRANTY; without even the implied warranty of\n")
-    (insert "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n")
-    (insert "GNU General Public License for more details.\n")
-    (insert "\n")
-    (insert "You should have received a copy of the GNU General Public License\n")
-    (insert "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n")
-    (comment-region beg (point))))
-
-(global-set-key (kbd "C-M-7") 'insert-full-copyright)
-
-
-;;;;; C-0 - text-scale-reset
-
-(defun text-scale-reset ()
-  (interactive)
-  (text-scale-set 0))
-(global-set-key (kbd "C-0") 'text-scale-reset)
-
-;;;;; C-M-0 - insert-apache
-
-(defun insert-apache ()
-  (interactive)
-  (beginning-of-line)
-  (let ((beg (point)))
-    (insert "Copyright (C) 2017 Ian Kelling\n")
-    (insert "\n")
-    (insert "Licensed under the Apache License, Version 2.0 (the \"License\");\n")
-    (insert "you may not use this file except in compliance with the License.\n")
-    (insert "You may obtain a copy of the License at\n")
-    (insert "\n")
-    (insert "    http://www.apache.org/licenses/LICENSE-2.0\n")
-    (insert "\n")
-    (insert "Unless required by applicable law or agreed to in writing, software\n")
-    (insert "distributed under the License is distributed on an \"AS IS\" BASIS,\n")
-    (insert "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n")
-    (insert "See the License for the specific language governing permissions and\n")
-    (insert "limitations under the License.\n")
-    (comment-region beg (point))))
-(global-set-key (kbd "C-M-0") 'insert-apache)
-
-
-;;;;; C-M-- - org-edit-src-exit
-;;;;; C-y - undo
-
-(global-set-key (kbd "C-y") 'undo)
-(add-hook 'org-mode-hook
-          (lambda () (define-key org-mode-map (kbd "C-y") nil)))
-
-
-;;;;; C-\ - sr-speedbar-toggle
-(global-set-key (kbd "C-\\") 'sr-speedbar-toggle)
-
-;;;;; C-M-\ - mark-defun
-
-(global-set-key (kbd "C-M-\\") 'mark-defun)
-
-;;;;; C-h - help-prefix
-
-;;;;; C-' - val-expression
-
-(global-set-key (kbd "C-'") 'eval-expression)
-
-;;;;; C-n - unpop to mark
-
-(defun unpop-to-mark-command ()
-  "Unpop off mark ring. Does nothing if mark ring is empty."
-  (interactive)
-  (when mark-ring
-    (let ((pos (marker-position (car (last mark-ring)))))
-      (if (not (= (point) pos))
-          (goto-char pos)
-        (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
-        (set-marker (mark-marker) pos)
-        (setq mark-ring (nbutlast mark-ring))
-        (goto-char (marker-position (car (last mark-ring))))))))
-
-(global-set-key (kbd "C-n") 'unpop-to-mark-command)
-
-;;;;; C-M-n - narrow-to-region
-
-(global-set-key (kbd "C-M-n") 'narrow-to-region)
-
-;;;;; C-escape - find-tag
-
-(global-set-key (kbd "<C-escape>") 'find-tag)