From c2778f0f713cc885087d6302196e421596ff248e Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Thu, 21 Aug 2014 00:23:56 +0200 Subject: Add Emacs config --- emacs/.emacs.d/init.el | 1492 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1492 insertions(+) create mode 100644 emacs/.emacs.d/init.el (limited to 'emacs/.emacs.d/init.el') diff --git a/emacs/.emacs.d/init.el b/emacs/.emacs.d/init.el new file mode 100644 index 0000000..29dbbc9 --- /dev/null +++ b/emacs/.emacs.d/init.el @@ -0,0 +1,1492 @@ +;;; init.el --- My Emacs init -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: + +(eval-and-compile + (require 'cask "~/projects/ext/cask/cask.el") + (cask-initialize)) + +(eval-when-compile + (require 'cl) + (require 'dash) + (require 'esh-io) + (require 'esh-proc) + (require 'fill-column-indicator) + (require 'magit) + (require 'yasnippet) + (require 'noflet)) + +(load (concat user-emacs-directory "init2")) + +;;;; Autoloads + +(autoload 'jabber-connect "jabber" nil t) +(autoload 'moz-minor-mode "moz" nil t) +(autoload 'notifications-notify "notifications") +(autoload 'php-mode "php-mode" nil t) +(autoload 'po-mode "po-mode" nil t) +(autoload 'pony-mode "pony-mode" nil t) +(autoload 'sawfish-mode "sawfish" nil t) +(autoload 'server-running-p "server") +(autoload 'tagedit-mode "tagedit" nil t) +(autoload 'tern-mode "tern" nil t) +(autoload 'w3m-bookmark-view "w3m" nil t) +(autoload 'w3m-goto-url "w3m" nil t) +(autoload 'xmodmap-mode "xmodmap-mode" nil t) + +;;;; Macros + +(defmacro auto-init (library) + "Load a file for LIBRARY after loading the library. + +The loaded file should be `LIBRARY-init', either `.el' or `.elc' +will do." + `(with-eval-after-load ',library + (load ,(concat (if (symbolp library) + (symbol-name library) + library) "-init")))) + +;; http://www.lunaryorn.com/2013/06/25/introducing-with-eval-after-load/ +(defmacro stante-after (feature &rest forms) + "After FEATURE is loaded, evaluate FORMS. + +FEATURE may be an unquoted feature symbol or a file name, see +`eval-after-load'." + (declare (indent 1) (debug t)) + `(,(if (or (not byte-compile-current-file) + (if (symbolp feature) + (require feature nil :noerror) + (load feature :no-message :no-error))) + `progn + (message "stante-after: cannot find %s" feature) + 'with-no-warnings) + (with-eval-after-load ',feature ,@forms))) + +(defmacro oni:add-hooks (hook &rest functions) + "Add to HOOK each function in FUNCTIONS." + (declare (indent 1)) + `(progn + ,@(mapcar (lambda (func) `(add-hook ,hook ,func)) functions))) + +(defmacro oni:add-function-to-hooks (func &rest hooks) + "Add FUNCTION to each hook in HOOKS." + (declare (indent 1)) + `(progn + ,@(mapcar (lambda (hook) `(add-hook ,hook ,func)) hooks))) + +(defmacro oni:email (user at host dot com) + "Turn arguments into an email address. +The resulting email address will look like: USER@HOST.COM, AT and +DOT are intentionally being skipped." + (ignore at dot) + (concat (symbol-name user) "@" (symbol-name host) "." + (symbol-name com))) + +(defmacro oni:eval-after-init (&rest body) + "Defer execution of BODY until after Emacs init." + (declare (indent 0)) + `(add-hook 'emacs-startup-hook #'(lambda () ,@body))) + +(defmacro oni:link-modes (mode1 mode2) + "Whenever MODE1 is started, also start MODE2. Same for stopping. + +If INVERSE is specified, make sure MODE2 is turned off whenever +MODE1 is enabled and vice-versa." + (let* ((mode1-name (symbol-name mode1)) + (mode2-name (symbol-name mode2)) + (function-name (intern (concat "toggle-" mode2-name + "-by-" mode1-name)))) + `(progn + (defun ,function-name () + ,(concat "Toggle `" mode2-name "' according to the variable `" + mode1-name "'.") + (,mode2 (or ,mode1 -1))) + (add-hook ',(intern (concat mode1-name "-hook")) + #',function-name)))) + +(defmacro oni:exclude-modes (mode1 mode2) + "Whenever MODE1 is started, stop MODE2. Switch for stopping." + (let* ((mode1-name (symbol-name mode1)) + (mode2-name (symbol-name mode2)) + (function-name + (intern (concat "toggle-" mode2-name + "-inverse-of-" mode1-name)))) + `(progn + (defvar ,mode1) + (defun ,function-name () + ,(concat "Toggle `" mode2-name + "' according to the inverse of `" mode1-name "'.") + (,mode2 (or (not ,mode1) -1))) + (add-hook ',(intern (concat mode1-name "-hook")) + #',function-name)))) + +;;;;; Vacuous + +(defvar elnode-do-init) +(defvar eshell-prompt-regexp) +(defvar gnus-init-file) +(defvar sql-product) +(defvar sql-prompt-regexp) +(defvar whitespace-style) +(defvar *jabber-connected*) +(defvar *jabber-current-status*) + +;;;; Functions + +(defun oni:add-import-from (package import) + (interactive + (list (completing-read "From package: " (oni:collect-from-imports)) + (read-string "Import: "))) + (save-excursion + (goto-char (point-min)) + (search-forward (concat "from " package " import (")) + (insert "\n " import ",") + (oni:sort-imports))) + +(defun oni:after-save-func () + "Function for `after-save-hook'." + (executable-make-buffer-file-executable-if-script-p) + (let* ((dom-dir (locate-dominating-file (buffer-file-name) "Makefile")) + (TAGSp (not (string= "" (shell-command-to-string + (concat "grep \"^TAGS:\" " dom-dir "Makefile")))))) + (when (and dom-dir TAGSp) + (shell-command + (concat "make -C " dom-dir " TAGS >/dev/null 2>&1"))))) + +(defun oni:augment-sql-prompt () + "Add the MariaDB prompt to the `sql-prompt-regexp'." + (if (eq sql-product 'mysql) + (setq sql-prompt-regexp + (rx (and line-start + (or "mysql" + (and "MariaDB [" (1+ nonl) "]")) + "> "))))) + +(defun oni:before-save-func () + "Function for `before-save-hook'." + (if (eq major-mode 'html-mode) + (oni:replace-html-special-chars)) + (if (not (eq major-mode 'markdown-mode)) + (delete-trailing-whitespace))) + +(defun oni:c-mode-func () + "Function for `c-mode-hook'." + (local-set-key [f9] 'compile)) + +(defun oni:change-number-at-point (change-func) + "Use CHANGE-FUNC to change the number at `point'." + (let ((num (number-to-string (funcall change-func (number-at-point)))) + (bounds (bounds-of-thing-at-point 'word))) + (save-excursion + (delete-region (car bounds) (cdr bounds)) + (insert num)))) + +(defun oni:change-prev-case (num dir) + (let ((regfunc (if (eq dir 'up) 'upcase-region 'downcase-region)) + (wordfunc (if (eq dir 'up) 'upcase-word 'downcase-word))) + (if (> num 1) + (funcall regfunc (point) (- (point) num)) + (funcall wordfunc -1)))) + +(defun oni:collect-from-imports () + (let (results) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "from \\(.+\\) import" nil :noerror) + (push (buffer-substring-no-properties (match-beginning 1) + (match-end 1)) results))) + results)) + +(defun oni:current-jabber-status () + "Return a string representing the current jabber status." + (or (and (not *jabber-connected*) "Offline") + (and (not (string= *jabber-current-status* "")) + *jabber-current-status*) + "Online")) + +(defun oni:decrease-number-at-point () + "Take the number at `point' and replace it with it decreased by 1." + (interactive) + (oni:change-number-at-point #'1-)) + +(defun oni:diary-display-func () + "Function for `diary-display-hook'." + (diary-fancy-display)) + +(defun oni:downcase-prev (num) + (interactive "p") + (oni:change-prev-case num 'down)) + +(defun oni:enable (functions) + "Set the `disabled' property for each item in FUNCTIONS to nil." + (mapc #'(lambda (f) (put f 'disabled nil)) functions)) + +(defun oni:eshell-handle-url () + (save-excursion + (goto-char eshell-last-output-start) + (while (re-search-forward + "https?://[^ \n]+" eshell-last-output-end :noerror) + (make-button (match-beginning 0) (match-end 0) + 'action (lambda (button) + (browse-url (button-label button))))))) + +(defun oni:eshell-prompt () + "Show a pretty shell prompt." + (concat (if (not (looking-back "\n")) "\n") + (oni:shorten-dir (abbreviate-file-name (eshell/pwd))) + " > ")) + +(defun oni:go-mode-func () + "Function for `go-mode-hook'." + (setq indent-tabs-mode nil)) + +(defun oni:haskell-mode-func () + "Function for `haskell-mode-hook'." + (turn-on-haskell-indentation)) + +(defun oni:increase-number-at-point () + "Take the number at `point' and replace it with it increased by 1." + (interactive) + (oni:change-number-at-point #'1+)) + +(defun indent-defun () + "Indent the current defun." + (interactive) + (save-excursion + (mark-defun) + (indent-region (region-beginning) (region-end)))) + +(defun oni:eshell-C-d () + "Either call `delete-char' interactively or quit." + (interactive) + (condition-case err + (call-interactively #'delete-char) + (error (if (and (eq (car err) 'end-of-buffer) + (looking-back eshell-prompt-regexp)) + (kill-buffer) + (signal (car err) (cdr err)))))) + +(defun oni:level (lst) + "Reduce a 2-level list LST to a flat list." + (let ((lsts (mapcar (lambda (l) (if (listp l) l (list l))) lst))) + (apply #'append lsts))) + +(defun oni:locally-enable-double-spaces () + "Specify that two spaces end a sentence in the current buffer." + (setq-local sentence-end-double-space t)) + +(defun oni:lua-mode-func() + "Function for `lua-mode-hook'." + (local-unset-key (kbd ")")) + (local-unset-key (kbd "]")) + (local-unset-key (kbd "}"))) + +(defun oni:make-import-multiline (from-point to-point) + (interactive (list (line-beginning-position) + (line-end-position))) + (goto-char from-point) + (search-forward "import" to-point) + (insert " (\n") + (delete-horizontal-space) + (let ((imports-start (point)) imports-end) + (while (search-forward "," to-point :noeror) + (insert "\n") + (delete-horizontal-space)) + (end-of-line) + (insert ",\n") + (setf imports-end (point)) + (insert ")") + (python-indent-shift-right imports-start imports-end) + (forward-line -1) + (oni:sort-imports))) + +(defun oni:make-readable () + "Make non-programming buffers a little more readable." + (setq line-spacing .2)) + +(defun oni:markdown-mode-func () + "Function for `markdown-mode-hook'." + (setq-local whitespace-style '(face trailing))) + +(defun oni:maybe-fci-mode () + "Turn on `fci-mode' if there is a filename for the buffer." + (when (buffer-file-name) + (fci-mode))) + +(defun oni:maybe-prettify-symbols-mode (&optional arg) + "See of `prettify-symbols-mode' is bound and call it if so." + (when (fboundp 'prettify-symbols-mode) + (prettify-symbols-mode arg))) + +(defun oni:maybe-switch-to-normal-state () + "Switch the current buffer to normal state. + +Only do this when the mode is not in emacs state by default." + (unless (memql major-mode (oni:modes-starting-in 'emacs)) + (evil-normal-state))) + +(defun oni:mini-fix-timestamp-string (date-string) + "A minimal version of Xah Lee's `fix-timestamp-string'. +Turn DATE-STRING into something else that can be worked with in +code. Found at http://xahlee.org/emacs/elisp_parse_time.html" + (setq date-string (replace-regexp-in-string "Jan" "01" date-string) + date-string (replace-regexp-in-string "Feb" "02" date-string) + date-string (replace-regexp-in-string "Mar" "03" date-string) + date-string (replace-regexp-in-string "Apr" "04" date-string) + date-string (replace-regexp-in-string "May" "05" date-string) + date-string (replace-regexp-in-string "Jun" "06" date-string) + date-string (replace-regexp-in-string "Jul" "07" date-string) + date-string (replace-regexp-in-string "Aug" "08" date-string) + date-string (replace-regexp-in-string "Sep" "09" date-string) + date-string (replace-regexp-in-string "Oct" "10" date-string) + date-string (replace-regexp-in-string "Nov" "11" date-string) + date-string (replace-regexp-in-string "Dec" "12" date-string)) + (string-match + "^\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{4\\}\\)$" + date-string) + (format "%s-%s-%s" + (match-string 3 date-string) + (match-string 2 date-string) + (match-string 1 date-string))) + +(defun oni:mode-line-current-song () + "Extract current song information from a path. + +EMMS only shows me the absolute path of a song, this function +extracts the parts I want to know about." + (let ((song (emms-track-name (emms-playlist-current-selected-track)))) + (if (string-match "\\([^/]+\\)/\\([0-9]\\{4\\}\\) - \\(.+\\)/\\([0-9]\\{2,3\\}\\) - \\(.+\\)\\..\\{3,4\\}$" song) + (let ((band (substring song (match-beginning 1) (match-end 1))) + (title (substring song (match-beginning 5) (match-end 5)))) + (format "[%s - %s]" band title)) + song))) + +(defun oni:modes-starting-in (state) + "Get a list of the modes whose default state is STATE." + (symbol-value (evil-state-property state :modes))) + +(defun oni:move-beginning-of-dwim () + "Move to beginning of line either after indentation or before." + (interactive) + (let ((start (point))) + (back-to-indentation) + (if (= start (point)) + (move-beginning-of-line 1)))) + +(defun oni:move-end-of-dwim () + "Move to end of line, either before any comments or after." + (interactive) + (let ((start (point)) + (eolpos (line-end-position))) + (beginning-of-line) + (if (and comment-start + (not (looking-at (regexp-quote comment-start))) + (comment-search-forward eolpos t)) + (progn + (search-backward-regexp (concat "[^ \t" comment-start "]")) + (forward-char) + + (when (or (bolp) + (= start (point))) + (end-of-line))) + (end-of-line)))) + +(defun oni:myepisodes-formatter (plist) + "Format RSS items from MyEpisodes as org tasks. +PLIST contains all the pertinent information." + (let ((str (plist-get plist :title))) + (string-match + "^\\[ \\([^\]]+\\) \\]\\[ \\([^\]]+\\) \\]\\[ \\([^\]]+\\) \\]\\[ \\([^\]]+\\) \\]$" + str) + (let* ((title (match-string 1 str)) + (episode (match-string 2 str)) + (name (match-string 3 str)) + (date (oni:mini-fix-timestamp-string (match-string 4 str)))) + (format "* ACQUIRE %s %s - %s \n SCHEDULED: <%s>" + title episode name date)))) + +(defun oni:php-mode-func () + "Function for `php-mode-hook'." + (c-set-offset 'arglist-intro '+) + (c-set-offset 'arglist-close '0) + (setq-local fci-rule-column 80)) + +(defun oni:print-keymap (keymap) + "Recursively print KEYMAP with keys as characters." + (mapcar (lambda (itm) + (if (consp itm) + (if (integerp (car itm)) + (cons (format "%c" (car itm)) + (if (listp (cdr itm)) + (oni:print-keymap (cddr itm)) + (cdr itm))) + itm) + itm)) keymap)) + +(defun oni:prog-mode-func () + "Function for `prog-mode-hook'." + (setq-local comment-auto-fill-only-comments t)) + +(defun oni:python-mode-func () + "Function for `python-mode-hook'." + (local-set-key (kbd "C->") 'python-indent-shift-right) + (local-set-key (kbd "C-<") 'python-indent-shift-left) + (set (make-local-variable 'electric-indent-chars) nil) + (setq-local fci-rule-column 79) + (setq-local fill-column 72) + (setq-local whitespace-style '(tab-mark))) + +(defun oni:raise-ansi-term (arg) + "Create or show an `ansi-term' buffer." + (interactive "P") + (let ((buffer (get-buffer "*ansi-term*"))) + (if (and buffer (not arg)) + (switch-to-buffer buffer) + (ansi-term (getenv "SHELL"))))) + +(defun oni:raise-eshell () + "Start or switch back to `eshell'. + +Also change directories to current working directory." + (interactive) + (let ((dir (file-name-directory + (or (buffer-file-name) "~/"))) + (hasfile (not (eq (buffer-file-name) nil))) + (started (and (boundp 'eshell-buffer-name) eshell-buffer-name + (buffer-live-p (get-buffer eshell-buffer-name))))) + (eshell) + (when (and hasfile (eq eshell-process-list nil)) + (eshell/cd dir) + (when started + (eshell-reset))))) + +(defun oni:raise-scratch (&optional mode) + "Show the *scratch* buffer. +If called with a universal argument, ask the user which mode to +use. If MODE is not nil, open a new buffer with the name +*MODE-scratch* and load MODE as its major mode." + (interactive (list (if current-prefix-arg + (read-string "Mode: ") + nil))) + (let* ((bname (if mode + (concat "*" mode "-scratch*") + "*scratch*")) + (buffer (get-buffer bname)) + (mode-sym (intern (concat mode "-mode")))) + + (unless buffer + (setq buffer (generate-new-buffer bname)) + (with-current-buffer buffer + (when (fboundp mode-sym) + (funcall mode-sym)))) + + (select-window (display-buffer buffer)))) + +(defun oni:reload-buffer () + "Reload current buffer." + (interactive) + (revert-buffer nil t nil)) + +(defun oni:replace-html-special-chars () + "Replace special characters with HTML escaped entities." + (oni:replace-occurrences "é" "é")) + +(defun oni:replace-occurrences (from to) + "Replace all occurrences of FROM with TO in the current buffer." + (save-excursion + (goto-char (point-min)) + (while (search-forward from nil t) + (replace-match to)))) + +(defun oni:request-pull () + "Start a mail to request pulling from a git repository." + (interactive) + (let* ((default-directory + (expand-file-name + (or (locate-dominating-file default-directory ".git") + (magit-read-top-dir nil)))) + (refs (magit-list-interesting-refs magit-uninteresting-refs)) + (from (cdr (assoc (completing-read "From: " refs) refs))) + (url (read-from-minibuffer "Pull URL: ")) + (to (symbol-name (read-from-minibuffer "Up to (HEAD): " + nil nil t nil "HEAD"))) + (patchp (and current-prefix-arg (listp current-prefix-arg)))) + (message "Requesting pull for %s from %s to %s at %s with%s patch" + default-directory from to url (if patchp "" "out")) + + (compose-mail + nil (concat + "Requesting pull for " + (file-name-base (directory-file-name default-directory)))) + + (save-excursion + (goto-char (point-max)) + (insert + (shell-command-to-string + (concat "git --git-dir='" default-directory ".git' --work-tree='" + default-directory "' request-pull " (when patchp "-p ") + from " " url " " to)))))) + +(defun oni:reset-default-directory () + "Reset `default-directory' to HOME." + (setq default-directory (getenv "HOME"))) + +(defun oni:scroll-down-or-prev-page (arg) + "Either scroll down or go to the previous page. + +Depending on the value of `buffer-narrowed-p'." + (interactive "^P") + (if (buffer-narrowed-p) + (let ((scroll-error-top-bottom nil)) + (condition-case nil + (scroll-down-command arg) + (beginning-of-buffer + (narrow-to-page -1) + (goto-char (point-min))))) + (scroll-down-command arg))) + +(defun oni:scroll-up-or-next-page (arg) + "Either scroll up or go to the next page. + +Depending on the value of `buffer-narrowed-p'." + (interactive "^P") + (if (buffer-narrowed-p) + (let ((scroll-error-top-bottom nil)) + (condition-case nil + (scroll-up-command arg) + (end-of-buffer + (narrow-to-page 1) + (goto-char (point-min))))) + (scroll-up-command arg))) + +(defun oni:self-insert-dwim () + "Execute self insert, but when the region is active call self +insert at the end of the region and at the beginning." + (interactive) + (if (region-active-p) + (let ((electric-pair-mode nil) + (beginning (region-beginning)) + (end (region-end))) + (goto-char end) + (self-insert-command 1) + (save-excursion + (goto-char beginning) + (self-insert-command 1))) + (self-insert-command 1))) + +(defun oni:set-emacs-lisp-keys () + "Set some keys for `emacs-lisp-mode'." + (local-set-key (kbd "C-.") 'find-function)) + +(defun oni:set-emacs-lisp-symbols () + "Set a few extra UTF-8 symbols for use in emacs-lisp." + (when (boundp 'prettify-symbols-alist) + (setq prettify-symbols-alist + (append prettify-symbols-alist + '(("<=" . ?≤) + (">=" . ?≥) + ("sqrt" . ?√)))))) + + +(defun oni:set-ispell-local-en-dict () + "Set `ispell-local-dictionary' to en." + (setq ispell-local-dictionary "en")) + +(defun oni:set-keys-for-dired () + "Set some keybindings for `dired'." + (local-set-key (kbd "E") #'wdired-change-to-wdired-mode)) + +(defun oni:set-keys-for-eshell () + "Set some keybindings for `eshell'." + (local-set-key (kbd "C-d") #'oni:eshell-C-d)) + +(defun oni:set-keys-for-hy () + "Set some keybindings for `hy-mode'." + (local-set-key (kbd "{") #'paredit-open-curly) + (local-set-key (kbd "}") #'paredit-close-curly)) + +(defun oni:set-keys-for-jabber-chat () + "Set certain keys for `jabber-chat-mode'." + (local-set-key (kbd "M-!") #'shell-command-with-command)) + +(defun oni:set-keys-for-tagedit () + "Set some keybindings for `tagedit-mode'." + (local-set-key (kbd "M-k") #'tagedit-kill-attribute)) + +(defun oni:set-python-imenu-function () + "Set the `imenu-create-index-function' variable. + +For `python-mode' I prefer `python-imenu-create-flat-index'." + (setq imenu-create-index-function #'python-imenu-create-flat-index)) + +(defun oni:set-python-symbols () + "Set a few extra UTF-8 symbols for use in python." + (when (boundp 'prettify-symbols-alist) + (setq prettify-symbols-alist + '(("lambda" . ?λ) + ("<=" . ?≤) + (">=" . ?≥) + ("!=" . ?≠))))) + +(defun oni:set-tab-maybe-toggle-outline () + "Wrap the current function mapped to `TAB'." + (let ((func (or (lookup-key (current-local-map) (kbd "TAB")) + (lookup-key (current-global-map) (kbd "TAB"))))) + (local-set-key (kbd "TAB") + (lambda () + (interactive) + (if (outline-on-heading-p) + (if (outline-invisible-p (line-end-position)) + (show-entry) + (hide-entry)) + (call-interactively func)))))) + +(let (setp) + (defun oni:set-theme (frame) + "Try to set the theme for the current (first) frame." + (ignore frame) + (unless setp + ;; (load-theme 'yoshi t) + (load-theme 'yoshi t) + ;; (smt/enable) + ;; (require 'my-smt) + ;; (smt/set-theme 'my-smt) + ;; (set-face-attribute 'mode-line nil :box nil) + ;; (set-face-attribute 'mode-line-inactive nil :box nil) + ))) + +(if (daemonp) + (add-hook 'after-make-frame-functions + (lambda (frame) + (noflet ((display-graphic-p (&optional display) t)) + (oni:set-theme frame)))) + (oni:eval-after-init (oni:set-theme nil))) + +(defun oni:shell-command-with-command (command &optional output-buffer) + "Print both COMMAND and the output into OUTPUT-BUFFER." + (interactive (list (read-shell-command "Shell command: " nil nil) + current-prefix-arg)) + (when output-buffer + (insert "`" command "':\n")) + (shell-command command output-buffer)) + +(defun oni:shorten-dir (dir) + "Shorten a directory, (almost) like fish does it." + (while (string-match "\\(\\.?[^./]\\)[^/]+/" dir) + (setq dir (replace-match "\\1/" nil nil dir))) + dir) + +(defun oni:show-buffer-position () + "Show the position in the current buffer." + (interactive) + (message (format "%d:%d" (line-number-at-pos) (current-column)))) + +(defun oni:show-org-index () + "Show the index of my org files." + (interactive) + (find-file "~/documents/org/index.org")) + +(defun oni:sort-imports () + "Sort python multiline imports using `()'." + (interactive) + (save-excursion + (sort-lines nil (1+ (search-backward "(")) + (1- (search-forward ")"))))) + +(defun oni:split-window-interactive (dir) + "Split windows in direction DIR. + +Can also delete or switch to another window." + (interactive + (list (read-char "Direction (h,v,q,d,o): "))) + (case dir + ((?v) (split-window-vertically)) + ((?h) (split-window-horizontally)) + ((?q) (delete-other-windows)) + ((?d) (delete-window)) + ((?o) (other-window 1)))) + +(defun oni:split-window-interactively (window) + "Ask for a direction and split WINDOW that way. + +If no direction is given, don't split." + (let ((dir (read-char "Direction (h,v): "))) + (case dir + ((?v) (split-window-vertically)) + ((?h) (split-window-horizontally)) + (t window)))) + +(defun oni:start-python-test-mail-server () + "Run the python test mailserver." + (interactive) + (start-process "python-test-mail-server" "*py-mail-server*" "python" "-m" + "smtpd" "-n" "-c" "DebuggingServer" "localhost:1025")) + +(defun oni:stop-python-test-mail-server () + "Stop the python test mailserver." + (interactive) + (kill-process "python-test-mail-server")) + +(defun oni:switch-to-other-buffer () + "Switch to the most recently viewed buffer." + (interactive) + (switch-to-buffer (other-buffer))) + +(defun oni:term-mode-func () + "Function for `term-mode-hook'." + (setq truncate-lines nil)) + +(defun oni:turn-on-compilation-shell-for-pony () + "Turn on option `compilation-shell-minor-mode' for `pony-minor-mode'." + (add-hook 'pony-minor-mode-hook 'compilation-shell-minor-mode nil t)) + +(defun oni:upcase-prev (num) + (interactive "p") + (oni:change-prev-case num 'up)) + +(defun oni:vala-mode-func () + "Function for `vala-mode-hook'." + (setq indent-tabs-mode nil)) + +(defun oni:write-file-func () + "Function for `write-file-hooks'." + (time-stamp)) + +(defun oni:yas-minor-mode-func () + "Function for `yas-minor-mode-hook'." + (define-key yas-minor-mode-map (kbd "TAB") nil) + (define-key yas-minor-mode-map [(tab)] nil) + (define-key yas-minor-mode-map (kbd "C-\\") 'yas-expand)) + +;;;; Modes + +;; Copied from electric.el, modified from `electric-indent-local-mode'. +(define-minor-mode oni:electric-pair-local-mode + "Toggle `electric-pair-mode' only in this buffer." + :variable (buffer-local-value 'electric-pair-mode (current-buffer)) + (cond + ((eq electric-pair-mode (default-value 'electric-pair-mode)) + (kill-local-variable 'electric-pair-mode)) + ((not (default-value 'electric-pair-mode)) + ;; Locally enabled, but globally disabled. + (electric-pair-mode 1) ; Setup the hooks. + (setq-default electric-pair-mode nil) ; But keep it globally disabled. + ))) + +;;;; Tests + +(stante-after ert + (ert-deftest oni:add-import-from () + (with-temp-buffer + (python-mode) + (insert "from myaethon2.core.administration.models import ( + Client, + Contact, + Individual, + Location, +)") + (oni:add-import-from "myaethon2.core.administration.models" "Debtor") + (should (equal (buffer-substring-no-properties (point-min) (point-max)) + "from myaethon2.core.administration.models import ( + Client, + Contact, + Debtor, + Individual, + Location, +)")))) + + (ert-deftest oni:collect-from-imports () + (with-temp-buffer + (python-mode) + (insert "import calendar as cal +import datetime + +from django.conf import settings +from django.contrib import messages +from django.contrib.auth.decorators import login_required, permission_required +from django.core.context_processors import csrf +from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from django.core.urlresolvers import reverse +from django.db import transaction +from django.db.models import Q +from django.shortcuts import get_object_or_404, render +from django.utils import formats +from django.utils.translation import ugettext as _ + +from myaethon2.core.business_units import BU +from myaethon2.core.forms import MultiFormWrapper +from myaethon2.core.models import AUser, Service +from myaethon2.core.planning.models import Booking, JOB_TYPES +from myaethon2.core.util import simplify_timedelta +from myaethon2.core.views import SearchAndSortListView +from myaethon2.jobs import forms, status +from myaethon2.jobs.models import Assignment, Job, JobGroup +from myaethon2.jobs.util import JobFactory +from myaethon2.workers.models import Worker +from myaethon2.export import Exporter, XLSGenerator + +from django.http import ( + HttpResponseForbidden, + HttpResponseNotAllowed, + HttpResponseRedirect, +) + +from django.views.generic import ( + CreateView, + DeleteView, + DetailView, + ListView, + UpdateView, +) + +from myaethon2.core.administration.models import ( + Client, + Contact, + Debtor, + Individual, + Location, +) + +from myaethon2.core.decorators import ( + json_response, + protect_with, + with_help_text, +)") + (should (equal (sort (oni:collect-from-imports) #'string-lessp) + '("django.conf" + "django.contrib" + "django.contrib.auth.decorators" + "django.core.context_processors" + "django.core.exceptions" + "django.core.paginator" + "django.core.urlresolvers" + "django.db" + "django.db.models" + "django.http" + "django.shortcuts" + "django.utils" + "django.utils.translation" + "django.views.generic" + "myaethon2.core.administration.models" + "myaethon2.core.business_units" + "myaethon2.core.decorators" + "myaethon2.core.forms" + "myaethon2.core.models" + "myaethon2.core.planning.models" + "myaethon2.core.util" + "myaethon2.core.views" + "myaethon2.export" + "myaethon2.jobs" + "myaethon2.jobs.models" + "myaethon2.jobs.util" + "myaethon2.workers.models"))))) + + (ert-deftest oni:make-import-multiline () + (with-temp-buffer + (python-mode) + (insert "from myaethon2.core.administration.models import Contact, Individual, Client, Location") + (oni:make-import-multiline (line-beginning-position) (line-end-position)) + (should (equal (buffer-substring-no-properties (point-min) (point-max)) + "from myaethon2.core.administration.models import ( + Client, + Contact, + Individual, + Location, +)"))))) + +;;;; Unconditional settings + +(eval '(setq inhibit-startup-echo-area-message "slash")) + +;;;; Module-specific settings + +(auto-init appt) +(auto-init avandu) + +(stante-after auto-complete + (add-to-list 'ac-modes 'slime-repl-mode) + (setq ac-auto-show-menu nil + ac-use-quick-help nil)) + +(stante-after "bindings" + (setq mode-line-default-help-echo "")) + +(stante-after browse-url + (setq browse-url-browser-function 'browse-url-generic) + (setq browse-url-generic-program "conkeror")) + +(stante-after cc-vars + (setq-default c-basic-offset 4) + (setq c-offsets-alist + '((statement-block-intro . +) + (knr-argdecl-intro . 5) + (substatement-open . +) + (substatement-label . 0) + (label . 0) + (statement-case-open . +) + (statement-cont . +) + (arglist-intro . +) + (arglist-close . 0) + (inline-open . 0) + (brace-list-open . +) + (topmost-intro-cont first c-lineup-topmost-intro-cont + c-lineup-gnu-DEFUN-intro-cont)))) + +(stante-after colemak-evil + (define-key evil-insert-state-map (kbd "C-g") #'evil-normal-state) + (define-key evil-replace-state-map (kbd "C-g") #'evil-normal-state) + (define-key evil-visual-state-map (kbd "C-g") #'evil-normal-state)) + +(stante-after compile + (setq compilation-scroll-output t)) + +(stante-after custom + (setq custom-theme-directory "~/.emacs.d/themes")) + +(stante-after desktop + (setq desktop-restore-frames nil) + (setq desktop-load-locked-desktop t) + (setq desktop-clear-preserve-buffers + (append (list (rx (and bol (or (and "+" (1+ nonl)) + "dailies" "work" "tasks" "org" + (or "bookmarks.org" + "contacts.org")) eol)) + (rx (or "*ielm*" "*-jabber-roster-*" "*eshell*" + "*ansi-term*" "*slime-repl sbcl*" + "*slime-events*")) + (rx (and "*" (or "magit" "scratch-") (1+ nonl) + "*")) + (rx (or "irc.freenode.net:6667" + (and "#" (1+ nonl))))) + desktop-clear-preserve-buffers)) + (setq desktop-files-not-to-save + (rx (or (regexp "\\(^/[^/:]*:\\|(ftp)$\\)") + (and "/" (or "dailies" "tasks" "org" "bookmarks.org" + "contacts.org" "work") eol)))) + (add-to-list 'desktop-globals-to-clear 'desktop-dirname)) + +(stante-after dired + (add-hook 'dired-mode-hook #'oni:set-keys-for-dired)) + +(stante-after eap + (setq eap-music-library "/mnt/music") + (setq eap-playlist-library "~/music/playlists")) + +(stante-after ediff-wind + (setq ediff-window-setup-function 'ediff-setup-windows-plain)) + +(stante-after eltuki + (setq eltuki-blog-dir "~/documents/blog")) + +(stante-after em-prompt + (setq eshell-highlight-prompt nil) + (setq eshell-prompt-function 'oni:eshell-prompt) + (setq eshell-prompt-regexp "^[~/].* > ")) + +(stante-after em-term + (add-to-list 'eshell-visual-commands "unison")) + +(stante-after emms + (emms-minimalistic) + (emms-default-players) + + (require 'emms-player-mpd) + (require 'emms-mode-line)) + +(stante-after emms-mode-line + (setq emms-mode-line-mode-line-function 'oni:mode-line-current-song) + (emms-mode-line 1)) + +(stante-after emms-player-mpd + (add-to-list 'emms-player-list 'emms-player-mpd) + (setq emms-player-mpd-music-directory "/mnt/music/mp3")) + +(stante-after erc + (setq erc-hide-list '("PART")) + (setq erc-nick "ryuslash")) + +(stante-after erc-join + (setq erc-autojoin-channels-alist + '(("freenode.net" "#ninthfloor" "#emacs" "#dispass")))) + +(stante-after erc-stamp + (setq erc-insert-timestamp-function 'erc-insert-timestamp-left) + (setq erc-timestamp-format "[%H:%M] ") + (setq erc-timestamp-only-if-changed-flag nil)) + +(stante-after esh-mode + (add-to-list 'eshell-output-filter-functions #'oni:eshell-handle-url) + (add-to-list 'eshell-output-filter-functions #'eshell-truncate-buffer)) + +(stante-after evil + (evil-define-operator oni:evil-sort-operator (beg end) + "Sort text." + :move-point nil + :type line + (sort-lines nil beg end)) + + (mapc (lambda (mode) (evil-set-initial-state mode 'emacs)) + '(jabber-roster-mode grep-mode avandu-overview-mode + avandu-article-mode gnus-summary-mode + gnus-article-mode gnus-group-mode + magit-status-mode magit-key-mode + sql-interactive-mode Info-mode + jabber-chat-mode diff-mode prodigy-mode + calculator-mode messages-buffer-mode + help-mode)) + (evil-set-initial-state 'git-commit-mode 'normal) + (require 'evil-nerd-commenter) + (define-key evil-normal-state-map ",s" 'oni:evil-sort-operator) + (add-hook 'before-save-hook #'oni:maybe-switch-to-normal-state)) + +(stante-after eww + (setq eww-download-path ; Don't go to ~/Downloads + "~/downloads/")) + +(stante-after files + (setq-default require-final-newline t) + (setq auto-mode-case-fold nil) + (setq auto-save-file-name-transforms + `((".*" "~/.local/share/emacs/autosave/" t))) + (setq backup-directory-alist + `((".*" . "~/.local/share/emacs/backup/"))) + (setq auto-mode-alist + (append '(("/PKGBUILD$" . sh-mode) + (".install$" . sh-mode) + ("\\.jl$" . sawfish-mode) + ("\\.js\\(on\\)?$" . js2-mode) + ("\\.m\\(ark\\)?d\\(?:o?wn\\)?$" . markdown-mode) + ("\\.php[345]?$" . php-mode) + ("\\.po\\'\\|\\.po\\." . po-mode) + ("\\.tm?pl$" . html-mode) + ("^\\.Xmodmap$" . xmodmap-mode)) + auto-mode-alist))) + +(stante-after fill-column-indicator + (setq fci-rule-column 73)) + +(stante-after fiplr + (add-to-list 'fiplr-root-markers ".emacs.desktop") + (push "*.pyc" (cadr (assoc 'files fiplr-ignored-globs))) + (push "*.cache" (cadr (assoc 'files fiplr-ignored-globs))) + (push "*.elc" (cadr (assoc 'files fiplr-ignored-globs))) + (push ".emacs.desktop*" (cadr (assoc 'files fiplr-ignored-globs))) + (push ".cask" (cadr (assoc 'directories fiplr-ignored-globs))) + (push "migrations" (cadr (assoc 'directories fiplr-ignored-globs))) + (push "vendor-lisp" (cadr (assoc 'directories fiplr-ignored-globs)))) + +(stante-after flycheck + (mapc (lambda (c) (delq c flycheck-checkers)) + '(python-pylint python-pyflakes)) + (setf flycheck-highlighting-mode 'columns) + (require 'flycheck-commit-check) + (setq flycheck-display-errors-function + #'flycheck-pos-tip-error-messages)) + +(stante-after geiser-repl + (setq geiser-repl-history-filename "~/.emacs.d/geiser-history")) + +(stante-after gnutls + (add-to-list + 'gnutls-trustfiles + (expand-file-name "~/ssl_20130810/sub.class1.server.ca.pem"))) + +(stante-after grep + (add-to-list 'grep-find-ignored-directories "migrations") + (add-to-list 'grep-find-ignored-directories "vendor") + (add-to-list 'grep-find-ignored-directories "tmp") + (add-to-list 'grep-find-ignored-directories "log") + (add-to-list 'grep-find-ignored-files "TAGS")) + +(stante-after help-at-pt + (setq help-at-pt-display-when-idle t)) + +(stante-after ido + (setq ido-ignore-buffers + (list "^\\` " "^irc\\." "^\\#" "^\\*Customize Option:" + (rx (or "*-jabber-roster-*" "*Messages*" "*fsm-debug*" + "*magit-process*" "*magit-edit-log*" "*Backtrace*" + "*Ibuffer*")))) + (setq ido-auto-merge-work-directories-length -1) + (setq ido-default-buffer-method 'pop-to-buffer) + (setq ido-max-window-height 1) + (setq ido-save-directory-list-file nil) + (setq ido-enable-flex-matching t) + (setq ido-use-faces nil)) + +(stante-after imenu + (setq imenu-auto-rescan t)) + +(stante-after jabber (load "jabber-init")) + +(stante-after jedi + (setq jedi:tooltip-method nil)) + +(stante-after jit-lock + (setq jit-lock-defer-time 0.2)) + +(stante-after magit + (setq magit-repo-dirs '("~/projects/")) + (setq magit-diff-refine-hunk 'all)) + +(stante-after message + (setq message-send-mail-function 'message-send-mail-with-sendmail) + (setq message-sendmail-extra-arguments '("-a" "ryuslash"))) + +(stante-after minibuf-eldef + (setq minibuffer-eldef-shorten-default t)) + +(stante-after mouse + (setq mouse-yank-at-point t)) + +(stante-after org + (require 'org-init) + (setq org-special-ctrl-a/e t)) + +(stante-after org2blog + (setq org2blog/wp-blog-alist + '(("ryublog" + :url "https://ryuslash.org/blog/xmlrpc.php" + :username "ryuslash")))) + +(stante-after "paragraphs" + (setq sentence-end-double-space nil)) + +(stante-after php-mode + (setq-default php-mode-warn-if-mumamo-off nil) + (setq php-function-call-face 'font-lock-function-name-face) + (setq php-mode-force-pear t)) + +(stante-after prodigy + (prodigy-define-service + :name "Python test mailserver" + :command "python" + :args '("-m" "smtpd" "-n" "-c" "DebuggingServer" "localhost:1025") + :tags '(work mail) + :kill-process-buffer-on-stop t) + + (prodigy-define-service + :name "Picturefix mollie-bank" + :command "bundle" + :args '("exec" "mollie-bank") + :cwd "~/projects/work/photension/picturefix" + :path '("~/.rbenv/shims") + :tags '(work) + :kill-signal 'sigkill) + + (prodigy-define-service + :name "Picturefix" + :command "bundle" + :args '("exec" "rails" "s") + :cwd "~/projects/work/photension/picturefix" + :path '("~/.rbenv/shims") + :tags '(work) + :kill-signal 'sigkill) + + (prodigy-define-service + :name "Picturefix sidekiq" + :command "bundle" + :args '("exec" "sidekiq") + :cwd "~/projects/work/photension/picturefix" + :path '("~/.rbenv/shims") + :tags '(work) + :kill-signal 'sigkill)) + +(stante-after python-environment + (setcar python-environment-virtualenv "virtualenv2")) + +(stante-after scheme + (require 'ac-geiser)) + +(stante-after sendmail + (setq send-mail-function 'sendmail-send-it) + (setq sendmail-program "/usr/bin/msmtp")) + +(stante-after simple + (setq read-mail-command 'gnus) + (define-key special-mode-map "z" #'kill-this-buffer)) + +(with-eval-after-load 'slime + (setq slime-lisp-implementations + '((sbcl ("sbcl" "--noinform") :coding-system utf-8-unix) + (clisp ("clisp") :coding-system utf-8-unix)) + slime-default-lisp 'sbcl)) + +(stante-after smex + (setq smex-key-advice-ignore-menu-bar t) + (setq smex-save-file "~/.emacs.d/smex-items")) + +(stante-after "startup" + (setq inhibit-default-init t) + (setq inhibit-startup-message t) + (setq initial-major-mode 'emacs-lisp-mode) + (setq initial-scratch-message nil)) + +(stante-after tern + (require 'tern-auto-complete) + (tern-ac-setup)) + +(stante-after time-stamp + (setq time-stamp-active t) + (setq time-stamp-format "%04y-%02m-%02d %02H:%02M:%02S (%u)")) + +(stante-after type-break + (setq type-break-good-rest-interval (* 60 10)) + (setq type-break-interval (* 60 50)) + (setq type-break-keystroke-threshold '(nil . nil))) + +(stante-after uniquify + (setq uniquify-buffer-name-style 'post-forward)) + +(stante-after w3m + (setq w3m-fill-column 72)) + +(stante-after "window" + (setq split-height-threshold 40) + (add-to-list + 'display-buffer-alist + '("^\\*\\(?:.+-\\)?scratch\\*$" display-buffer-same-window)) + (add-to-list + 'display-buffer-alist + '("^\\*magit: .*\\*$" display-buffer-same-window))) + +(stante-after woman + (setq woman-fill-column 72)) + +(stante-after yasnippet + (setq yas-fallback-behavior nil) + (setq yas-prompt-functions '(yas-ido-prompt))) + +;;;; Hooks + +(add-hook 'after-save-hook 'oni:after-save-func t) +(add-hook 'before-save-hook 'oni:before-save-func) +(add-hook 'comint-mode-hook #'oni:turn-on-compilation-shell-for-pony) +(add-hook 'css-mode-hook #'rainbow-mode) +(add-hook 'diary-display-hook 'oni:diary-display-func) +(add-hook 'git-commit-mode-hook #'oni:set-ispell-local-en-dict) +(add-hook 'haskell-mode-hook 'oni:haskell-mode-func) +(add-hook 'js-mode-hook #'moz-minor-mode) +(add-hook 'outline-minor-mode-hook #'oni:set-tab-maybe-toggle-outline) +(add-hook 'slime-mode-hook #'set-up-slime-ac) +(add-hook 'sql-interactive-mode-hook #'oni:augment-sql-prompt) +(add-hook 'term-mode-hook 'oni:term-mode-func) +(add-hook 'vala-mode-hook #'oni:vala-mode-func) +(add-hook 'write-file-hooks 'oni:write-file-func) +(add-hook 'yas-global-mode-hook 'oni:yas-minor-mode-func) +(add-hook 'scheme-mode-hook (lambda () (setq ac-sources '(ac-source-geiser)))) +(add-hook 'java-mode-hook #'oni:electric-pair-local-mode) + +(oni:add-function-to-hooks #'flycheck-mode + 'perl-mode-hook 'rst-mode-hook 'rust-mode-hook 'sh-mode-hook + 'git-commit-mode-hook) + +(oni:add-function-to-hooks #'oni:make-readable + 'Info-mode-hook 'gnus-article-mode-hook 'gnus-group-mode-hook + 'org-agenda-mode-hook) + +(oni:add-function-to-hooks #'paredit-mode + 'clojure-mode-hook 'geiser-repl-mode-hook 'sawfish-mode-hook + 'scheme-mode-hook) + +(oni:add-function-to-hooks #'hl-sexp-mode + 'clojure-mode-hook 'geiser-repl-mode-hook 'sawfish-mode-hook + 'scheme-mode-hook) + +(oni:add-hooks 'c-mode-hook + #'oni:c-mode-func #'oni:electric-pair-local-mode) + +(oni:add-hooks 'emacs-lisp-mode-hook + (lambda () + (setf ac-sources '(ac-source-emacs-lisp-features + ac-source-functions + ac-source-variables + ac-source-symbols))) + #'oni:locally-enable-double-spaces #'oni:set-emacs-lisp-symbols + #'paredit-mode #'flycheck-mode #'eldoc-mode #'oni:set-emacs-lisp-keys + #'hl-sexp-mode) + +(oni:add-hooks 'eshell-mode-hook + #'buffer-disable-undo #'oni:set-keys-for-eshell + #'eshell-fringe-status-mode) + +(oni:add-hooks 'gnus-summary-mode-hook + #'oni:make-readable (lambda () + (local-set-key (kbd "M-d") (lambda () + (interactive) + (gnus-summary-delete-article) + (gnus-summary-next-subject 1))))) + +(oni:add-hooks 'go-mode-hook + #'oni:go-mode-func #'flycheck-mode) + +(oni:add-hooks 'html-mode-hook + #'flycheck-mode #'oni:maybe-fci-mode #'tagedit-mode #'turn-off-flyspell + #'turn-off-auto-fill) + +(oni:add-hooks 'hy-mode-hook + #'paredit-mode #'oni:set-keys-for-hy #'hl-sexp-mode) + +(oni:add-hooks 'ielm-mode-hook + #'paredit-mode #'eldoc-mode #'oni:set-emacs-lisp-keys #'hl-sexp-mode) + +(oni:add-hooks 'jabber-chat-mode-hook + #'oni:set-keys-for-jabber-chat #'oni:make-readable + #'oni:reset-default-directory) + +(oni:add-hooks 'js2-mode-hook + #'tern-mode #'moz-minor-mode #'oni:electric-pair-local-mode) + +(oni:add-hooks 'lisp-mode-hook + (lambda () (setf ac-sources '(ac-source-slime-simple))) + #'oni:set-emacs-lisp-symbols #'paredit-mode #'hl-sexp-mode) + +(oni:add-hooks 'lua-mode-hook + #'oni:lua-mode-func #'flycheck-mode #'oni:electric-pair-local-mode) + +(oni:add-hooks 'markdown-mode-hook + #'whitespace-mode #'oni:markdown-mode-func) + +(oni:add-hooks 'php-mode-hook + #'oni:php-mode-func #'flycheck-mode) + +(oni:add-hooks 'prog-mode-hook + #'oni:prog-mode-func #'oni:maybe-fci-mode #'rainbow-delimiters-mode + #'oni:maybe-prettify-symbols-mode) + +(oni:add-hooks 'python-mode-hook + (lambda () (setq ac-sources '(ac-source-jedi-direct))) + #'oni:set-python-symbols #'flycheck-mode #'whitespace-mode + #'oni:python-mode-func #'oni:set-python-imenu-function + #'jedi:setup #'subword-mode #'oni:electric-pair-local-mode) + +(oni:add-hooks 'ruby-mode-hook + #'flycheck-mode #'oni:electric-pair-local-mode) + +(oni:add-hooks 'slime-repl-mode-hook + #'paredit-mode #'set-up-slime-ac #'hl-sexp-mode) + +(oni:add-hooks 'tagedit-mode-hook + #'tagedit-add-experimental-features + #'tagedit-add-paredit-like-keybindings #'oni:set-keys-for-tagedit) + +(oni:add-hooks 'texinfo-mode-hook + #'flycheck-mode #'outline-minor-mode) + +(oni:add-hooks 'text-mode-hook + #'auto-fill-mode #'flyspell-mode #'oni:make-readable) + +;;;; Keybindings + +(global-set-key (kbd "'") 'oni:self-insert-dwim) +(global-set-key (kbd "") 'oni:raise-scratch) +(global-set-key (kbd "") 'gnus) +(global-set-key (kbd "") 'git-project-show-files) +(global-set-key (kbd "") #'oni:reload-buffer) +(global-set-key (kbd "") 'magit-status) +(global-set-key (kbd "") #'oni:raise-eshell) +(global-set-key (kbd "") 'oni:show-org-index) +(global-set-key (kbd "") 'oni:scroll-up-or-next-page) +(global-set-key (kbd "") 'oni:scroll-down-or-prev-page) +(global-set-key (kbd "C-. C-.") #'oni:switch-to-other-buffer) +(global-set-key (kbd "C-<") 'indent-shift-left) +(global-set-key (kbd "C->") 'indent-shift-right) +(global-set-key (kbd "C-M-4") 'split-window-vertically) +(global-set-key (kbd "C-M-SPC") 'er/expand-region) +(global-set-key (kbd "C-M-d") 'kill-word) +(global-set-key (kbd "C-M-w") 'backward-kill-word) +(global-set-key (kbd "C-M-x") 'smex-major-mode-commands) +(global-set-key (kbd "C-M-z") 'indent-defun) +(global-set-key (kbd "C-S-k") 'kill-whole-line) +(global-set-key (kbd "C-c +") #'oni:increase-number-at-point) +(global-set-key (kbd "C-c -") #'oni:decrease-number-at-point) +(global-set-key (kbd "C-c Q") #'delete-other-windows) +(global-set-key (kbd "C-c R") #'delete-window) +(global-set-key (kbd "C-c S") #'split-window-right) +(global-set-key (kbd "C-c a") 'org-agenda) +(global-set-key (kbd "C-c c") 'org-capture) +(global-set-key (kbd "C-c d c") 'desktop-clear) +(global-set-key (kbd "C-c d d") 'desktop-registry-change-desktop) +(global-set-key (kbd "C-c d k") #'desktop-registry-remove-desktop) +(global-set-key (kbd "C-c d s") 'desktop-save-in-desktop-dir) +(global-set-key (kbd "C-c g b") 'magit-checkout) +(global-set-key (kbd "C-c g f") 'magit-fetch) +(global-set-key (kbd "C-c g i") 'magit-init) +(global-set-key (kbd "C-c g s") 'magit-status) +(global-set-key (kbd "C-c h r") 'hypo-region) +(global-set-key (kbd "C-c i p") 'identica-update-status-interactive) +(global-set-key (kbd "C-c m") 'gnus) +(global-set-key (kbd "C-c p") 'oni:show-buffer-position) +(global-set-key (kbd "C-c s") #'split-window-below) +(global-set-key (kbd "C-c t") 'oni:raise-ansi-term) +(global-set-key (kbd "C-c u") #'upcase-transient-mode) +(global-set-key (kbd "C-c w d") 'oni:downcase-prev) +(global-set-key (kbd "C-c w u") 'oni:upcase-prev) +(global-set-key (kbd "C-e") 'oni:move-end-of-dwim) +(global-set-key (kbd "C-x 4 f") #'fiplr-find-file-other-window) +(global-set-key (kbd "C-x 5 f") #'fiplr-find-file-other-frame) +(global-set-key (kbd "C-x 8 e") "€") +(global-set-key (kbd "C-x C-b") 'ibuffer) +(global-set-key (kbd "C-x f") 'fiplr-find-file) +(global-set-key (kbd "M-0") 'delete-window) +(global-set-key (kbd "M-1") 'delete-other-windows) +(global-set-key (kbd "M-2") 'split-window-below) +(global-set-key (kbd "M-3") 'split-window-right) +(global-set-key (kbd "M-4") 'split-window-horizontally) +(global-set-key (kbd "M-n") 'idomenu) +(global-set-key (kbd "M-o") 'other-window) +(global-set-key (kbd "M-x") 'smex) +(global-set-key (kbd "\"") 'oni:self-insert-dwim) +(global-set-key [remap move-beginning-of-line] #'oni:move-beginning-of-dwim) +(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines) +(global-set-key (kbd "M-+") 'mc/mark-next-like-this) +(global-set-key (kbd "M--") 'mc/mark-previous-like-this) +(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) + +;;;; Misc modes + +(oni:enable '(downcase-region narrow-to-page narrow-to-region scroll-left + upcase-region)) + +(oni:link-modes outline-minor-mode persistent-outline-mode) +(oni:exclude-modes magit-blame-mode fci-mode) + +(oni:eval-after-init + (require 'auto-complete-config) + (ac-config-default) + + (ido-ubiquitous-mode) + (smex-initialize) + (global-diff-hl-mode) + (mode-icons-mode) + (desktop-registry-auto-register) + (yas-global-mode) + + (require 'popwin) + (popwin-mode) + + (evil-mode) + (require 'colemak-evil) + (global-evil-surround-mode)) + +(when (equal system-name "drd") + (load "eap-autoloads")) + +(auto-insert-mode) +(electric-indent-mode -1) +(ido-mode 1) +(minibuffer-electric-default-mode) +(savehist-mode) +(show-paren-mode) +(winner-mode) + +(help-at-pt-set-timer) +(windmove-default-keybindings) + +(load system-name :noerror) + +;;;; End + +(provide 'init) +;;; init.el ends here -- cgit v1.2.3-54-g00ecf