1 ;; Copyright (C) 2020 Ian Kelling
3 ;; This program is free software: you can redistribute it and/or modify
4 ;; it under the terms of the GNU General Public License as published by
5 ;; the Free Software Foundation, either version 3 of the License, or
6 ;; (at your option) any later version.
8 ;; This program is distributed in the hope that it will be useful,
9 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ;; GNU General Public License for more details.
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ;; do m-x benchmark-init to see some benchmark stats
17 ;;(add-to-list 'load-path (concat user-emacs-directory "src/benchmark-init-el/")
18 ;;(require 'benchmark-init-loaddefs)
19 ;;(benchmark-init/activate)
21 ;;; init.el --- the start of customization
23 ;;(toggle-debug-on-error) ;uncomment to help debug
27 ;; stop from minimizing & freezing the gui
28 ;; used to freeze emacs and was really annoying,
29 ;; seems its changed now. no harm in keeping this though.
30 (global-unset-key (kbd "C-z"))
32 ;; speed up init https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/
33 ;; https://github.com/jwiegley/dot-emacs/blob/master/init.el
34 (defvar file-name-handler-alist-old file-name-handler-alist)
35 (setq package-enable-at-startup nil
36 file-name-handler-alist nil
38 gc-cons-threshold 402653184
39 gc-cons-percentage 0.6
40 auto-window-vscroll nil)
42 (add-hook 'after-init-hook
44 (setq file-name-handler-alist file-name-handler-alist-old
46 gc-cons-threshold 100000000))
47 ;; taken from wiegley, dunno why the t is there.
50 ;; stuff to allow an alternate location for ~/.emacs.d
51 (setq user-emacs-directory (file-name-directory user-init-file))
52 (when (getenv "EHOME")
53 (setenv "HOME" (getenv "EHOME")))
57 ;; ; uncomment the following block
58 ;;(require 'benchmark-init)
59 ;;(add-hook 'after-init-hook 'benchmark-init/deactivate)
61 ;; ; emacs -f benchmark-init/show-durations-tabulated
62 ;; ; emacs -f benchmark-init/show-durations-tree
63 ;; ; to catch things post-init
64 ;; ; emacs -f benchmark-init/deactivate
67 ;; these need to be done before the hook in order to satisfy the byte compiler or batch mode
69 (add-to-list 'load-path (concat user-emacs-directory "src/readline-complete"))
71 ;; disabled since not used.
72 ;;(add-to-list 'load-path (concat user-emacs-directory "src/bbdb-csv-import"))
73 ;;(add-to-list 'load-path (concat user-emacs-directory "src/spray"))
75 (add-to-list 'load-path (concat user-emacs-directory "src/visible-mark"))
79 (setq init-dir (file-name-directory load-file-name))
80 ;; previously, i was doing byte-recompile-directory, but
81 ;; now i just have one init file
82 (unless (equal (user-uid) 0) ; don't make root owned files
83 (byte-recompile-file (expand-file-name "init.el" init-dir) nil 0)
84 (when (file-exists-p "/p/c/mymu4e.el")
85 (byte-recompile-file "/p/c/mymu4e.el" nil 0))
88 ;;; misc emacs documentation
90 ;;;; how to find auto-saved files that need recovering
91 ;; find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it.
92 ;; #file# is an auto-save file. It may or may not be different than the file is corresponds to.
93 ;; If it is different, emacs will give a message about recovering it when you open it.
95 ;;;; misc org functions
97 ;; ;; these are usefull with (goto-char)
98 ;; ;; find named entity, other than headline
99 ;; (org-find-entry-with-id "string-number-or-symbol")
101 ;; (org-find-exact-headline-in-buffer "heading" nil t)
103 ;; ;; remove any indent level which is throughout the buffer
104 ;; (org-do-remove-indentation)
109 ;; good info http://www.emacswiki.org/emacs/GnusTutorial
110 ;; good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm
113 ;; After downloading mailing list archives, once you have an mbox file,
114 ;; there are rather straightforward ways to get it into any mail program,
115 ;; but I will cover gnus, which I use and is a bit tricky.
117 ;; gnus has a native search (limited, too slow for body text searches), and external search engine integration.
118 ;; gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus
119 ;; takes 10+ minutes, so scratch that option. it suggests 2 alternate options
120 ;; mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox
121 ;; and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise
124 ;; local imap server which will use the mbox and provide search.
125 ;; dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its
126 ;; description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the
130 ;; dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/<username>
131 ;; those locations are adjustable and well documented via the var mail_location in
132 ;; /etc/dovecot/conf.d/10-mail.conf
133 ;; 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
134 ;; is. you could make the var be empty, which apparently has the same effect.
136 ;; Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems
137 ;; other things like postfix use that location
139 ;; based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html
140 ;; other links that poped up contained outdated, innacurate information
141 ;; http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/
142 ;; http://www.emacswiki.org/emacs/JamesFerguson
143 ;; http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/
145 ;; Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility.
149 ;; doc group for mbox:
150 ;; in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file
152 ;; info about groups created within gnus is stored in ~/.newsrc.eld
153 ;; also stored is a duplication of what email messages are read/unread,
154 ;; what newsgroups are subsribed to and read/unread,
155 ;; probably more stuff, everything that gnus saves.
158 ;; searching the body of the messages, i cut off after a few minutes.
159 ;; i can grep the file in just a couple seconds
163 ;; we can also get mbox from gmane
164 ;; http://notmuchmail.org/howto/#index7h2
167 ;; gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command
168 ;; line, but not from within gnus, but from mairix.el, which can then open the results in gnus
170 ;; mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the
171 ;; headers and generates a nov file for each.
173 ;; nnfolder-generate-active-file
175 ;; to reset things, when changing mail group. I duno all the proper way, but it works to delete
176 ;; ~/Mail ~/.newsrc.eld ~/.newsrc-dribble
179 ;;;;; mail sources vs select methods background
180 ;; I found this very confusing when first reading through the manual. "mail sources" is a term that does not simply mean
181 ;; sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail
182 ;; sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use
183 ;; "mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their
184 ;; location, but use them in their native format. This is what I want to do, and I can simply ignore mail
185 ;; sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it
186 ;; means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail.
190 ;;;;; caching background
193 ;; there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why.
194 ;; Grepped for caching in the manual, found 2 main things.
195 ;; cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence
196 ;; gnus-use-cache, which puts things if they are
197 ;; gnus-cache-enter-articles
198 ;; things go in cache when they are marked certain ways by default, ticked and dormant
199 ;; and read articles are moved out of the cache
200 ;; still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached
201 ;; I'm gonna delete the cache, and check on it later see what exactly is going in there
202 ;; And of course, I moved ~/News to my encrypted drive and symlinked it
206 ;;; things that should be at the beginning
208 ;; from its README.md
210 (require 'use-package))
211 (use-package use-package-ensure-system-package
214 ;; Ubiquitous Packages. these could go anywhere actually
216 ;; find file at point
222 (setq package-archives
224 (("gnu" . "https://elpa.gnu.org/packages/")
225 ("MELPA" . "https://melpa.org/packages/"))))
227 ;;(add-to-list 'package-archives
229 ;; "http://marmalade-repo.org/packages/"))
231 ;; down atm 2020-08-30
232 ;;(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
235 ;; keep our init.el clean, by moving customization elisp to it's own file
236 (setq custom-file (concat user-emacs-directory "custom.el"))
238 ;;(load custom-file 'noerror)
243 ;; auto-completion in minibuffer
244 ;; disabled while I look for another alternative
247 (require 'auto-complete-config)
251 ;; complete after 1 char instead of default 2
252 (setq ac-auto-start 1)
253 (setq ac-delay 0.001)
255 (add-to-list 'ac-modes 'org-mode 'sql-mode)
258 ;; for org mode completion source taken from wiki.
259 ;; it did not work. no idea why. todo, investigate
260 ;; the ac-sources code is at http://www.emacswiki.org/emacs/AutoCompleteSources
261 ;; i've deleted it here so as to save space and not spam this file
262 ;;(defun my-ac-org-mode ()
263 ;; (setq ac-sources (append ac-sources '(ac-source-org))))
266 ;; this makes the org-self-insert command not do a flyspell spell check.
267 ;; low priority thing to look into sometime
268 (ac-flyspell-workaround)
271 (define-key ac-completing-map (kbd "<up>") nil)
272 (define-key ac-completing-map (kbd "<down>") nil)
273 (define-key ac-completing-map (kbd "<S-return>") 'ac-expand)
274 (define-key ac-completing-map "\t" 'ac-complete)
275 ;;(define-key ac-completing-map (kbd "<tab>") 'ac-complete)
276 (define-key ac-completing-map (kbd "TAB") 'ac-complete)
280 ;;; auto-complete readline-complete
282 (require 'readline-complete)
283 ;; not sure how I made these, but I deleted, and
284 ;; it would be nice to make them again sometime
285 ;;(require 'src-loaddefs)
287 ;; disabled cuz broken
288 ;; redefining function in readline-complete so ac-complete only uses readline as a source
289 (defun ac-rlc-setup-sources ()
290 "Add me to shell-mode-hook!"
291 (setq ac-sources '(ac-source-shell)))
292 (add-hook 'shell-mode-hook 'ac-rlc-setup-sources)
294 ;; generally unnecessary, but why not
295 (setq explicit-shell-file-name "bash")
297 ;; readline-complete says to add this line.
298 ;; however, it up my procfs directory tracking hook
299 ;; because get-process doesn't notice the child shell.
300 ;; instead, I've removed export EMACS=t from
301 ;; comint-exec-1 (the function which initially sets it)
302 ;; by finding it in emacs sources and redefinind it here
303 ;; and done stty echo in my bashrc
304 ;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash"))
307 (setq explicit-bash-args nil)
308 (setq comint-process-echoes t)
309 ;; default of 30 is way too slow. todo, consider pushing this upstream
310 (setq rlc-attempts 5)
312 (add-to-list 'ac-modes 'shell-mode)
314 ;; readline-complete recommends this (i assume this format),
315 ;; but greping finds no reference in emacs or my .emacs.d
316 ;; so I'm assuming it is for an older emacs
317 ;;(setq explicit-ssh-args '("-t"))
319 (add-hook 'shell-mode-hook
321 ;;(define-key shell-mode-map (kbd "<tab>") 'auto-complete)
322 (define-key shell-mode-map (kbd "TAB") 'auto-complete)
326 ;;; readline complete fix
328 ;; I need this function here, where INSIDE_EMACS is replaced with LC_INSIDE_EMACS.
329 ;; ian: last update 2017-1-7. update this periodically from upstream
330 ;; like when we do a major emacs update
331 (defun comint-exec-1 (name buffer command switches)
332 (let ((process-environment
334 ;; If using termcap, we specify `emacs' as the terminal type
335 ;; because that lets us specify a width.
336 ;; If using terminfo, we specify `dumb' because that is
337 ;; a defined terminal type. `emacs' is not a defined terminal type
338 ;; and there is no way for us to define it here.
339 ;; Some programs that use terminfo get very confused
340 ;; if TERM is not a valid terminal type.
341 ;; ;; There is similar code in compile.el.
342 (if (and (boundp 'system-uses-terminfo) system-uses-terminfo)
343 (list "TERM=dumb" "TERMCAP="
344 (format "COLUMNS=%d" (window-width)))
346 (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width))))
347 (list (format "LC_INSIDE_EMACS=%s,comint" emacs-version))
348 process-environment))
350 (if (file-accessible-directory-p default-directory)
353 proc decoding encoding changed)
354 (let ((exec-path (if (and command (file-name-directory command))
355 ;; If the command has slashes, make sure we
356 ;; first look relative to the current directory.
357 (cons default-directory exec-path) exec-path)))
358 (setq proc (apply 'start-file-process name buffer command switches)))
359 ;; Some file name handler cannot start a process, fe ange-ftp.
360 (unless (processp proc) (error "No process started"))
361 (let ((coding-systems (process-coding-system proc)))
362 (setq decoding (car coding-systems)
363 encoding (cdr coding-systems)))
364 ;; Even if start-file-process left the coding system for encoding data
365 ;; sent from the process undecided, we had better use the same one
366 ;; as what we use for decoding. But, we should suppress EOL
368 (if (and decoding (not encoding))
369 (setq encoding (coding-system-change-eol-conversion decoding 'unix)
372 (set-process-coding-system proc decoding encoding))
377 ;; todo: patch this so i can turn it off like my-as-off-local.
378 ;; then try it out and see if it can replace my autosave.
379 ;; Or maybe with the new auto-save-visited-mode.
380 ;; (use-package super-save
383 ;; (setq super-save-exclude '("")
384 ;; super-save-triggers
387 ;; org-babel-execute-src-block
390 ;; split-window-below
391 ;; split-window-horizontally
392 ;; start-process-shell-command
399 ;; (super-save-mode +1))
403 (setq auto-save-timeout 1) ; idle time before auto-save.
405 ;; main hook for my auto save
406 (add-hook 'auto-save-hook 'my-auto-save)
407 ;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active
408 (add-hook 'window-configuration-change-hook 'my-auto-save-win)
410 ;; this function from mu4e really does not like buffer saving
411 (advice-add 'message-send-and-exit :before 'my-as-off)
412 (advice-add 'message-send-and-exit :after 'my-as-on)
414 ;; avoid window config hook saving too much, it can
415 ;; get into loops in some random situations
416 (defvar my-auto-save-last nil)
418 (defvar my-auto-save-last nil)
419 (defun my-auto-save-win ()
420 (unless (eq (current-buffer) my-auto-save-last)
421 (my-auto-save (current-buffer))))
423 (defun my-auto-save (&optional last)
427 ;; mu4e has a bug right now, undo breaks when saving drafts
428 (not (string= (buffer-file-name) "*draft*"))
430 (not (and (boundp 'org-src-edit-buffer-p) (org-src-edit-buffer-p))))
431 ;; serial is incremented on each save, so let's do a bit less of them
432 (not (derived-mode-p 'dns-mode))
433 (setq my-auto-save-last last)
434 (let (message-log-max)
435 ;; a bit of a hack to partially suppress the constant saving in the echo area
436 (with-temp-message ""
437 (basic-save-buffer)))))
439 ;; in the message-send-and-exit advice, got an error because it passed an arg.
440 ;; didn't look into why, just add ignored args.
441 (defun my-as-off (&rest ignore)
445 (defun my-as-off-local (&rest ignore)
447 (setq-local my-as nil))
449 (defun my-as-on (&rest ignore)
453 (defun my-as-on-local (&rest ignore)
455 (setq-local my-as t))
457 ;; based on suggestion in the emacs docs, redefine these 2 functions
458 ;; to avoid prompt spamming the user when we do auto-save
459 (defun ask-user-about-supersession-threat (fn)
462 "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however
463 a backup is being created in case that is not what you intended." buffer-file-name)
464 (setq buffer-backed-up nil))
466 (defadvice ask-user-about-lock (before lock-deactivate-as activate)
467 (make-local-variable 'my-as)
469 (message "proper autosave has been turned off for this buffer because of lock file problem.
470 In this buffer, do M-x my-as-on to reenable"))
472 ;; todo, this doesn't work consistently to override the auto-save message
473 (defalias 'do-auto-save-original (symbol-function 'do-auto-save))
474 (defun do-auto-save (&optional no-message current-only)
475 "This function has been modified to wrap the original so that NO-MESSAGE
476 is always set to t, since we auto-save a lot, it spams otherwise.
477 The original doc string is as follows:
479 Auto-save all buffers that need it.
480 This is all buffers that have auto-saving enabled
481 and are changed since last auto-saved.
482 Auto-saving writes the buffer into a file
483 so that your editing is not lost if the system crashes.
484 This file is not the file you visited; that changes only when you save.
485 Normally we run the normal hook `auto-save-hook' before saving.
488 A non-nil NO-MESSAGE argument means do not print any message if successful.
489 A non-nil CURRENT-ONLY argument means save only current buffer."
491 (do-auto-save-original t current-only))
493 ;; enable MY auto-save
496 ;;; backups, separate from auto-save
499 ;; set backup file location
500 (setq backup-directory-alist '(("." . "~/.editor-backups")))
501 (setq auto-save-file-name-transforms
502 '((".*" "~/.editor-backups/" t)))
504 (setq version-control t ;; Use version numbers for backups
505 kept-new-versions 100
507 delete-old-versions t ;; delete old versions silently
508 ;; assume hard linked files are done on purpose, don't screw them up
509 backup-by-copying-when-linked t)
511 (defvar last-backup-time 0)
512 ;; todo, the time needs to be an integer, not a vector type thing
513 (defun constant-backup ()
514 "Backup conditioned on some time passing since last one.
515 Hooked into 'before-save-hook."
516 (cl-flet ((b-time (minutes)
518 ;; current-time is seconds, so convert minutes to seconds.
519 (- (current-time) (* 60 minutes)))))
520 (when (or (not (boundp 'last-backup-time)) (and (< (buffer-size) 10000000) (b-time 5)) (b-time 30))
521 (setq buffer-backed-up nil)
522 (setq-local last-backup-time (current-time)))))
524 ;; make a backup on auto-save, because the backup feature is not
525 ;; utilized with my-auto-save, only normal interactive save.
526 ;; todo, enable when fixed
527 ;;(add-hook 'before-save-hook 'constant-backup)
529 (add-hook 'auto-save-hook 'auto-save-size-limit)
531 (defun auto-save-size-limit ()
532 (when (and (not backup-inhibited) (> (buffer-size) 2000000))
533 (message "Backups disabled for this buffer due to size > 2 megs")
534 (make-local-variable 'backup-inhibited)
535 (setq backup-inhibited t)))
539 ;; ;; the faq suggests to auto-save using
540 ;; (setq auto-save-visited-file-name t)
541 ;; and to toggle auto-saving in the current buffer, type `M-x auto-save-mode'
543 ;; however, this is buggy.
544 ;; it leaves around lock files, which can be disabled with
545 ;; (setq create-lockfiles nil)
546 ;; but it is also buggy on other things that appear to hook onto file saving
547 ;; so i created my own function, which originally had bugs,
548 ;; but new emacs version fixed all that, yay!.
551 ;; not using, but here for documentation,
552 ;; alternate way to enable and specify how long between autosaves.
553 ;; number of input events between autosave.
554 ;; lowest bound of functionality is actually about 15 input events
555 ;; (setq auto-save-interval ...)
559 ;; A Theme builder is available at http://elpa.gnu.org/themes/ along with
560 ;; a list of pre-built themes at http://elpa.gnu.org/themes/view.html and
561 ;; themes are available through ELPA.
564 (defun override-theme (arg)
566 (while custom-enabled-themes
567 (disable-theme (car custom-enabled-themes)))
570 ;; not a real var? remove when I see this again
571 ;;(setq color-theme-is-global t)
573 ;; temporary, make night be default
575 (defun toggle-night ()
577 (cond ((equal (car custom-enabled-themes) 'naquadah)
578 (override-theme 'leuven))
580 (override-theme 'naquadah))))
583 ;; in the leuven theme file, i made this change. will need to remake it
584 ;; on package updates. I could fork, but its a pretty simple change
585 ;; < `(default ((,class (:foreground "#333333" :background "#FFFFFF"))))
586 ;; > `(default ((,class (:foreground "#333333" :background "#F6F6F0"))))
587 (override-theme 'leuven)
590 ;; disable color thing with this:
591 ;;(disable-theme (car custom-enabled-themes))
593 ;; decent dark themes
595 ;;(override-theme 'tangotango)
596 ;;(override-theme 'deeper-blue)
597 ;;(override-theme 'tango-dark)
598 ;;(override-theme 'tsdh-dark)
600 ;;(override-theme 'heroku)
601 ;;(override-theme 'inkpot) ;; part of inkpot-theme package
602 ;;(override-theme 'naquadah) ; org mode features, part of naquadah-theme package
603 ;;(override-theme 'spolsky) ;; part of sublime-themes package
604 ;;(override-theme 'twilight-anti-bright) ;; from twilight-anti-bright-theme package
606 ;; interesting but not usable colors
607 ;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package
608 ;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which
609 ;;(override-theme 'misterioso) ; cursor not visible enough
611 ;;decent light themes
612 ;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package
613 ;;(override-theme 'occidental) ; from occidental-theme package
616 ;;color-theme is deprecated in emacs 24.
618 ;; theme packages i tried then removed:
619 ;; ignored ones that didn't use the new theme engine
621 ;;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)
625 ;;; cross session settings
628 ;; defer & commands from jwiegley
630 :commands (recentf-mode
632 recentf-apply-filename-handlers)
635 (setq recentf-max-saved-items 400
636 recentf-max-menu-items 15)
638 ;; save it every 5 minutes. https://www.emacswiki.org/emacs/RecentFiles
639 (run-at-time nil (* 5 60) 'recentf-save-list)
641 (use-package saveplace
642 :unless noninteractive
645 save-place-version-control 'nospecial
646 save-place-limit 4000
647 save-place-file (concat user-emacs-directory "places"))
651 ;; savehist keeps track of some history search entries
652 (use-package savehist
653 :unless noninteractive
655 (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring)
657 savehist-autosave-interval 60
658 ;; keep the home clean
659 savehist-file (concat user-emacs-directory ".savehist"))
664 ;; dired - reuse current buffer by pressing 'a'
665 (put 'dired-find-alternate-file 'disabled nil)
668 ;; copied from dired-x info manual
669 (with-eval-after-load 'dired
671 ;; use e instead for find file. i would like
672 ;; dired-do-async-shell-command, except it pops open some async
673 ;; shell buffer. i should figure out how to get rid of that.
674 (define-key dired-mode-map "f" 'dired-do-shell-command)
675 ;; Set dired-x global variables here. For example:
676 ;; (setq dired-guess-shell-gnutar "gtar")
677 ;; (setq dired-x-hands-off-my-keys nil)
679 (add-hook 'dired-mode-hook
681 ;; Set dired-x buffer-local variables here. For example:
682 ;; (dired-omit-mode 1)
685 ;; the defaults are just some weird predefined list, like xpdf for pdf.
686 (setq dired-guess-shell-alist-user
688 (list ".*" "xdg-open")
693 ;; when manually evaluating lisp, go into debugger on error
694 (setq eval-expression-debug-on-error t)
699 isearch-allow-scroll t
700 search-ring-update t) ;; dont start an edit when going to previous search
702 (defun isearch-yank-regexp (regexp)
703 "Pull REGEXP into search regexp."
704 (let ((isearch-regexp nil)) ;; Dynamic binding of global.
705 (isearch-yank-string regexp))
706 (isearch-search-and-update))
708 (defun isearch-yank-symbol (&optional partialp backward)
709 "Put symbol at current point into search string.
711 If PARTIALP is non-nil, find all partial matches."
714 (let (from to bound sym)
716 ; this block taken directly from find-tag-default
717 ; we couldn't use the function because we need the internal from and to values
719 ;; Look at text around `point'.
721 (skip-syntax-backward "w_") (setq from (point)))
723 (skip-syntax-forward "w_") (setq to (point)))
725 ;; Look between `line-beginning-position' and `point'.
727 (and (setq bound (line-beginning-position))
728 (skip-syntax-backward "^w_" bound)
729 (> (setq to (point)) bound)
730 (skip-syntax-backward "w_")
731 (setq from (point))))
732 ;; Look between `point' and `line-end-position'.
734 (and (setq bound (line-end-position))
735 (skip-syntax-forward "^w_" bound)
736 (< (setq from (point)) bound)
737 (skip-syntax-forward "w_")
739 (buffer-substring-no-properties from to)))
741 (message "No symbol at point"))
743 (goto-char (1+ from)))
745 (goto-char (1- to))))
748 (isearch-yank-string sym)
750 (concat "\\_<" (regexp-quote sym) "\\_>")))))
752 (defun isearch-current-symbol (&optional partialp)
753 "Incremental search forward with symbol under point.
755 Prefixed with \\[universal-argument] will find all partial
758 (let ((start (point)))
759 (isearch-forward-regexp nil 1)
760 (isearch-yank-symbol partialp)))
763 (defun isearch-backward-current-symbol (&optional partialp)
764 "Incremental search backward with symbol under point.
766 Prefixed with \\[universal-argument] will find all partial
769 (let ((start (point)))
770 (isearch-backward-regexp nil 1)
771 (isearch-yank-symbol partialp)))
774 ;; automatically wrap to the top of the buffer when isearch fails
775 (defadvice isearch-search (after isearch-no-fail activate)
776 (unless isearch-success
777 (ad-disable-advice 'isearch-search 'after 'isearch-no-fail)
778 (ad-activate 'isearch-search)
779 (isearch-repeat (if isearch-forward 'forward))
780 (ad-enable-advice 'isearch-search 'after 'isearch-no-fail)
781 (ad-activate 'isearch-search)))
783 ;; Activate occur easily inside isearch
784 (define-key isearch-mode-map (kbd "C-o")
785 (lambda () (interactive)
786 (let ((case-fold-search isearch-case-fold-search))
787 (occur (if isearch-regexp
789 (regexp-quote isearch-string))))))
790 ;;; lisp / elisp mode setings
792 (add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save)
793 (defun starter-kit-remove-elc-on-save ()
794 "If you're saving an elisp file, likely the .elc is no longer valid."
795 (make-local-variable 'after-save-hook)
796 (add-hook 'after-save-hook
798 (if (file-exists-p (concat buffer-file-name "c"))
799 (delete-file (concat buffer-file-name "c"))))))
802 (defun emacs-lisp-mode-defaults ()
803 ;; checkdoc has an annoying feature that wants a header and footer
804 ;; in every elisp buffer as if they all were packages
805 ;; todo, see if there is a way
806 ;; to make checkdoc usable instead of just disabling it as I do here
807 (if (boundp 'flycheck-checkers)
808 (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers)))
810 (add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults)
812 (define-key lisp-mode-map (kbd "<M-up>") 'backward-up-list)
813 (define-key lisp-mode-map (kbd "<M-down>") 'down-list)
814 (define-key emacs-lisp-mode-map (kbd "<M-up>") 'backward-up-list)
815 (define-key emacs-lisp-mode-map (kbd "<M-down>") 'down-list)
816 (define-key emacs-lisp-mode-map (kbd "<M-escape>") 'find-function-at-point)
818 ;; interactive modes don't need whitespace checks
819 (defun interactive-lisp-coding-defaults ()
820 (whitespace-mode -1))
822 ;;; modes with little configuration needed
826 (custom-set-variables
827 '(css-indent-offset 2)
828 '(sh-here-document-word "'EOF'")
829 '(outline-minor-mode-prefix "
\ 3\ 1")
830 '(tramp-default-method "ssh")
831 ;; change last thing from gnu.
832 ;; notably this avoids brace indent after if, and 4 space indent
833 ;; for emacs itself, use
834 ;; (setq c-default-style '((java-mode . "java")
835 ;; (awk-mode . "awk")
837 ;; (setq-default c-basic-offset 2)
838 '(c-default-style '((java-mode . "java")
840 (other . "stroustrup")))
845 ;; ediff-buffers is the main command to use
846 ;; don't start another frame for the control panel
847 ;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers
848 ;; so disable this temporarily with the next line if you want that
849 ;; sometime I should setup 2 functions to explicitly do each type
850 ediff-window-setup-function 'ediff-setup-windows-plain
851 ;;(setq ediff-window-setup-function 'ediff-setup-windows-default)
852 ;; do side by side diffs
853 ediff-split-window-function 'split-window-horizontally
854 ;; ediff things I tried which didn't work, which intuitively I think should
855 ;; work better: I can open the second diff buffer in a new frame, and
856 ;; close it's window in the first frame after starting ediff, but when I
857 ;; hit n to go to the next diff, it restores the window in the first
858 ;; frame. Another thing I tried is to open 2 new frames and set them up
859 ;; as I want. However, if I try to open the *Ediff Control Panel* buffer
860 ;; in a different window from its original one, my mouse jumps to one of
861 ;; the diff frames, or if that isn't visible, the buffer just hangs
862 ;; until I select the original ediff control panel window. This seems
863 ;; like a bug to me. I am using a very recent development version of
868 ;; disabled temporarily. todo, look into it
869 ;;(add-hook 'outline-minor-mode-hook 'outshine-mode)
873 ;; this file includes setting up my email addresses, which are not public,
875 ;; mu4e-user-mail-address-list
877 ;; inspired by mu4e info manual, search for mu4e-compose-pre-hook.
878 (when (file-exists-p "/p/c/mymu4e.el")
879 (load "/p/c/mymu4e.el"))
882 (when (file-exists-p "/a/h/iank-mod.el")
883 (load-file "/a/h/iank-mod.el"))
885 ;; from when i was running my own patches
886 ;;(add-to-list 'load-path "/a/opt/ws-butler")
889 ;; todo: I think this is broken, it keeps collapsing the last line
890 ;; for empty messages.
892 ;; the main problem is when it deletes the blank line at the end
893 ;; of a message with an empty body. but I might also
894 ;; be pasting whitespace significant things in here, so
895 ;; just don't do anything.
896 ;; todo: propose this upstream
897 ;; fundamental mode for files like .asc
898 (add-to-list 'ws-butler-global-exempt-modes 'message-mode)
899 (add-to-list 'ws-butler-global-exempt-modes 'dns-mode)
900 (add-to-list 'ws-butler-global-exempt-modes 'fundamental-mode)
902 (ws-butler-global-mode)
904 ;; disabled because i dont edit nginx files enough
905 ;; to have this loaded at startup
906 ;;(use-package nginx-mode)
907 ;;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:
908 ;;(add-to-list 'auto-mode-alist '("/etc/nginx/sites-available/.*" . nginx-mode))
910 ;; todo, put this on a hook with prog mode
911 ;;(highlight-indentation-mode 1)
914 ;; example of a syntax highlighted tail
915 (use-package autorevert
918 (defvar prev-auto-revert-max)
919 (defun tail-colorize ()
920 (ansi-color-apply-on-region prev-auto-revert-max (point-max))
921 (setq-local prev-auto-revert-max (point-max)))
922 (add-hook 'auto-revert-tail-mode-hook
926 "/var/log/cloudman/development/cm-service.log")
927 (setq-local prev-auto-revert-max 0)
928 ;; set buffer-local hook
929 (add-hook 'after-revert-hook 'tail-colorize nil t))))
932 ;; delete active selection with self-insert commands
933 (delete-selection-mode t)
935 ;; Transparently open compressed files
936 (auto-compression-mode t)
938 ;; dot mode, repeats last action
940 (add-hook 'find-file-hook 'dot-mode-on)
942 ;; clean up obsolete buffers automatically at midnight
945 ;; saner regex syntax
946 (require 're-builder)
947 (setq reb-re-syntax 'string)
950 ;; show the name of the current function definition in the modeline
951 (setq which-func-modes t)
952 (which-function-mode 1)
954 ;; enable winner-mode to manage window configurations
957 ;; meaningful names for buffers with the same name
959 (setq uniquify-buffer-name-style 'forward
960 uniquify-separator "/"
961 ;; for sdx work. until I figure out a better way.
962 ;; maybe something like projectile can do it,
963 ;; or hacking around the status bar
964 uniquify-min-dir-content 2
965 uniquify-after-kill-buffer-p t ; rename after killing uniquified
966 uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
969 ;; makefiles require tabs
970 ;; todo: find a makefile indent function that works,
971 ;; best I could find is this one which means don't indent at all
973 (add-hook 'makefile-mode-hook
975 (setq indent-tabs-mode t)
976 (setq indent-line-function (lambda () 'no-indent))))
979 ;; todo, turn on auto-fill just for txt files
980 ;;(add-hook 'text-mode-hook 'turn-on-auto-fill)
982 ;; random extra highlights
983 (require 'volatile-highlights)
984 (volatile-highlights-mode t)
987 ;; make help buffers smaller when it makes sense
988 (temp-buffer-resize-mode 1)
991 (defun my-info-init()
993 ;; based on suggestions in info+.el, I also installed misc-fns, strings, and thingatpt+
994 ;; remove some bad keybinds from info+
995 (define-key Info-mode-map [mouse-4] nil)
996 (define-key Info-mode-map [mouse-5] nil))
998 (add-hook 'info-mode-hook 'my-info-init)
1001 ;;; misc general settings
1004 ;; I tried to look for a function that would set this that is
1005 ;; not part of the emacs interactive customize stuff, but didn't see one
1006 ;; in the faces documentation.
1009 ;; custom-set-faces was added by Custom.
1010 ;; If you edit it by hand, you could mess it up, so be careful.
1011 ;; Your init file should contain only one such instance.
1012 ;; If there is more than one, they won't work right.
1013 '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil))))
1014 '(region ((t nil))))
1017 ;; from tramp manual, use the same ssh controlmaster. I was having problems with
1018 ;; tramp prompting me for a username and pass.
1019 (customize-set-variable 'tramp-use-ssh-controlmaster-options nil)
1022 ;; avoid this stupid prompt when doing sudo-edit
1023 ;; Save auth info to file ~/.authinfo? [y/n/N/e/?]
1024 ;; which doesn't actually use the default N by pressing enter,
1025 ;; and doesn't actually save the 'never' setting like it claims.
1026 ;; todo: file a bug.
1027 auth-source-save-behavior nil
1028 auto-revert-interval 2
1029 ;; fix eof end of file newline
1030 mode-require-final-newline t
1031 require-final-newline t
1032 auto-revert-verbose nil
1033 auto-revert-remote-files t
1034 ;; save bookmarks whenever they are changed instead of just when emacs quits
1035 bookmark-save-flag 1
1036 ;; increase bookmark context size for better functionality
1037 bookmark-search-size 2000
1038 ;; https://www.emacswiki.org/emacs/FillParagraph
1039 ;; make list items start paragraphs.
1040 paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] "
1042 vc-follow-symlinks t
1043 dired-confirm-shell-command nil
1044 dired-deletion-confirmer '(lambda (x) t)
1045 dired-listing-switches "-alh"
1046 dired-recursive-deletes 'always
1047 dired-clean-confirm-killing-deleted-buffers nil
1048 undo-outer-limit 100000000 ; per undo command
1049 undo-limit 500000000 ; undo history limit
1050 undo-strong-limit 600000000 ; undo history limit plus some extra
1056 (add-hook 'text-mode-hook (lambda () (auto-fill-mode t)))
1057 (setq counsel-find-file-at-point t)
1059 (eval-after-load "ido"
1060 ;; easier to read with just spaces as separator
1061 (quote (setf (nth 2 ido-decorations) " ")))
1063 ;; Seed the random-number generator
1066 ;; easier to remember than keybinds
1067 (defalias 'scrypt 'mml-secure-message-encrypt-pgpmime)
1068 (defalias 'sign 'mml-secure-message-sign-pgpmime)
1069 ;; otherwise we get error on sending:
1070 ;; mml-secure-epg-sign: Couldn’t find any signer names; try setting `mml-secure-smime-sign-with-sender'.
1071 ;; i dunno why sign+encrypt doesnt cause this, seems kinda dumb,
1073 (setq mml-secure-openpgp-sign-with-sender t)
1074 ;; i dun use smime, the smime signing fails complaining it doesnt have
1075 ;; my key. todo: learn about smime
1076 (setq mml-secure-smime-sign-with-sender t)
1079 (mml-secure-message-encrypt-pgpmime 'dontsign))
1081 ;; don't highlight the region.
1082 (set-face-background 'region nil)
1084 ;; this fixes save error for python example code
1085 (define-coding-system-alias 'UTF-8 'utf-8)
1087 ;; i don't use frame titles, but if I ever do
1088 ;; this starter kit setting is probably good
1089 (if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b"))))
1092 ;;(prefer-coding-system 'utf-8-unix)
1094 ;; remove ugly 3d box feature
1095 (set-face-attribute 'mode-line nil :box nil)
1097 (add-to-list 'default-frame-alist
1098 '(font . "DejaVu Sans Mono-11"))
1099 ; the default will jump 2 sizes.
1100 (setq text-scale-mode-step 1.1)
1101 (setq font-lock-maximum-decoration t
1102 inhibit-startup-message t
1103 transient-mark-mode t
1104 shift-select-mode nil
1105 truncate-partial-width-windows nil
1106 uniquify-buffer-name-style 'forward
1107 oddmuse-directory (concat user-emacs-directory "oddmuse")
1110 sort-fold-case t ; case insensitive line sorting
1111 global-mark-ring-max 1000
1112 ;; the visible bell seems to lag the ui
1114 ;; turn off audible bell
1115 ;; https://www.emacswiki.org/emacs/AlarmBell
1116 ring-bell-function 'ignore
1118 revert-without-query '(".*")
1119 font-lock-maximum-decoration t) ; probably default and not necesary
1122 (setq-default indent-tabs-mode nil ;; don't use tabs to indent
1126 ;; wrap at word boundaries instead of mid-word
1129 indicate-empty-lines t) ; mark end of buffer
1132 (blink-cursor-mode 0)
1137 ;; enable various commands
1138 (put 'narrow-to-region 'disabled nil)
1139 (put 'narrow-to-page 'disabled nil)
1140 (put 'narrow-to-defun 'disabled nil)
1141 (put 'upcase-region 'disabled nil)
1142 (put 'downcase-region 'disabled nil)
1143 (put 'scroll-left 'disabled nil)
1144 ;; these from graphene, haven't read about them yet
1145 (put 'ido-complete 'disabled nil)
1146 (put 'ido-exit-minibuffer 'disabled nil)
1147 (put 'dired-find-alternate-file 'disabled nil)
1148 (put 'autopair-newline 'disabled nil)
1152 ;;disable and minimize various prompts/messages
1153 (fset 'yes-or-no-p 'y-or-n-p)
1154 (setq confirm-nonexistent-file-or-buffer nil
1155 inhibit-startup-message t
1156 inhibit-startup-echo-area-message t
1157 inhibit-startup-screen t
1158 kill-buffer-query-functions (remq 'process-kill-buffer-query-function
1159 kill-buffer-query-functions))
1162 ;; exit without bothering me
1163 ;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042
1164 (add-hook 'comint-exec-hook
1165 (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil)))
1166 ;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting
1167 ;; apparently this would need to be in some later hook. dunno where is best, but this works
1168 (defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate)
1169 (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions)))
1173 ;; (custom-set-faces
1174 ;; ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin
1175 ;; '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil))))
1176 ;; ;; don't highlight the region
1177 ;; '(region ((t nil))))
1178 (setq-default header-line-format " ")
1181 (setq initial-scratch-message nil)
1184 ;; vertical margin background.
1185 ;; google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html
1186 ;; the xresource doesn't work for me, probably an xmonad thing.
1188 ;; figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search
1190 ;; then M-x customize-face
1192 ;; unchecked some stuff so that it inherits from default.
1194 ;;; misc function definitions
1197 (defun fill-buffer ()
1199 (save-mark-and-excursion
1200 (goto-char (point-min))
1201 (while (= (forward-line) 0)
1205 (defun next-backup-dir ()
1206 "In a directory listing from rsync -n,
1207 Go to the next directory based on where the cursor is."
1209 (let* ((start-col (current-column))
1210 (end-col (progn (skip-chars-forward "^/\n") (current-column)))
1212 (beginning-of-line 1)
1213 (buffer-substring-no-properties (point) (+ (point) end-col)))))
1216 (while (and (not (eobp))
1217 (string= dir (buffer-substring-no-properties (point) (+ (point) end-col))))
1219 (forward-char-same-line start-col)))
1220 ;; copy paste this for fast keybind
1221 ;;(local-set-key (kbd "<kp-enter>"))
1224 (defun goto-buffer-or-find-file (file-name)
1225 "If buffer is with FILE-NAME exists, go to it, else open the file using full path."
1227 (let ((b (get-buffer (file-name-nondirectory file-name))))
1229 (switch-to-buffer b)
1230 (find-file file-name))))
1235 ;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something
1236 (defun unpop-global-mark ()
1237 "Unpop off global mark ring. Does nothing if mark ring is empty."
1239 (when global-mark-ring
1240 (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
1241 (let ((lm (car (last global-mark-ring))))
1242 (set-marker (mark-marker) (marker-position lm) (marker-buffer lm)))
1243 (when (null (mark t)) (ding))
1244 (setq global-mark-ring (nbutlast global-mark-ring))
1245 (goto-char (marker-position (mark-marker)))))
1247 (defun indent-buffer ()
1248 "Indents the entire buffer."
1250 (cond ((derived-mode-p 'org-mode)
1251 (org-indent-region (point-min) (point-max)))
1252 ((derived-mode-p 'python-mode)
1255 (indent-region (point-min) (point-max)))))
1258 ;; TODO doesn't work with uniquify
1259 (defun rename-file-and-buffer ()
1260 "Renames current buffer and file it is visiting."
1262 (let ((name (buffer-name))
1263 (filename (buffer-file-name)))
1264 (if (not (and filename (file-exists-p filename)))
1265 (message "Buffer '%s' is not visiting a file!" name)
1266 (let ((new-name (read-file-name "New name: " filename)))
1267 (cond ((get-buffer new-name)
1268 (message "A buffer named '%s' already exists!" new-name))
1270 (rename-file name new-name 1)
1271 (rename-buffer new-name)
1272 (set-visited-file-name new-name)
1273 (set-buffer-modified-p nil)))))))
1277 (defun sudo-edit (&optional arg)
1279 (if (or arg (not buffer-file-name))
1280 (find-file (concat "/sudo::" (ido-read-file-name "File: ")))
1281 (find-alternate-file (concat "/sudo::" buffer-file-name))))
1285 (defun backward-symbol (arg)
1287 (forward-symbol (- arg)))
1290 ;; make window title be the buffer name
1291 (setq frame-title-format "%b")
1293 (defun my-after-change-major-mode-hook ()
1294 (setq mode-line-mule-info nil
1295 minor-mode-alist nil
1296 mode-line-position nil)) ; todo, make only flymake status show up
1298 (add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook)
1302 (setq focus-follows-mouse t
1303 mouse-autoselect-window t
1305 ;;;; move-mouse-to-point
1306 ;; todo, this is buggy with multiple windows open.
1307 (defun move-mouse-to-point ()
1309 (let* ((pos (posn-col-row (posn-at-point)))
1310 (x (+ (car pos) 2)) ; no idea why this is off by 1-2
1312 (set-mouse-position (selected-frame) x y)))
1316 ;; todo work on org-cycle-emulate-tab
1318 ;; todo, this doesn't work for a non-standard keybind
1319 ;;(setq org-special-ctrl-k t)
1321 ;; todo, generally fix org mode keys
1322 ;; todo, org-mark-element, unbdind from M-h, bind to mark defun key
1324 ;(org-babel-do-load-languages
1325 ; 'org-babel-load-languages
1326 ; '((emacs-lisp . t)
1331 ;; make shell work like interactive bash shell
1332 (setq org-babel-default-header-args:sh
1333 '((:results . "output") (:shebang . "#!/bin/bash -l")))
1335 ;; my patch to output stderr
1336 (setq org-babel-use-error-buffer nil)
1339 ;; org-mode manual suggests these, but I haven't used them.
1340 ;;(global-set-key "\C-cl" 'org-store-link)
1341 ;;(global-set-key "\C-ca" 'org-agenda)
1342 ;; this got in the way of a haskell mode command
1343 ;;(global-set-key "\C-cb" 'org-iswitchb)
1347 ;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix
1349 (setq org-src-fontify-natively t ; make babel blocks nice
1350 org-adapt-indentation nil
1351 org-src-preserve-indentation t
1352 ;; The most basic logging is to keep track of when a TODO item was finished.
1354 ;; use a drawer to keep the logs tidy
1355 org-log-into-drawer t
1356 org-extend-today-until 0
1357 org-startup-truncated nil
1359 org-use-sub-superscripts "{}"
1360 org-export-with-sub-superscripts nil
1361 org-clock-mode-line-total 'today
1362 ;; global STYLE property values for completion
1363 org-global-properties (quote (("STYLE_ALL" . "habit")))
1364 org-special-ctrl-a/e t ;; home and end work special in headlines
1365 org-completion-use-ido t
1366 org-catch-invisible-edits 'smart)
1369 org-default-notes-file "/a/t.org"
1372 ;; modeilne populated from (org-clock-get-clocked-time)
1373 ;; which is populated from the var org-clock-total-time
1374 ;; which is populated by a function which starts from (org-clock-get-sum-start)
1377 (eval-after-load "org"
1378 '(org-clock-persistence-insinuate))
1380 (defun time-to-org-day (time)
1381 (round (time-to-number-of-days
1382 (time-subtract time (list 0 (* 3600 org-extend-today-until) 0)))))
1384 (defun my-org-confirm-babel-evaluate (lang body)
1385 (not (or (string= (buffer-file-name) "/a/t.org")
1387 (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
1390 (defun org-time-stamp-with-time (arg)
1392 ;; '(4) is the argument passed by universal prefix
1393 (org-time-stamp (if arg arg '(4)) t))
1395 ;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables
1396 ;; keywords: proportional font, monospace
1398 (defun variable-pitch-on ()
1399 (variable-pitch-mode 1))
1400 (add-hook 'fundamental-mode-hook 'variable-pitch-on)
1401 (add-hook 'org-mode-hook 'variable-pitch-on)
1402 (add-hook 'text-mode-hook 'variable-pitch-on)
1403 (defun variable-pitch-off ()
1404 (variable-pitch-mode 0))
1405 (add-hook 'yaml-mode-hook 'variable-pitch-off)
1406 (add-hook 'dns-mode-hook 'variable-pitch-off)
1409 (defun my-org-face-init()
1410 (set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family))
1411 (set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family))
1412 (set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family))
1413 (set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family))
1414 (set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family))
1415 (set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family))
1418 (eval-after-load "org" '(my-org-face-init))
1420 (defun remove-org-binds ()
1421 (define-key org-mode-map (kbd "<M-return>") nil)
1422 (define-key org-mode-map (kbd "C-'") nil)
1423 (define-key org-mode-map (kbd "C-y") nil)
1424 (define-key org-mode-map (kbd "<C-return>") nil)
1425 (define-key org-mode-map (kbd "<C-M-kp-enter>") nil)
1426 (define-key org-mode-map (kbd "C-,") nil)
1427 (define-key org-mode-map (kbd "C-M-m") nil)
1428 (define-key org-mode-map (kbd "C-k") nil)
1429 (define-key org-mode-map (kbd "C-j") nil)
1430 (define-key org-mode-map (kbd "C-M-i") nil)
1431 (define-key org-mode-map (kbd "C-M-t") nil)
1432 (define-key org-mode-map (kbd "M-a") 'nil)
1433 (define-key org-mode-map (kbd "C-a") nil)
1434 (define-key org-mode-map (kbd "M-e") nil)
1435 (define-key org-mode-map (kbd "C-e") nil)
1436 (define-key org-mode-map (kbd "C-3") nil)
1437 (define-key org-mode-map (kbd "<M-left>") nil)
1438 (define-key org-mode-map (kbd "<M-right>") nil)
1439 (define-key org-mode-map (kbd "<S-return>") nil)
1440 (define-key org-mode-map (kbd "<tab>") nil)
1441 (define-key org-mode-map (kbd "<C-S-down>") nil)
1442 (define-key org-mode-map (kbd "<C-S-up>") nil)
1443 (define-key org-mode-map (kbd "<S-down>") nil)
1444 (define-key org-mode-map (kbd "<S-up>") nil)
1445 (define-key org-mode-map "\t" nil))
1446 (add-hook 'org-mode-hook 'remove-org-binds)
1448 ;;; prog-mode-defaults
1451 (defun prog-mode-defaults ()
1452 "Default coding hook, useful with any programming language."
1453 ;; so that I can do completion before the dialog pops up
1454 ;;(local-set-key (kbd "<tab>") 'auto-complete)
1455 (local-set-key (kbd "TAB") 'auto-complete)
1456 ;; todo, this is causing error message on loading file, prolly not working
1457 ;;(flycheck-mode +1)
1458 (setq ac-sources (delq 'ac-source-dictionary ac-sources))
1459 (highlight-symbol-mode)
1460 (make-local-variable 'column-number-mode)
1461 ;; this says do autofilling using newcomment.el. The "only" is a misnomer.
1462 (set (make-local-variable 'comment-auto-fill-only-comments) t)
1463 (column-number-mode t)
1465 ;; (turn-on-smartparens-mode)
1468 (font-lock-add-keywords
1469 nil `(("(\\(lambda\\>\\)"
1470 (0 (progn (compose-region (match-beginning 1) (match-end 1)
1471 ,(make-char 'greek-iso8859-7 107))
1473 (add-hook 'prog-mode-hook 'prog-mode-defaults)
1477 ;;; yank auto-indent
1478 ;; automatically indenting yanked text if in programming-modes
1479 (defvar yank-indent-modes
1480 '(LaTeX-mode TeX-mode)
1481 "Modes in which to indent regions that are yanked (or yank-popped).
1482 Only modes that don't derive from `prog-mode' should be listed here.")
1484 (defvar yank-indent-blacklisted-modes
1485 '(python-mode slim-mode haml-mode)
1486 "Modes for which auto-indenting is suppressed.")
1488 (defvar yank-advised-indent-threshold 2000
1489 "Threshold (# chars) over which indentation does not automatically occur.")
1491 (defun yank-advised-indent-function (beg end)
1492 "Do indentation, as long as the region isn't too large."
1493 (if (<= (- end beg) yank-advised-indent-threshold)
1494 (indent-region beg end nil)))
1496 (defadvice yank (after yank-indent activate)
1497 "If current mode is one of 'yank-indent-modes,
1498 indent yanked text (with prefix arg don't indent)."
1499 (if (and (not (ad-get-arg 0))
1500 (not (member major-mode yank-indent-blacklisted-modes))
1501 (or (derived-mode-p 'prog-mode)
1502 (member major-mode yank-indent-modes)))
1503 (let ((transient-mark-mode nil))
1504 (yank-advised-indent-function (region-beginning) (region-end)))))
1506 (defadvice yank-pop (after yank-pop-indent activate)
1507 "If current mode is one of 'yank-indent-modes,
1508 indent yanked text (with prefix arg don't indent)."
1509 (if (and (not (ad-get-arg 0))
1510 (not (member major-mode yank-indent-blacklisted-modes))
1511 (or (derived-mode-p 'prog-mode)
1512 (member major-mode yank-indent-modes)))
1513 (let ((transient-mark-mode nil))
1514 (yank-advised-indent-function (region-beginning) (region-end)))))
1520 ;; # eval: (outline-minor-mode)
1521 ;; # outline-regexp: "\\( *\\)# [*]\\{1,8\\} "
1523 (defun outline-level ()
1524 "Return the depth to which a statement is nested in the outline.
1525 Point must be at the beginning of a header line.
1526 This is actually either the level specified in `outline-heading-alist'
1527 or else the number of characters matched by `outline-regexp'."
1528 (or (cdr (assoc (match-string 0) outline-heading-alist))
1529 (let ((whitespace-end (match-end 1))
1530 (match-begin (match-beginning 0)))
1531 (if (= whitespace-end match-begin)
1532 (- (match-end 0) match-begin)
1533 (- (match-end 0) whitespace-end)
1536 ;;(or (cdr (assoc (match-string 0) outline-heading-alist))
1537 ;; (- (match-end 0) (match-beginning 0))))
1541 ;; avoid stupid git crap like "warning, terminal not fully functional"
1542 (setenv "PAGER" "cat")
1543 ;; don't store successive duplicates in comint command history
1544 (setq comint-input-ignoredups t)
1546 (defun add-mode-line-dirtrack ()
1547 (add-to-list 'mode-line-buffer-identification
1548 '(:propertize (" " default-directory " ") face dired-directory)))
1549 (add-hook 'shell-mode-hook 'add-mode-line-dirtrack)
1552 ;; don't fully understand it, but it works.
1553 ;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs
1554 (defun track-shell-directory/procfs ()
1555 (shell-dirtrack-mode 0)
1556 (add-hook 'comint-preoutput-filter-functions
1559 (when (string-match comint-prompt-regexp str)
1561 (format "/proc/%s/cwd" (process-id
1563 (current-buffer)))))))))
1565 (setq comint-buffer-maximum-size 100000)
1566 (add-to-list 'comint-output-filter-functions 'comint-truncate-buffer)
1569 (shell (generate-new-buffer-name "*shell*")))
1571 (defun shell-wrap (prefix)
1572 "wrap the shell function, automatically generate a new name for a prefix arg"
1578 (add-hook 'shell-mode-hook 'track-shell-directory/procfs)
1579 ;;; spell correction
1581 ispell-program-name "hunspell"
1582 ispell-silently-savep t) ; don't prompt to save personal dictionary
1584 (use-package rw-hunspell
1586 ;; rw-hunspell sets up hunspell dictionary automagically.
1588 (use-package flyspell
1589 :ensure-system-package hunspell
1590 :hook ((prog-mode . flyspell-prog-mode)
1591 (text-mode . turn-on-flyspell)))
1593 ;; Rant: Hunspell SHOULD be standard. its used by firefox and openoffice and
1594 ;; osx. In contrast, the first few words I added to aspell dictionary were
1595 ;; "emacs" "customizable" and "timestamp". Hunspell already has those,
1598 ;; ispell-personal-dictionary does not document where the hunspell
1599 ;; dictionary goes by default, but it is ~/.hunspell_en_US for me
1604 (use-package latex-mode
1607 (setq-default TeX-PDF-mode t) ; use pdf
1608 ;; more sensible defaults based on info manual quickstart
1609 (setq TeX-auto-save t
1611 ;; not documented, but looking at the source, I find this
1612 ;; stops me from being asked what command on every C-c-c
1613 ;; when doing a latex document.
1614 TeX-command-force "LaTeX"
1617 ;;; visible mark mode
1619 ;; since it is not easy to change the mark overlay priority, I change this one.
1620 (setq show-paren-priority 999)
1622 (defface visible-mark-active
1623 '((((type tty) (class mono)))
1624 (t (:background "magenta"))) "")
1626 (defface mouse-cursor-face
1627 '((((type tty) (class mono)))
1628 (t (:background "DeepPink1"))) "")
1631 (require 'visible-mark)
1634 visible-mark-faces '(visible-mark-face1 visible-mark-face2)
1635 visible-mark-forward-faces '(visible-mark-forward-face1)
1636 ;; highlight the last 2 marks
1638 ;; highlight 1 forward mark
1639 visible-mark-forward-max 1)
1640 ;; globally activate visible-mark-mode
1641 (global-visible-mark-mode +1)
1644 ;; todo, it doesn't seem to be exposed in elisp, but it would be nice
1645 ;; if I could define overlay faces to use inverse foreground color
1648 ;; (setq comment-start "<br align=\"left\"")
1651 ;; (setq comment-start "#" comment-padding " ")
1654 ;; graphviz fill, for html left aligned labels
1657 (setq comment-start "<br align=\"left\"/> ")
1658 (setq comment-padding " ")
1659 (setq fill-column 50)
1660 ;; (setq fill-column 30)
1662 ;; (call-interactively 'uncomment-region)
1664 (call-interactively 'comment-region)
1667 (goto-char (region-beginning))
1675 (message "chirp nothing"))
1680 (when (string= (system-name) "kd") (setq vol 60))
1681 ;; speed is there so i can adjust and make it go slow so it plays long enough to adjust in pavucontrol
1682 (start-process-shell-command "ignoreme" nil (format "mpv --speed=1 --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
1683 ;; from https://www.emacswiki.org/emacs/ErcSound
1687 (when (string= (system-name) "tp") (setq vol 80))
1688 ;; speed is there so i can adjust and make it go slow so it plays long enough to adjust in pavucontrol
1689 (start-process-shell-command "ignoreme" nil (format "mpv --speed=.2 --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol)))
1691 (defun erc-my-privmsg-sound (proc parsed)
1692 (let* ((tgt (car (erc-response.command-args parsed)))
1693 (privp (erc-current-nick-p tgt)))
1696 ;; We must return nil. See help for `erc-server-PRIVMSG-functions'
1699 (defun erc-sound-if-not-server (match-type nickuserhost msg)
1700 (unless (string-match "Server:[0-9]+" nickuserhost)
1706 (setq erc-fill-prefix ""
1707 ;; consider invisible frames to be unseen. seems like an obvious default
1708 erc-track-visibility 'visible
1709 ;; switch to buffer where i've been mentioned, etc instead of oldest
1710 erc-track-switch-direction 'importance
1711 ;; defaults minus fill. todo: modify the list instead of specifying it explicitly in case the defaults change
1713 '(autojoin button completion irccontrols list match menu move-to-prompt netsplit networks noncommands readonly ring stamp track)
1716 (add-hook 'erc-server-PRIVMSG-functions
1717 'erc-my-privmsg-sound)
1718 (add-hook 'erc-text-matched-hook 'erc-sound-if-not-server)
1721 (defun rm-file-and-buffer ()
1722 "Removes file connected to current buffer and kills buffer."
1724 (let ((filename (buffer-file-name))
1725 (buffer (current-buffer))
1726 (name (buffer-name)))
1727 (if (not (and filename (file-exists-p filename)))
1728 (error "Buffer '%s' is not visiting a file!" name)
1729 (delete-file filename)
1730 (kill-buffer buffer)
1731 (message "File '%s' successfully removed" filename))))
1733 ;;; persistent registers
1734 ;; This needs to be at the end, because I visit a file, thus setting a
1735 ;; mode, and the mode hook needs to be setup before that.
1737 ;; I'm using persistent registers instead of bookmarks. I dun use them
1738 ;; much, so the added hassle of having to set it within this file is
1739 ;; worth the benefit of only having one concept in my mind.
1742 (?i (file . ,(concat user-emacs-directory "init.el")))
1743 (?o (file . ,"/a/work.org"))
1744 (?t (file . ,"/a/t.org"))
1745 (?s (file . ,"/usr/share/doc/exim4-base/spec.txt.gz"))
1746 (?w (file . ,"/p/w.org"))
1747 (?k (file . ,"/a/bin/ds/Arduino/Model01-Firmware/Model01-Firmware.ino"))
1748 (?x (file . ,"/a/x.txt"))
1750 (set-register (car r) (cadr r)))
1752 (setq undo-outer-limit 100000000 ; per undo command
1753 undo-limit 500000000 ; undo history limit
1754 undo-strong-limit 600000000) ; undo history limit plus some extra
1759 ;; thank god i'm done with undo-tree and the bug where my auto-saveing
1760 ;; would cause it to lose all undo history, strangely especially in
1761 ;; email buffers. it would claim the undo was outside the visible
1764 (use-package undo-fu
1766 (global-unset-key (kbd "C-z")))
1768 (use-package undo-fu-session
1770 (setq undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'")))
1772 (unless (equal (user-uid) 0) ; don't make root owned files
1773 (global-undo-fu-session-mode)
1774 (when (file-exists-p "/p/c/undo-fu-session")
1775 (setq undo-fu-session-directory "/p/c/undo-fu-session"))
1783 (define-prefix-command 'terminal-key-map)
1784 (global-set-key (kbd "\e[") 'terminal-key-map)
1786 (global-set-key (kbd "C-x C-b") 'ibuffer)
1790 ;; Activate occur easily inside isearch
1793 (define-key isearch-mode-map (kbd "C-o")
1794 (lambda () (interactive)
1795 (let ((case-fold-search isearch-case-fold-search))
1796 (occur (if isearch-regexp
1798 (regexp-quote isearch-string))))))
1801 (defun my-isearch-toggle-regexp ()
1803 (isearch-toggle-regexp)
1804 (cond (isearch-regexp
1805 (global-set-key (kbd "C-r") 'isearch-backward-regexp)
1806 (define-key global-map (kbd "<f12>") 'isearch-forward-regexp))
1808 (global-set-key (kbd "C-r") 'isearch-backward)
1809 (define-key global-map (kbd "<f12>") 'isearch-forward))))
1810 (define-key isearch-mode-map (kbd "M-r") 'my-isearch-toggle-regexp)
1813 (define-key Info-mode-map "x" 'Info-follow-nearest-node)
1816 ;;;; single/special keys
1818 ;; todo: this doesnt work. needs <tab>, which doesnt work in terminal. fix that.
1819 (define-key isearch-mode-map (kbd "TAB") 'isearch-query-replace)
1821 ;;;;; f12 - isearch-forward
1822 ;; explained in http://stackoverflow.com/questions/7411920/how-to-bind-search-and-search-repeat-to-c-f-in-emacs
1823 (global-set-key (kbd "<kp-add>") 'isearch-forward)
1824 (global-set-key (kbd "<f12>") 'isearch-forward)
1825 (define-key isearch-mode-map (kbd "<kp-add>") 'isearch-repeat-forward)
1826 (define-key isearch-mode-map (kbd "<f12>") 'isearch-repeat-forward)
1827 ;; get rid of the standard completion binding, always use auto-complete
1828 ;; this didn't work very well
1829 ;;(global-set-key (kbd "TAB") 'auto-complete)
1830 (define-key global-map [remap completion-at-point] 'auto-complete)
1832 ;;;;; end - move-end-of-line
1833 ;; taken from emacs wiki, along with home function
1834 ;; http://www.emacswiki.org/emacs/BackToIndentationOrBeginning
1835 (defun point-in-comment ()
1836 "Determine if the point is inside a comment"
1838 (let ((syn (syntax-ppss)))
1840 (not (nth 3 syn)))))
1841 (defun end-of-code-or-line (arg)
1842 "Move to end of line, or before start of comments depending on situation.
1843 Toggle back and forth positions if we are already at one.
1844 Comments are recognized in any mode that sets syntax-ppss
1848 (let ((start (point))
1849 (bol (save-excursion
1852 (eol (progn (move-end-of-line arg) (point))))
1853 (while (point-in-comment)
1855 (when (= (point) bol)
1857 (throw 'bol (and (not (= eol start)) (>= start (point))))))
1858 (move-end-of-line arg)))
1860 (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)))
1862 ;;;;; home - back-to-indentation
1863 (defun back-to-indentation-or-beginning ()
1865 (if (= (point) (progn (back-to-indentation) (point)))
1866 (if (derived-mode-p 'org-mode)
1867 (org-beginning-of-line)
1868 (beginning-of-line))))
1869 (global-set-key (kbd "<home>") 'back-to-indentation-or-beginning)
1871 ;;;;; s-tab - indent-buffer
1872 ;; This is translated from S-<iso-lefttab> in graphicsal mode. previously, I had
1873 ;; also set (kbd "<S-iso-lefttab>"),
1874 ;; But I stopped because it overrides minor mode mappings, and i don't want to do that, at least not only in graphical mode.
1876 (global-set-key (kbd "<backtab>") 'indent-buffer)
1878 (add-hook 'org-mode-hook
1880 (define-key org-mode-map (kbd "<backtab>") nil)))
1882 ;;;;; s-delete - send-shell
1884 (global-set-key (kbd "<S-delete>") 'send-shell)
1886 ;; optional variables used by send-shell
1887 (setq shell-send-yank-key nil)
1889 (defun repeat-shell ()
1891 "Repeat the last command in shell-mode, displaying the window if needed."
1892 (let ((shell-buffer (get-buffer "*shell*")))
1894 (buffer-window-show shell-buffer)
1895 (let ((original-buffer (current-buffer)))
1897 (setq shell-buffer (current-buffer))
1898 (switch-to-buffer original-buffer)))
1899 (with-current-buffer shell-buffer
1900 (goto-char (point-max))
1901 (call-interactively 'comint-previous-input)
1902 ;; the t flag makes the buffer advance
1903 (comint-send-input nil t))))
1905 (setq compilation-filenames '("Makefile" "makefile"))
1907 (defun get-nearest-compilation-file ()
1908 "Search for the compilation file traversing up the directory tree."
1910 (let ((dir default-directory)
1911 (parent-dir (file-name-directory (directory-file-name default-directory)))
1912 (nearest-compilation-file 'nil))
1913 (while (and (not (string= dir parent-dir))
1914 (not nearest-compilation-file))
1915 (dolist (filename compilation-filenames)
1916 (setq file-path (concat dir filename))
1917 (when (file-readable-p file-path)
1918 (setq nearest-compilation-file file-path)))
1919 (setq dir parent-dir
1920 parent-dir (file-name-directory (directory-file-name parent-dir))))
1921 nearest-compilation-file))
1924 "call run-fun if it is set, else run make if there is a makefile,
1925 else save and repeat last shell command.
1926 run-fun is meant to store file local variables, which show how to
1927 do the main thing we want on this file, generally compile and
1930 example of setting it in a file:
1932 ;; run-fun: merge-test
1935 (if (and (boundp 'run-fun) run-fun)
1937 (let ((makefile (get-nearest-compilation-file)))
1938 (if (and makefile (stringp mode-name) (string= mode-name "C/l"))
1940 "make -f %s" (get-nearest-compilation-file)))
1944 (defun send-shell ()
1946 (send-shell-buffer "*shell*" 'shell (kbd "C-v")))
1948 (defun send-python ()
1950 (send-shell-buffer "*Python*" 'py-shell (kbd "C-v")))
1953 (defun send-shell-buffer (buffer-name &optional init shell-send-yank-key)
1954 "Send current line or region to shell-mode buffer.
1955 When in shell-mode, copy the current line to the
1956 most recently visited visible window.
1958 SHELL-SEND-YANK-KEY: key to use instead
1959 of yank to paste into recent window. This allows compatibility with
1960 modes like org-mode which have their own yank function."
1961 (if (string= (buffer-name) buffer-name)
1962 ;; this section is copied out of comint-send-input
1964 (let ((proc (get-buffer-process (current-buffer))))
1965 (if (not proc) (user-error "Current buffer has no process")
1968 (let* ((pmark (process-mark proc))
1969 (intxt (if (>= (point) (marker-position pmark))
1970 (progn (if comint-eol-on-send (end-of-line))
1971 (buffer-substring pmark (point)))
1972 (let ((copy (funcall comint-get-old-input)))
1977 (if (= (length intxt) 0)
1978 (kill-new (comint-previous-matching-input-string "." 1))
1979 (kill-new intxt)))))
1980 (kill-append "\n" nil)
1981 (select-window (previous-window nil nil 'visible))
1982 (if (and (boundp 'shell-send-yank-key) shell-send-yank-key)
1983 (call-interactively (global-key-binding shell-send-yank-key))
1985 (select-window (next-window nil nil 'visible)))
1990 (setq start (save-excursion (beginning-of-line) (point))
1991 end (save-excursion (end-of-line) (point)))
1992 (let (line-move-visual)
1993 (call-interactively 'next-line)))
1994 (send-comint-input buffer-name start end init))))
1996 ;; supporting functions
1997 (defun send-comint-input (buffer-name start end &optional init)
1998 "Input the region to BUFFER-NAME, assuming it is a comint-derived buffer.
1999 Show BUFFER-NAME if it is not show.
2000 Call INIT if BUFFER-NAME does not exist."
2001 (let ((input (filter-buffer-substring start end)))
2002 (send-comint-string buffer-name input init)))
2004 (defun send-comint-string (buffer-name string &optional init)
2005 "Input the string to BUFFER-NAME, assuming it is a comint-derived buffer.
2006 Show BUFFER-NAME if it is not show.
2007 Call INIT if BUFFER-NAME does not exist."
2008 (let ((buffer (get-buffer buffer-name)))
2010 (message "nobuffer")
2011 ;; save-excursion etc. don't work for (shell), so I do this instead
2012 (if init (let ((original-buffer (current-buffer)))
2013 (funcall init (and (boundp 'send-shell-buffer-name) send-shell-buffer-name))
2014 (switch-to-buffer original-buffer)
2015 (setq buffer (get-buffer buffer-name)))
2016 (error "No existing buffer found and no init function argument. ")))
2017 (buffer-window-show buffer)
2018 (with-current-buffer buffer
2019 (let ((proc (get-buffer-process buffer)))
2020 (goto-char (process-mark proc))
2022 (comint-send-input nil t)))))
2024 (defun buffer-window-show (&optional buffer action)
2025 "Like temp-buffer-window-show, but removed stuff
2026 relevant to it being temp or help."
2028 (with-current-buffer buffer
2029 (when (let ((window-combination-limit
2030 ;; When `window-combination-limit' equals
2031 ;; `temp-buffer' or `temp-buffer-resize' and
2032 ;; `temp-buffer-resize-mode' is enabled in this
2033 ;; buffer bind it to t so resizing steals space
2034 ;; preferably from the window that was split.
2035 (if (or (eq window-combination-limit 'temp-buffer)
2036 (and (eq window-combination-limit
2037 'temp-buffer-resize)
2038 temp-buffer-resize-mode))
2040 window-combination-limit)))
2042 ;;(message "window-combination-limit")
2043 ;;(print window-combination-limit)
2044 (setq window (display-buffer buffer action)))
2045 (setq frame (window-frame window))
2046 (unless (eq frame (selected-frame))
2047 (raise-frame frame))
2048 (setq minibuffer-scroll-window window)
2049 (set-window-hscroll window 0)
2050 ;; Return the window.
2054 ;; when poping help, etc, allow reusing a window in a different frame if it is visible
2055 ;; figured this out after spending quite a while reading doc string for display-buffer
2056 ;; which is the main function which uses this.
2057 ;; it will use other vars or its arg to override this,
2058 ;; but those things are often nil.
2059 ;; aha moments in reading it: ACTION = (FUNCTION-or-FUNCTIONLIST ALIST)
2060 ;; FRAME adds an association to ACTION's alist, but it's not used if ACTION arg is nil.
2061 (setq display-buffer-fallback-action `(,(car display-buffer-fallback-action) . '(reusable-frames . visible)))
2062 ;; stop splitting windows verticallly when I open a buffer or shell
2063 (setq split-height-threshold nil)
2065 ;;;;; s-left arrow - ---
2066 ;; cant be used in terminal
2067 ;; When I had a binding, i did this so org-mode wouldnt clobber it
2068 ;; (add-hook 'org-mode-hook
2070 ;; (define-key org-mode-map (kbd "<S-left>") nil)))
2072 ;;;;; s-right arrow - keyboard-yank-primary
2073 (defun keyboard-yank-primary ()
2075 (let ((mouse-yank-at-point t))
2076 (mouse-yank-primary nil)))
2078 (global-set-key (kbd "<S-right>") 'keyboard-yank-primary)
2079 (add-hook 'org-mode-hook
2081 (define-key org-mode-map (kbd "<S-right>") nil)))
2082 ;;;;; esc --- terminal dup
2083 ;; todo, test out if this can be used
2084 ;;;;; return - new line
2086 ;; todo, this doesn't set the keybind for the help minibuffer
2089 (global-set-key (kbd "\r") 'indent-new-comment-line)
2091 ;; don't use enter for autocomplete, we use tab or something
2092 (define-key ac-completing-map (kbd "<return>") nil)
2093 (define-key ac-completing-map "\r" nil)
2095 (add-hook 'org-mode-hook
2097 ;; copied from org-mode, replace org-enter with org-enter-indent
2098 (org-defkey org-mode-map "\C-m" 'org-return-indent)))
2101 (add-hook 'comint-mode-hook
2103 (define-key comint-mode-map "\r" nil)
2104 (define-key comint-mode-map (kbd "RET") 'comint-send-input)))
2106 (add-hook 'comint-mode-hook
2108 (define-key comint-mode-map "\C-m" nil)
2109 (define-key comint-mode-map "\C-d" nil)))
2111 ;;;;; s-return - auto-correct-prev-word
2112 (global-set-key (kbd "<S-return>") 'flyspell-auto-correct-previous-word)
2113 ;; kp-enter is shift return in terminal
2114 (global-set-key (kbd "<kp-enter>") 'flyspell-auto-correct-previous-word)
2116 ;;;;; s-up arrow - my-contract-region
2117 (global-set-key (kbd "<S-up>") 'my-contract-region)
2118 ;;;;; c-up/down move 8 lines
2120 ;; compiling warns that next-line should be called interactively,
2121 ;; but we would have to do something dumb, like give it a
2122 ;; vector of keys in order to supply the 8 argument
2130 (global-set-key (kbd "<C-up>") 'up-fast)
2131 (global-set-key (kbd "<C-down>") 'down-fast)
2133 ;;;;; c-scroll comint prev/next prompt
2135 (add-hook 'comint-mode-hook
2137 (define-key comint-mode-map (kbd "<C-mouse-4>") 'comint-previous-prompt)
2138 (define-key comint-mode-map (kbd "<C-mouse-5>") 'comint-next-prompt)))
2139 ;;;;; m-scroll prev/next sexp
2140 (global-set-key (kbd "<M-mouse-4>") 'backward-sexp)
2141 (global-set-key (kbd "<M-mouse-5>") 'forward-sexp)
2142 ;;;;; S-scroll expand/contract region
2143 (global-set-key (kbd "<S-mouse-13>") 'my-contract-region)
2144 (global-set-key (kbd "<S-mouse-14>") 'er/expand-region)
2145 (global-set-key (kbd "<S-mouse-4>") 'my-contract-region)
2146 (global-set-key (kbd "<S-mouse-5>") 'er/expand-region)
2148 (defun my-contract-region (arg)
2150 (let ((current-prefix-arg '-))
2151 (call-interactively 'er/expand-region)))
2153 ;; todo: define c-m scroll. i manually set to normal scrolling, i dunno why
2156 ;;;;; c-s-scroll scale text
2158 (global-set-key (kbd "<C-S-mouse-4>") 'text-scale-increase)
2159 (global-set-key (kbd "<C-S-mouse-5>") 'text-scale-decrease)
2160 (global-set-key (kbd "<C-S-mouse-13>") 'text-scale-increase)
2161 (global-set-key (kbd "<C-S-mouse-14>") 'text-scale-decrease)
2162 (global-set-key (kbd "<C-S-down>") 'text-scale-increase)
2163 (global-set-key (kbd "<C-S-up>") 'text-scale-decrease)
2166 ;;;;; s-up arrow er/expand-region
2167 (global-set-key (kbd "<S-down>") 'er/expand-region)
2168 ;;;;; c-left/right move symbol
2170 (global-set-key (kbd "<C-left>") 'backward-symbol)
2171 (global-set-key (kbd "<C-right>") 'forward-symbol)
2175 ;;;;; M-2 shell-cd-to-file
2178 (defun shell-cd-to-file ()
2180 (let ((file (buffer-file-name)))
2182 (send-comint-string "*shell*"
2183 (concat "c " (file-name-directory file))
2185 (message "%s" "shell-cd-to-file: buffer has no file name"))))
2186 (global-set-key (kbd "M-2") 'shell-cd-to-file)
2188 ;;;;; C-M-2 copy-symbol
2189 (global-unset-key (kbd "C-M-2"))
2190 (defun copy-symbol (&optional arg)
2191 "Copy symbol at point into kill-ring"
2193 (kill-new (thing-at-point 'symbol)))
2195 (global-set-key (kbd "C-M-2") 'copy-symbol)
2197 ;;;;; M-3 dot-mode-execute
2199 (global-set-key (kbd "M-3") 'dot-mode-execute)
2201 ;;;;; C-M-3 recenter-top-bottom
2203 (global-set-key (kbd "C-M-3") 'recenter-top-bottom)
2205 ;;;;; C-q org/bicycle-cycle, comint previous arg
2207 (global-set-key (kbd "C-q") 'bicycle-cycle)
2208 (add-hook 'org-mode-hook
2209 (lambda () (define-key org-mode-map (kbd "C-q") 'org-cycle)))
2210 (define-key widget-keymap (kbd "C-q") 'widget-forward)
2211 (add-hook 'comint-mode-hook
2212 (lambda () (define-key comint-mode-map (kbd "C-q") 'comint-insert-previous-argument)))
2214 ;;;;; M-q org/bicycle-cycle global
2216 (add-hook 'org-mode-hook
2218 (define-key org-mode-map (kbd "M-q") 'org-shifttab)))
2219 (global-set-key (kbd "M-q") 'bicycle-cycle-global)
2221 ;;;;; C-M-q quoted-insert
2223 (global-set-key (kbd "C-M-q") 'quoted-insert)
2225 ;;;;; C-w counsel-find-file
2227 (global-set-key (kbd "C-w") 'counsel-find-file)
2231 (global-set-key (kbd "M-w") 'shell-wrap)
2235 ;; todo, make repeated calls to this append the kills
2236 (defun copy-line (&optional arg)
2237 "Copy lines (as many as prefix argument) in the kill ring.
2238 Ease of use features:
2239 - Move to start of next line.
2240 - Appends the copy on sequential calls.
2241 - Use newline as last char even on the last line of the buffer.
2242 - If region is active, copy its lines."
2244 (let ((beg (line-beginning-position))
2245 (end (line-end-position (or arg 1))))
2247 (if (> (point) (mark))
2248 (setq beg (save-excursion (goto-char (mark)) (line-beginning-position)))
2249 (setq end (save-excursion (goto-char (mark)) (line-end-position)))))
2250 (if (eq last-command 'copy-line)
2251 (kill-append (buffer-substring beg end) (< end beg))
2252 (kill-ring-save beg end)))
2253 (kill-append "\n" nil)
2254 ;; dun need cuz I have yank-better
2255 ;;(beginning-of-line (or (and arg (1+ arg)) 2))
2256 (if (and arg (not (= 1 arg))) (message "%d lines copied" arg)))
2258 (global-set-key (kbd "C-e") 'copy-line)
2262 ;;;;; C-r isearch-backward
2264 (global-set-key (kbd "C-r") 'isearch-backward)
2265 (add-hook 'comint-mode-hook
2267 (define-key comint-mode-map (kbd "C-r") 'comint-history-isearch-backward-regexp)))
2272 ;;;;; C-a copy buffer
2275 "Copy entire buffer to clipboard"
2277 (clipboard-kill-ring-save (point-min) (point-max)))
2278 (global-set-key (kbd "C-a") 'copy-all)
2280 ;;;;; C-s - c-x prefix
2281 ;; prefix key binds.
2282 ;; good info http://www.masteringemacs.org/articles/2011/02/08/mastering-key-bindings-emacs/
2283 ;; rebinding the prefix keys are tricky. apparently, some modes ignore any redefinition of a prefix key and use it explicitly,
2284 ;; so you have to dig into their key maps and redo things.
2285 ;; There are 2 simpler alternatives which have their own downsides.
2286 ;; One is cua mode, which I do not like because it smashes 2 keybinds onto 1 and limits what you can do.
2287 ;; The other is keyboard-translate, which translates the key presses before anything else.
2288 ;; The downside is that it translates them when you aren't using them as a prefix.
2289 ;; Since the swaps I'm using are all very accessible, the only downside is some mental jugling when reading docs etc about these keybinds.
2291 ;; I've seen this as an another suggestion, it was a total fail. The prefix command took over both keys.
2292 ;; (define-key key-translation-map [f12] "\C-c")
2293 ;; (define-key key-translation-map "\C-c" [left])
2296 ;;idea to remove the hook later since it is only needed at startup.
2297 ;; did not work however, and there is not a real need to fix it, so I did not investigate
2298 ;;(defun removeSwapHook ()
2299 ;; (remove-hook 'buffer-list-update-hook 'myKeySwap)
2300 ;; (remove-hook 'change-major-mode-hook 'removeSwapHook))
2301 ;;(add-hook 'change-major-mode-hook 'removeSwapHook)
2304 ;; went through almost all the relevant standard hooks,
2305 ;; this overcomes a known bug that (keyboard-translate) does not get applied when running emacs daemon
2306 (add-hook 'buffer-list-update-hook (lambda () (interactive)
2307 (keyboard-translate ?\C-x ?\C-s)
2308 (keyboard-translate ?\C-s ?\C-x)
2309 (keyboard-translate ?\C-c ?\C-d)
2310 (keyboard-translate ?\C-d ?\C-c)))
2314 ;; these all don't work
2315 ;; don't know why this doesn't error but reversing the keys does
2316 ;;(keyboard-translate ?\t ?\M-\t)
2317 ;;(keyboard-translate [M-tab] [tab])
2318 ;; from what i can tell, it wants to use a keyboard-translate-table,
2319 ;; which is a char table, which is a vector indexed by chars,
2320 ;; and mod+tab is not a char (it has too many bits), it is an integer
2321 ;; it actually says it can hold vectors or strings, but that it is obsolete to do so
2322 ;;(characterp ?\M-a)
2323 ;;(characterp ?\C-a)
2325 ;;;;; C-M-s - split-window-vertically
2327 (global-set-key (kbd "C-M-s") 'split-window-vertically)
2329 ;;;;; C-d - C-c prefix
2333 (global-set-key (kbd "M-d") 'run)
2335 ;;;;; C-M-d - split-window-horizontally
2337 (global-set-key (kbd "C-M-d") 'split-window-horizontally)
2340 ;;;;; C-f - kill-whole-line
2342 (global-set-key (kbd "C-f") 'kill-whole-line-wrapper)
2343 (defun kill-whole-line-wrapper (&optional arg)
2344 "If we are at the end of the file, kill backwards instead of doing nothing."
2346 (if (= (point) (point-max))
2347 (kill-whole-line -1)
2348 (kill-whole-line arg)))
2350 ;;;;; M-f - print-var-at-point
2352 (defun print-var-at-point ()
2354 (let ((v (variable-at-point)))
2356 (message "%s: %s" v (symbol-value v))
2357 (message "no symbol found at point"))))
2358 (global-set-key (kbd "M-f") 'print-var-at-point)
2361 ;;;;; C-M-f - kill rest of line
2364 (add-hook 'org-mode-hook
2366 (define-key org-mode-map (kbd "C-M-f") 'org-kill-line)))
2368 (global-set-key (kbd "C-M-f") 'kill-line)
2369 ;;;;; C-g - keyboard-quit
2370 ;;;;; M-g - abort-recursive-edit
2372 (global-set-key (kbd "M-g") 'abort-recursive-edit)
2376 (global-set-key (kbd "C-M-g") 'mu4e)
2378 ;;;;; C-z - undo-only
2379 ;;(global-set-key (kbd "C-z") 'undo-tree-undo)
2380 (global-set-key (kbd "C-z") 'undo-fu-only-undo)
2381 ;;;;; C-M-z - suspend-frame
2382 (global-set-key (kbd "C-M-z") 'suspend-frame)
2383 ;; this is never good in a gui
2384 (when (window-system)
2385 (defun suspend-frame() (interactive)))
2387 ;;;;; C-x - kill-region
2389 (global-set-key (kbd "C-s") 'kill-region)
2391 ;;;;; M-x - counsel-m-x
2394 ;; todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings.
2395 ;; this must be before smex-initialize
2397 smex-save-file (concat user-emacs-directory ".smex-items"))
2400 (global-set-key (kbd "M-x") 'counsel-M-x)
2402 ;;;;; C-M-x - cut-to-register
2404 ;; same args as copy-to-register
2405 (defun cut-to-register (register start end &optional delete-flag region)
2406 (interactive (list (register-read-with-preview "Cut to register: ")
2411 (copy-to-register register start end t region))
2413 (global-set-key (kbd "C-M-x") 'cut-to-register)
2417 (global-set-key (kbd "C-d") 'kill-ring-save)
2418 (add-hook 'c-mode-common-hook
2420 (define-key c-mode-map (kbd "C-d") nil)
2421 (define-key c++-mode-map (kbd "C-d") nil)))
2422 (add-hook 'comint-mode-hook
2424 (define-key comint-mode-map (kbd "C-d") nil)))
2425 ;; the base map is shared by many c-modes, like java
2426 (add-hook 'c-mode-hook
2428 (define-key c-mode-base-map "\C-d" nil)
2429 (define-key c-mode-base-map (kbd "<deletechar>") 'c-electric-delete-forward)))
2432 ;;;;; M-c - delete-other-windows
2434 (define-key global-map "\M-c" 'delete-other-windows)
2436 ;;;;; C-M-c - copy-to-register
2438 (global-set-key (kbd "C-M-c") 'copy-to-register)
2442 (global-set-key (kbd "C-v") 'yank-better)
2446 (defun yank-better (arg)
2447 "Paste, linewise if our kill ends with a newline.
2448 I change the behavior of plain prefix. It makes it not do linewise paste,
2449 because sometimes you want to yank pop and a linewise paste screws that up.
2450 c-u with no number normally makes the point go before the yank.
2451 That is pointless for me, as it would be just as easier and less
2452 thought to pop the mark after yanking cuz it is set to before the mark."
2454 (if (and (not (equal arg '(4))) (string-suffix-p "\n" (current-kill 0 t)))
2455 (beginning-of-line))
2456 (if (and (stringp mode-name) (string= mode-name "Org"))
2457 (call-interactively 'org-yank)
2458 (setq this-command 'yank)
2459 (call-interactively 'yank (and (not (equal arg '(4)))))))
2461 (put 'yank-better 'delete-selection 'yank)
2463 ;;;;; M-v - insert-register
2465 (global-set-key (kbd "M-v") 'insert-register)
2467 ;;;;; C-M-v - yank-pop
2469 (global-set-key (kbd "C-M-v") 'yank-pop)
2471 ;;;;; C-b - other-window
2473 (global-set-key (kbd "C-b") 'other-window)
2475 ;;;;; M-b - isearch-backward-current-symbol
2477 (global-set-key (kbd "M-b") 'isearch-backward-current-symbol)
2479 ;;;;; C-M-b - isearch-current-symbol
2481 (global-set-key (kbd "C-M-b") 'isearch-current-symbol)
2484 ;; in terminal, it's just TAB, duplicate keybind.
2486 ;; in terminal it's duplicated of C-M-i
2487 ;;;;; C-delete - kill-symbol
2489 (global-set-key (kbd "<C-delete>") 'kill-symbol)
2490 (defun kill-symbol (arg)
2492 (kill-region (point) (save-excursion (forward-symbol arg) (point))))
2495 ;;;;; C-M-delete - kill-sexp
2497 (global-set-key (kbd "<C-M-delete>") 'kill-sexp)
2499 ;;;;; C-left-arrow - compile / comint search
2502 (and (bound-and-true-p var)
2503 (not (eq var 'unset))))
2504 (global-set-key (kbd "C-(") 'run)
2506 ;; make compile work from the gtags root dir
2507 (defadvice compile (before pre-compile-advice activate)
2509 (when (set-p ggtags-project-root)
2510 (setq-local compile-saved-dir default-directory)
2511 (setq default-directory ggtags-project-root)))
2512 (defadvice compile (after post-compile-advice activate)
2513 (when (bound-and-true-p compile-saved-dir)
2514 (setq default-directory compile-saved-dir)))
2517 (add-hook 'c-mode-hook (lambda () (define-key c-mode-map (kbd "C-(") 'compile)))
2518 (add-hook 'comint-mode-hook
2520 (define-key isearch-mode-map (kbd "C-(") 'isearch-repeat-backward)
2521 (define-key comint-mode-map (kbd "C-(") 'isearch-backward)))
2524 ;;;;; C-M-left-arrow - org-shiftup
2526 (add-hook 'org-mode-hook
2527 (lambda () (define-key org-mode-map (kbd "C-M-(") 'org-shiftup)))
2529 ;;;;; C-right-arrow - forward-symbol
2530 ;;;;; C-M-right-arrow - org-shiftdown
2531 (add-hook 'org-mode-hook
2532 (lambda () (define-key org-mode-map (kbd "C-M-)") 'org-shiftdown)))
2534 ;;;;; C-backspace - backward-kill-symbol
2536 (define-key terminal-key-map (kbd "4b") 'backward-kill-symbol) ;c-backspace in my konsole
2538 ;; c-w is duplicate in terminal
2539 (global-set-key (kbd "<C-backspace>") 'backward-kill-symbol)
2540 (add-hook 'comint-mode-hook
2542 (define-key comint-mode-map (kbd "<C-backspace>") 'backward-kill-word)))
2543 (defun backward-kill-symbol (arg)
2545 (kill-region (point) (save-excursion (backward-symbol arg) (point))))
2547 ;;;;; C-M-backspace - backward-kill-sexp
2549 (global-set-key (kbd "<C-M-backspace>") 'backward-kill-sexp)
2552 ;;;;; M-8 - delete-window-or-exit
2554 (global-set-key (kbd "M-8") 'delete-window-or-exit)
2556 (defun delete-window-or-exit ()
2557 "Delete window or exit emacs."
2559 (if (condition-case nil (delete-window) (error t))
2560 (if (or (boundp 'server-process) (> (length (frame-list)) 1))
2561 (progn (basic-save-buffer) (delete-frame))
2562 (save-buffers-kill-terminal t))))
2564 ;;;;; C-* - --- terminal
2565 ;;;;; C-M-* - calc-dispatch
2567 (global-set-key (kbd "C-M-*") 'calc-dispatch)
2569 ;;;;; M-9 - kill-buffer
2571 (defun kill-buffer-no-ido ()
2572 "kill-buffer, avoid the ido remapping"
2575 (global-set-key (kbd "M-9") 'kill-buffer-no-ido)
2577 ;; strangely, in simple mode, this is overridden.
2578 ;; I found this map to override, but it didn't work, so it seems its being bound some other way.
2579 ;; I did a grep of the emacs sources, but couldn't find anything.
2580 ;; (define-key universal-argument-map [?9 nil)
2582 ;;;;; C-M-9 - end server edit
2583 ;; save & kill buffer if it was opened externally via emacsclient
2586 (defun server-edit-save ()
2590 (global-set-key (kbd "C-M-9") 'server-edit-save)
2592 ;;;;; C-u - universal-argument
2593 ;;;;; C-M-u - search-keybind
2595 (global-set-key (kbd "C-M-u") 'search-keybind)
2597 (defun search-keybind (regexp &optional nlines)
2598 (interactive (occur-read-primary-args))
2601 (set-buffer "*Help*")
2603 (delete-windows-on "*Help*")
2607 ;; todo: try making use
2608 ;; this is the key in terminal
2609 ;;M-[ 4 d is undefined
2611 ;; previously had this for enhancing graphical keybinds,
2612 ;; but afaik its no help since i want terminal to work
2614 ;; (define-key input-decode-map [?\C-i] [C-i])
2616 ;;;;; C-M-i - query-replace-regexp
2618 (global-set-key (kbd "C-M-i") 'query-replace-regexp)
2619 (add-hook 'flyspell-mode-hook
2620 (lambda () (define-key flyspell-mode-map (kbd "C-M-i") nil)))
2621 (add-hook 'text-mode-hook
2622 (lambda () (define-key text-mode-map (kbd "C-M-i") nil)))
2627 (global-set-key (kbd "C-o") 'occur)
2629 ;;;;; C-M-o - counsel-imenu
2631 (global-set-key (kbd "C-M-o") 'counsel-imenu)
2633 ;;;;; C-p - move-mouse-to-point
2635 (global-set-key (kbd "C-p") 'move-mouse-to-point)
2637 ;;;;; C-M-p - delete-horizontal-space
2639 (global-set-key (kbd "C-M-p") 'delete-horizontal-space)
2641 ;;;;; C-j - pop-to-mark
2643 (defun my-pop-to-mark-command ()
2644 "Jump to mark, and pop a new position for mark off the ring.
2645 \(Does not affect global mark ring\)."
2647 (pop-to-mark-command)
2648 (if (and (derived-mode-p 'org-mode) (outline-invisible-p))
2649 (org-show-context 'mark-goto)))
2651 (global-set-key (kbd "C-j") 'my-pop-to-mark-command)
2652 (add-hook 'ido-setup-hook
2654 (define-key ido-common-completion-map (kbd "C-j") 'ido-select-text)
2656 (add-hook 'lisp-interaction-mode-hook
2658 (define-key lisp-interaction-mode-map (kbd "C-j") nil)))
2661 ;;;;; M-j - previous-error
2663 (global-set-key (kbd "M-j") 'previous-error)
2665 ;;;;; C-M-j - register prefix
2667 (define-key global-map (kbd "C-M-j") ctl-x-r-map)
2668 (define-key ctl-x-r-map "m" 'kmacro-to-register)
2671 ;;;;; C-k - jump-to-register
2674 (global-set-key (kbd "C-k") 'jump-to-register)
2676 ;;;;; M-k - next-error
2678 (global-set-key (kbd "M-k") 'next-error)
2682 (global-set-key (kbd "C-M-k") 'man)
2684 ;;;;; C-l - ivy-switch-buffer
2686 (global-set-key (kbd "C-l") 'ivy-switch-buffer)
2688 ;;;;; C-M-l - move cursor top bottom mid, comint clear screen
2690 (global-set-key (kbd "C-M-l") 'move-to-window-line-top-bottom)
2692 ;;;;; C-; - used in flyspell, not sure what for, otherwise unbound
2693 ;;;;; M-; - comment-dwim
2694 ;;;;; C-M-; - comment-current-line-dwim
2696 (defun comment-current-line-dwim ()
2697 "Comment or uncomment the current line."
2700 (push-mark (beginning-of-line) t t)
2703 (move-beginning-of-line 2))
2704 (global-set-key (kbd "C-M-;") 'comment-current-line-dwim)
2707 ;; terminal/console needs this. otherwise, we could do this
2708 ;; to make C-m be a valid key in graphical mode.
2709 ;; (define-key input-decode-map [?\C-m] [C-m])
2710 ;;;;; C-M-m - recursive grep
2712 (define-key global-map (kbd "C-M-m") 'rgrep)
2715 ;; not recognized by terminal, can't get konsole keydef file to recognize comma,
2716 ;; todo: dig into konsole sources, or try newer version than t8
2718 (add-hook 'flyspell-mode-hook
2719 (lambda () (define-key flyspell-mode-map (kbd "C-,") nil)))
2721 ;;;;; C-M-, - ind-file-in-project
2723 (global-set-key (kbd "C-M-,") 'find-file-in-project)
2725 ;;;;; C-. - find recent file
2727 (add-hook 'flyspell-mode-hook
2728 (lambda () (define-key flyspell-mode-map (kbd "C-.") nil)))
2729 (define-key dot-mode-map (kbd "C-.") nil)
2730 (define-key terminal-key-map (kbd "4c") 'counsel-recentf)
2731 (global-set-key (kbd "C-.") 'counsel-recentf)
2732 (add-hook 'php-mode-hook
2733 (lambda () (define-key php-mode-map (kbd "C-.") nil)))
2737 (define-key dot-mode-map (kbd "C-M-.") nil)
2738 ;; (global-set-key (kbd "C-M-.") 'execute-extended-command)
2740 ;;;;; C-/ - join lines
2742 (defun vim-style-join-line ()
2746 (global-set-key (kbd "C-_") 'vim-style-join-line)
2748 (global-set-key (kbd "C-/") 'vim-style-join-line)
2750 ;;;;; C-M-/ - copy-buffer-file-name
2752 ;; haven't bound this atm, todo, maybe someday?
2753 (defun copy-variable (variable)
2755 (let ((v (variable-at-point))
2756 (enable-recursive-minibuffers t)
2758 (setq val (completing-read (if (symbolp v)
2760 "Describe variable (default %s): " v)
2761 "Describe variable: ")
2764 (or (get vv 'variable-documentation)
2765 (and (boundp vv) (not (keywordp vv)))))
2767 (if (symbolp v) (symbol-name v))))
2768 (list (if (equal val "")
2770 (kill-new (symbol-value variable)))
2772 (defun copy-buffer-file-name ()
2775 ((derived-mode-p 'mu4e-view-mode) (mu4e-message-field-at-point :path))
2776 (t buffer-file-name))
2782 (global-set-key (kbd "C-M-/") 'copy-buffer-file-name)
2786 ;;;;; C-up-arrow - org prev headline
2788 ;; disabled just because i don't want to accidentally hit it
2789 (define-key global-map "\C-_" nil)
2790 (global-set-key (kbd "<C-_>") 'beginning-of-defun)
2792 (add-hook 'org-mode-hook
2794 (define-key org-mode-map (kbd "\C-_") 'outline-previous-visible-heading)))
2799 ;;;;; C-S-up-arrow - winner undo
2801 (global-set-key (kbd "<C-S-_>") 'winner-undo)
2803 ;;;;; C-down-arrow - org next headline
2805 (global-set-key (kbd "<C-kp-enter>") 'end-of-defun)
2807 (add-hook 'org-mode-hook
2809 (define-key org-mode-map (kbd "<C-kp-enter>") 'outline-next-visible-heading)))
2814 ;;;;; C-M-down-arrow - toggle-mark-activation
2816 (defun toggle-mark-activation ()
2822 (global-set-key (kbd "<C-M-kp-enter>") 'toggle-mark-activation)
2824 ;;;;; C-S-down-arrow winner redo
2826 (global-set-key (kbd "<C-S-kp-enter>") 'winner-redo)
2829 ;;;;; C-S-down-arrow - m-x for major mode
2831 ;; todo, update this for ivy
2832 (global-set-key (kbd "<C-S-kp-enter>") 'smex-major-mode-commands)
2834 ;;;;; C-lbracket - ----
2835 ;;;;; C-M-lbracket - scroll-right
2837 (global-set-key (kbd "C-M-[") 'scroll-right)
2839 ;;;;; C-rbracket - fill-paragraph
2841 (global-set-key (kbd "C-]") 'fill-paragraph)
2843 ;;;;; C-M-rbracket - scroll-left
2845 (global-set-key (kbd "C-M-]") 'scroll-left)
2847 ;;;;; C-return - newline-anywhere
2849 (defun newline-anywhere ()
2850 "Add a newline from anywhere in the line."
2853 (newline-and-indent))
2854 ;; todo use alternate keybind make this work for terminal
2855 (global-set-key (kbd "<C-return>") 'newline-anywhere)
2858 ;;;;; M-return - plain newline
2860 (defun plain-newline ()
2863 (global-set-key (kbd "M-RET") 'plain-newline)
2866 ;;;;; C-space - org-edit-special
2868 ;; commented due to new keyboard needing ctrl-space for mark
2869 ;; (kbd "<C-space>") does not work, (kbd "C-SPC") should work
2870 ;; (add-hook 'org-mode-hook
2872 ;; (define-key org-mode-map (kbd "C-SPC") 'org-edit-special)
2873 ;; ;; org-src-mode-map is broken in git version of emacs.
2874 ;; ;; temporarily use this for exiting edit-special mode.
2875 ;; (global-set-key (kbd "C-M--") 'org-edit-src-exit)
2876 ;; (define-key org-src-mode-map (kbd "C-SPC") 'org-edit-src-exit)))
2878 ;;;;; C-M-space - before or under cursor
2880 (global-set-key (kbd "C-M-SPC") 'ispell-word)
2884 (global-set-key (kbd "C-M-4") 'widen)
2886 ;;;;; C-tab-key - query-replace
2889 (global-set-key (kbd "<C-kp-add>") 'query-replace)
2891 ;;;;; C-t - org cycle todo / toggle comint motion
2893 (add-hook 'org-mode-hook
2895 (define-key org-mode-map (kbd "C-t") 'org-todo)))
2899 (defun my-comint-previous-input (arg)
2901 (if (comint-after-pmark-p)
2902 (comint-previous-input arg)
2905 (defun my-comint-next-input (arg)
2907 (if (comint-after-pmark-p)
2908 (comint-next-input arg)
2911 (add-hook 'comint-mode-hook
2913 (define-key comint-mode-map (kbd "C-t") 'comint-toggle-arrow-keys)
2914 (define-key comint-mode-map (kbd "<up>") 'my-comint-previous-input)
2915 (define-key comint-mode-map (kbd "<down>") 'my-comint-next-input)))
2918 (defun comint-toggle-arrow-keys ()
2920 (toggle-arrow-keys comint-mode-map))
2922 (setq-default comint-arrow-movement nil)
2923 (defun toggle-arrow-keys (map)
2924 (cond ((lookup-key map (kbd "<up>"))
2925 (setq-local comint-arrow-movement t)
2926 (define-key map (kbd "<up>") nil)
2927 (define-key map (kbd "<down>") nil))
2929 (setq-local comint-arrow-movement nil)
2930 (define-key map (kbd "<up>") 'my-comint-previous-input)
2931 (define-key map (kbd "<down>") 'my-comint-next-input)
2932 (goto-char (point-max)))))
2934 (eval-after-load "message"
2935 '(define-key message-mode-map (kbd "C-t") 'mail-signature))
2938 ;;;;; C-M-t - org timestamp
2940 (global-set-key (kbd "C-M-t") 'org-time-stamp-with-time)
2942 ;;;;; C-home - start of buffer
2943 ;;;;; C-end - end of buffer
2944 ;;;; right secondary
2945 ;;;;; C-^ - save-buffers-kill-emacs exit quit
2947 (global-set-key (kbd "C-^") 'save-buffers-kill-emacs)
2949 ;;;;; C-M-6 - insert-small-copyright
2951 (defun insert-small-copyright ()
2954 (let ((beg (point)))
2955 (insert "Copyright (C) 2019 Ian Kelling\nThis program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>")
2956 (comment-region beg (point))))
2958 (global-set-key (kbd "C-M-6") 'insert-small-copyright)
2960 ;;;;; M-7 - calc-embedded-word
2962 (global-set-key (kbd "M-7") 'calc-embedded-word)
2964 ;;;;; C-M-7 - insert-full-copyright
2966 (defun insert-full-copyright ()
2969 (let ((beg (point)))
2970 (insert "Copyright (C) 2019 Ian Kelling\n")
2972 (insert "This program is free software: you can redistribute it and/or modify\n")
2973 (insert "it under the terms of the GNU General Public License as published by\n")
2974 (insert "the Free Software Foundation, either version 3 of the License, or\n")
2975 (insert "(at your option) any later version.\n")
2977 (insert "This program is distributed in the hope that it will be useful,\n")
2978 (insert "but WITHOUT ANY WARRANTY; without even the implied warranty of\n")
2979 (insert "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n")
2980 (insert "GNU General Public License for more details.\n")
2982 (insert "You should have received a copy of the GNU General Public License\n")
2983 (insert "along with this program. If not, see <http://www.gnu.org/licenses/>.\n")
2984 (comment-region beg (point))))
2986 (global-set-key (kbd "C-M-7") 'insert-full-copyright)
2989 ;;;;; C-0 - text-scale-reset
2991 (defun text-scale-reset ()
2994 (global-set-key (kbd "C-0") 'text-scale-reset)
2996 ;;;;; C-M-0 - insert-apache
2998 (defun insert-apache ()
3001 (let ((beg (point)))
3002 (insert "Copyright (C) 2017 Ian Kelling\n")
3004 (insert "Licensed under the Apache License, Version 2.0 (the \"License\");\n")
3005 (insert "you may not use this file except in compliance with the License.\n")
3006 (insert "You may obtain a copy of the License at\n")
3008 (insert " http://www.apache.org/licenses/LICENSE-2.0\n")
3010 (insert "Unless required by applicable law or agreed to in writing, software\n")
3011 (insert "distributed under the License is distributed on an \"AS IS\" BASIS,\n")
3012 (insert "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n")
3013 (insert "See the License for the specific language governing permissions and\n")
3014 (insert "limitations under the License.\n")
3015 (comment-region beg (point))))
3016 (global-set-key (kbd "C-M-0") 'insert-apache)
3019 ;;;;; C-M-- - org-edit-src-exit
3022 ;;(global-set-key (kbd "C-y") 'undo-tree-redo)
3023 (global-set-key (kbd "C-y") 'undo-fu-only-redo)
3024 (add-hook 'org-mode-hook
3025 (lambda () (define-key org-mode-map (kbd "C-y") nil)))
3028 ;;;;; C-\ - sr-speedbar-toggle
3029 (global-set-key (kbd "C-\\") 'sr-speedbar-toggle)
3031 ;;;;; C-M-\ - mark-defun
3033 (global-set-key (kbd "C-M-\\") 'mark-defun)
3035 ;;;;; C-h - help-prefix
3037 ;;;;; C-' - val-expression
3039 (global-set-key (kbd "C-'") 'eval-expression)
3041 ;;;;; C-n - unpop to mark
3043 (defun unpop-to-mark-command ()
3044 "Unpop off mark ring. Does nothing if mark ring is empty."
3047 (let ((pos (marker-position (car (last mark-ring)))))
3048 (if (not (= (point) pos))
3050 (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
3051 (set-marker (mark-marker) pos)
3052 (setq mark-ring (nbutlast mark-ring))
3053 (goto-char (marker-position (car (last mark-ring))))))))
3055 (global-set-key (kbd "C-n") 'unpop-to-mark-command)
3057 ;;;;; C-M-n - narrow-to-region
3059 (global-set-key (kbd "C-M-n") 'narrow-to-region)
3061 ;;;;; C-escape - find-tag
3063 (global-set-key (kbd "<C-escape>") 'find-tag)
3067 ;; eval: (outline-minor-mode)
3068 ;; outline-regexp: "\\( *\\);;;\\{1,8\\} "