;;; copyright ;; Copyright (C) 2019 Ian Kelling ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; misc emacs documentation ;;;; how to find auto-saved files that need recovering ;; find a recently dated file in ~/.emacs.d/auto-save-list/, and see the files listed in it. ;; #file# is an auto-save file. It may or may not be different than the file is corresponds to. ;; If it is different, emacs will give a message about recovering it when you open it. ;;;; misc org functions ;; ;; these are usefull with (goto-char) ;; ;; find named entity, other than headline ;; (org-find-entry-with-id "string-number-or-symbol") ;; (org-find-exact-headline-in-buffer "heading" nil t) ;; ;; remove any indent level which is throughout the buffer ;; (org-do-remove-indentation) ;;;; gnus ;; good info http://www.emacswiki.org/emacs/GnusTutorial ;; good info http://www.emacs.uniyar.ac.ru/doc/em24h/emacs183.htm ;; After downloading mailing list archives, once you have an mbox file, ;; there are rather straightforward ways to get it into any mail program, ;; but I will cover gnus, which I use and is a bit tricky. ;; gnus has a native search (limited, too slow for body text searches), and external search engine integration. ;; gnus manual recommends converting to maildir for searching local mail, but importing lots of maildir messages to gnus ;; takes 10+ minutes, so scratch that option. it suggests 2 alternate options ;; mairix. for mbox, it doesn't integrate 100% with gnus, it copies the search results to a mbox ;; and tells gnus to make a group of that mbox and display it. This means the read state won't be persistent, but otherwise ;; works great. ;; local imap server which will use the mbox and provide search. ;; dovecot is modular, theres a dovecot-common which uses recommends to install i guess it's most used modules. Its ;; description is completely not useful. Anyways, I'm not sure if there is any benefit to installing this over just the ;; module we need. ;; pi dovecot-imapd ;; dovecot by default also makes a an inbox folder based on the normal local mail location /var/mail/ ;; those locations are adjustable and well documented via the var mail_location in ;; /etc/dovecot/conf.d/10-mail.conf ;; I forward my local mail, didn't see immediately how to turn off the inbox, but it will always be empty, so I left as ;; is. you could make the var be empty, which apparently has the same effect. ;; Originally just linked the default location ~/.mail, but I changed to altering the config since ~/.mail since it seems ;; other things like postfix use that location ;; based on http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html ;; other links that poped up contained outdated, innacurate information ;; http://sachachua.com/blog/2008/05/geek-how-to-use-offlineimap-and-the-dovecot-mail-server-to-read-your-gmail-in-emacs-efficiently/ ;; http://www.emacswiki.org/emacs/JamesFerguson ;; http://www.sanityinc.com/articles/read-mailing-lists-in-emacs-over-imap/ ;; Within emacs you can move messages between mbox and maildir etc, which is a nice flexibility. ;; doc group for mbox: ;; in gnus, do gnus-group-make-doc-group (G f in groups buffer) and point to the file ;; info about groups created within gnus is stored in ~/.newsrc.eld ;; also stored is a duplication of what email messages are read/unread, ;; what newsgroups are subsribed to and read/unread, ;; probably more stuff, everything that gnus saves. ;; searching the body of the messages, i cut off after a few minutes. ;; i can grep the file in just a couple seconds ;; random side note ;; we can also get mbox from gmane ;; http://notmuchmail.org/howto/#index7h2 ;; gnus can't search mboxes except with its builtin search which is extremely slow. mairix can do mbox files from the command ;; line, but not from within gnus, but from mairix.el, which can then open the results in gnus ;; mbox can be converted to maildir easily, but gnus loads lots of maildir messages extremely slow. it parses all the ;; headers and generates a nov file for each. ;; nnfolder-generate-active-file ;; to reset things, when changing mail group. I duno all the proper way, but it works to delete ;; ~/Mail ~/.newsrc.eld ~/.dribble (or something) ;;;;; mail sources vs select methods background ;; I found this very confusing when first reading through the manual. "mail sources" is a term that does not simply mean ;; sources of mail, it is much narrower for gnus. sources of mail can be either "mail sources" or select methods. Mail ;; sources will move mail to ~/Mail (not sure what format), and split it into groups according to variables. You can use ;; "mail sources" for maildir / imap, but those can also be read via select methods, which do not move the mail from their ;; location, but use them in their native format. This is what I want to do, and I can simply ignore mail ;; sources. Confusing terminology is that "fetching mail" "scanning mail", lots of things mail doesn't mean all mail, it ;; means specifically from "mail sources". The words "articles" and "news" is used in connection with select methods, aka my actual mail. ;;;;; caching background ;; caching: ;; there is also ~/News/cache, filled with a bunch of articles, like 300 megs. can't figure out why. ;; Grepped for caching in the manual, found 2 main things. ;; cache is for 2 purposes. to cache locally, and to keep articles from expiring, called persistence ;; gnus-use-cache, which puts things if they are ;; gnus-cache-enter-articles ;; things go in cache when they are marked certain ways by default, ticked and dormant ;; and read articles are moved out of the cache ;; still no idea why i have a bunch in the cache, but I set a var so that my mail won't get cached ;; I'm gonna delete the cache, and check on it later see what exactly is going in there ;; And of course, I moved ~/News to my encrypted drive and symlinked it ;;; things that should be at the beginning ;; todo, evaluating this manually disables debug on error instead of toggling it ;;(toggle-debug-on-error) ;uncomment to help debug and catch errors ;; packages installed from package manager: i pretty much prioritize repos this way: gnu, then melpa, then marmalade. ;; package-activated-list: ;; ac-dabbrev ac-haskell-process ack-and-a-half alect-themes auctex bash-completion bbdb csv-mode cyberpunk-theme dot-mode expand-region f find-file-in-project flycheck foreign-regexp ggtags ghc gnuplot-mode goto-chg haskell-mode heroku-theme highlight-indentation highlight-symbol htmlize inf-ruby info+ inkpot-theme jedi auto-complete jedi-core epc ctable concurrent key-chord leuven-theme logstash-conf magit git-commit magit-popup misc-fns mouse+ naquadah-theme nginx-mode occidental-theme org paredit pcsv php-mode pkg-info epl popup py-autopep8 python-environment deferred python-info python-mode rainbow-mode rust-mode rw-hunspell s smartparens smex smooth-scroll sr-speedbar strings swiper ivy tabulated-list tangotango-theme thingatpt+ undo-tree vimrc-mode volatile-highlights web-mode with-editor dash async ws-butler yasnippet ;;;; alternate keyboards ;; todo, figure out an easy way to disable this when using external keyboard (if (display-graphic-p) (setq enter-key (kbd "") s-enter-key (kbd "") c-m-enter-key (kbd "") m-enter (kbd "") c-enter (kbd "")) (setq enter-key (kbd "C-m") s-enter-key (kbd "C-8") c-m-enter-key (kbd "C-M-8") m-enter (kbd "M-m") c-enter (kbd "C-8"))) (setq tp (string= (system-name) "tp")) (setq x200 (string= (system-name) "x2")) (setq laptop-keyboard (or tp x200)) ;; Ubiquitous Packages which should be loaded on startup rather than ;; autoloaded on demand since they are likely to be used in every ;; session. (require 'saveplace) (require 'ffap) (require 'uniquify) (require 'ansi-color) (require 'recentf) ;; Better to have a list of packages in here vs installed manually. ;; However, I install manually because sometimes there are two ;; versions and it is not necessarily easy to reconcile that. ;; based on marmalage website front page. (require 'package) ;; little kit to help remove a down server ;; (setq package-archives nil) ;;(add-to-list 'package-archives ;; '("marmalade" . ;; "http://marmalade-repo.org/packages/")) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t) (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) ;; keep our init.el clean, by moving customization elisp to it's own file (setq custom-file "~/.emacs.d/custom.el") (load custom-file 'noerror) ;; undo tree stuff ;; more resilient undo-tree-history if we have their locations set up front. (setq undo-tree-history-directory-alist '(("." . "~/.undo-tree-history"))) ;; Undo in region just happens accidentally, and throws me off, and it's been buggy in the past (setq undo-tree-enable-undo-in-region nil) ;;; abreviations ;; turn on abbrev mode globally (setq-default abbrev-mode t) ;; default abbreviation mode file is .emacs.d/abbrev_defs. ;; add-global-abbrev, add-mode-abbrev for expansion at point ;; if all else fails, edit the abbrev file ;;; auto-complete ;; auto-completion in minibuffer ;; disabled while I look for another alternative ;;(icomplete-mode) (require 'auto-complete-config) (ac-config-default) ;; complete after 1 char instead of default 2 (setq ac-auto-start 1) (setq ac-delay 0.001) (add-to-list 'ac-modes 'org-mode 'sql-mode) (defun ac-common-setup () (add-to-list 'ac-sources 'ac-source-yasnippet)) ;; for org mode completion source taken from wiki. ;; it did not work. no idea why. todo, investigate ;; the ac-sources code is at http://www.emacswiki.org/emacs/AutoCompleteSources ;; i've deleted it here so as to save space and not spam this file ;;(defun my-ac-org-mode () ;; (setq ac-sources (append ac-sources '(ac-source-org)))) ;; this makes the org-self-insert command not do a flyspell spell check. ;; low priority thing to look into sometime (ac-flyspell-workaround) (define-key ac-completing-map (kbd "") nil) (define-key ac-completing-map (kbd "") nil) (define-key ac-completing-map (kbd "") 'ac-expand) (define-key ac-completing-map "\t" 'ac-complete) (define-key ac-completing-map (kbd "") 'ac-complete) ;;; auto-complete readline-complete (require 'readline-complete) ;; not sure how I made these, but I deleted, and ;; it would be nice to make them again sometime ;;(require 'src-loaddefs) ;; disabled cuz broken ;; redefining function in readline-complete so ac-complete only uses readline as a source (defun ac-rlc-setup-sources () "Add me to shell-mode-hook!" (setq ac-sources '(ac-source-shell))) (add-hook 'shell-mode-hook 'ac-rlc-setup-sources) ;; generally unnecessary, but why not (setq explicit-shell-file-name "bash") ;; readline-complete says to add this line. ;; however, it up my procfs directory tracking hook ;; because get-process doesn't notice the child shell. ;; instead, I've removed export EMACS=t from ;; comint-exec-1 (the function which initially sets it) ;; by finding it in emacs sources and redefinind it here ;; and done stty echo in my bashrc ;;(setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash")) (setenv "EMACS" "") (setq explicit-bash-args nil) (setq comint-process-echoes t) ;; default of 30 is way too slow. todo, consider pushing this upstream (setq rlc-attempts 5) (add-to-list 'ac-modes 'shell-mode) ;; readline-complete recommends this (i assume this format), ;; but greping finds no reference in emacs or my .emacs.d ;; so I'm assuming it is for an older emacs ;;(setq explicit-ssh-args '("-t")) (add-hook 'shell-mode-hook (lambda () (define-key shell-mode-map (kbd "") 'auto-complete))) ;;; readline complete fix ;; I need this function here, where INSIDE_EMACS is replaced with RLC_INSIDE_EMACS. ;; ian: last update 2017-1-7. update this periodically from upstream ;; like when we do a major emacs update (defun comint-exec-1 (name buffer command switches) (let ((process-environment (nconc ;; If using termcap, we specify `emacs' as the terminal type ;; because that lets us specify a width. ;; If using terminfo, we specify `dumb' because that is ;; a defined terminal type. `emacs' is not a defined terminal type ;; and there is no way for us to define it here. ;; Some programs that use terminfo get very confused ;; if TERM is not a valid terminal type. ;; ;; There is similar code in compile.el. (if (and (boundp 'system-uses-terminfo) system-uses-terminfo) (list "TERM=dumb" "TERMCAP=" (format "COLUMNS=%d" (window-width))) (list "TERM=emacs" (format "TERMCAP=emacs:co#%d:tc=unknown:" (window-width)))) (list (format "RLC_INSIDE_EMACS=%s,comint" emacs-version)) process-environment)) (default-directory (if (file-accessible-directory-p default-directory) default-directory "/")) proc decoding encoding changed) (let ((exec-path (if (and command (file-name-directory command)) ;; If the command has slashes, make sure we ;; first look relative to the current directory. (cons default-directory exec-path) exec-path))) (setq proc (apply 'start-file-process name buffer command switches))) ;; Some file name handler cannot start a process, fe ange-ftp. (unless (processp proc) (error "No process started")) (let ((coding-systems (process-coding-system proc))) (setq decoding (car coding-systems) encoding (cdr coding-systems))) ;; Even if start-file-process left the coding system for encoding data ;; sent from the process undecided, we had better use the same one ;; as what we use for decoding. But, we should suppress EOL ;; conversion. (if (and decoding (not encoding)) (setq encoding (coding-system-change-eol-conversion decoding 'unix) changed t)) (if changed (set-process-coding-system proc decoding encoding)) proc)) ;;; auto save & backup (setq auto-save-timeout 1) ; idle time before auto-save. ;; main hook for my auto save (add-hook 'auto-save-hook 'my-auto-save) ;; additional hook to try to deal with emacs not auto-saving when a buffer isn't active (add-hook 'window-configuration-change-hook 'my-auto-save-win) ;; this function from mu4e really does not like buffer saving (advice-add 'message-send-and-exit :before 'my-as-off) (advice-add 'message-send-and-exit :after 'my-as-on) ;; avoid window config hook saving too much, it can ;; get into loops in some random situations (setq my-auto-save-last nil) (defun my-auto-save-win () (unless (eq (current-buffer) my-auto-save-last) (my-auto-save (current-buffer)))) (defun my-auto-save (&optional last) (when (and my-as (buffer-file-name) ;; mu4e has a bug right now, undo breaks when saving drafts (not (string= (buffer-file-name) "*draft*")) (buffer-modified-p) (not (org-src-edit-buffer-p))) ;; serial is incremented on each save, so let's do a bit less of them (not (derived-mode-p 'dns-mode)) (setq my-auto-save-last last) (let (message-log-max) ;; a bit of a hack to partially suppress the constant saving in the echo area (with-temp-message "" (basic-save-buffer))))) ;; in the message-send-and-exit advice, got an error because it passed an arg. ;; didn't look into why, just add ignored args. (defun my-as-off (&rest ignore) (interactive) (setq my-as nil)) (defun my-as-off-local (&rest ignore) (interactive) (setq-local my-as nil)) (defun my-as-on (&rest ignore) (interactive) (setq my-as t)) (defun my-as-on-local (&rest ignore) (interactive) (setq-local my-as on)) ;; based on suggestion in the emacs docs, redefine these 2 functions ;; to avoid prompt spamming the user when we do auto-save (defun ask-user-about-supersession-threat (fn) (discard-input) (message "File for %s has changed on disk outside of emacs. Auto-save is overwriting it, however a backup is being created in case that is not what you intended." buffer-file-name) (setq buffer-backed-up nil)) (defadvice ask-user-about-lock (before lock-deactivate-as activate) (make-local-variable 'my-as) (setq my-as nil) (message "proper autosave has been turned off for this buffer because of lock file problem. In this buffer, do M-x my-as-on to reenable")) ;; todo, this doesn't work consistently to override the auto-save message (defalias 'do-auto-save-original (symbol-function 'do-auto-save)) (defun do-auto-save (&optional no-message current-only) "This function has been modified to wrap the original so that NO-MESSAGE is always set to t, since we auto-save a lot, it spams otherwise. The original doc string is as follows: Auto-save all buffers that need it. This is all buffers that have auto-saving enabled and are changed since last auto-saved. Auto-saving writes the buffer into a file so that your editing is not lost if the system crashes. This file is not the file you visited; that changes only when you save. Normally we run the normal hook `auto-save-hook' before saving. A non-nil NO-MESSAGE argument means do not print any message if successful. A non-nil CURRENT-ONLY argument means save only current buffer." (interactive) (do-auto-save-original t current-only)) ;; enable MY auto-save (my-as-on) ;;; backups, separate from auto-save ;; set backup file location (setq backup-directory-alist '(("." . "~/.editor-backups"))) (setq auto-save-file-name-transforms '((".*" "~/.editor-backups/" t))) (setq version-control t ;; Use version numbers for backups kept-new-versions 100 kept-old-versions 2 delete-old-versions t ;; delete old versions silently ;; assume hard linked files are done on purpose, don't screw them up backup-by-copying-when-linked t) ;; todo, the time needs to be an integer, not a vector type thing (defun constant-backup () "Backup conditioned on some time passing since last one. Hooked into 'before-save-hook." (cl-flet ((b-time (minutes) (< last-backup-time (- (current-time) (* 60 minutes))))) (when (or (not (boundp 'last-backup-time)) (and (< (buffer-size) 10000000) (b-time 5)) (b-time 30)) (setq buffer-backed-up nil) (setq-local last-backup-time (current-time))))) ;; make a backup on auto-save, because the backup feature is not ;; utilized with my-auto-save, only normal interactive save. ;; todo, enable when fixed ;;(add-hook 'before-save-hook 'constant-backup) (add-hook 'auto-save-hook 'auto-save-size-limit) (defun auto-save-size-limit () (when (and (not backup-inhibited) (> (buffer-size) 2000000)) (message "Backups disabled for this buffer due to size > 2 megs") (make-local-variable 'backup-inhibited) (setq backup-inhibited t))) ;; ;; background: ;; ;; the faq suggests to auto-save using ;; (setq auto-save-visited-file-name t) ;; and to toggle auto-saving in the current buffer, type `M-x auto-save-mode' ;; however, this is buggy. ;; it leaves around lock files, which can be disabled with ;; (setq create-lockfiles nil) ;; but it is also buggy on other things that appear to hook onto file saving ;; so i created my own function, which originally had bugs, ;; but new emacs version fixed all that, yay!. ; not using, but here for documentation, ; alternate way to enable and specify how long between autosaves. ; number of input events between autosave. ; lowest bound of functionality is actually about 15 input events ;(setq auto-save-interval ;;; bbdb ;; based on bbdb manual ;; also has instructions to initialize upon launching gnus, etc ;; but I figure try this to make sure everything works all the time first (require 'bbdb) (bbdb-initialize 'message) ;; recommended by gnus, ;; but seems like it could be good to have set for other stuff (setq user-full-name "Ian Kelling") ;; general email setting? recommended by mu4e (setq message-kill-buffer-on-exit t) ;; based on emacs24-starter-kit (setq bbdb-offer-save 'auto bbdb-notice-auto-save-file t bbdb-expand-mail-aliases t bbdb-canonicalize-redundant-nets-p t bbdb-complete-name-allow-cycling t) ;; use d instead (add-hook 'bbdb-mode-hook (lambda () (define-key bbdb-mode-map (kbd "C-k") nil))) (require 'bbdb-csv-import) ;;; bookmark settings ; save bookmarks whenever they are changed instead of just when emacs quits (setq bookmark-save-flag 1) ; increase bookmark context size for better functionality (setq bookmark-search-size 2000) ;;; c-like settings ;; change last thing from gnu. ;; notably this avoids brace indent after if, and 4 space indent (setq c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "stroustrup"))) ;; for emacs itself, use ;; (setq c-default-style '((java-mode . "java") ;; (awk-mode . "awk") ;; (other . "gnu"))) ;; (setq-default c-basic-offset 2) ;;; color theme ;; A Theme builder is available at http://elpa.gnu.org/themes/ along with ;; a list of pre-built themes at http://elpa.gnu.org/themes/view.html and ;; themes are available through ELPA. ;; interesting light themes (defun override-theme (arg) (interactive) (while custom-enabled-themes (disable-theme (car custom-enabled-themes))) (load-theme arg t)) (setq color-theme-is-global t) (defun toggle-night () (interactive) (cond ((equal (car custom-enabled-themes) 'naquadah) (override-theme 'occidental)) (t (override-theme 'naquadah)))) ;; for a long time i used leuven plus this, but it doesn't like dark terminal ;;(custom-set-faces `(default ((t (:background "#F6F6F0"))))) (override-theme 'occidental) ;; disable color thing with this: ;;(disable-theme (car custom-enabled-themes)) ;; decent dark themes ;;(override-theme 'tangotango) ;;(override-theme 'deeper-blue) ;;(override-theme 'tango-dark) ;;(override-theme 'tsdh-dark) ;;(override-theme 'heroku) ;;(override-theme 'inkpot) ;; part of inkpot-theme package ;;(override-theme 'naquadah) ; org mode features, part of naquadah-theme package ;;(override-theme 'spolsky) ;; part of sublime-themes package ;;(override-theme 'twilight-anti-bright) ;; from twilight-anti-bright-theme package ;; interesting but not usable colors ;;(override-theme 'cyberpunk) ; cool org mode features, from cyberpunk-theme package ;;(override-theme 'wombat) ; cursor not visible enough. from a wombat package, not sure which ;;(override-theme 'misterioso) ; cursor not visible enough ;;decent light themes ;;(override-theme 'alect-light) ; theres a -alt version, don't see a dif. could use this without dimming. from alect-something package ;;(override-theme 'occidental) ; from occidental-theme package ;;color-theme is deprecated in emacs 24. ;; theme packages i tried then removed: ;; ignored ones that didn't use the new theme engine ;;66 packages (zenburn-theme-2.1, zen-and-art-theme-1.0.1, waher-theme-20130917.7, ujelly-theme-1.0.35, twilight-theme-1.0.0, twilight-bright-theme-20130605.143, twilight-anti-bright-theme-20120713.316, tronesque-theme-1.3, tron-theme-12, toxi-theme-0.1.0, tommyh-theme-1.2, tango-2-theme-1.0.0, sunny-day-theme-20131203.1250, sublime-themes-20140117.323, subatomic-theme-20131011.1048, soothe-theme-0.3.16, soft-morning-theme-20131211.1342, soft-charcoal-theme-20130924.1206, sea-before-storm-theme-0.3, purple-haze-theme-20130929.1751, phoenix-dark-pink-theme-20130905.941, phoenix-dark-mono-theme-20130306.1215, pastels-on-dark-theme-0.3, obsidian-theme-20130920.937, nzenburn-theme-20130513, noctilux-theme-20131019.31, mustang-theme-20130920.939, monokai-theme-0.0.10, molokai-theme-20130828.0, late-night-theme-0.0, jujube-theme-0.1, ir-black-theme-20130302.2355, gruvbox-theme-20131229.1458, gruber-darker-theme-0.6, grandshell-theme-20140118.1003, github-theme-0.0.3, gandalf-theme-0.1, flatland-theme-20131204.858, django-theme-20131022.202, deep-thought-theme-0.1.1, dakrone-theme-20131212.1159, colorsarenice-theme-20131128.1106, color-theme-wombat+-0.0.2, color-theme-wombat-0.0.1, color-theme-twilight-0.1, color-theme-tango-0.0.2, color-theme-solarized-20120301, color-theme-sanityinc-solarized-2.25, color-theme-railscasts-0.0.2, color-theme-monokai-0.0.5, color-theme-molokai-0.1, color-theme-ir-black-1.0.1, color-theme-heroku-1.0.0, color-theme-github-0.0.3, color-theme-eclipse-0.0.2, color-theme-dpaste-0.0.1, color-theme-dawn-night-1.0, color-theme-colorful-obsolescence-0.0.1, color-theme-cobalt-0.0.2, color-theme-20080305.34, clues-theme-20130908.801, busybee-theme-20130920.942, bubbleberry-theme-0.1.2, mblage-theme-20130715.621, anti-zenburn-theme-20140104.1542, ample-zen-theme-0.2) ;;; yasnippet ;; cd ~/.emacs.d/src ;; git clone --recursive https://github.com/capitaomorte/yasnippet ;; touch snippets/.yas-make-groups ;; This all makes it so I can look through the default snippets ;; in the menu bar, but they don't show up elsewhere, because they are ;; mostly things I don't want. (require 'yasnippet) ;; this needs to be before yas-global-mode (setq yas-snippet-dirs (list "~/.emacs.d/snippets")) (yas-global-mode 1) (setq yas-also-auto-indent-first-line t yas-choose-tables-first t yas-use-menu (quote full) ;; this sets ido-prompt as first function yas-prompt-functions '(yas-ido-prompt yas-dropdown-prompt yas-x-prompt yas-completing-prompt yas-no-prompt)) ;; todo, explore this option for wrapping region ;; '(yas/wrap-around-region t)) ;;; cross session settings ;; Save a list of recent files visited. (recentf-mode 1) (setq recentf-max-saved-items 200 recentf-max-menu-items 15) (setq save-place t save-place-version-control 'nospecial save-place-limit 40000 save-place-file "~/.emacs.d/places") ;; savehist keeps track of some history ;; search entries (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring) ;; save every minute savehist-autosave-interval 60 ;; keep the home clean savehist-file "~/.emacs.d/.savehist") (savehist-mode 1) ;;; ediff ;; ediff-buffers is the main command to use ;; ediff - don't start another frame for the control panel ;; unfortunately, this doesn't allow me to use 2 frames for the diff buffers ;; so disable this temporarily with the next line if you want that ;; sometime I should setup 2 functions to explicitly do each type (setq ediff-window-setup-function 'ediff-setup-windows-plain) ;;(setq ediff-window-setup-function 'ediff-setup-windows-default) ;; do side by side diffs (setq ediff-split-window-function 'split-window-horizontally) ;; Things I tried which didn't work, which intuitively I think should ;; work better: I can open the second diff buffer in a new frame, and ;; close it's window in the first frame after starting ediff, but when I ;; hit n to go to the next diff, it restores the window in the first ;; frame. Another thing I tried is to open 2 new frames and set them up ;; as I want. However, if I try to open the *Ediff Control Panel* buffer ;; in a different window from its original one, my mouse jumps to one of ;; the diff frames, or if that isn't visible, the buffer just hangs ;; until I select the original ediff control panel window. This seems ;; like a bug to me. I am using a very recent development version of ;; emacs. ;;; dired ;; dired - reuse current buffer by pressing 'a' (put 'dired-find-alternate-file 'disabled nil) ;;; mu4e ;; alsot tried notmuch, it had some glitches, and it's config has a list ;; of folders which i'd rather not publish, so it's config is archived. ;;(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e") ;;(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") (require 'mu4e) ;; (setq mu4e-headers-results-limit 2000) (setq ;; common to gnus. default sendmail-query-once asks us, then sets this via customize. send-mail-function (quote sendmail-send-it) ;; use the standard imap folders mu4e-sent-folder "/Sent" mu4e-drafts-folder "/Drafts" mu4e-trash-folder "/Trash" ;; reindex new mail this often in seconds ;; show addresses instead of just names mu4e-view-show-addresses t mu4e-use-fancy-chars t mu4e-confirm-quit nil mu4e-headers-leave-behavior 'apply ;; dont ask, do whatever was marked mu4e-headers-fields (delq (assoc :mailing-list mu4e-headers-fields) mu4e-headers-fields) ;; default 500. mu4e-headers-results-limit 1000 ;; tell exim to use from: as envelope from. ;; exim's default is use outgoing_msg_localpart@hostname. mail-specify-envelope-from t ;; looking up the list of maildirs when doing jo from summary ;; can take a few seconds if we have a ton of messages. ;; Only take that time for the first lookup. ;; if we add a new maildir, just restart mu4e for it to be in that list. mu4e-cache-maildir-list t ;; default is 8, way too small for my big monitors mu4e-headers-visible-lines 50 ) ;; fucks up reading unread bookmark. when that is fixed, enable it ;; (setq mu4e-update-interval 60) ;; this file includes setting up my email addresses, which are not public, ;; including ;; mu4e-user-mail-address-list ;; and a function ;; inspired by mu4e info manual, search for mu4e-compose-pre-hook. (load "/p/c/mu4e.el") (defun my-decrypt () ;; use for decrypting in mu4e (interactive) (beginning-of-buffer) (when (search-forward "-----BEGIN PGP MESSAGE-----" nil t) (read-only-mode 0) (let ((start (match-beginning 0)) (end (search-forward "-----END PGP MESSAGE-----" nil t))) (shell-command-on-region start end "gpg2 -dq" nil t shell-command-default-error-buffer t) ))) (add-hook 'mu4e-view-mode-hook 'my-decrypt) (defun mu-set-from-name (regexes) "If we find an address matching regex, then set that address as the to, and whatever was used" (when mu4e-compose-parent-message (let ((found nil)) (while (and regexes (not found)) (setq re (car regexes) regexes (cdr regexes) found (mu4e-message-contact-field-matches mu4e-compose-parent-message :to re))) (when found (setq user-mail-address (cdr found) user-full-name (car found))) found))) (defun mu-set-from (regexes) "If we find an address matching regex, then set that address as the to, and Ian Kelling as the name" (when mu4e-compose-parent-message (let ((found nil)) (while (and regexes (not found)) (setq re (car regexes) regexes (cdr regexes) found (cdr (mu4e-message-contact-field-matches mu4e-compose-parent-message :to re)))) (when found (setq user-mail-address found user-full-name "Ian Kelling")) found))) (defun my-mu4e-to-fsf () "inspired by mu4e info manual, search for mu4e-compose-pre-hook." (cond ((mu-set-from '("iank@fsf.org" "iank@gnu.org"))) ((setq user-mail-address "iank@fsf.org" user-full-name "Ian Kelling")))) ;; on first run mkdir -p /nocow/user/.mufsf; mu index --maildir=/nocow/user/fsfmd (defun mu-exit-wait () (interactive) ;; taken from the mu source (let* ((buf (get-buffer mu4e~proc-name)) (proc (and (buffer-live-p buf) (get-buffer-process buf)))) (mu4e-quit) ;; without sleep, we get database locked by another process error when hitting u ;; if another mu was running. (if proc (sleep-for 0 1000)))) (defun fsf-mu4e () (interactive) (unless (equal mu4e-maildir "/nocow/user/fsfmd") (mu-exit-wait)) (setq ;; fsf monitor is smaller mu4e-headers-visible-lines 15 mu4e-maildir "/nocow/user/fsfmd" mu4e-refile-folder "/Spam" mu4e-index-lazy-check nil mu4e-get-mail-command "true" user-mail-address "iank@fsf.org" mail-signature " -- Ian Kelling | Senior Systems Administrator, Free Software Foundation GPG Key: B125 F60B 7B28 7FF6 A2B7 DF8F 170A F0E2 9542 95DF https://fsf.org | https://gnu.org " mu4e-user-mail-address-list '("iank@fsf.org" "iank@gnu.org") mu4e-maildir-shortcuts '( ("/INBOX" . ?i) ("/sysadmin" . ?a) ("/sec" . ?x) ("/rtcc" . ?c) ("/Drafts" . ?d) ("/Sent" . ?s) ) ) ;; end setq (call-process "/a/exe/lnf" nil nil nil "-T" "/nocow/user/.mufsf" (concat (getenv "HOME") "/.mu")) (add-hook 'mu4e-compose-pre-hook 'my-mu4e-to-fsf) (remove-hook 'mu4e-compose-pre-hook 'my-mu4e-to) (mu4e)) ;; end defun fsf-mu4e ;; it's implemented in mu4e, but not in the actions list for ;; some reason. (add-to-list 'mu4e-view-actions '("browser view" . mu4e-action-view-in-browser) t) ;; normally, you would add to this, but we want to ;; modify unread messages. the first 4 are defined by default. (setq mu4e-bookmarks `( ,(make-mu4e-bookmark :name "Unread messages" ;; old less restrictive unread, for adapting in the future: ;; flag:unread AND NOT flag:trashed AND NOT maildir:/Junk AND NOT maildir:/fwfw AND NOT maildir:/log :query "flag:unread maildir:/INBOX" :key ?u) ,(make-mu4e-bookmark :name "Today's messages" :query "date:today..now" :key ?t) ,(make-mu4e-bookmark :name "Last 7 days" :query "date:7d..now" :key ?w) ,(make-mu4e-bookmark :name "Messages with images" :query "mime:image/*" :key ?p)) ) (defun mu4e-action-msgs-by-this-sender (msg) "In header view, view messages by the sender of the message under point." (let ((from (mu4e-message-field msg :from))) (unless from (mu4e-error "No from header for this message")) ;; from is structured like: (("Anacron" . "root@x2.lan")) (mu4e-headers-search (concat "f:" (cdar from))))) (add-to-list 'mu4e-headers-actions '("from this sender" . mu4e-action-msgs-by-this-sender) t) (add-to-list 'mu4e-view-actions '("from this sender" . mu4e-action-msgs-by-this-sender) t) ;;; elisp settings ; when manually evaluating lisp, go into debugger on error (setq eval-expression-debug-on-error t) ;reminder of useful var: debug-on-error ;;; haskell ;; useful comint-shell mode commands. If not prefaced with *, it means it is not in the haskell custom repl ;; *todo: setup haskell c-t toggle arrow keys ;; tab completion ;; C-q insert prev arg ;; C-( history search ;; c-m-left/right move to next/prev prompts ;; *c-enter, multi-line input ;; *s-delete, send input across windows. (i can implement this) ;; *c-m-l clear screen ;; *haskell-process-interrupt, c-cc terminate job (i can implement this maybe) ;; nice bash/readline functions missing in comint: ;; yank-nth-arg ;; operate-get-next ;; menu-complete ;; usefull comint commands: ;; c-cl : list historic command in temp buffer ;; C-c C-o comint-delete-output ;; comint-restore-input, todo: put this on a randomish c-c key ;; todo: ;; checkout haskell repl functions: ;; c-cv haskell-check, hlint ;; C-M-q prog-indent-sexp ;; c-c. haskell-mode-format-imports ;; C-c M-/ haskell-doc-check-active ;; haskell-process-generate-tags ;; haskell-process-cabal-build ;; haskell-cabal-command.. or something ;; haskell-process-restart ;; C-h v haskell-process-log ;; C-h v haskell-process-show-debug-tips ;; various not immediately useful functions: ;; haskell-process-add-dependency ;; haskell-process-touch-buffer ;; haskell-process-cd ;; haskell-process-unignore ;; haskell-process-reload-devel-main ;; rebind ;; home: C-a haskell-interactive-mode-beginning ;; c-return: C-j haskell-interactive-mode-newline-indent ;; up/down: haskell-interactive-mode-history-next ;; todo haskell mode better binds for: ;; 'haskell-process-load-file ;; 'haskell-process-do-type ;; 'haskell-process-do-info ;; 'inferior-haskell-send-decl ;; commands which don't work in haskell-interactive-mode(hi) vs inferior-haskell-mode(ih, default) ;; functions not in hi: ;; inferior-haskell-find-definition, use tags instead ;; inferior-haskell-find-haddock, todo, test if this works ;; redefined ih to hi ;; switch-to-haskell -> 'haskell-interactive-switch ;; haskell-process-load-file -> inferior-haskell-load-file ;; haskell-process-do-type -> inferior-haskell-type ;; switch-to-haskell -> haskell-interactive-switch ;; inferior-haskell-load-file -> 'haskell-process-load-file ;; haskell-mode installation from source, based on its readme ;; in the git directory, ;; make all ;; remove default option to not link the file (setq haskell-compile-command "ghc -Wall -ferror-spans -fforce-recomp %s") (add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map [?\C-d] nil) (define-key haskell-indentation-mode-map (kbd "") 'haskell-indentation-delete-char))) ;;copied from haskell-mode docs in order to use the new, better, nondefault ;;interactive mode. (eval-after-load "haskell-mode" '(progn (define-key haskell-mode-map (kbd "C-x C-d") nil) (define-key haskell-mode-map (kbd "C-c C-z") 'haskell-interactive-switch) (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-file) (define-key haskell-mode-map (kbd "C-c C-b") 'haskell-interactive-switch) (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type) (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info) (define-key haskell-mode-map (kbd "C-c M-.") nil) (define-key haskell-mode-map (kbd "C-c C-d") nil))) ;; ghc-mod install http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html ;; todo, try this out ;; (autoload 'ghc-init "ghc" nil t) ;;(add-hook 'haskell-mode-hook (lambda () (ghc-init) (flymake-mode))) ;; from the package readme for ghci-completion (require 'ghci-completion) (add-hook 'inferior-haskell-mode-hook 'turn-on-ghci-completion) ;; disable some rebinds. they are set to appropriate keys in the keybinds section (eval-after-load "haskell-mode" '(progn (define-key haskell-mode-map (kbd "C-a") 'nil) (define-key haskell-mode-map (kbd "C-j") 'nil))) (eval-after-load "python-mode" '(progn (define-key python-mode-map (kbd "C-j") nil))) (defun pretty-lambdas-haskell () (font-lock-add-keywords nil `((,(concat "(?\\(" (regexp-quote "\\") "\\)") (0 (progn (compose-region (match-beginning 1) (match-end 1) ,(make-char 'greek-iso8859-7 107)) nil)))))) ;; from haskell-mode manual (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan) (when (window-system) (add-hook 'haskell-mode-hook 'pretty-lambdas-haskell)) ;; added from haskell-mode website install instructions ;(load "/usr/share/emacs/site-lisp/haskell-mode/haskell-site-file") (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) ;;the three indentation modules are mutually exclusive - add at most one. Trying out the "most advanced" (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation) ;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent) ;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent) ;; todo, set this to some other key ;; (local-set-key (kbd "C-e") 'my-haskell-load-and-run) (defun my-haskell-load-and-run () "Loads and runs the current Haskell file." (interactive) (let ((start-buffer (current-buffer))) (inferior-haskell-load-and-run inferior-haskell-run-command) (sleep-for 0 100) (end-of-buffer) (pop-to-buffer start-buffer))) ;; show haskell function in mode line ;; todo, this broke after updating emacs ;;(eval-after-load "which-func" ;; '(add-to-list 'which-func-modes 'haskell-mode)) (add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup) (add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup) (eval-after-load "auto-complete" '(add-to-list 'ac-modes 'haskell-interactive-mode)) (add-hook 'haskell-mode-hook (lambda () (define-key haskell-mode-map (kbd "C-(") (lambda () (interactive) (basic-save-buffer) (haskell-compile) (run-with-timer .3 nil 'repeat-shell))))) (add-hook 'haskell-cabal-mode-hook (lambda () (define-key haskell-cabal-mode-map (kbd "C-(") 'haskell-compile))) (add-hook 'haskell-interactive-mode-hook (lambda () (define-key haskell-interactive-mode-map "\r" nil) (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-return))) (add-hook 'haskell-indentation-mode-hook (lambda () (define-key haskell-indentation-mode-map "\r" nil))) (add-hook 'haskell-interactive-mode-hook (lambda () (define-key haskell-interactive-mode-map (kbd "") 'haskell-interactive-mode-newline-indent))) ;;; isearch (setq isearch-allow-scroll t search-ring-update t) ;; dont start an edit when going to previous search (defun isearch-yank-regexp (regexp) "Pull REGEXP into search regexp." (let ((isearch-regexp nil)) ;; Dynamic binding of global. (isearch-yank-string regexp)) (isearch-search-and-update)) (defun isearch-yank-symbol (&optional partialp backward) "Put symbol at current point into search string. If PARTIALP is non-nil, find all partial matches." (interactive "P") (let (from to bound sym) (setq sym ; this block taken directly from find-tag-default ; we couldn't use the function because we need the internal from and to values (when (or (progn ;; Look at text around `point'. (save-excursion (skip-syntax-backward "w_") (setq from (point))) (save-excursion (skip-syntax-forward "w_") (setq to (point))) (> to from)) ;; Look between `line-beginning-position' and `point'. (save-excursion (and (setq bound (line-beginning-position)) (skip-syntax-backward "^w_" bound) (> (setq to (point)) bound) (skip-syntax-backward "w_") (setq from (point)))) ;; Look between `point' and `line-end-position'. (save-excursion (and (setq bound (line-end-position)) (skip-syntax-forward "^w_" bound) (< (setq from (point)) bound) (skip-syntax-forward "w_") (setq to (point))))) (buffer-substring-no-properties from to))) (cond ((null sym) (message "No symbol at point")) ((null backward) (goto-char (1+ from))) (t (goto-char (1- to)))) (isearch-search) (if partialp (isearch-yank-string sym) (isearch-yank-regexp (concat "\\_<" (regexp-quote sym) "\\_>"))))) (defun isearch-current-symbol (&optional partialp) "Incremental search forward with symbol under point. Prefixed with \\[universal-argument] will find all partial matches." (interactive "P") (let ((start (point))) (isearch-forward-regexp nil 1) (isearch-yank-symbol partialp))) ;; todo, make this (defun isearch-backward-current-symbol (&optional partialp) "Incremental search backward with symbol under point. Prefixed with \\[universal-argument] will find all partial matches." (interactive "P") (let ((start (point))) (isearch-backward-regexp nil 1) (isearch-yank-symbol partialp))) ; lets look through emacs starter kit before we throw this out. ; automatically wrap to the top of the buffer when isearch fails (defadvice isearch-search (after isearch-no-fail activate) (unless isearch-success (ad-disable-advice 'isearch-search 'after 'isearch-no-fail) (ad-activate 'isearch-search) (isearch-repeat (if isearch-forward 'forward)) (ad-enable-advice 'isearch-search 'after 'isearch-no-fail) (ad-activate 'isearch-search))) ;; Activate occur easily inside isearch (define-key isearch-mode-map (kbd "C-o") (lambda () (interactive) (let ((case-fold-search isearch-case-fold-search)) (occur (if isearch-regexp isearch-string (regexp-quote isearch-string)))))) ;;; lisp / elisp mode setings (add-hook 'emacs-lisp-mode-hook 'starter-kit-remove-elc-on-save) (defun starter-kit-remove-elc-on-save () "If you're saving an elisp file, likely the .elc is no longer valid." (make-local-variable 'after-save-hook) (add-hook 'after-save-hook (lambda () (if (file-exists-p (concat buffer-file-name "c")) (delete-file (concat buffer-file-name "c")))))) (defun emacs-lisp-mode-defaults () ;; checkdoc has an annoying feature that wants a header and footer ;; in every elisp buffer as if they all were packages ;; todo, see if there is a way ;; to make checkdoc usable instead of just disabling it as I do here (if (boundp 'flycheck-checkers) (setq flycheck-checkers (remove 'emacs-lisp-checkdoc flycheck-checkers))) (eldoc-mode 1)) (add-hook 'emacs-lisp-mode-hook 'emacs-lisp-mode-defaults) (define-key lisp-mode-map (kbd "") 'backward-up-list) (define-key lisp-mode-map (kbd "") 'down-list) (define-key emacs-lisp-mode-map (kbd "") 'backward-up-list) (define-key emacs-lisp-mode-map (kbd "") 'down-list) (define-key emacs-lisp-mode-map (kbd "") 'find-function-at-point) ;; interactive modes don't need whitespace checks (defun interactive-lisp-coding-defaults () (whitespace-mode -1)) (setq prelude-interactive-lisp-coding-hook 'prelude-interactive-lisp-coding-defaults) ;; ielm is an interactive Emacs Lisp shell (defun ielm-mode-defaults () (run-hooks 'prelude-interactive-lisp-coding-hook) (turn-on-eldoc-mode)) (add-hook 'ielm-mode-hook 'ielm-mode-defaults) ;;; mediawiki (eval-after-load "mediawiki" '(progn (remove-hook 'outline-minor-mode-hook 'mediawiki-outline-magic-keys) (add-hook 'mediawiki-mode-hook (lambda () (define-key mediawiki-mode-map (kbd "C-(") 'mediawiki-save-reload))) ;; mediawiki mode has a bug that it will claim an edit conflict unless you reload after saving. ;; I also like to save with no edit summary for previewing on my local mw instance (defun mediawiki-save-reload () (interactive) (and (mediawiki-save "") (mediawiki-reload))))) ;;; modes with little configuration needed ;; busted: ;;(require 'csv-mode) ;;(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode)) (require 'outshine) (add-hook 'outline-minor-mode-hook 'outshine-hook-function) (add-hook 'emacs-lisp-mode-hook 'outline-minor-mode) (add-hook 'sh-mode-hook 'outline-minor-mode) (setq org-caldav-url "https://cal.iankelling.org" org-caldav-calendar-id "ian" org-caldav-inbox "/p/cal.org") ;;(org-caldav-sync) ;;(require 'dtrt-indent) ;;(setq dtrt-indent-mode t) (setq css-indent-offset 2) (load-file "/a/h/iank-mod.el") ;; from when i was running my own patches ;;(add-to-list 'load-path "/a/opt/ws-butler") (require 'ws-butler) ;; todo: I think this is broken, it keeps collapsing the last line ;; for empty messages. ;; the main problem is when it deletes the blank line at the end ;; of a message with an empty body. but I might also ;; be pasting whitespace significant things in here, so ;; just don't do anything. ;; todo: propose this upstream (add-to-list 'ws-butler-global-exempt-modes 'message-mode) (ws-butler-global-mode) (require 'nginx-mode) ;;The mode should automatically activate for files called nginx.conf and files under /etc/nginx - if not, you can add something like this to your init file: ;;(add-to-list 'auto-mode-alist '("/etc/nginx/sites-available/.*" . nginx-mode)) ;; todo, put this on a hook with prog mode ;;(highlight-indentation-mode 1) (add-hook 'auto-revert-tail-mode-hook (lambda () (when (string= buffer-file-name "/var/log/cloudman/development/cm-service.log") (setq-local prev-auto-revert-max 0) ;; set buffer-local hook (add-hook 'after-revert-hook 'tail-colorize nil t)))) (defun tail-colorize () (ansi-color-apply-on-region prev-auto-revert-max (point-max)) (setq-local prev-auto-revert-max (point-max))) ;; gnu global (require 'ggtags) (add-hook 'c-mode-common-hook (lambda () (ggtags-mode 1) (setq c-label-minimum-indentation 0))) ;; specific to my unusual keybind setup, you may want to ;; pick different keys (define-key ggtags-mode-map (kbd "C-M-o") 'ggtags-find-tag-dwim) (define-key ggtags-mode-map (kbd "C-M-m") 'ggtags-grep) (defun gtags-update-single(filename) "Update Gtags database for changes in a single file" (interactive) (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " ggtags-project-root " ; gtags --single-update " filename ))) (defun gtags-update-current-file() (interactive) (let ((rel-filename (replace-regexp-in-string ggtags-project-root "." (buffer-file-name (current-buffer))))) (gtags-update-single rel-filename))) (defun gtags-update-hook() "Update GTAGS file incrementally upon saving a file" (when (and ggtags-mode ggtags-project-root) (gtags-update-current-file))) (add-hook 'after-save-hook 'gtags-update-hook) ;; i'd like to make some elisp which modifies a keymap to remove ;; all binds which don't match a predicate. ;; I tried setting a keymap to a new keymap, ;; but that didn't register as functional. ;; so I'd need to modify the list in place. (require 'magit) ;; colorize hex colors: use rainbow mode ;; message mode prompted me on first message. ;; a function which describes options then sets this ;; the other options were to use smtp directly or pass to another mail client ;; here we use the standard sendmail interface, which I use postfix for (setq send-mail-function (quote sendmail-send-it)) (require 'spray) (global-set-key (kbd "C-M-w") 'spray-mode) ;; remember, h/l = move. f/s = faster/slower, space = pause, all others quit ;; delete active selection with self-insert commands (delete-selection-mode t) ;; Transparently open compressed files (auto-compression-mode t) ;; Highlight matching parenthesesq when the pointq is on them. ;; not needed since smart paren mode? ;; (show-paren-mode 1) ;; not documented, but looking at the source, I find this ;; stops me from being asked what command on every C-c-c ;; when doing a latex document. (setq TeX-command-force "LaTeX") ;; dot mode, repeats last action (require 'dot-mode) (add-hook 'find-file-hooks 'dot-mode-on) ;; clean up obsolete buffers automatically at midnight (require 'midnight) ;; disabled because it takes 400ms on startup ;; ;; emacs regexes are too limited. ;; (require 'foreign-regexp) ;; ;; perl is most powerful, but javascript is pretty close and ;; ;; I'd rather know javascript stuff than perl ;; (custom-set-variables ;; '(foreign-regexp/regexp-type 'javascript) ;; Choose by your preference. ;; '(reb-re-syntax 'foreign-regexp)) ;; Tell re-builder to use foreign regexp. ;; ;; it would be nice to add documentation to do this for more commands to that package ;; ;; disabled because it's too slow. but I'd still m-x it for advanced replacements ;; ;;(define-key global-map [remap isearch-forward-regexp] 'foreign-regexp/isearch-forward) ;; saner regex syntax (require 're-builder) (setq reb-re-syntax 'string) ;; use shift + arrow keys to switch between visible buffers ;; todo, set these keys to something else (require 'windmove) (windmove-default-keybindings) ;; show the name of the current function definition in the modeline (require 'which-func) (setq which-func-modes t) (which-function-mode 1) ;; enable winner-mode to manage window configurations (winner-mode +1) ;; meaningful names for buffers with the same name (require 'uniquify) (setq uniquify-buffer-name-style 'forward uniquify-separator "/" ;; for sdx work. until I figure out a better way. ;; maybe something like projectile can do it, ;; or hacking around the status bar uniquify-min-dir-content 2 uniquify-after-kill-buffer-p t ; rename after killing uniquified uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers ;; makefiles require tabs ;; todo: find a makefile indent function that works, ;; best I could find is this one which means don't indent at all ;; (add-hook 'makefile-mode-hook (lambda () (setq indent-tabs-mode t) (setq indent-line-function (lambda () 'no-indent)))) ;; todo, turn on auto-fill just for txt files ;;(add-hook 'text-mode-hook 'turn-on-auto-fill) (add-hook 'text-mode-hook 'turn-on-flyspell) ;; auto indent shell script comments (setq sh-indent-comment t) ;; random extra highlights (require 'volatile-highlights) (volatile-highlights-mode t) ;; make help buffers smaller when it makes sense (temp-buffer-resize-mode 1) (require 'info+) ;; based on suggestions in info+.el, I also installed misc-fns, strings, and thingatpt+ ;; remove some bad keybinds from info+ (define-key Info-mode-map [mouse-4] nil) (define-key Info-mode-map [mouse-5] nil) (require 'smooth-scroll) ;; long gnus summary buffers lags too much with this, ;; but I like it enough to leave it enabled by default ;; and crank up the step size to be faster ;; and it doesn't have a way to enable it only for certain modes etc. ;; todo sometime, make it work for certain modes only (smooth-scroll-mode t) ;; its too slow with the default of 2 (setq smooth-scroll/vscroll-step-size 7) ;; sublimity doesn't work as good going fast by default ;; smooth-scrolling.el, does not do smooth scrolling. its about cursor location (setq sh-here-document-word "'EOF'") (setq tramp-default-method "ssh") ;;; misc general settings ;; https://www.emacswiki.org/emacs/FillParagraph ;; make list items start paragraphs. (setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") (setq sh-basic-offset 2) (setq vc-follow-symlinks t) ;; give us a shell to start instead of scratch ;;(setq initial-buffer-choice (lambda () (new-shell))) ;; disable this nasty function, as I always use a gui (defun suspend-frame() (interactive)) ;; Seed the random-number generator (random t) ;; easier to remember than keybinds (defalias 'scrypt 'mml-secure-message-encrypt-pgpmime) (defalias 'sign 'mml-secure-message-sign-pgpmime) (defun encrypt () (interactive) (mml-secure-message-encrypt-pgpmime 'dontsign)) ;; don't highlight the region. (set-face-background 'region nil) ;; this fixes save error for python example code (define-coding-system-alias 'UTF-8 'utf-8) ;; i don't use frame titles, but if I ever do ;; this starter kit setting is probably good (if window-system (setq frame-title-format '(buffer-file-name "%f" ("%b")))) ;;(prefer-coding-system 'utf-8-unix) ;; remove ugly 3d box feature (set-face-attribute 'mode-line nil :box nil) (add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-11")) ; the default will jump 2 sizes. (setq text-scale-mode-step 1.1) (setq font-lock-maximum-decoration t inhibit-startup-message t transient-mark-mode t delete-by-moving-to-trash t shift-select-mode nil truncate-partial-width-windows nil uniquify-buffer-name-style 'forward oddmuse-directory "~/.emacs.d/oddmuse" echo-keystrokes 0.1 mark-ring-max 160 sort-fold-case t ; case insensitive line sorting global-mark-ring-max 1000 ;; the visible bell seems to lag the ui ;;visible-bell t ;; turn off audible bell ;; https://www.emacswiki.org/emacs/AlarmBell ring-bell-function 'ignore case-replace nil revert-without-query '(".*") ;; don't pause display code on input. ;; smoother display performance at slight cost of input performance redisplay-dont-pause t font-lock-maximum-decoration t) ; probably default and not necesary (setq-default indent-tabs-mode nil ;; don't use tabs to indent cursor-type 'box fill-column 72 ;; wrap at word boundaries instead of mid-word word-wrap t imenu-auto-rescan t indicate-empty-lines t) ; mark end of buffer (blink-cursor-mode '(-4)) (menu-bar-mode -1) (tool-bar-mode -1) ;; enable various commands (put 'narrow-to-region 'disabled nil) (put 'narrow-to-page 'disabled nil) (put 'narrow-to-defun 'disabled nil) (put 'upcase-region 'disabled nil) (put 'downcase-region 'disabled nil) (put 'scroll-left 'disabled nil) ;; these from graphene, haven't read about them yet (put 'ido-complete 'disabled nil) (put 'ido-exit-minibuffer 'disabled nil) (put 'dired-find-alternate-file 'disabled nil) (put 'autopair-newline 'disabled nil) ;;disable and minimize various prompts/messages (fset 'yes-or-no-p 'y-or-n-p) (setq confirm-nonexistent-file-or-buffer nil inhibit-startup-message t inhibit-startup-echo-area-message t inhibit-startup-screen t compilation-read-command nil ;; just don't compile with unsafe file local vars kill-buffer-query-functions (remq 'process-kill-buffer-query-function kill-buffer-query-functions)) ;; exit without bothering me ;; http://stackoverflow.com/questions/2706527/make-emacs-stop-asking-active-processes-exist-kill-them-and-exit-anyway/2708042#2708042 (add-hook 'comint-exec-hook (lambda () (set-process-query-on-exit-flag (get-buffer-process (current-buffer)) nil))) ;; based on save-buffers-kill-emacs help string, don't ask about clients when exiting ;; apparently this would need to be in some later hook. dunno where is best, but this works (defadvice save-buffers-kill-emacs (before no-client-prompt-advice activate) (setq kill-emacs-query-functions (delq 'server-kill-emacs-query-function kill-emacs-query-functions))) ;; (custom-set-faces ;; ;; setting header-line-format to " " as a hack for a top margin the oly thning I could find to do a top margin ;; '(header-line ((t (:background "default" :foreground "default" :overline nil :underline nil)))) ;; ;; don't highlight the region ;; '(region ((t nil)))) (setq-default header-line-format " ") (setq initial-scratch-message nil) ;; vertical margin background. ;; google turned up: http://lists.gnu.org/archive/html/help-gnu-emacs/2014-03/msg00544.html ;; the xresource doesn't work for me, probably an xmonad thing. ;; figured out I needed to customize the header line face. To find the face, M-x list-faces-display or just google / search ;; info, ;; then M-x customize-face ;; header-line ;; unchecked some stuff so that it inherits from default. ;;; misc function definitions (defun fill-buffer () (interactive) (save-mark-and-excursion (beginning-of-buffer) (while (= (forward-line) 0) (fill-paragraph)))) (defun next-backup-dir () "In a directory listing from rsync -n, Go to the next directory based on where the cursor is." (interactive) (let* ((start-col (current-column)) (end-col (progn (skip-chars-forward "^/\n") (current-column))) (dir (progn (beginning-of-line 1) (buffer-substring-no-properties (point) (+ (point) end-col))))) (message dir) (forward-line 1) (while (and (not (eobp)) (string= dir (buffer-substring-no-properties (point) (+ (point) end-col)))) (forward-line 1)) (forward-char-same-line start-col))) ;; copy paste this for fast keybind ;;(local-set-key (kbd "")) (defun goto-buffer-or-find-file (file-name) "If buffer is with FILE-NAME exists, go to it, else open the file using full path." (interactive) (let ((b (get-buffer (file-name-nondirectory file-name)))) (if b (switch-to-buffer b) (find-file file-name)))) ;; todo, i think this is broken. perhaps the last goto-char is not accounting for buffer or something (defun unpop-global-mark () "Unpop off global mark ring. Does nothing if mark ring is empty." (interactive) (when global-mark-ring (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring)) (let ((lm (car (last global-mark-ring)))) (set-marker (mark-marker) (marker-position lm) (marker-buffer lm))) (when (null (mark t)) (ding)) (setq global-mark-ring (nbutlast global-mark-ring)) (goto-char (marker-position (mark-marker))))) (defun indent-buffer () "Indents the entire buffer." (interactive) (cond ((derived-mode-p 'org-mode) (org-indent-region (point-min) (point-max))) ((derived-mode-p 'python-mode) (py-autopep8)) (t (indent-region (point-min) (point-max))))) ;; TODO doesn't work with uniquify (defun rename-file-and-buffer () "Renames current buffer and file it is visiting." (interactive) (let ((name (buffer-name)) (filename (buffer-file-name))) (if (not (and filename (file-exists-p filename))) (message "Buffer '%s' is not visiting a file!" name) (let ((new-name (read-file-name "New name: " filename))) (cond ((get-buffer new-name) (message "A buffer named '%s' already exists!" new-name)) (t (rename-file name new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil))))))) (defun sudo-edit (&optional arg) (interactive "P") (if (or arg (not buffer-file-name)) (find-file (concat "/sudo::" (ido-read-file-name "File: "))) (find-alternate-file (concat "/sudo::" buffer-file-name)))) (defun backward-symbol (arg) (interactive "p") (forward-symbol (- arg))) ;;; mode line ;; make window title be the buffer name (setq frame-title-format "%b") ; ----------------------------- ; fixing up the mode line ; modified from mastering emacs blog ; ---------------------------- (defvar mode-line-cleaner-alist `((auto-complete-mode . "") (yas/minor-mode . "") (paredit-mode . "") (auto-fill-function . "") (eldoc-mode . "") (abbrev-mode . "") (flyspell-mode . "") (glasses-mode . "") (dot-mode . "") (yas-global-mode . "") (yas-minor-mode . "") (undo-tree-mode . "") (volatile-highlights-mode . "") (highlight-symbol-mode . "") ;; Major modes (lisp-interaction-mode . "λ") (hi-lock-mode . "") (python-mode . "Py") (emacs-lisp-mode . "EL") (nxhtml-mode . "nx")) "Alist for `clean-mode-line'. When you add a new element to the alist, keep in mind that you must pass the correct minor/major mode symbol and a string you want to use in the modeline *in lieu of* the original.") (defun clean-mode-line () (interactive) (loop for cleaner in mode-line-cleaner-alist do (let* ((mode (car cleaner)) (mode-str (cdr cleaner)) (old-mode-str (cdr (assq mode minor-mode-alist)))) (when old-mode-str (setcar old-mode-str mode-str)) ;; major mode (when (eq mode major-mode) (setq mode-name mode-str))))) ; disabled ; (add-hook 'after-change-major-mode-hook 'clean-mode-line) ;;; alias the new `flymake-report-status-slim' to ;;; `flymake-report-status' (defalias 'flymake-report-status 'flymake-report-status-slim) (defun flymake-report-status-slim (e-w &optional status) "Show \"slim\" flymake status in mode line." (when e-w (setq flymake-mode-line-e-w e-w)) (when status (setq flymake-mode-line-status status)) (let* ((mode-line " Φ")) (when (> (length flymake-mode-line-e-w) 0) (setq mode-line (concat mode-line ":" flymake-mode-line-e-w))) (setq mode-line (concat mode-line flymake-mode-line-status)) (setq flymake-mode-line mode-line) (force-mode-line-update))) (defun my-after-change-major-mode-hook () (setq mode-line-mule-info nil minor-mode-alist nil mode-line-position nil)) ; todo, make only flymake status show up (add-hook 'after-change-major-mode-hook 'my-after-change-major-mode-hook) ;;; mouse related ;;;; settings (setq focus-follows-mouse t mouse-autoselect-window t xterm-mouse-mode t) ;;;; move-mouse-to-point ;; todo, this is buggy with multiple windows open. (defun move-mouse-to-point () (interactive) (let* ((pos (posn-col-row (posn-at-point))) (x (+ (car pos) 2)) ; no idea why this is off by 1-2 (y (cdr pos))) (set-mouse-position (selected-frame) x y))) ;;; org mode ;; todo work on org-cycle-emulate-tab ;; todo, this doesn't work for a non-standard keybind ;;(setq org-special-ctrl-k t) ;; todo, generally fix org mode keys ;; todo, org-mark-element, unbdind from M-h, bind to mark defun key ;(org-babel-do-load-languages ; 'org-babel-load-languages ; '((emacs-lisp . t) ; (sh . t))) ;; make shell work like interactive bash shell (setq org-babel-default-header-args:sh '((:results . "output") (:shebang . "#!/bin/bash -l"))) ;; my patch to output stderr (setq org-babel-use-error-buffer nil) ; ;; org-mode manual suggests these, but I haven't used them. ;;(global-set-key "\C-cl" 'org-store-link) ;;(global-set-key "\C-ca" 'org-agenda) ;; this got in the way of a haskell mode command ;;(global-set-key "\C-cb" 'org-iswitchb) ;; org-src-tab-acts-natively t ; broken option. using next instead, todo fix (setq org-src-fontify-natively t ; make babel blocks nice org-adapt-indentation nil org-src-preserve-indentation t ;; The most basic logging is to keep track of when a TODO item was finished. org-log-done 'time ;; use a drawer to keep the logs tidy org-log-into-drawer t org-extend-today-until 0 org-startup-truncated nil org-clock-persist t org-clock-mode-line-total 'today ;; global STYLE property values for completion org-global-properties (quote (("STYLE_ALL" . "habit"))) org-special-ctrl-a/e t ;; home and end work special in headlines org-completion-use-ido t org-catch-invisible-edits 'smart) ;; non universally recommended settings (setq org-default-notes-file (concat org-directory "/a/t.org") org-agenda-files (quote ("/a/t.org")) org-mobile-directory "/p/org-mobile" org-mobile-inbox-for-pull "/p/from-mobile.org" org-directory "/p") ;; modeilne populated from (org-clock-get-clocked-time) ;; which is populated from the var org-clock-total-time ;; which is populated by a function which starts from (org-clock-get-sum-start) ;; (org-clock-persistence-insinuate) (defun time-to-org-day (time) (round (time-to-number-of-days (time-subtract time (list 0 (* 3600 org-extend-today-until) 0))))) (defun my-org-confirm-babel-evaluate (lang body) (not (or (string= (buffer-file-name) "/a/t.org") (string= (buffer-file-name) "/home/iank/.emacs.d/my-init.org") ))) (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate) (defun org-time-stamp-with-time (arg) (interactive "P") ;; '(4) is the argument passed by universal prefix (org-time-stamp (if arg arg '(4)) t)) (defun ian-org-work-time () (interactive) (save-excursion (set-buffer "t.org") (goto-char (org-find-entry-with-id "ian-identifier-1")) (org-clock-in))) (defun ian-org-idle-time () (interactive) (save-excursion (goto-char (org-find-entry-with-id "ian-identifier-2")) (set-buffer "t.org") (org-clock-in))) ;; based on http://stackoverflow.com/questions/3758139/variable-pitch-for-org-mode-fixed-pitch-for-tables ;; keywords: proportional font, monospace (defun variable-pitch-on () (variable-pitch-mode 1)) (add-hook 'fundamental-mode-hook 'variable-pitch-on) (add-hook 'org-mode-hook 'variable-pitch-on) (add-hook 'text-mode-hook 'variable-pitch-on) (defun variable-pitch-off () (variable-pitch-mode 0)) (add-hook 'yaml-mode-hook 'variable-pitch-off) (set-face-attribute 'org-table nil :family (face-attribute 'fixed-pitch :family)) (set-face-attribute 'org-code nil :family (face-attribute 'fixed-pitch :family)) (set-face-attribute 'org-formula nil :family (face-attribute 'fixed-pitch :family)) (set-face-attribute 'org-link nil :family (face-attribute 'fixed-pitch :family)) (set-face-attribute 'org-block nil :family (face-attribute 'fixed-pitch :family)) (set-face-attribute 'org-date nil :family (face-attribute 'fixed-pitch :family)) (defun remove-org-binds () (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "C-'") nil) (define-key org-mode-map (kbd "C-y") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "C-,") nil) (define-key org-mode-map (kbd "C-M-m") nil) (define-key org-mode-map (kbd "C-k") nil) (define-key org-mode-map (kbd "C-j") nil) (define-key org-mode-map (kbd "C-M-i") nil) (define-key org-mode-map (kbd "C-M-t") nil) (define-key org-mode-map (kbd "M-a") 'nil) (define-key org-mode-map (kbd "C-a") nil) (define-key org-mode-map (kbd "M-e") nil) (define-key org-mode-map (kbd "C-e") nil) (define-key org-mode-map (kbd "C-3") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map (kbd "") nil) (define-key org-mode-map "\t" nil)) (add-hook 'org-mode-hook 'remove-org-binds) ;;; prog-mode-defaults (defun prog-mode-defaults () "Default coding hook, useful with any programming language." ;; so that I can do completion before the dialog pops up (local-set-key (kbd "") 'auto-complete) ;; todo, this is causing error message on loading file, prolly not working ;;(flycheck-mode +1) (setq ac-sources (delq 'ac-source-dictionary ac-sources)) (highlight-symbol-mode) (make-local-variable 'column-number-mode) ;; this says do autofilling using newcomment.el. The "only" is a misnomer. (set (make-local-variable 'comment-auto-fill-only-comments) t) (column-number-mode t) (turn-on-smartparens-mode) ;; prettify lambdas (font-lock-add-keywords nil `(("(\\(lambda\\>\\)" (0 (progn (compose-region (match-beginning 1) (match-end 1) ,(make-char 'greek-iso8859-7 107)) nil)))))) (add-hook 'prog-mode-hook 'prog-mode-defaults) ;; enable flyspell in prog mode. text mode is handled (add-hook 'prog-mode-hook 'flyspell-prog-mode) ;;; yank auto-indent ;; automatically indenting yanked text if in programming-modes (defvar yank-indent-modes '(LaTeX-mode TeX-mode) "Modes in which to indent regions that are yanked (or yank-popped). Only modes that don't derive from `prog-mode' should be listed here.") (defvar yank-indent-blacklisted-modes '(python-mode slim-mode haml-mode) "Modes for which auto-indenting is suppressed.") (defvar yank-advised-indent-threshold 2000 "Threshold (# chars) over which indentation does not automatically occur.") (defun yank-advised-indent-function (beg end) "Do indentation, as long as the region isn't too large." (if (<= (- end beg) yank-advised-indent-threshold) (indent-region beg end nil))) (defadvice yank (after yank-indent activate) "If current mode is one of 'yank-indent-modes, indent yanked text (with prefix arg don't indent)." (if (and (not (ad-get-arg 0)) (not (member major-mode yank-indent-blacklisted-modes)) (or (derived-mode-p 'prog-mode) (member major-mode yank-indent-modes))) (let ((transient-mark-mode nil)) (yank-advised-indent-function (region-beginning) (region-end))))) (defadvice yank-pop (after yank-pop-indent activate) "If current mode is one of 'yank-indent-modes, indent yanked text (with prefix arg don't indent)." (if (and (not (ad-get-arg 0)) (not (member major-mode yank-indent-blacklisted-modes)) (or (derived-mode-p 'prog-mode) (member major-mode yank-indent-modes))) (let ((transient-mark-mode nil)) (yank-advised-indent-function (region-beginning) (region-end))))) ;;; shell mode ;; avoid stupid git crap like "warning, terminal not fully functional" (setenv "PAGER" "cat") ;; don't store successive duplicates in comint command history (setq comint-input-ignoredups t) (defun add-mode-line-dirtrack () (add-to-list 'mode-line-buffer-identification '(:propertize (" " default-directory " ") face dired-directory))) (add-hook 'shell-mode-hook 'add-mode-line-dirtrack) ;; don't fully understand it, but it works. ;; http://www.emacswiki.org/emacs/ShellDirtrackByProcfs (defun track-shell-directory/procfs () (shell-dirtrack-mode 0) (add-hook 'comint-preoutput-filter-functions (lambda (str) (prog1 str (when (string-match comint-prompt-regexp str) (cd (file-symlink-p (format "/proc/%s/cwd" (process-id (get-buffer-process (current-buffer))))))))) nil t)) (setq comint-buffer-maximum-size 100000) (add-to-list 'comint-output-filter-functions 'comint-truncate-buffer) (defun new-shell () (interactive) (shell (generate-new-buffer-name "*shell*"))) ;; (defun shell-wrap (prefix) "wrap the shell function, automatically generate a new name for a prefix arg" (interactive "P") (if prefix (new-shell) (shell))) (add-hook 'shell-mode-hook 'track-shell-directory/procfs) ;;; smartparens ;; the melpa git version had a catastrophic bug I reported. ;; downgraded to marmalade version and everything is working fine. (require 'smartparens-config) (show-smartparens-global-mode t) (defun gp/sp/pair-on-newline-and-indent (id action context) "Open a new brace or bracket expression, with relevant newlines and indent. " (save-excursion (newline) (indent-according-to-mode)) (indent-according-to-mode)) ;; when opening a pair, and then inserting a newline, push the closing pair to another newline (sp-pair "{" nil :post-handlers '(:add ((lambda (id action context) (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) (sp-pair "[" nil :post-handlers '(:add ((lambda (id action context) (gp/sp/pair-on-newline-and-indent id action context)) (kbd "")))) ;; in my version, this is not a pairing. ;; not sure if it is in a future version since I reverted to marmalade ;; Don't need c-comments in strings -- they frustrate filename globs ;; (sp-pair "/*" nil :unless '(sp-in-string-p)) ;; Don't need quotes to pair next to words (sp-pair "\"" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) (sp-pair "'" nil :unless '(sp-point-before-word-p sp-point-after-word-p)) ;; todo, testout these mode specific settings from graphene. ;; Ruby-specific pairs and handlers (require 'smartparens-ruby) ;; Markdown (sp-local-pair '(markdown-mode gfm-mode) "*" "*" :unless '(sp-in-string-p) :actions '(insert wrap)) ;; Except in HTML (sp-local-pair 'html-mode "\"" nil :unless '(:rem sp-point-after-word-p)) ;;; smex ;; todo; check out smex-show-unbound-commands shows frequently used commands that have no key bindings. ; these must be before smex-initialize (setq smex-save-file "~/.emacs.d/.smex-items") (smex-initialize) ;;; spell correction (setq ispell-program-name "hunspell" ispell-silently-savep t) ; don't prompt to save personal dictionary (require 'rw-hunspell) ;; rw-hunspell sets up hunspell dictionary automagically. ;; Rant: Hunspell SHOULD be standard. its used by firefox and openoffice and ;; osx. In contrast, the first few words I added to aspell dictionary were ;; "emacs" "customizable" and "timestamp". Hunspell already has those, ;; thank god. ;; ispell-personal-dictionary does not document where the hunspell ;; dictionary goes by default, but it is ~/.hunspell_en_US for me ;;; tex (setq-default TeX-PDF-mode t) ; use pdf ; more sensible defaults based on info manual quickstart (setq TeX-auto-save t) (setq TeX-parse-self t) ;;; undo tree ;; undo-tree checks for minor modes which override ;; its minor mode keymap, and sets global keybinds if ;; that happens. this will prevent that, but I have no ;; reason to do that, so it is commented. ;; (defun undo-tree-overridden-undo-bindings-p () nil) ;; todo, send patch undo-tree-visualize should scroll with the scroll key, instead of just pgup pgdn (aka next/prior) (global-undo-tree-mode) ;; disabled due to bug, something like unknown entry in undo tree canary ;; (setq undo-tree-auto-save-history t) (setq undo-outer-limit 100000000 ; per undo command undo-limit 500000000 ; undo history limit undo-strong-limit 600000000) ; undo history limit plus some extra ;;; visible mark mode ;; since it is not easy to change the mark overlay priority, I change this one. (setq show-paren-priority 999) (defface visible-mark-active '((((type tty) (class mono))) (t (:background "magenta"))) "") (defface mouse-cursor-face '((((type tty) (class mono))) (t (:background "DeepPink1"))) "") (require 'visible-mark) (setq visible-mark-faces '(visible-mark-face1 visible-mark-face2)) (setq visible-mark-forward-faces '(visible-mark-forward-face1)) ; highlight the last 2 marks (setq visible-mark-max 2) ; highlight 1 forward mark (setq visible-mark-forward-max 1) ; globally activate visible-mark-mode (global-visible-mark-mode +1) ;; todo, it doesn't seem to be exposed in elisp, but it would be nice ;; if I could define overlay faces to use inverse foreground color ;;; zrc (require 'znc) (setq erc-fill-prefix "") (defun chirp() (interactive) (setq vol 50) (when (string= (system-name) "tp") (setq vol 40)) (start-process-shell-command "ignoreme" nil (format "mpv --no-terminal --vo=null --volume=%d /a/bin/data/bird.mp3" vol))) ;; from https://www.emacswiki.org/emacs/ErcSound (defun erc-my-privmsg-sound (proc parsed) (let* ((tgt (car (erc-response.command-args parsed))) (privp (erc-current-nick-p tgt))) (and privp (chirp) ;; We must return nil. See help for `erc-server-PRIVMSG-functions' nil))) (add-hook 'erc-server-PRIVMSG-functions 'erc-my-privmsg-sound) (defun erc-sound-if-not-server (match-type nickuserhost msg) (unless (string-match "Server:[0-9]+" nickuserhost) (chirp))) (add-hook 'erc-text-matched-hook 'erc-sound-if-not-server) (erc-track-mode 1) (setq ;; consider invisible frames to be unseen. seems like an obvious default erc-track-visibility 'visible ;; switch to buffer where i've been mentioned, etc instead of oldest erc-track-switch-direction 'importance) ;;; persistent registers ;; This needs to be at the end, because I visit a file, thus setting a ;; mode, and the mode hook needs to be setup before that. ;; I'm using persistent registers instead of bookmarks. I dun use them ;; much, so the added hassle of having to set it within this file is ;; worth the benefit of only having one concept in my mind. (dolist (r `( (?i (file . ,"~/.emacs.d/my-init.org")) (?t (file . ,"/a/x.txt")) )) (set-register (car r) (cadr r)))