From d9cae60fa5048abd3528f96a285109329639fda6 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Fri, 23 Jan 2015 23:23:05 -0500 Subject: Improve organization and consistency of files - Add pages and more headings for large files. - Try to use consistent order for file (or page) structure. * Loading * Settings * Hooks * Any mode activation or function calls * My functions * Key bindings --- lisp/init-ace.el | 17 +-- lisp/init-appearance.el | 9 +- lisp/init-babel.el | 7 +- lisp/init-bib.el | 12 +- lisp/init-bog.el | 7 +- lisp/init-buffile.el | 97 ++++++------ lisp/init-diminish.el | 3 +- lisp/init-dired.el | 154 ++++++++++--------- lisp/init-editing.el | 131 ++++++++-------- lisp/init-ess.el | 3 +- lisp/init-external.el | 49 +++--- lisp/init-framewin.el | 19 ++- lisp/init-general.el | 58 ++++--- lisp/init-git.el | 106 +++++++------ lisp/init-gnus.el | 295 +++++++++++++++++++----------------- lisp/init-ido.el | 18 +-- lisp/init-org.el | 391 +++++++++++++++++++++++++----------------------- lisp/init-projectile.el | 126 ++++++++-------- lisp/init-python.el | 38 +++-- lisp/init-smex.el | 4 +- lisp/init-snakemake.el | 11 +- lisp/init-tex.el | 4 +- lisp/init-view.el | 4 +- lisp/init-yas.el | 8 +- 24 files changed, 812 insertions(+), 759 deletions(-) diff --git a/lisp/init-ace.el b/lisp/init-ace.el index 1e4bc55..42c04f2 100644 --- a/lisp/init-ace.el +++ b/lisp/init-ace.el @@ -1,15 +1,10 @@ ;;; Ace Jump -(key-chord-define-global ";a" 'ace-jump-mode) - (setq ace-jump-mode-scope 'frame) -;;; Ace Link - -(ace-link-setup-default) +(key-chord-define-global ";a" 'ace-jump-mode) -(after 'org - (define-key org-mode-map (kbd "C-c m o") 'ace-link-org)) +;;; Ace Link (defun km/ace-link-dired () "Ace jump to files in dired buffers." @@ -28,18 +23,20 @@ (push it points))) (nreverse points)))) +(ace-link-setup-default) +(after 'org + (define-key org-mode-map (kbd "C-c m o") 'ace-link-org)) (after 'dired - ;; This overrides the binding for `dired-find-file-other-window', which - ;; is rebound to 'r'. + ;; This overrides the binding for `dired-find-file-other-window'. (define-key dired-mode-map "o" 'km/ace-link-dired) (define-key dired-mode-map "r" 'dired-find-file-other-window)) ;;; Ace Window -(define-key km/window-map "a" 'ace-window) (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) aw-scope 'global) +(define-key km/window-map "a" 'ace-window) (key-chord-define-global ",w" 'ace-window) (provide 'init-ace) diff --git a/lisp/init-appearance.el b/lisp/init-appearance.el index 99d2033..b9c4ea1 100644 --- a/lisp/init-appearance.el +++ b/lisp/init-appearance.el @@ -6,10 +6,11 @@ (menu-bar-mode -1) (blink-cursor-mode -1) -;; Line info -(line-number-mode t) -(column-number-mode t) -(size-indication-mode t) +(line-number-mode) +(column-number-mode) +(size-indication-mode) + +;;; Theme (load-theme 'stekene-light t) diff --git a/lisp/init-babel.el b/lisp/init-babel.el index 47fcad2..615c860 100644 --- a/lisp/init-babel.el +++ b/lisp/init-babel.el @@ -1,4 +1,6 @@ -;; Set up babel languages. +(setq org-confirm-babel-evaluate nil + org-src-fontify-natively t) + (org-babel-do-load-languages 'org-babel-load-languages '((sh . t) @@ -7,7 +9,4 @@ (emacs-lisp . t) (latex . t))) -;; Don't ask for confirmation before running code. -(setq org-confirm-babel-evaluate nil) - (provide 'init-babel) diff --git a/lisp/init-bib.el b/lisp/init-bib.el index fe8a8f1..3cdd047 100644 --- a/lisp/init-bib.el +++ b/lisp/init-bib.el @@ -1,10 +1,10 @@ ;; Make cite key have form . -(setq bibtex-autokey-year-length 4 +(setq bibtex-autokey-titlewords 1 + bibtex-autokey-titleword-ignore '("A" "An" "On" "The" "[0-9].*") bibtex-autokey-titleword-length nil bibtex-autokey-titlewords-stretch 0 - bibtex-autokey-titlewords 1 - bibtex-autokey-year-title-separator "" - bibtex-autokey-titleword-ignore '("A" "An" "On" "The" "[0-9].*")) + bibtex-autokey-year-length 4 + bibtex-autokey-year-title-separator "") (setq bibtex-align-at-equal-sign t) ; Used by `bibtex-fill-entry'. @@ -12,6 +12,8 @@ (setq bibtex-entry-format (append '(realign sort-fields) bibtex-entry-format))) +(add-hook 'bibtex-clean-entry-hook 'km/bibtex-use-title-case) + (defvar km/bibtex-unimportant-title-words '("a" "aboard" "about" "above" "absent" "across" "after" "against" "along" "alongside" "amid" "amidst" "among" "amongst" "an" "and" @@ -67,8 +69,6 @@ all other words unless they are protected by brackets." (downcase-word 1) (capitalize-word 1)))))))) -(add-hook 'bibtex-clean-entry-hook 'km/bibtex-use-title-case) - (defun km/browse-doi (doi) "Open DOI in browser. When called interactively, take the DOI from the text under diff --git a/lisp/init-bog.el b/lisp/init-bog.el index 5a9d9c6..94b71c2 100644 --- a/lisp/init-bog.el +++ b/lisp/init-bog.el @@ -1,12 +1,11 @@ (add-to-list 'load-path "~/src/emacs/bog/") - (require 'bog-autoloads) -(setq bog-keymap-prefix (kbd "C-c b")) -(global-set-key (kbd "C-c B") 'bog-commander) +(setq bog-keymap-prefix (kbd "C-c b") + bog-use-citekey-cache t) (add-hook 'org-mode-hook 'bog-mode) -(setq bog-use-citekey-cache t) +(global-set-key (kbd "C-c B") 'bog-commander) (provide 'init-bog) diff --git a/lisp/init-buffile.el b/lisp/init-buffile.el index 00c1934..5ec3054 100644 --- a/lisp/init-buffile.el +++ b/lisp/init-buffile.el @@ -2,8 +2,9 @@ (require 'uniquify) -(setq uniquify-buffer-name-style 'forward - require-final-newline t) +(setq require-final-newline t) + +(setq uniquify-buffer-name-style 'forward) (defun km/rename-current-buffer-file () "Rename current buffer and file it is visiting." @@ -22,8 +23,6 @@ (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))) -(global-set-key (kbd "C-x C-r") 'km/rename-current-buffer-file) - ;; https://github.com/purcell/emacs.d/blob/master/lisp/init-utils.el (defun km/delete-this-file () "Delete the current file, and kill the buffer." @@ -43,77 +42,77 @@ (setq file (concat "/sudo:root@localhost:" file))) (find-file file))) -(global-set-key (kbd "C-x F") 'km/find-file-as-root) - (defun km/save-and-kill-buffer () "Save current buffer and then kill it." (interactive) (save-buffer) (kill-this-buffer)) +(global-set-key (kbd "C-x C-r") 'km/rename-current-buffer-file) +(global-set-key (kbd "C-x F") 'km/find-file-as-root) (global-set-key (kbd "C-x K") 'kill-buffer-and-window) -(key-chord-define-global ",f" 'find-file) - -(define-key ctl-x-4-map "v" 'view-file-other-window) +(key-chord-define-global ",d" 'km/save-and-kill-buffer) +(key-chord-define-global ",f" 'find-file) (key-chord-define-global ",s" 'save-buffer) (key-chord-define-global ",q" 'kill-this-buffer) -(key-chord-define-global ",d" 'km/save-and-kill-buffer) + +(define-key ctl-x-4-map "v" 'view-file-other-window) (define-prefix-command 'km/file-map) (global-set-key (kbd "C-c f") 'km/file-map) - (define-key km/file-map "v" 'view-file) + +;;; Search + (autoload 'vc-git-grep "vc-git" "Run git grep, searching for REGEXP in FILES in directory DIR. The search is limited to file names matching shell pattern FILES. FILES may use abbreviations defined in `grep-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'.") +(add-hook 'grep-setup-hook 'km/grep-hide-header) + (defun km/grep-hide-header () (save-excursion (goto-char (point-min)) (forward-line 4) (narrow-to-region (point) (point-max)))) -(add-hook 'grep-setup-hook 'km/grep-hide-header) (key-chord-define-global ",z" 'rgrep) (define-prefix-command 'km/file-search-map) (define-key km/file-map "s" 'km/file-search-map) +(define-key km/file-search-map "d" 'find-grep-dired) +(define-key km/file-search-map "D" 'find-dired) +(define-key km/file-search-map "f" 'grep-find) (define-key km/file-search-map "g" 'lgrep) (define-key km/file-search-map "G" 'grep) -(define-key km/file-search-map "f" 'grep-find) - +(define-key km/file-search-map "n" 'find-name-dired) (define-key km/file-search-map "r" 'rgrep) - (define-key km/file-search-map "v" 'vc-git-grep) (define-key km/file-search-map "z" 'zrgrep) -(define-key km/file-search-map "n" 'find-name-dired) -(define-key km/file-search-map "d" 'find-grep-dired) -(define-key km/file-search-map "D" 'find-dired) - + ;;; Ibuffer -;; Replace buffer-menu with ibuffer. +(setq ibuffer-expert t + ibuffer-restore-window-config-on-quit t + ibuffer-show-empty-filter-groups nil) + +;; Replace `list-buffers' with ibuffer. (global-set-key (kbd "C-x C-b") 'ibuffer) -(setq - ibuffer-restore-window-config-on-quit t - ;; Don't prompt to delete unmodified buffers. - ibuffer-expert t - ;; Don't show empty filter groups. - ibuffer-show-empty-filter-groups nil) + ;;; Recent files -(setq recentf-save-file "~/.emacs.d/cache/recentf" +(setq recentf-max-menu-items 15 recentf-max-saved-items 200 - recentf-max-menu-items 15) -(recentf-mode t) + recentf-save-file "~/.emacs.d/cache/recentf") +(recentf-mode) ;; Modified from prelude (defun km/recentf-find-file () @@ -125,16 +124,16 @@ entering `ch' is equivalent to `*.[ch]'.") "Find a file from `recentf-list' in other window." (interactive) (find-file-other-window (km/read-recent-file))) - +;; This overrides `find-file-read-only-other-window', but +;; `view-file-other-window', which I map to 'v', has the same +;; functionality. (defun km/read-recent-file () (ido-completing-read "Choose recent file: " recentf-list nil t)) (key-chord-define-global ",r" 'km/recentf-find-file) -;; This overrides `find-file-read-only-other-window', but -;; `view-file-other-window', which I map to 'v', has the same -;; functionality. (define-key ctl-x-4-map "r" 'km/recentf-find-file-other-window) + ;;; Scratch files (defvar km/find-scratch-buffers @@ -150,22 +149,6 @@ entering `ch' is equivalent to `*.[ch]'.") Format of each element should be (CHARACTER EXTENSION DOC). DOC is not required.") -;; This is based off of Projectile's commander. -(defun km/scratch--get-file-name () - (-let* ((choices (-map #'car km/find-scratch-buffers)) - (prompt (concat "Scratch buffer [" choices "]: ")) - (ch (read-char-choice prompt choices)) - ((_ ext _) (assq ch km/find-scratch-buffers))) - (concat "/tmp/scratch" ext))) - -(defun km/scratch--find-file-no-select (erase) - (let ((scratch-buffer - (find-file-noselect (km/scratch--get-file-name)))) - (when erase - (with-current-buffer scratch-buffer - (erase-buffer))) - scratch-buffer)) - (defun km/scratch-find-file (erase) "Find scratch buffer. @@ -181,6 +164,22 @@ With prefix ERASE, delete contents of buffer." (interactive "P") (switch-to-buffer-other-window (km/scratch--find-file-no-select erase))) +(defun km/scratch--find-file-no-select (erase) + (let ((scratch-buffer + (find-file-noselect (km/scratch--get-file-name)))) + (when erase + (with-current-buffer scratch-buffer + (erase-buffer))) + scratch-buffer)) + +;; This is based off of Projectile's commander. +(defun km/scratch--get-file-name () + (-let* ((choices (-map #'car km/find-scratch-buffers)) + (prompt (concat "Scratch buffer [" choices "]: ")) + (ch (read-char-choice prompt choices)) + ((_ ext _) (assq ch km/find-scratch-buffers))) + (concat "/tmp/scratch" ext))) + (global-set-key (kbd "C-c s") 'km/scratch-find-file) (define-key ctl-x-4-map "s" 'km/scratch-find-file-other-window) diff --git a/lisp/init-diminish.el b/lisp/init-diminish.el index c86b062..6c63bad 100644 --- a/lisp/init-diminish.el +++ b/lisp/init-diminish.el @@ -1,7 +1,6 @@ (require 'diminish) (diminish 'abbrev-mode "Ab") -(after 'whitespace (diminish 'global-whitespace-mode)) (after 'flyspell (diminish 'flyspell-mode "Fy")) (after 'paredit (diminish 'paredit-mode " Pe")) (after 'magit (diminish 'magit-auto-revert-mode)) @@ -11,5 +10,7 @@ (after 'projectile (diminish 'projectile-mode)) (after 'reftex (diminish 'reftex-mode "Rf")) (after 'view (diminish 'view-mode "Vw")) +(after 'whitespace (diminish 'global-whitespace-mode)) +(after 'yasnippet (diminish 'yas-minor-mode)) (provide 'init-diminish) diff --git a/lisp/init-dired.el b/lisp/init-dired.el index b046c81..7c40a06 100644 --- a/lisp/init-dired.el +++ b/lisp/init-dired.el @@ -1,7 +1,7 @@ -(put 'dired-find-alternate-file 'disabled nil) - (require 'dired-x) +(put 'dired-find-alternate-file 'disabled nil) + ;; .git is present as part of `dired-omit-extensions', but this seems to ;; only be taken into account if a non-exension part exists. (setq dired-omit-files @@ -22,66 +22,17 @@ (append dired-omit-extensions km/latex-omit-extensions)) (setq-default dired-omit-mode t) -(setq dired-listing-switches "-alh" - dired-dwim-target t) +(setq dired-dwim-target t + dired-listing-switches "-alh") (setq dired-guess-shell-alist-user '(("\\.pdf\\'" "zathura"))) -(setq dired-recursive-deletes t - dired-recursive-copies t) - -(defun km/dired-copy-project-filename-as-kill () - "Copy names of marked project files into kill ring. -This is similar to `dired-copy-filename-as-kill', but the leading -path is always relative to `projectile-project-root'." - (interactive) - (km/dired-copy-filename-relative-to-directory - (projectile-project-root))) - -(defun km/dired-copy-filename-relative-to-directory (directory) - "Like `dired-copy-filename-as-kill', but the filename is always -relative to DIRECTORY." - (let* ((string - (mapconcat 'identity - (--map (file-relative-name it directory) - (dired-get-marked-files t)) - " "))) - (if (eq last-command 'kill-region) - (kill-append string nil) - (kill-new string)) - (message "%s" string))) - -(defun km/dired-copy-relative-filename-as-kill () - "Copy names of marked files into kill ring. -This is similar to `dired-copy-filename-as-kill', but the leading -path is always relative to the `default-directory' of the other -window." - (interactive) - (km/dired-copy-filename-relative-to-directory - (km/other-default-directory))) - -(defun km/other-default-directory () - "Get `default-directory' for result of `(other-window 1)'." - (save-window-excursion - (other-window 1) - default-directory)) - -(define-prefix-command 'km/dired-copy-filename-map) -(define-key km/dired-copy-filename-map "o" - 'km/dired-copy-relative-filename-as-kill) -(define-key km/dired-copy-filename-map "w" 'dired-copy-filename-as-kill) -(after 'projectile - (define-key km/dired-copy-filename-map "p" - 'km/dired-copy-project-filename-as-kill)) - -;; This overrides the default binding for `dired-copy-filename-as-kill'. -(define-key dired-mode-map "w" 'km/dired-copy-filename-map) +(setq dired-recursive-copies t + dired-recursive-deletes t) (add-hook 'dired-mode-hook 'dired-hide-details-mode) -(define-key dired-mode-map (kbd "C-c C-b") 'dired-up-directory) - (defun km/dired-switch-to-buffer () (interactive) (switch-to-buffer (km/dired-completing-buffer))) @@ -99,10 +50,6 @@ window." (derived-mode-p 'dired-mode)) (buffer-list))) -(define-key ctl-x-4-map "D" 'km/dired-switch-to-buffer-other-window) -;; This overrides the binding for `list-directory'. -(global-set-key (kbd "C-x C-d") 'km/dired-switch-to-buffer) - (defun km/org-open-dired-marked-files (&optional in-emacs) (interactive "P") (let* ((files (dired-get-marked-files)) @@ -111,36 +58,97 @@ window." (yes-or-no-p (format "Open %s files?" num-files))) (--each files (org-open-file it in-emacs))))) +;; This overrides the binding for `list-directory'. +(define-key dired-mode-map (kbd "C-c C-b") 'dired-up-directory) +(global-set-key (kbd "C-x C-d") 'km/dired-switch-to-buffer) + +(define-key ctl-x-4-map "D" 'km/dired-switch-to-buffer-other-window) + +(define-prefix-command 'km/dired-prefix-map) +(define-key dired-mode-map (kbd "C-c m") 'km/dired-prefix-map) + (after 'org ;; This overrides `dired-find-file', which is also bound to "f". (define-key dired-mode-map "e" 'km/org-open-dired-marked-files)) + +;;; Dired Narrow + +(define-key dired-mode-map "/" 'dired-narrow) + (define-prefix-command 'km/dired-narrow-prefix-map) -(define-key km/dired-narrow-prefix-map "n" 'dired-narrow) +(define-key km/dired-prefix-map "n" 'km/dired-narrow-prefix-map) + (define-key km/dired-narrow-prefix-map "f" 'dired-narrow-fuzzy) +(define-key km/dired-narrow-prefix-map "n" 'dired-narrow) (define-key km/dired-narrow-prefix-map "r" 'dired-narrow-regexp) -(define-key dired-mode-map "/" 'dired-narrow) + +;;; Dired Subtree (define-prefix-command 'km/dired-subtree-prefix-map) -(define-key km/dired-subtree-prefix-map "i" 'dired-subtree-insert) -(define-key km/dired-subtree-prefix-map "r" 'dired-subtree-remove) +(define-key km/dired-prefix-map "s" 'km/dired-subtree-prefix-map) + +(define-key km/dired-subtree-prefix-map "@" 'dired-subtree-mark-subtree) +(define-key km/dired-subtree-prefix-map "." 'dired-subtree-unmark-subtree) +(define-key km/dired-subtree-prefix-map "<" 'dired-subtree-beginning) +(define-key km/dired-subtree-prefix-map ">" 'dired-subtree-end) (define-key km/dired-subtree-prefix-map "g" 'dired-subtree-revert) -(define-key km/dired-subtree-prefix-map "s" 'dired-subtree-narrow) -(define-key km/dired-subtree-prefix-map "u" 'dired-subtree-up) (define-key km/dired-subtree-prefix-map "d" 'dired-subtree-down) +(define-key km/dired-subtree-prefix-map "i" 'dired-subtree-insert) (define-key km/dired-subtree-prefix-map "n" 'dired-subtree-next-sibling) (define-key km/dired-subtree-prefix-map "p" 'dired-subtree-previous-sibling) -(define-key km/dired-subtree-prefix-map "<" 'dired-subtree-beginning) -(define-key km/dired-subtree-prefix-map ">" 'dired-subtree-end) -(define-key km/dired-subtree-prefix-map "@" 'dired-subtree-mark-subtree) -(define-key km/dired-subtree-prefix-map "." 'dired-subtree-unmark-subtree) +(define-key km/dired-subtree-prefix-map "r" 'dired-subtree-remove) +(define-key km/dired-subtree-prefix-map "s" 'dired-subtree-narrow) +(define-key km/dired-subtree-prefix-map "u" 'dired-subtree-up) -(define-prefix-command 'km/dired-prefix-map) + +;;; Copying file names -(define-key km/dired-prefix-map "n" 'km/dired-narrow-prefix-map) -(define-key km/dired-prefix-map "s" 'km/dired-subtree-prefix-map) +(defun km/dired-copy-project-filename-as-kill () + "Copy names of marked project files into kill ring. +This is similar to `dired-copy-filename-as-kill', but the leading +path is always relative to `projectile-project-root'." + (interactive) + (km/dired-copy-filename-relative-to-directory + (projectile-project-root))) -(define-key dired-mode-map (kbd "C-c m") 'km/dired-prefix-map) +(defun km/dired-copy-relative-filename-as-kill () + "Copy names of marked files into kill ring. +This is similar to `dired-copy-filename-as-kill', but the leading +path is always relative to the `default-directory' of the other +window." + (interactive) + (km/dired-copy-filename-relative-to-directory + (km/other-default-directory))) + +(defun km/dired-copy-filename-relative-to-directory (directory) + "Like `dired-copy-filename-as-kill', but the filename is always +relative to DIRECTORY." + (let* ((string + (mapconcat 'identity + (--map (file-relative-name it directory) + (dired-get-marked-files t)) + " "))) + (if (eq last-command 'kill-region) + (kill-append string nil) + (kill-new string)) + (message "%s" string))) + +(defun km/other-default-directory () + "Get `default-directory' for result of `(other-window 1)'." + (save-window-excursion + (other-window 1) + default-directory)) + +(define-prefix-command 'km/dired-copy-filename-map) +;; This overrides the default binding for `dired-copy-filename-as-kill'. +(define-key dired-mode-map "w" 'km/dired-copy-filename-map) + +(after 'projectile + (define-key km/dired-copy-filename-map "p" + 'km/dired-copy-project-filename-as-kill)) +(define-key km/dired-copy-filename-map "o" 'km/dired-copy-relative-filename-as-kill) +(define-key km/dired-copy-filename-map "w" 'dired-copy-filename-as-kill) (provide 'init-dired) diff --git a/lisp/init-editing.el b/lisp/init-editing.el index ea1efac..f0a8277 100644 --- a/lisp/init-editing.el +++ b/lisp/init-editing.el @@ -1,16 +1,8 @@ -(global-set-key (kbd "C-x \\") 'align-regexp) - -;; Overrides `suspend-emacs' (which is also bound to C-x C-z). -(global-set-key (kbd "C-z") 'zap-to-char) ;; http://irreal.org/blog/?p=1536 (autoload 'zap-up-to-char "misc" "Kill up to, but not including ARGth occurrence of CHAR.") -(global-set-key (kbd "M-z") 'zap-up-to-char) - -(global-set-key (kbd "C-'") 'backward-kill-word) -(global-set-key (kbd "M-/") 'hippie-expand) (setq hippie-expand-try-functions-list '(try-complete-file-name-partially try-complete-file-name try-expand-all-abbrevs @@ -20,9 +12,7 @@ try-complete-lisp-symbol-partially try-complete-lisp-symbol)) -(define-key ctl-x-4-map "nd" 'ni-narrow-to-defun-other-window) -(define-key ctl-x-4-map "nn" 'ni-narrow-to-region-other-window) -(define-key ctl-x-4-map "np" 'ni-narrow-to-page-indirect-other-window) +(electric-indent-mode -1) ;; http://www.emacswiki.org/emacs/UnfillParagraph (defun km/unfill-paragraph () @@ -72,11 +62,6 @@ special case. (forward-line -1) (delete-blank-lines)))) -(define-key search-map "s" 'query-replace) -(define-key search-map "S" 'replace-string) -(define-key search-map "r" 'query-replace-regexp) -(define-key search-map "R" 'replace-regexp) - (defun km/narrow-to-comment-heading () "Narrow to the current comment heading subtree. @@ -130,8 +115,6 @@ and '<<<' mark the bounds of the narrowed region. (outline-mark-subtree) (narrow-to-region (region-beginning) (region-end))))) -(define-key narrow-map "c" 'km/narrow-to-comment-heading) - (defun km/toggle-line-or-region-comment () "Comment/uncomment the current line or region." (interactive) @@ -142,28 +125,60 @@ and '<<<' mark the bounds of the narrowed region. (comment-or-uncomment-region beg end)) (forward-line)) +;; From http://whattheemacsd.com/key-bindings.el-01.html +(defun km/goto-line-with-feedback () + "Show line numbers when prompting for the line number input." + (interactive) + (unwind-protect + (progn + (linum-mode 1) + (call-interactively 'goto-line)) + (linum-mode -1))) + +(global-set-key (kbd "C-x \\") 'align-regexp) + +(global-set-key (kbd "C-;") 'er/expand-region) + +;; Overrides `suspend-emacs' (which is also bound to C-x C-z). +(global-set-key (kbd "C-z") 'zap-to-char) +(global-set-key (kbd "M-z") 'zap-up-to-char) +(global-set-key (kbd "C-'") 'backward-kill-word) + +(global-set-key (kbd "M-/") 'hippie-expand) + (key-chord-define-global ",c" 'km/toggle-line-or-region-comment) -;; Put multiple cursors map under insert prefix. +(define-key ctl-x-4-map "nd" 'ni-narrow-to-defun-other-window) +(define-key ctl-x-4-map "nn" 'ni-narrow-to-region-other-window) +(define-key ctl-x-4-map "np" 'ni-narrow-to-page-indirect-other-window) + +(define-key narrow-map "c" 'km/narrow-to-comment-heading) + +(define-key search-map "s" 'query-replace) +(define-key search-map "S" 'replace-string) +(define-key search-map "r" 'query-replace-regexp) +(define-key search-map "R" 'replace-regexp) + +(global-set-key [remap goto-line] 'km/goto-line-with-feedback) + (define-prefix-command 'km/editing-map) (global-set-key (kbd "C-c e") 'km/editing-map) -(define-key km/editing-map "l" 'mc/edit-lines) -(define-key km/editing-map "b" 'mc/edit-beginnings-of-lines) -(define-key km/editing-map "e" 'mc/edit-ends-of-lines) -(define-key km/editing-map "n" 'mc/mark-next-like-this) -(define-key km/editing-map "p" 'mc/mark-previous-like-this) -(define-key km/editing-map "a" 'mc/mark-all-like-this) +(define-key km/editing-map "f" 'km/fill-surrounding-indented) +(define-key km/editing-map "i" 'indent-relative) -;; Buffer-specific prevention modified from -;; http://stackoverflow.com/questions/14913398/ -;; in-emacs-how-do-i-save-without-running-save-hooks. -(defvar-local km/prevent-cleanup nil - "If set, `km/cleanup-buffer' does not perform clean up on save.") + +;;; Buffer cleanup (setq whitespace-style '(face trailing indentation)) + (global-whitespace-mode 1) +(add-hook 'before-save-hook 'km/cleanup-buffer) + +(defvar-local km/prevent-cleanup nil + "If set, `km/cleanup-buffer' does not perform clean up on save.") + (defun km/toggle-prevent-cleanup () "Toggle state of `km/prevent-cleanup'." (interactive) @@ -186,32 +201,10 @@ and '<<<' mark the bounds of the narrowed region. (unless km/prevent-cleanup (whitespace-cleanup))) -(add-hook 'before-save-hook 'km/cleanup-buffer) - (define-key km/editing-map "t" 'km/toggle-prevent-cleanup) -(global-set-key (kbd "C-;") 'er/expand-region) - -(define-key km/editing-map "i" 'indent-relative) -(define-key km/editing-map "f" 'km/fill-surrounding-indented) - -(electric-indent-mode -1) - -;; From http://whattheemacsd.com/key-bindings.el-01.html -(defun km/goto-line-with-feedback () - "Show line numbers when prompting for the line number input." - (interactive) - (unwind-protect - (progn - (linum-mode 1) - (call-interactively 'goto-line)) - (linum-mode -1))) - -(global-set-key [remap goto-line] 'km/goto-line-with-feedback) - -;; Kill map -(define-prefix-command 'km/kill-map) -(global-set-key (kbd "C-c k") 'km/kill-map) + +;;; Kill map (defun km/kill-string-at-point () (interactive) @@ -219,6 +212,12 @@ and '<<<' mark the bounds of the narrowed region. (goto-char string-start) (kill-sexp))) +;; Taken from prelude-core.el. +(defun km/join-next-line-with-space () + "Join current line to the next line with a space in between." + (interactive) + (delete-indentation 1)) + (defmacro km/make-kill-thing-at-point (name thing kill-func) `(defun ,(intern (concat "km/kill-" name "-at-point")) (arg) (interactive "p") @@ -231,18 +230,24 @@ and '<<<' mark the bounds of the narrowed region. (km/make-kill-thing-at-point "line" 'line 'kill-line) (km/make-kill-thing-at-point "sexp" 'sexp 'kill-sexp) -(define-key km/kill-map "s" 'km/kill-string-at-point) +(define-prefix-command 'km/kill-map) +(global-set-key (kbd "C-c k") 'km/kill-map) + (define-key km/kill-map "." 'km/kill-sentence-at-point) -(define-key km/kill-map "w" 'km/kill-word-at-point) -(define-key km/kill-map "p" 'km/kill-paragraph-at-point) +(define-key km/kill-map "j" 'km/join-next-line-with-space) (define-key km/kill-map "l" 'km/kill-line-at-point) +(define-key km/kill-map "p" 'km/kill-paragraph-at-point) +(define-key km/kill-map "s" 'km/kill-string-at-point) +(define-key km/kill-map "w" 'km/kill-word-at-point) -;; Taken from prelude-core.el. -(defun km/join-next-line-with-space () - "Join current line to the next line with a space in between." - (interactive) - (delete-indentation 1)) + +;;; Multiple cursors -(define-key km/kill-map "j" 'km/join-next-line-with-space) +(define-key km/editing-map "a" 'mc/mark-all-like-this) +(define-key km/editing-map "b" 'mc/edit-beginnings-of-lines) +(define-key km/editing-map "e" 'mc/edit-ends-of-lines) +(define-key km/editing-map "l" 'mc/edit-lines) +(define-key km/editing-map "n" 'mc/mark-next-like-this) +(define-key km/editing-map "p" 'mc/mark-previous-like-this) (provide 'init-editing) diff --git a/lisp/init-ess.el b/lisp/init-ess.el index 6564b27..29d570e 100644 --- a/lisp/init-ess.el +++ b/lisp/init-ess.el @@ -1,7 +1,8 @@ (autoload 'R-mode "ess-site") -(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . R-mode)) (setq ess-smart-S-assign-key ";") +(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . R-mode)) + (provide 'init-ess) diff --git a/lisp/init-external.el b/lisp/init-external.el index 96e5522..3d44f64 100644 --- a/lisp/init-external.el +++ b/lisp/init-external.el @@ -1,20 +1,29 @@ + +(setq x-select-enable-clipboard t ; Share clipboard with system. + x-select-enable-primary t) + +(setq browse-url-browser-function 'browse-url-generic + browse-url-generic-program "firefox") + +(setq ispell-program-name "aspell") + (define-prefix-command 'km/external-map) (global-set-key (kbd "C-c x") 'km/external-map) -(setq shell-command-switch "-ic" - x-select-enable-clipboard t ; Share clipboard with system. - x-select-enable-primary t - ispell-program-name "aspell" - browse-url-browser-function 'browse-url-generic - browse-url-generic-program "firefox") +(define-key km/external-map "w" 'woman) +(define-key km/external-map "i" 'ispell-buffer) -;;; Terminals + +;;; Shells + +(setq shell-command-switch "-ic") (defvar km/terminal "urxvt") (defun km/open-external-terminal () (interactive) (start-process "ext-term" nil km/terminal)) +(define-key km/external-map "t" 'km/open-external-terminal) (defun km/zsh-ansi-term (&optional directory) "Open an ansi-term buffer running ZSH in DIRECTORY. @@ -76,13 +85,14 @@ BUFFER defaults to current buffer." (-distinct (-keep #'km/zsh-ansi-term-directory (buffer-list)))) (define-key km/external-map "a" 'km/zsh-ansi-term) -;; This overrides binding for `add-change-log-entry-other-window'. -(define-key ctl-x-4-map "a" 'km/zsh-ansi-term-other-window) -(define-key km/external-map "t" 'km/open-external-terminal) (define-key km/external-map "r" 'shell-command-on-region) (define-key km/external-map "s" 'shell-command) (define-key km/external-map "S" 'shell) +;; This overrides binding for `add-change-log-entry-other-window'. +(define-key ctl-x-4-map "a" 'km/zsh-ansi-term-other-window) + + ;;; Compilation (defadvice compile (around prevent-duplicate-compilation-windows activate) @@ -117,16 +127,19 @@ monitor setup)." (define-key km/compile-map "c" 'compile) (define-key km/compile-map "g" 'recompile) -(define-key km/compile-map "r" 'km/recompile-current-compilation) (define-key km/compile-map "o" 'km/display-compilation-other-window) +(define-key km/compile-map "r" 'km/recompile-current-compilation) (key-chord-define-global ",e" 'km/recompile-current-compilation) + ;;; Diff (setq diff-command "/bin/diff" diff-switches "-u") +(setq ediff-window-setup-function 'ediff-setup-windows-plain) + (defadvice diff (after diff-select-and-view activate) (select-window (get-buffer-window "*Diff*")) (view-mode 1)) @@ -135,6 +148,8 @@ monitor setup)." (interactive) (revert-buffer) (view-mode 1)) +(after 'diff + (define-key diff-mode-map (kbd "C-c C-g") 'km/revert-buffer-and-view)) (defun km/ediff-with-other-window () "Run Ediff on current window's file and other window's file." @@ -149,18 +164,13 @@ monitor setup)." (ediff file-a file-b) (user-error "At least one buffer is not visiting a file")))) -(setq ediff-window-setup-function 'ediff-setup-windows-plain) - (define-key km/external-map "d" 'diff) (define-key km/external-map "e" 'ediff) (define-key km/external-map "o" 'km/ediff-with-other-window) -(after 'diff - (define-key diff-mode-map (kbd "C-c C-g") 'km/revert-buffer-and-view)) + ;;; WebJump -(define-key km/external-map "j" 'webjump) - (setq webjump-sites '(("Arch User Repository" . [simple-query "https://aur.archlinux.org" @@ -185,9 +195,6 @@ monitor setup)." [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""]))) -;;; Misc - -(define-key km/external-map "w" 'woman) -(define-key km/external-map "i" 'ispell-buffer) +(define-key km/external-map "j" 'webjump) (provide 'init-external) diff --git a/lisp/init-framewin.el b/lisp/init-framewin.el index 2425562..ebe818b 100644 --- a/lisp/init-framewin.el +++ b/lisp/init-framewin.el @@ -1,5 +1,10 @@ ;;; Frames and windows +(defadvice clone-indirect-buffer-other-window + (after clone-indirect-and-widen activate) + "Widen after cloning an indirect buffer." + (widen)) + ;; From prelude (defun km/swap-windows () "Swap 2 windows." @@ -32,19 +37,13 @@ Assumes that the window is only split into two." (split-window-vertically)) (switch-to-buffer nil))) +(global-set-key (kbd "M-o") 'scroll-other-window) + (define-prefix-command 'km/window-map) (global-set-key (kbd "C-c w") 'km/window-map) -(define-key km/window-map "s" 'km/swap-windows) -(define-key km/window-map "l" 'km/switch-window-split) - (define-key km/window-map "f" 'make-frame) - -(global-set-key (kbd "M-o") 'scroll-other-window) - -(defadvice clone-indirect-buffer-other-window - (after clone-indirect-and-widen activate) - "Widen after cloning an indirect buffer." - (widen)) +(define-key km/window-map "l" 'km/switch-window-split) +(define-key km/window-map "s" 'km/swap-windows) (provide 'init-framewin) diff --git a/lisp/init-general.el b/lisp/init-general.el index adc9df3..f6606a6 100644 --- a/lisp/init-general.el +++ b/lisp/init-general.el @@ -1,27 +1,18 @@ + (setq echo-keystrokes 0.1 use-dialog-box nil visible-bell t - tramp-default-method "ssh" enable-recursive-minibuffers t) +(setq tramp-default-method "ssh") + (setq-default indicate-empty-lines t indent-tabs-mode nil) -(show-paren-mode t) - -(defalias 'yes-or-no-p 'y-or-n-p) - -;; Set location of custom.el. (setq custom-file "~/.emacs.d/custom.el") (load custom-file) -(global-auto-revert-mode t) - -;; Make scripts executable at save. -(add-hook 'after-save-hook - 'executable-make-buffer-file-executable-if-script-p) - -(transient-mark-mode -1) +(defalias 'yes-or-no-p 'y-or-n-p) (put 'narrow-to-region 'disabled nil) (put 'narrow-to-page 'disabled nil) @@ -29,23 +20,13 @@ (put 'downcase-region 'disabled nil) (put 'upcase-region 'disabled nil) -(key-chord-mode 1) - -(global-set-key (kbd "C-h :") 'find-function) - -;; This is also bound to 'm', but I always want to press 'j' because -;; binding for `imenu' and `org-goto'. -(define-key Info-mode-map "j" 'Info-menu) - -;; Disable `suspend-frame' binding. -(global-unset-key (kbd "C-x C-z")) - -;; Avoid shift key for `backward-paragraph' and `forward-paragraph'. -(global-unset-key (kbd "M-}")) -(global-set-key (kbd "M-]") 'forward-paragraph) -(global-unset-key (kbd "M-{")) -(global-set-key (kbd "M-[") 'backward-paragraph) +(add-hook 'after-save-hook + 'executable-make-buffer-file-executable-if-script-p) +(show-paren-mode) +(global-auto-revert-mode) +(transient-mark-mode -1) +(key-chord-mode 1) (defun km/imenu (rescan) "Call `imenu', rescanning if RESCAN is non-nil." @@ -58,8 +39,6 @@ (setq imenu--index-alist nil)) (call-interactively #'imenu)) -(global-set-key (kbd "C-c j") 'km/imenu) - ;; Taken from ;; http://milkbox.net/note/single-file-master-emacs-configuration/. (defmacro after (mode &rest body) @@ -68,6 +47,23 @@ `(eval-after-load ,mode '(progn ,@body))) +(global-set-key (kbd "C-h :") 'find-function) + +(global-set-key (kbd "C-c j") 'km/imenu) + +;; Disable `suspend-frame' binding. +(global-unset-key (kbd "C-x C-z")) + +;; Avoid shift key for `backward-paragraph' and `forward-paragraph'. +(global-unset-key (kbd "M-}")) +(global-set-key (kbd "M-]") 'forward-paragraph) +(global-unset-key (kbd "M-{")) +(global-set-key (kbd "M-[") 'backward-paragraph) + +;; This is also bound to 'm', but I always want to press 'j' because +;; binding for `imenu' and `org-goto'. +(define-key Info-mode-map "j" 'Info-menu) + (define-key occur-mode-map "n" 'next-line) (define-key occur-mode-map "p" 'previous-line) diff --git a/lisp/init-git.el b/lisp/init-git.el index 371a058..57069d1 100644 --- a/lisp/init-git.el +++ b/lisp/init-git.el @@ -1,22 +1,34 @@ -(add-to-list 'load-path "~/src/emacs/magit/") -(add-to-list 'load-path "~/src/emacs/magit-annex/") -(add-to-list 'load-path "~/src/emacs/orgit/") +(require 'git-annex) + +(setq vc-follow-symlinks t) + +(setq git-annex-commit nil) + +(define-prefix-command 'km/git-map) +(global-set-key (kbd "C-c g") 'km/git-map) + + +;;; Magit +(add-to-list 'load-path "~/src/emacs/magit/") (require 'magit-autoloads) +(add-to-list 'load-path "~/src/emacs/orgit/") (require 'orgit) -(require 'git-annex) - -(setq git-annex-commit nil) +(setq magit-restore-window-configuration t + magit-completing-read-function 'magit-ido-completing-read + magit-delete-by-moving-to-trash nil + magit-log-show-margin nil) -(require 'magit-annex-autoloads) +(add-hook 'magit-find-file-hook 'view-mode) +(after 'magit + (remove-hook 'magit-refs-sections-hook 'magit-insert-tags) -(after 'magit-annex - (setq magit-annex-all-action-arguments - (delete "--auto" magit-annex-all-action-arguments))) + (magit-backup-mode -1)) -(key-chord-define-global ",g" 'magit-status) +(after 'git-commit + (add-hook 'git-commit-setup-hook 'git-commit-turn-on-flyspell)) (defun km/magit-auto-commit () "Commit all changes with \"auto\" commit message. @@ -138,19 +150,6 @@ START-POINT set to the current branch. ad-do-it (delete-other-windows)) -(setq magit-restore-window-configuration t - magit-completing-read-function 'magit-ido-completing-read - magit-delete-by-moving-to-trash nil - magit-popup-show-help-echo nil - magit-popup-show-help-section nil - magit-popup-use-prefix-argument 'default - magit-log-show-margin nil) - -(setq vc-follow-symlinks t) - -(after 'git-commit - (add-hook 'git-commit-setup-hook 'git-commit-turn-on-flyspell)) - (defun km/git-rebase-show-commit () "Show the commit on the current line if any. Unlike `git-rebase-show-commit', display (but don't switch to) @@ -162,25 +161,17 @@ the commit buffer. And no dinging." (match-string 2)) (magit-show-commit it t)))) -(after 'git-rebase - (define-key git-rebase-mode-map "\s" 'km/git-rebase-show-commit)) - -(after 'magit - (magit-backup-mode -1) - (add-hook 'magit-find-file-hook 'view-mode) - - (remove-hook 'magit-refs-sections-hook 'magit-insert-tags) - - (define-key magit-mode-map "Q" 'km/magit-mode-quit-all-windows) +(define-key ctl-x-4-map "g" 'magit-find-file-other-window) +(define-key km/file-map "g" 'magit-find-file) - (define-key magit-popup-mode-map (kbd "SPC ") 'magit-invoke-popup-switch) - (define-key magit-popup-mode-map (kbd "SPC SPC ") 'magit-invoke-popup-option) +(key-chord-define-global ",g" 'magit-status) +(after 'magit ;; Remove `magit-add-change-log-entry-other-window', which overrides ;; my binding for `km/zsh-ansi-term-other-window'. (define-key magit-mode-map (kbd "C-x 4 a") nil) - (define-key magit-mode-map "N" 'km/magit-stage-file-intent) + (define-key magit-mode-map "Q" 'km/magit-mode-quit-all-windows) ;; `magit-diff-visit-file-worktree' is also on C-RET. (define-key magit-file-section-map (kbd "C-j") 'magit-diff-visit-file-worktree) @@ -190,6 +181,28 @@ the commit buffer. And no dinging." (define-key magit-refs-mode-map "j" 'ace-jump-mode) (define-key magit-cherry-mode-map "j" 'ace-jump-mode) + (define-key km/git-map "c" 'km/magit-show-commit-under-point) + (define-key km/git-map "C" 'km/magit-show-project-commit-under-point) + (define-key km/git-map "e" 'km/magit-commit-extend-all) + (define-key km/git-map "u" 'km/magit-auto-commit)) + +(after 'git-rebase + (define-key git-rebase-mode-map "\s" 'km/git-rebase-show-commit)) + + +;;; Magit popups + +(setq magit-popup-show-help-echo nil + magit-popup-show-help-section nil + magit-popup-use-prefix-argument 'default) + +(after 'magit + (setq magit-branch-arguments + (delete "--track" magit-branch-arguments)) + + (define-key magit-popup-mode-map (kbd "SPC ") 'magit-invoke-popup-switch) + (define-key magit-popup-mode-map (kbd "SPC SPC ") 'magit-invoke-popup-option) + (magit-define-popup-action 'magit-commit-popup ?u "Auto commit" 'km/magit-auto-commit) (magit-define-popup-action 'magit-push-popup @@ -217,19 +230,16 @@ the commit buffer. And no dinging." (defadvice magit-merge-editmsg (around km/magit-merge-editmsg-no-ff activate) "Set '--no-ff' flag when running `magit-merge-editmsg'." (let ((args '("--no-ff"))) - ad-do-it)) + ad-do-it))) - (setq magit-branch-arguments - (delete "--track" magit-branch-arguments))) + +;;; Magit Annex -(define-key ctl-x-4-map "g" 'magit-find-file-other-window) -(define-key km/file-map "g" 'magit-find-file) +(add-to-list 'load-path "~/src/emacs/magit-annex/") +(require 'magit-annex-autoloads) -(define-prefix-command 'km/git-map) -(global-set-key (kbd "C-c g") 'km/git-map) -(define-key km/git-map "c" 'km/magit-show-commit-under-point) -(define-key km/git-map "C" 'km/magit-show-project-commit-under-point) -(define-key km/git-map "e" 'km/magit-commit-extend-all) -(define-key km/git-map "u" 'km/magit-auto-commit) +(after 'magit-annex + (setq magit-annex-all-action-arguments + (delete "--auto" magit-annex-all-action-arguments))) (provide 'init-git) diff --git a/lisp/init-gnus.el b/lisp/init-gnus.el index 8fdc85a..5acde06 100644 --- a/lisp/init-gnus.el +++ b/lisp/init-gnus.el @@ -1,52 +1,34 @@ (require 'gnus) +(autoload 'gnus-group-topic "gnus-topic") + +(require 'org-gnus) + +(setq gnus-home-directory "~/.gnus.d/" + gnus-directory gnus-home-directory + gnus-article-save-directory (expand-file-name "saved/" gnus-directory) + gnus-kill-files-directory (expand-file-name "scores/" gnus-directory)) + +(setq gnus-startup-file (expand-file-name "newsrc" gnus-home-directory) + gnus-init-file (expand-file-name "gnus" gnus-home-directory) + gnus-save-newsrc-file nil + gnus-read-newsrc-file nil) + +(setq sendmail-program "/usr/bin/msmtp" + gnus-gcc-mark-as-read t + gnus-visible-headers '("^From" "^Subject" "^Date" "^To" "^Cc" "^User-Agent") + gnus-confirm-mail-reply-to-news t) + +(setq imap-shell-program "/usr/lib/dovecot/imap -c ~/.dovecotrc" + gnus-select-method '(nnimap "dov" (nnimap-stream shell)) + gnus-secondary-select-methods '((nntp "news.gmane.org"))) -(setq - ;; Locations - gnus-home-directory "~/.gnus.d/" - gnus-directory gnus-home-directory - gnus-article-save-directory (expand-file-name "saved/" gnus-directory) - gnus-kill-files-directory (expand-file-name "scores/" gnus-directory) - ;; Startup files - gnus-startup-file (expand-file-name "newsrc" gnus-home-directory) - gnus-init-file (expand-file-name "gnus" gnus-home-directory) - gnus-save-newsrc-file nil - gnus-read-newsrc-file nil - ;; Select methods - imap-shell-program "/usr/lib/dovecot/imap -c ~/.dovecotrc" - gnus-select-method '(nnimap "dov" (nnimap-stream shell)) - gnus-secondary-select-methods '((nntp "news.gmane.org")) - ;; Groups - gnus-topic-display-empty-topics nil - gnus-group-list-inactive-groups nil - ;; Messages - message-send-mail-function 'message-send-mail-with-sendmail - sendmail-program "/usr/bin/msmtp" - message-sendmail-envelope-from 'header - gnus-gcc-mark-as-read t - message-citation-line-function 'message-insert-formatted-citation-line - message-citation-line-format "%f wrote:" - message-kill-buffer-on-exit t - gnus-visible-headers '("^From" "^Subject" "^Date" "^To" "^Cc" "^User-Agent") - gnus-confirm-mail-reply-to-news t - footnote-section-tag "" - ;; Threading - gnus-thread-hide-subtree t - gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-number) - gnus-summary-line-format "%U%R %&user-date;%-20= %-15,15f %B %S \n" - gnus-sum-thread-tree-indent " " - gnus-sum-thread-tree-root "." - gnus-sum-thread-tree-false-root "o " - gnus-sum-thread-tree-single-indent "" - gnus-sum-thread-tree-leaf-with-other "+-> " - gnus-sum-thread-tree-vertical "| " - gnus-sum-thread-tree-single-leaf "`-> " - ;; Agent - gnus-agent-go-online t - gnus-agent-synchronize-flags t - ;; Miscellaneous - gnus-auto-select-next 'quietly - mm-discouraged-alternatives '("text/html" "text/richtext") - gnus-interactive-exit nil) +(setq gnus-agent-go-online t + gnus-agent-synchronize-flags t) + +(setq mm-discouraged-alternatives '("text/html" "text/richtext")) +(setq gnus-interactive-exit nil) + +(add-hook 'kill-emacs-hook 'gnus-grace-exit-before-kill-emacs) (defun km/sync-mail () (interactive) @@ -70,17 +52,23 @@ (gnus-alive-p)) (let ((noninteractive t)) (gnus-group-exit)))) -(add-hook 'kill-emacs-hook 'gnus-grace-exit-before-kill-emacs) -(defun km/message-confirm-sender () - "Stop sending message from the wrong address." - (unless (yes-or-no-p (format "Send message from %s?" - (message-field-value "From"))) - (user-error "Not sending message"))) +(define-prefix-command 'km/mail-map) +(global-set-key (kbd "C-x m") 'km/mail-map) -(add-hook 'message-send-hook 'km/message-confirm-sender) +(define-key km/mail-map "g" 'gnus) +(define-key km/mail-map "p" 'gnus-plugged) +(define-key km/mail-map "u" 'gnus-unplugged) +(define-key km/mail-map "s" 'km/sync-mail) -(autoload 'gnus-group-topic "gnus-topic") + +;;; Gnus group buffer + +(setq gnus-topic-display-empty-topics nil + gnus-group-list-inactive-groups nil) + +(setq gnus-group-sort-function '(km/gnus-group-sort-by-topic + gnus-group-sort-by-level)) (defun km/gnus-group-sort-by-topic (info1 info2) "Sort alphabetically by group topic. @@ -89,11 +77,30 @@ is off." (string< (gnus-group-topic (gnus-info-group info1)) (gnus-group-topic (gnus-info-group info2)))) -(setq gnus-group-sort-function '(km/gnus-group-sort-by-topic - gnus-group-sort-by-level)) +(define-key gnus-group-mode-map "e" 'gnus-group-select-group) -(add-hook 'message-mode-hook - (lambda () (flyspell-mode 1))) + +;;; Gnus summary and article buffer + +(setq gnus-summary-line-format "%U%R %&user-date;%-20= %-15,15f %B %S \n" + gnus-sum-thread-tree-indent " " + gnus-sum-thread-tree-root "." + gnus-sum-thread-tree-false-root "o " + gnus-sum-thread-tree-single-indent "" + gnus-sum-thread-tree-leaf-with-other "+-> " + gnus-sum-thread-tree-vertical "| " + gnus-sum-thread-tree-single-leaf "`-> ") + +(setq gnus-auto-select-next 'quietly) + +(setq gnus-thread-hide-subtree t + gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-number)) + +(add-hook 'gnus-summary-mode-hook 'km/gnus-setup-local-ace-jump) + +(defun km/gnus-setup-local-ace-jump () + (add-hook 'ace-jump-mode-end-hook (lambda () (gnus-summary-scroll-up 0)) + nil t)) (defun km/gnus-follow-last-message-link (arg) "Follow link at bottom of message. @@ -106,11 +113,6 @@ follow it." (shr-copy-url) (widget-button-press (point)))) -(define-key gnus-summary-mode-map - (kbd "C-c j") 'km/gnus-follow-last-message-link) -(define-key gnus-article-mode-map - (kbd "C-c j") 'km/gnus-follow-last-message-link) - (defun km/gnus-open-github-patch () "Open patch from github email. A new buffer with the patch contents is opened in another window." @@ -132,57 +134,55 @@ A new buffer with the patch contents is opened in another window." (select-window (gnus-get-buffer-window gnus-article-buffer)) (goto-char (point-max))) -(require 'notmuch) -(require 'org-gnus) -(require 'org-notmuch) -(setq org-gnus-prefer-web-links t) +;; From http://ivan.kanis.fr/ivan-gnus.el +(defun km/gnus-catchup-and-goto-next-group (&optional all) + "Mark all articles in this group as read and select the next group. +If given a prefix, mark all articles, unread as well as ticked, as +read. Don't ask to confirm." + (interactive "P") + (save-excursion + (gnus-summary-catchup all t)) + (gnus-summary-next-group)) -(define-key gnus-group-mode-map "GG" 'notmuch-search) -;; http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html -(defun km/notmuch-shortcut () - (define-key gnus-group-mode-map "GG" 'notmuch-search)) +;; From http://ivan.kanis.fr/ivan-gnus.el +(defadvice gnus-summary-next-group (before km/gnus-next-group activate) + "Go to next group without selecting the first article." + (ad-set-arg 0 t)) -(defun km/notmuch-file-to-group (file) - "Calculate the Gnus group name from the given file name." - (let ((group (file-name-directory (directory-file-name (file-name-directory file))))) - (setq group (replace-regexp-in-string ".*/mail/" "nnimap+dov:" group)) - (setq group (replace-regexp-in-string "/$" "" group)) - (if (string-match ":$" group) - (concat group "INBOX") - (replace-regexp-in-string ":\\." ":" group)))) +(define-key gnus-summary-mode-map + (kbd "C-c j") 'km/gnus-follow-last-message-link) +(define-key gnus-summary-mode-map ";" 'gnus-summary-universal-argument) +;; This overrides `gnus-summary-post-news', which is also bound to +;; 'S p'. +(define-key gnus-summary-mode-map "a" 'ace-jump-mode) +(define-key gnus-summary-mode-map "c" 'km/gnus-catchup-and-goto-next-group) +(define-key gnus-summary-mode-map "e" 'gnus-summary-scroll-up) +(define-key gnus-summary-mode-map "j" 'ace-jump-mode) -(defun km/notmuch-goto-message-in-gnus () - "Open a summary buffer containing the current notmuch article." - (interactive) - (let ((group (km/notmuch-file-to-group (notmuch-show-get-filename))) - (message-id (replace-regexp-in-string - "^id:" "" (notmuch-show-get-message-id)))) - (setq message-id (replace-regexp-in-string "\"" "" message-id)) - (if (and group message-id) - (progn - (switch-to-buffer "*Group*") - (org-gnus-follow-link group message-id)) - (message "Couldn't get relevant infos for switching to Gnus.")))) +(define-key gnus-article-mode-map + (kbd "C-c j") 'km/gnus-follow-last-message-link) +(define-key gnus-article-mode-map "e" 'shr-browse-url) -(defun km/gnus-goto-message-in-notmuch () - "Show message in notmuch." - (interactive) - (when (and (memq major-mode '(gnus-summary-mode gnus-article-mode)) - (string= (cadr (gnus-find-method-for-group gnus-newsgroup-name)) - "dov")) - (let* ((header (with-current-buffer gnus-summary-buffer - (gnus-summary-article-header))) - (message-id (org-remove-angle-brackets (mail-header-id header)))) - (notmuch-show (concat "id:" message-id))))) + +;;; Message mode -(add-hook 'km/org-store-link-hook 'km/gnus-goto-message-in-notmuch) +(setq message-send-mail-function 'message-send-mail-with-sendmail + message-sendmail-envelope-from 'header + message-citation-line-function 'message-insert-formatted-citation-line + message-citation-line-format "%f wrote:" + message-kill-buffer-on-exit t + footnote-section-tag "") -(define-key notmuch-show-mode-map (kbd "C-c C-c") 'km/notmuch-goto-message-in-gnus) -(add-hook 'gnus-group-mode-hook 'km/notmuch-shortcut) +(add-hook 'message-send-hook 'km/message-confirm-sender) +(add-hook 'message-mode-hook + (lambda () (flyspell-mode 1))) -(setq notmuch-fcc-dirs nil - notmuch-search-oldest-first nil) +(defun km/message-confirm-sender () + "Stop sending message from the wrong address." + (unless (yes-or-no-p (format "Send message from %s?" + (message-field-value "From"))) + (user-error "Not sending message"))) ;; Modified from ;; http://emacs-fu.blogspot.com/2008/12/some-simple-tricks-boxquote-footnote.html. @@ -211,12 +211,8 @@ paragraph." (define-key message-mode-map (kbd "C-c m s") 'km/snip-mail-quote) -(define-key gnus-summary-mode-map "c" 'km/gnus-catchup-and-goto-next-group) -(define-key gnus-summary-mode-map ";" 'gnus-summary-universal-argument) -(define-key gnus-summary-mode-map "e" 'gnus-summary-scroll-up) - -(define-key gnus-group-mode-map "e" 'gnus-group-select-group) -(define-key gnus-article-mode-map "e" 'shr-browse-url) + +;;; Select and bury ;; Modified from http://www.xsteve.at/prg/gnus/ @@ -261,40 +257,57 @@ paragraph." (bury-buffer) (bury-buffer buf)))))) -;; From http://ivan.kanis.fr/ivan-gnus.el -(defun km/gnus-catchup-and-goto-next-group (&optional all) - "Mark all articles in this group as read and select the next group. -If given a prefix, mark all articles, unread as well as ticked, as -read. Don't ask to confirm." - (interactive "P") - (save-excursion - (gnus-summary-catchup all t)) - (gnus-summary-next-group)) +(define-key km/mail-map "b" 'km/gnus-select-or-bury) -;; From http://ivan.kanis.fr/ivan-gnus.el -(defadvice gnus-summary-next-group (before km/gnus-next-group activate) - "Go to next group without selecting the first article." - (ad-set-arg 0 t)) + +;;; Notmuch -(defun km/gnus-setup-local-ace-jump () - (add-hook 'ace-jump-mode-end-hook (lambda () (gnus-summary-scroll-up 0)) - nil t)) -(add-hook 'gnus-summary-mode-hook 'km/gnus-setup-local-ace-jump) +(require 'notmuch) +(require 'org-notmuch) -;; This overrides `gnus-summary-post-news', which is also bound to -;; 'S p'. -(define-key gnus-summary-mode-map "a" 'ace-jump-mode) +(setq org-gnus-prefer-web-links t) -(define-key gnus-summary-mode-map "j" 'ace-jump-mode) +(setq notmuch-fcc-dirs nil + notmuch-search-oldest-first nil) -(define-prefix-command 'km/mail-map) -(global-set-key (kbd "C-x m") 'km/mail-map) +(add-hook 'km/org-store-link-hook 'km/gnus-goto-message-in-notmuch) + +(defun km/notmuch-file-to-group (file) + "Calculate the Gnus group name from the given file name." + (let ((group (file-name-directory (directory-file-name (file-name-directory file))))) + (setq group (replace-regexp-in-string ".*/mail/" "nnimap+dov:" group)) + (setq group (replace-regexp-in-string "/$" "" group)) + (if (string-match ":$" group) + (concat group "INBOX") + (replace-regexp-in-string ":\\." ":" group)))) + +(defun km/notmuch-goto-message-in-gnus () + "Open a summary buffer containing the current notmuch article." + (interactive) + (let ((group (km/notmuch-file-to-group (notmuch-show-get-filename))) + (message-id (replace-regexp-in-string + "^id:" "" (notmuch-show-get-message-id)))) + (setq message-id (replace-regexp-in-string "\"" "" message-id)) + (if (and group message-id) + (progn + (switch-to-buffer "*Group*") + (org-gnus-follow-link group message-id)) + (message "Couldn't get relevant infos for switching to Gnus.")))) + +(defun km/gnus-goto-message-in-notmuch () + "Show message in notmuch." + (interactive) + (when (and (memq major-mode '(gnus-summary-mode gnus-article-mode)) + (string= (cadr (gnus-find-method-for-group gnus-newsgroup-name)) + "dov")) + (let* ((header (with-current-buffer gnus-summary-buffer + (gnus-summary-article-header))) + (message-id (org-remove-angle-brackets (mail-header-id header)))) + (notmuch-show (concat "id:" message-id))))) + +(define-key notmuch-show-mode-map (kbd "C-c C-c") 'km/notmuch-goto-message-in-gnus) +(define-key gnus-group-mode-map "GG" 'notmuch-search) -(define-key km/mail-map "g" 'gnus) -(define-key km/mail-map "b" 'km/gnus-select-or-bury) -(define-key km/mail-map "p" 'gnus-plugged) -(define-key km/mail-map "u" 'gnus-unplugged) -(define-key km/mail-map "s" 'km/sync-mail) (define-key km/mail-map "n" 'notmuch-search) (provide 'init-gnus) diff --git a/lisp/init-ido.el b/lisp/init-ido.el index ad597e5..9332081 100644 --- a/lisp/init-ido.el +++ b/lisp/init-ido.el @@ -10,9 +10,8 @@ ido-save-directory-list-file "~/.emacs.d/cache/ido.hist" ido-max-directory-size 100000) -(add-hook 'dired-mode-hook - (lambda () - (set (make-local-variable 'ido-use-filename-at-point) nil))) +;; Disable ido faces to see flx highlights. +(setq ido-use-faces nil) (setq ido-file-extensions-order '(".org" ".txt" ".md" ".rst" ".tex" ".py" ".el" ".hs")) @@ -21,14 +20,15 @@ (append '(".out" ".log" ".fls" ".fdb" ".fdb_latexmk") completion-ignored-extensions)) -;; Disable ido faces to see flx highlights. -(setq ido-use-faces nil) +(add-hook 'dired-mode-hook + (lambda () + (set (make-local-variable 'ido-use-filename-at-point) nil))) (ido-mode 1) -(ido-vertical-mode 1) -(ido-everywhere 1) -(flx-ido-mode 1) -(ido-ubiquitous-mode 1) +(ido-vertical-mode) +(ido-everywhere) +(flx-ido-mode) +(ido-ubiquitous-mode) (ido-at-point-mode) (key-chord-define-global ",b" 'ido-switch-buffer) diff --git a/lisp/init-org.el b/lisp/init-org.el index cc43e1c..a674610 100644 --- a/lisp/init-org.el +++ b/lisp/init-org.el @@ -2,112 +2,32 @@ (add-to-list 'load-path "~/src/emacs/org-mode/contrib/lisp/" t) (add-to-list 'Info-directory-list "~/src/emacs/org-mode/doc/") -(setq org-modules '(org-bibtex org-gnus org-info) - org-log-done t - org-todo-keywords '((sequence "TODO(t)" "STARTED(s)" "WAITING(w@)" - "|" "DONE(d)" "NA(n@)")) +(setq org-modules '(org-bibtex org-gnus org-info)) + +(setq org-log-done t org-log-into-drawer t org-clock-into-drawer t - org-use-speed-commands t - org-use-extra-keys t - org-fast-tag-selection-single-key 'expert - org-catch-invisible-edits 'error - org-goto-interface 'outline-path-completionp - org-src-fontify-natively t + org-todo-keywords '((sequence "TODO(t)" "STARTED(s)" "WAITING(w@)" + "|" "DONE(d)" "NA(n@)"))) + +(setq org-catch-invisible-edits 'error org-special-ctrl-k t - org-outline-path-complete-in-steps nil - org-completion-use-ido t - org-reverse-note-order t - org-link-search-must-match-exact-headline nil org-insert-heading-respect-content t org-M-RET-may-split-line nil org-blank-before-new-entry '((heading . t) (plain-list-item . auto))) -(setq org-capture-templates - '(("t" "task" entry (file+headline "~/notes/tasks.org" "Inbox") - "* TODO %?\n%i") - ("d" "date" entry (file+headline "~/notes/calendar.org" "Inbox") - "* %?\n%i") - ("m" "misc" entry (file+headline "~/notes/misc.org" "Inbox") - "* %?\n%i") - ;; Link counterparts - ("T" "task link" entry (file+headline "~/notes/tasks.org" "Inbox") - "* TODO %?\n%i\nLink: %a") - ("D" "date link" entry (file+headline "~/notes/calendar.org" "Inbox") - "* %?\n%i\nLink: %a") - ("M" "misc link" entry (file+headline "~/notes/misc.org" "Inbox") - "* %?\n%i\nLink: %a") - ;; Clipboard - ("x" "task clipboard" entry (file+headline "~/notes/tasks.org" "Inbox") - "* TODO %?\n%x") - ("X" "misc clipboard" entry (file+headline "~/notes/misc.org" "Inbox") - "* %?\n%x"))) -(key-chord-define-global ",t" 'org-capture) - -(defadvice org-open-file (after km/org-open-add-to-recentf activate) - (recentf-add-file path)) - -(defun km/org-open-file-at-point () - "Open file at point with `org-open-file'." - (interactive) - (let ((file (thing-at-point 'filename))) - (if (and file (file-exists-p file)) - (org-open-file file) - (user-error "No file at point")))) - -(defun km/org-open-file () - "Interactive version of `org-open-file'." - (interactive) - (org-open-file (read-file-name "Open file: " nil nil t))) +(setq org-link-search-must-match-exact-headline nil) -(defun km/org-open-annex-file () - "Open a git annex file with `org-open-file'." - (interactive) - (--if-let (magit-annex-present-files) - (org-open-file (magit-completing-read "Open annex file" it nil t)) - (message "No annex files found"))) - -(defun km/org-open-recent-file () - "Open a file from `recentf-list' with `org-open-file'." - (interactive) - (org-open-file (km/read-recent-file))) - -(autoload 'magit-annex-present-files "magit-annex") - -(after 'init-buffile - (define-key km/file-map "a" 'km/org-open-annex-file) - (define-key km/file-map "o" 'km/org-open-file) - (define-key km/file-map "p" 'km/org-open-file-at-point) - (define-key km/file-map "r" 'km/org-open-recent-file)) - -(define-prefix-command 'km/global-org-map) -(global-set-key (kbd "C-c o") 'km/global-org-map) - -(defvar km/org-store-link-hook nil - "Hook run before by `km/org-store-link-hook'. -These are run within a `save-window-excursion' block.") - -(defun km/org-store-link () - "Run `km/org-store-link-hook' before `org-store-link'. -The hook functions and `org-store-link' are called within a -`save-window-excursion' block." - (interactive) - (save-window-excursion - (run-hooks 'km/org-store-link-hook) - (call-interactively 'org-store-link))) +(setq org-use-speed-commands t + org-use-extra-keys t + org-fast-tag-selection-single-key 'expert) -(define-key km/global-org-map "l" 'km/org-store-link) -(define-key km/global-org-map "o" 'org-open-at-point-global) -(define-key km/global-org-map "a" 'org-agenda) -(define-key km/global-org-map "j" 'km/org-goto-agenda-heading) -(define-key km/global-org-map "b" 'org-iswitchb) -(define-key km/global-org-map "s" 'org-save-all-org-buffers) -(define-key km/global-org-map "w" 'org-refile-goto-last-stored) -(define-key km/global-org-map "p" 'poporg-dwim) -(key-chord-define-global ",a" 'org-agenda) +(setq org-completion-use-ido t + org-outline-path-complete-in-steps nil + org-goto-interface 'outline-path-completionp + org-goto-max-level 3) -(after 'poporg - (define-key poporg-mode-map (kbd "C-c C-c") 'poporg-edit-exit)) +(put 'org-goto-max-level 'safe-local-variable #'integerp) (setq org-structure-template-alist '(("p" "#+property: " "") @@ -137,36 +57,20 @@ The hook functions and `org-store-link' are called within a ("i" "#+index: ?" "#+index: ?") ("I" "#+include: %file ?" ""))) -(define-prefix-command 'km/org-prefix-map) -(define-key km/org-prefix-map "w" 'km/org-refile-to-other-org-buffer) -(define-key km/org-prefix-map "s" 'km/org-sort-parent) -(define-key km/org-prefix-map "l" 'km/org-remove-title-leader) - -(after 'org - (define-key org-mode-map (kbd "C-c C-x B") - 'km/org-tree-to-indirect-buffer-current-window) - (define-key org-mode-map [remap org-tree-to-indirect-buffer] - 'km/org-tree-to-indirect-buffer) - (define-key org-mode-map (kbd "C-c m") 'km/org-prefix-map) - ;; Override global `imenu' binding. - (define-key org-mode-map (kbd "C-c j") 'org-goto) - ;; Don't let `org-cycle-agenda-files' binding override custom - ;; `backward-kill-word' binding (`org-cycle-agenda-files' is still bound - ;; to C-,). - (define-key org-mode-map (kbd "C-'") nil) - ;; Rebind `org-insert-drawer' to so that `org-metadown' has the - ;; expected "C-c C-x" keybinding. - (define-key org-mode-map (kbd "C-c C-x d") 'org-metadown) - (define-key org-mode-map (kbd "C-c C-x w") 'org-insert-drawer) - ;; Avoid conflict when amsmath is loaded. - (setcar (rassoc '("wasysym" t) org-latex-default-packages-alist) - "nointegrals") - (add-to-list 'org-latex-packages-alist '("" "amsmath" t))) - (add-to-list 'auto-mode-alist '("\\.org.txt\\'" . org-mode)) -(setq org-goto-max-level 3) -(put 'org-goto-max-level 'safe-local-variable #'integerp) +(defvar km/org-store-link-hook nil + "Hook run before by `km/org-store-link-hook'. +These are run within a `save-window-excursion' block.") + +(defun km/org-store-link () + "Run `km/org-store-link-hook' before `org-store-link'. +The hook functions and `org-store-link' are called within a +`save-window-excursion' block." + (interactive) + (save-window-excursion + (run-hooks 'km/org-store-link-hook) + (call-interactively 'org-store-link))) (defun km/org-tree-to-indirect-buffer (&optional arg) "Run `org-tree-to-indirect-buffer', keeping previous buffer. @@ -296,24 +200,111 @@ to (km/reduce-to-single-spaces) (km/org-add-blank-before-heading)) +(defun km/org-switch-to-buffer-other-window (&optional arg) + (interactive "P") + (noflet ((org-pop-to-buffer-same-window (&optional buffer-or-name norecord label) + (funcall 'pop-to-buffer buffer-or-name nil norecord))) + (org-switchb arg))) + +(after 'org + (define-key org-mode-map (kbd "C-c C-x B") + 'km/org-tree-to-indirect-buffer-current-window) + (define-key org-mode-map [remap org-tree-to-indirect-buffer] + 'km/org-tree-to-indirect-buffer) + + ;; Rebind `org-insert-drawer' to so that `org-metadown' has the + ;; expected "C-c C-x" keybinding. + (define-key org-mode-map (kbd "C-c C-x d") 'org-metadown) + (define-key org-mode-map (kbd "C-c C-x w") 'org-insert-drawer) + + ;; Override global `imenu' binding. + (define-key org-mode-map (kbd "C-c j") 'org-goto) + ;; Don't let `org-cycle-agenda-files' binding override custom + ;; `backward-kill-word' binding (`org-cycle-agenda-files' is still bound + ;; to C-,). + (define-key org-mode-map (kbd "C-'") nil) + + (define-key org-mode-map (kbd "C-c m") 'km/org-prefix-map)) + +(define-prefix-command 'km/org-prefix-map) +(define-key km/org-prefix-map "l" 'km/org-remove-title-leader) (define-key km/org-prefix-map "n" 'km/org-normalize-spaces) +(define-key km/org-prefix-map "s" 'km/org-sort-parent) -;;; Org in other modes -(defun km/load-orgstruct () - (turn-on-orgstruct++) - (turn-on-orgtbl)) +(define-prefix-command 'km/global-org-map) +(global-set-key (kbd "C-c o") 'km/global-org-map) -(add-hook 'message-mode-hook 'km/load-orgstruct) +(define-key km/global-org-map "a" 'org-agenda) +(define-key km/global-org-map "b" 'org-iswitchb) +(define-key km/global-org-map "l" 'km/org-store-link) +(define-key km/global-org-map "o" 'org-open-at-point-global) +(define-key km/global-org-map "s" 'org-save-all-org-buffers) -(after 'git-commit - (add-hook 'git-commit-setup-hook 'km/load-orgstruct)) +(define-key ctl-x-4-map "o" 'km/org-switch-to-buffer-other-window) -(add-hook 'next-error-hook (lambda () - (when (eq major-mode 'org-mode) - (org-show-context)))) + +;;; Org capture + +(setq org-capture-templates + '(("t" "task" entry (file+headline "~/notes/tasks.org" "Inbox") + "* TODO %?\n%i") + ("d" "date" entry (file+headline "~/notes/calendar.org" "Inbox") + "* %?\n%i") + ("m" "misc" entry (file+headline "~/notes/misc.org" "Inbox") + "* %?\n%i") + ;; Link counterparts + ("T" "task link" entry (file+headline "~/notes/tasks.org" "Inbox") + "* TODO %?\n%i\nLink: %a") + ("D" "date link" entry (file+headline "~/notes/calendar.org" "Inbox") + "* %?\n%i\nLink: %a") + ("M" "misc link" entry (file+headline "~/notes/misc.org" "Inbox") + "* %?\n%i\nLink: %a") + ;; Clipboard + ("x" "task clipboard" entry (file+headline "~/notes/tasks.org" "Inbox") + "* TODO %?\n%x") + ("X" "misc clipboard" entry (file+headline "~/notes/misc.org" "Inbox") + "* %?\n%x"))) + +(key-chord-define-global ",t" 'org-capture) + ;;; Agenda +(setq org-default-notes-file "~/notes/agenda/tasks.org") +(defvar km/org-agenda-file-directory "~/notes/agenda/") +(setq org-agenda-files (list km/org-agenda-file-directory)) +(setq org-agenda-text-search-extra-files + (file-expand-wildcards "~/notes/extra/*.org")) + +(setq org-agenda-restore-windows-after-quit t + org-agenda-sticky nil) + +(setq org-agenda-dim-blocked-tasks nil + org-agenda-show-all-dates t + org-agenda-skip-deadline-if-done t + org-agenda-skip-scheduled-if-done t + org-agenda-start-on-weekday nil + org-agenda-use-time-grid nil) + +(setq org-agenda-sorting-strategy + '((agenda time-up deadline-up scheduled-up priority-down category-keep) + (todo priority-down category-keep) + (tags priority-down category-keep) + (search category-keep))) + +(setq org-agenda-custom-commands + '(("d" todo "DONE" nil) + ("u" "Unschedule TODO entries" alltodo "" + ((org-agenda-skip-function + (lambda nil + (org-agenda-skip-entry-if 'scheduled 'deadline + 'regexp "\n]+>"))) + (org-agenda-overriding-header "Unscheduled TODO entries: "))) + ("p" "Past timestamps" tags "TIMESTAMP<=\"\""))) + +(add-hook 'org-agenda-mode-hook 'km/org-agenda-cd-and-read-dir-locals) +(add-hook 'org-agenda-finalize-hook 'km/org-agenda-store-current-span) + (after 'org-agenda (defadvice org-agenda-list (around org-agenda-fullscreen activate) "Start agenda in fullscreen. @@ -330,19 +321,6 @@ be restored properly." (setq default-directory "~/notes/") (hack-local-variables)) -(add-hook 'org-agenda-mode-hook 'km/org-agenda-cd-and-read-dir-locals) - -(setq org-agenda-restore-windows-after-quit t - org-agenda-sticky nil) - -(setq org-default-notes-file "~/notes/agenda/tasks.org" - org-agenda-show-all-dates t - org-agenda-skip-deadline-if-done t - org-agenda-skip-scheduled-if-done t - org-agenda-dim-blocked-tasks nil - org-agenda-use-time-grid nil - org-agenda-start-on-weekday nil) - (defun km/org-agenda-store-current-span () "Store the current span value in `org-agenda-span'. This allows the view to persist when the agenda buffer is @@ -350,19 +328,6 @@ killed." (when org-agenda-current-span (setq org-agenda-span org-agenda-current-span))) -(add-hook 'org-agenda-finalize-hook 'km/org-agenda-store-current-span) - -(setq org-agenda-sorting-strategy - '((agenda time-up deadline-up scheduled-up priority-down category-keep) - (todo priority-down category-keep) - (tags priority-down category-keep) - (search category-keep))) - -(defvar km/org-agenda-file-directory "~/notes/agenda/") -(setq org-agenda-files (list km/org-agenda-file-directory)) -(setq org-agenda-text-search-extra-files - (file-expand-wildcards "~/notes/extra/*.org")) - (defun km/org-agenda-add-or-remove-file (file) "Add or remove link to FILE in `km/org-agenda-file-directory'. If a link for FILE does not exist, create it. Otherwise, remove @@ -384,8 +349,6 @@ displayed in the agenda." (when (called-interactively-p) (message "Adding %s" agenda-file)) (make-symbolic-link file agenda-file)))) -(define-key km/global-org-map "n" 'km/org-agenda-add-or-remove-file) - (defun km/org-open-default-notes-file-inbox () "Open \"Inbox\" heading of `org-default-notes-file'." (interactive) @@ -394,18 +357,6 @@ displayed in the agenda." (recenter-top-bottom 0) (show-children)) -(define-key km/global-org-map "m" 'km/org-open-default-notes-file-inbox) - -(setq org-agenda-custom-commands - '(("d" todo "DONE" nil) - ("u" "Unschedule TODO entries" alltodo "" - ((org-agenda-skip-function - (lambda nil - (org-agenda-skip-entry-if 'scheduled 'deadline - 'regexp "\n]+>"))) - (org-agenda-overriding-header "Unscheduled TODO entries: "))) - ("p" "Past timestamps" tags "TIMESTAMP<=\"\""))) - (defun km/org-goto-agenda-heading () "Jump to heading in agenda files." (interactive) @@ -414,11 +365,18 @@ displayed in the agenda." (org-agenda-text-search-extra-files :maxlevel . 3)))) (org-refile '(4)))) +(key-chord-define-global ",a" 'org-agenda) + +(define-key km/global-org-map "j" 'km/org-goto-agenda-heading) +(define-key km/global-org-map "m" 'km/org-open-default-notes-file-inbox) +(define-key km/global-org-map "n" 'km/org-agenda-add-or-remove-file) + + ;;; Refiling -(defun km/verify-refile-target () - "Exclude DONE state from refile targets." - (not (member (nth 2 (org-heading-components)) org-done-keywords))) +(setq org-reverse-note-order t) + +(setq org-refile-target-verify-function 'km/org-refile-verify-target) (setq org-refile-targets '((nil :maxlevel . 2)) org-refile-cache nil) @@ -431,7 +389,9 @@ displayed in the agenda." (add-to-list 'safe-local-variable-values (cons 'org-refile-targets km/org-agenda-refile-targets)) -(setq org-refile-target-verify-function 'km/verify-refile-target) +(defun km/org-refile-verify-target () + "Exclude DONE state from refile targets." + (not (member (nth 2 (org-heading-components)) org-done-keywords))) (defadvice org-refile (around km/org-refile-dwim activate) "Rebind `org-refile-targets' if next window is an Org buffer. @@ -491,16 +451,18 @@ global value. A numeric prefix sets MAXLEVEL (defaults to 2)." (set (make-local-variable 'org-refile-targets) `((,buffer-file :maxlevel . ,maxlevel)))))) -(defun km/org-switch-to-buffer-other-window (&optional arg) - (interactive "P") - (noflet ((org-pop-to-buffer-same-window (&optional buffer-or-name norecord label) - (funcall 'pop-to-buffer buffer-or-name nil norecord))) - (org-switchb arg))) - -(define-key ctl-x-4-map "o" 'km/org-switch-to-buffer-other-window) +(define-key km/global-org-map "w" 'org-refile-goto-last-stored) +(define-key km/org-prefix-map "w" 'km/org-refile-to-other-org-buffer) + ;;; Export +(after 'org + ;; Avoid conflict when amsmath is loaded. + (setcar (rassoc '("wasysym" t) org-latex-default-packages-alist) + "nointegrals") + (add-to-list 'org-latex-packages-alist '("" "amsmath" t))) + (after 'ox-latex (add-to-list 'org-latex-classes '("short" @@ -511,4 +473,63 @@ global value. A numeric prefix sets MAXLEVEL (defaults to 2)." ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) + +;;; Org in other modes + +(after 'git-commit + (add-hook 'git-commit-setup-hook 'km/load-orgstruct)) + +(add-hook 'next-error-hook (lambda () + (when (eq major-mode 'org-mode) + (org-show-context)))) + +(add-hook 'message-mode-hook 'km/load-orgstruct) + +(defun km/load-orgstruct () + (turn-on-orgstruct++) + (turn-on-orgtbl)) + +(after 'poporg + (define-key poporg-mode-map (kbd "C-c C-c") 'poporg-edit-exit)) + +(define-key km/global-org-map "p" 'poporg-dwim) + + +;;; Org open file + +(defadvice org-open-file (after km/org-open-add-to-recentf activate) + (recentf-add-file path)) + +(defun km/org-open-file-at-point () + "Open file at point with `org-open-file'." + (interactive) + (let ((file (thing-at-point 'filename))) + (if (and file (file-exists-p file)) + (org-open-file file) + (user-error "No file at point")))) + +(defun km/org-open-file () + "Interactive version of `org-open-file'." + (interactive) + (org-open-file (read-file-name "Open file: " nil nil t))) + +(autoload 'magit-annex-present-files "magit-annex") +(defun km/org-open-annex-file () + "Open a git annex file with `org-open-file'." + (interactive) + (--if-let (magit-annex-present-files) + (org-open-file (magit-completing-read "Open annex file" it nil t)) + (message "No annex files found"))) + +(defun km/org-open-recent-file () + "Open a file from `recentf-list' with `org-open-file'." + (interactive) + (org-open-file (km/read-recent-file))) + +(after 'init-buffile + (define-key km/file-map "a" 'km/org-open-annex-file) + (define-key km/file-map "o" 'km/org-open-file) + (define-key km/file-map "p" 'km/org-open-file-at-point) + (define-key km/file-map "r" 'km/org-open-recent-file)) + (provide 'init-org) diff --git a/lisp/init-projectile.el b/lisp/init-projectile.el index 1571906..b518e4a 100644 --- a/lisp/init-projectile.el +++ b/lisp/init-projectile.el @@ -1,10 +1,10 @@ -(projectile-global-mode) - (setq projectile-switch-project-action 'projectile-commander projectile-find-dir-includes-top-level t projectile-use-git-grep t) +(projectile-global-mode) + (defun km/projectile-switch-project-to-file () "Provide access to the of default `projectile-find-file'. @@ -50,88 +50,90 @@ Interactive arguments are processed according to (kill-new fname)) (message "%s" fname))) -;; Default binding is D. -(def-projectile-commander-method ?t - "Open project root in dired." - (projectile-dired)) +(define-key projectile-command-map (kbd "4 v") + 'km/projectile-view-file-other-window) -(def-projectile-commander-method ?D - "Find a project directory in other window." - (call-interactively 'projectile-find-dir-other-window)) +(define-key projectile-command-map "." + 'km/projectile-copy-project-filename-as-kill) +;; Swap `projectile-invalidate-cache' and `projectile-ibuffer'. +(define-key projectile-command-map "I" 'projectile-invalidate-cache) +(define-key projectile-command-map "i" 'projectile-ibuffer) +(define-key projectile-command-map "j" + 'km/projectile-switch-project-to-file) -;; Default binding is v. -(def-projectile-commander-method ?m - "Open project root in vc-dir or magit." - (projectile-vc)) +(key-chord-define-global ";c" 'projectile-commander) +(key-chord-define-global ";d" 'projectile-find-dir) +(key-chord-define-global ";f" 'projectile-find-file) +(key-chord-define-global ";g" 'projectile-grep) +(key-chord-define-global ";r" 'projectile-recentf) +(key-chord-define-global ";s" 'projectile-switch-project) +(key-chord-define-global ";t" 'km/projectile-open-external-terminal-in-root) +(key-chord-define-global ";v" 'km/projectile-view-file) -(def-projectile-commander-method ?v - "View project file." - (km/projectile-view-file)) +(define-prefix-command 'km/projectile-ctl-x-4-map) +(define-key ctl-x-4-map "p" 'km/projectile-ctl-x-4-map) -(def-projectile-commander-method ?V - "View project file in other window." - (km/projectile-view-file-other-window)) +(define-key km/projectile-ctl-x-4-map (kbd "C-o") + 'projectile-display-buffer) +(define-key km/projectile-ctl-x-4-map "b" + 'projectile-switch-to-buffer-other-window) +(define-key km/projectile-ctl-x-4-map "d" + 'projectile-find-dir-other-window) +(define-key km/projectile-ctl-x-4-map "f" + 'projectile-find-file-other-window) +(define-key km/projectile-ctl-x-4-map "t" + 'projectile-find-implementation-or-test-other-window) +(define-key km/projectile-ctl-x-4-map "v" + 'km/projectile-view-file-other-window) + + +;;; Commander methods + +(def-projectile-commander-method ?B + "Find project buffer in other window." + (call-interactively 'projectile-switch-to-buffer-other-window)) (def-projectile-commander-method ?c "Run project compilation command." (call-interactively 'projectile-compile-project)) -;; Default binding is e. -(def-projectile-commander-method ?r - "Find recently visited file in project." - (projectile-recentf)) +(def-projectile-commander-method ?D + "Find a project directory in other window." + (call-interactively 'projectile-find-dir-other-window)) (def-projectile-commander-method ?F "Find project file in other window." (call-interactively 'projectile-find-file-other-window)) -(def-projectile-commander-method ?B - "Find project buffer in other window." - (call-interactively 'projectile-switch-to-buffer-other-window)) - -(def-projectile-commander-method ?O - "Display a project buffer in other window." - (call-interactively 'projectile-display-buffer)) - (def-projectile-commander-method ?i "Open an IBuffer window showing all buffers in the current project." (call-interactively 'projectile-ibuffer)) -(key-chord-define-global ";s" 'projectile-switch-project) -(key-chord-define-global ";f" 'projectile-find-file) -(key-chord-define-global ";v" 'km/projectile-view-file) -(key-chord-define-global ";d" 'projectile-find-dir) -(key-chord-define-global ";t" 'km/projectile-open-external-terminal-in-root) -(key-chord-define-global ";g" 'projectile-grep) -(key-chord-define-global ";r" 'projectile-recentf) -(key-chord-define-global ";c" 'projectile-commander) +;; Default binding is v. +(def-projectile-commander-method ?m + "Open project root in vc-dir or magit." + (projectile-vc)) -(define-key projectile-command-map "j" - 'km/projectile-switch-project-to-file) -(define-key projectile-command-map "." - 'km/projectile-copy-project-filename-as-kill) +(def-projectile-commander-method ?O + "Display a project buffer in other window." + (call-interactively 'projectile-display-buffer)) -;; Swap `projectile-invalidate-cache' and `projectile-ibuffer'. -(define-key projectile-command-map "I" 'projectile-invalidate-cache) -(define-key projectile-command-map "i" 'projectile-ibuffer) +;; Default binding is e. +(def-projectile-commander-method ?r + "Find recently visited file in project." + (projectile-recentf)) -(define-key projectile-command-map (kbd "4 v") - 'km/projectile-view-file-other-window) +;; Default binding is D. +(def-projectile-commander-method ?t + "Open project root in dired." + (projectile-dired)) -(define-prefix-command 'km/projectile-ctl-x-4-map) -(define-key ctl-x-4-map "p" 'km/projectile-ctl-x-4-map) +(def-projectile-commander-method ?v + "View project file." + (km/projectile-view-file)) -(define-key km/projectile-ctl-x-4-map (kbd "C-o") - 'projectile-display-buffer) -(define-key km/projectile-ctl-x-4-map "b" - 'projectile-switch-to-buffer-other-window) -(define-key km/projectile-ctl-x-4-map "d" - 'projectile-find-dir-other-window) -(define-key km/projectile-ctl-x-4-map "f" - 'projectile-find-file-other-window) -(define-key km/projectile-ctl-x-4-map "v" - 'km/projectile-view-file-other-window) -(define-key km/projectile-ctl-x-4-map "t" - 'projectile-find-implementation-or-test-other-window) +(def-projectile-commander-method ?V + "View project file in other window." + (km/projectile-view-file-other-window)) (provide 'init-projectile) diff --git a/lisp/init-python.el b/lisp/init-python.el index b16a005..2003777 100644 --- a/lisp/init-python.el +++ b/lisp/init-python.el @@ -1,9 +1,17 @@ +(setq python-fill-docstring-style 'pep-257-nn) + +(setq jedi:tooltip-method nil + ac-auto-start nil) + +(add-to-list 'interpreter-mode-alist '("python2" . python-mode)) +(add-to-list 'interpreter-mode-alist '("python3" . python-mode)) (add-hook 'python-mode-hook 'jedi:setup) (add-hook 'python-mode-hook 'auto-complete-mode) -(setq jedi:tooltip-method nil - ac-auto-start nil) +(defun km/python-hook () + (set (make-local-variable 'compile-command) "py.test")) +(add-hook 'python-mode-hook 'km/python-hook) ;; http://www.emacswiki.org/emacs/PythonProgrammingInEmacs#toc5 (defun km/setup-ipython-shell () @@ -95,33 +103,23 @@ This is inspired by `ess-eval-function-or-paragraph-and-step'." (goto-char pos) n)) -(define-prefix-command 'km/python-prefix-map) -(define-key km/python-prefix-map "t" 'km/find-python-test-file-other-window) - (after 'python - (define-key python-mode-map (kbd "C-c m") 'km/python-prefix-map) + (key-chord-define python-mode-map ";w" 'auto-complete) + (define-key python-mode-map (kbd "C-c C-.") + 'km/python-shell-send-buffer-up-to-point) + (define-key python-mode-map (kbd "C-c C-b") 'python-shell-send-buffer) ;; Rebind `python-shell-send-buffer'. (define-key python-mode-map (kbd "C-c C-c") 'km/python-shell-send-function-or-paragraph-and-step) - (define-key python-mode-map (kbd "C-c C-b") 'python-shell-send-buffer) - (define-key python-mode-map (kbd "C-c C-.") - 'km/python-shell-send-buffer-up-to-point) - - (key-chord-define python-mode-map ";w" 'auto-complete) ;; Swap `python-shell-send-defun' and `python-eldoc-at-point'. (define-key python-mode-map (kbd "C-c C-f") 'python-shell-send-defun) - (define-key python-mode-map (kbd "C-M-x") 'python-eldoc-at-point)) - -(defun km/python-hook () - (set (make-local-variable 'compile-command) "py.test")) - -(add-hook 'python-mode-hook 'km/python-hook) + (define-key python-mode-map (kbd "C-M-x") 'python-eldoc-at-point) -(add-to-list 'interpreter-mode-alist '("python2" . python-mode)) -(add-to-list 'interpreter-mode-alist '("python3" . python-mode)) + (define-prefix-command 'km/python-prefix-map) + (define-key python-mode-map (kbd "C-c m") 'km/python-prefix-map) -(setq python-fill-docstring-style 'pep-257-nn) + (define-key km/python-prefix-map "t" 'km/find-python-test-file-other-window)) (provide 'init-python) diff --git a/lisp/init-smex.el b/lisp/init-smex.el index 56183b9..86d12a7 100644 --- a/lisp/init-smex.el +++ b/lisp/init-smex.el @@ -1,7 +1,7 @@ -(smex-initialize) - (global-set-key (kbd "M-X") 'smex-major-mode-commands) (key-chord-define-global ",x" 'smex) +(smex-initialize) + (provide 'init-smex) diff --git a/lisp/init-snakemake.el b/lisp/init-snakemake.el index bb69614..380a74a 100644 --- a/lisp/init-snakemake.el +++ b/lisp/init-snakemake.el @@ -1,7 +1,8 @@ (add-to-list 'load-path "~/src/emacs/snakemake-mode/") - (require 'snakemake-mode-autoloads) +(autoload 'snakemake-compile-command "snakemake-mode") + (setq snakemake-compile-command-options '("-p")) ;; Although `compile-command' is set when snakemake-mode is derived from @@ -35,12 +36,10 @@ run." (let ((default-directory (projectile-project-root))) (call-interactively #'snakemake-compile-rule))) -(autoload 'snakemake-compile-command "snakemake-mode") - (after 'init-external - (define-key km/compile-map "p" - 'km/snakemake-compile-project-file) (define-key km/compile-map "b" - 'km/snakemake-compile-project-rule)) + 'km/snakemake-compile-project-rule) + (define-key km/compile-map "p" + 'km/snakemake-compile-project-file)) (provide 'init-snakemake) diff --git a/lisp/init-tex.el b/lisp/init-tex.el index 00d3881..866e9d2 100644 --- a/lisp/init-tex.el +++ b/lisp/init-tex.el @@ -1,8 +1,8 @@ -(add-hook 'LaTeX-mode-hook 'turn-on-reftex) - (setq reftex-default-bibliography '("refs.bib")) (put 'LaTeX-narrow-to-environment 'disabled nil) +(add-hook 'LaTeX-mode-hook 'turn-on-reftex) + (provide 'init-tex) diff --git a/lisp/init-view.el b/lisp/init-view.el index c849183..38e2c64 100644 --- a/lisp/init-view.el +++ b/lisp/init-view.el @@ -1,5 +1,3 @@ -(key-chord-define-global ",v" 'view-mode) - (setq view-read-only t) (after 'view @@ -11,4 +9,6 @@ (define-key view-mode-map "[" 'backward-paragraph) (define-key view-mode-map "j" 'km/imenu)) +(key-chord-define-global ",v" 'view-mode) + (provide 'init-view) diff --git a/lisp/init-yas.el b/lisp/init-yas.el index 9c708b0..a2e0db9 100644 --- a/lisp/init-yas.el +++ b/lisp/init-yas.el @@ -1,13 +1,11 @@ (require 'yasnippet) -(yas-global-mode 1) - -(define-key yas-minor-mode-map (kbd "") nil) -(define-key yas-minor-mode-map (kbd "TAB") nil) +(yas-global-mode) (key-chord-define-global ";e" 'yas-expand) -(diminish 'yas-minor-mode) +(define-key yas-minor-mode-map (kbd "") nil) +(define-key yas-minor-mode-map (kbd "TAB") nil) (provide 'init-yas) -- cgit v1.2.3