diff options
| author | Ravi R Kiran <aine.marina@gmail.com> | 2015-10-23 18:57:59 (GMT) |
|---|---|---|
| committer | Ravi R Kiran <aine.marina@gmail.com> | 2015-10-23 18:57:59 (GMT) |
| commit | cd1924466152177ea06b17c843f256463c1b91b8 (patch) | |
| tree | af90afe028e5e392f242a3ea36302aafe1c1769d /lisp | |
| parent | 5561df232cfa49822f322196d98170f95aa1139e (diff) | |
| parent | 74c319ef12dd3130f6afc17abc59404b59d601d1 (diff) | |
| download | dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.zip dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.tar.gz dotemacs-cd1924466152177ea06b17c843f256463c1b91b8.tar.bz2 | |
Merge branch 'master' into rtags-attempt
* master: (139 commits)
Add pdf-tools as a nicer replacement for doc-view
Add pdf-tools submodule
Fix maildir data with correct path
Add desktop notifications for email
Potential use for modes without repls
Attach files more easily in mu
Update to newest version of mu
Please remove tooltips after a while, please
ace-window gets confused when tooltips are present
Sometimes the dispatch list does come in handy
Pre-populate searches
Succumb to muscle memory of control keys
Remove ropemacs due to disuse
Do not let company-quickhelp steal a global key
Manage word navigation
Use proper helm function to replace completing-read
Electric operators on python mode
Use which-key in preference to guide-key
Navigate easier
Simplify config with magit 2.1.0
...
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ravi-ergodox-mode.el | 83 | ||||
| -rw-r--r-- | lisp/ravi-init-appearance.el | 428 | ||||
| -rw-r--r-- | lisp/ravi-init-cpp.el | 451 | ||||
| -rw-r--r-- | lisp/ravi-init-dired.el | 149 | ||||
| -rw-r--r-- | lisp/ravi-init-files.el | 159 | ||||
| -rw-r--r-- | lisp/ravi-init-function.el | 144 | ||||
| -rw-r--r-- | lisp/ravi-init-helm.el | 118 | ||||
| -rw-r--r-- | lisp/ravi-init-ido.el | 176 | ||||
| -rw-r--r-- | lisp/ravi-init-insertion.el | 155 | ||||
| -rw-r--r-- | lisp/ravi-init-layouts.el | 57 | ||||
| -rw-r--r-- | lisp/ravi-init-maps.el | 58 | ||||
| -rw-r--r-- | lisp/ravi-init-marks.el | 78 | ||||
| -rw-r--r-- | lisp/ravi-init-mu.el | 218 | ||||
| -rw-r--r-- | lisp/ravi-init-navigation.el | 404 | ||||
| -rw-r--r-- | lisp/ravi-init-org.el | 62 | ||||
| -rw-r--r-- | lisp/ravi-init-python.el | 164 | ||||
| -rw-r--r-- | lisp/ravi-init-repl.el | 76 | ||||
| -rw-r--r-- | lisp/ravi-init-tex.el | 192 | ||||
| -rw-r--r-- | lisp/ravi-init-vc.el | 104 | ||||
| -rw-r--r-- | lisp/ravi-init-web.el | 112 |
20 files changed, 3388 insertions, 0 deletions
diff --git a/lisp/ravi-ergodox-mode.el b/lisp/ravi-ergodox-mode.el new file mode 100644 index 0000000..a4867be --- /dev/null +++ b/lisp/ravi-ergodox-mode.el @@ -0,0 +1,83 @@ +;;; ravi-ergodox-mode.el --- Keybindings fof Ergodox keyboard + +;; Copyright (C) 2014 Ravikiran Rajagopal + +;; Author: Ravikiran Rajagopal <ravi@nero.lan> +;; Keywords: convenience, hardware + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Set up keymap for ergodox bindings + +;;; Code: + +(defgroup ravi-ergodox-mode nil + "Keybindings for ergodox." + :group 'ravi-ergodox-mode) + +(defvar ravi-ergodox-mode-map (make-sparse-keymap) + "Keymaps for command `ravi-ergodox-mode-map'.") + +(defcustom ravi-ergodox-mode-disable-predicates nil + "List of predicates that disable the mode. +Each function in the list receive no argument." + :group 'ravi-ergodox-mode) + +(defcustom ravi-ergodox-mode-disabled-modes nil + "Modes where `ravi-ergodox-mode' should not activate." + :group 'ravi-ergodox-mode + :type '(repeat symbol)) + +(define-minor-mode ravi-ergodox-mode + "Enable Ergodox keyboard special bindings." + :lighter " RE" :group 'convenience + :keymap ravi-ergodox-mode-map + :global t + (if ravi-ergodox-mode + (progn + (setq x-meta-keysym 'super) + (setq x-super-keysym 'meta)) + (progn + (setq x-meta-keysym nil) + (setq x-super-keysym nil)) + ) + ) + +(define-key ravi-ergodox-mode-map (kbd "H-m") 'magit-status) +(define-key ravi-ergodox-mode-map (kbd "<f6>") 'ff-find-other-file) +(if (and (boundp 'ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + (progn + (define-key ravi-ergodox-mode-map (kbd "<f1>") 'helm-multi-files) + (define-key ravi-ergodox-mode-map (kbd "<f2>") 'helm-find-files)) + (progn + (define-key ravi-ergodox-mode-map (kbd "<f1>") 'ido-switch-buffer) + (define-key ravi-ergodox-mode-map (kbd "<f2>") 'ido-find-file))) + +(defun ravi-ergodox-mode-enable () + "Turn on ergodox bindings mode." + (and (not (memq major-mode ravi-ergodox-mode-disabled-modes)) + (not (catch 'disable + (dolist (pred ravi-ergodox-mode-disable-predicates) + (and (funcall pred) + (throw 'disable t))))) + (ravi-ergodox-mode 1))) + +(defun ravi-ergodox-mode-disable () + "Turn off ergodox bindings mode." + (ravi-ergodox-mode -1)) + +(provide 'ravi-ergodox-mode) +;;; ravi-ergodox-mode.el ends here diff --git a/lisp/ravi-init-appearance.el b/lisp/ravi-init-appearance.el new file mode 100644 index 0000000..fe81dcb --- /dev/null +++ b/lisp/ravi-init-appearance.el @@ -0,0 +1,428 @@ +;;; ravi-init-appearance.el --- Emacs appearance + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Customization of emacs appearance + +;;; Code: + +;; No splash screen please +(setq inhibit-startup-message t) + +;; Allow pasting selection outside of Emacs +(setq x-select-enable-clipboard t) + +;; Show keystrokes in progress +(setq echo-keystrokes 0.1) + +;; Real emacs knights don't use shift to mark things +(setq shift-select-mode nil) + +;; Enable syntax highlighting for older Emacsen that have it off +(global-font-lock-mode t) +(setq font-lock-maximum-decoration t) + +;; Sounds. +;; Turn off sound. +(setq bell-volume 0) +(setq sound-alist nil) + +(add-to-list 'default-frame-alist '(cursor-color . "#ffb90f") t) + +;; Answering just 'y' or 'n' will do +(defalias 'yes-or-no-p 'y-or-n-p) + +;; Customization of modeline. +(line-number-mode 1) +(column-number-mode 1) +(display-time) + +;; Change the way the buffer name is displayed in the modeline. +(setq-default mode-line-buffer-identification '("%17b")) + +;; Undo/redo window configuration with C-c <left>/<right> +(winner-mode 1) + +;; Never insert tabs +(set-default 'indent-tabs-mode nil) + +;; Show me empty lines after buffer end (replaced, see below) +;(set-default 'indicate-empty-lines t) + +(use-package whitespace + :init + (setq whitespace-style '(face trailing indentation tabs)) + :config + (progn + (global-whitespace-mode 1)) + ; No need for 'ensure: t' since whitespace mode is built in + :diminish global-whitespace-mode + ) + +(use-package ws-butler + :config + (progn + (ws-butler-global-mode 1)) + :diminish ws-butler-mode + :ensure t) + +(diminish 'abbrev-mode) + +;; Handling end of files. +(setq require-final-newline t) +;; Prevent addition of lines at end of file when down arrow is pressed. +(setq next-line-add-newlines nil) + +;; Kill the entire line, please +(setq kill-whole-line t) + +;; Delete hungrily +(use-package hungry-delete + :commands (hungry-delete-forward hungry-delete-backward) + :bind (("C-d" . hungry-delete-forward)) + :init + (progn + (defun jschaf/hungry-delete-backward (n &optional killflag) + "Delete non-vertical whitespace backwards on first key press. +Delete all whitespace on a successive key press." + (interactive "p\nP") + (if (eq last-command 'jschaf/hungry-delete-backward) + (hungry-delete-backward n killflag) + (let ((hungry-delete-chars-to-skip " \t\f\v")) + (hungry-delete-backward n killflag)))) + ;;(define-key global-map [remap backward-delete-char-untabify] 'jschaf/hungry-delete-backward) + (define-key global-map [remap backward-delete-char-untabify] 'hungry-delete-backward) + ) + :ensure t) + +;; Easier compaction of whitespace +(use-package shrink-whitespace + :bind (("M-SPC" . shrink-whitespace)) + :ensure t) + +(setq sentence-end-double-space nil) +(use-package unfill + :bind (("M-q" . toggle-fill-unfill)) + :ensure t) + +(use-package subword + :config + (global-superword-mode 1) + :diminish superword-mode) + +;; Make word-navigation more palatable +(use-package syntax-subword + :init + (progn + (setq syntax-subword-skip-spaces t)) + :config + (progn + (defun ravi/turn-on-syntax-subword-mode () + (interactive) + (syntax-subword-mode 1)) + (add-hook 'prog-mode-hook 'ravi/turn-on-syntax-subword-mode)) + :ensure t) + +(use-package rectangle-utils + :bind (("C-x R" . rectangle-menu)) + :ensure t) + +;; Keep cursor away from edges when scrolling up/down +(use-package smooth-scrolling + :ensure t) + +;; Enable automatic indentation, if possible +(use-package smart-newline + :commands (smart-newline) + :init + (progn + (bind-key "<return>" 'smart-newline prog-mode-map) + (bind-key "<return>" 'smart-newline emacs-lisp-mode-map)) + :ensure t) + +;; Case toggling: from Oleg Krehel http://oremacs.com/2014/12/25/ode-to-toggle/ +(defun oremacs/char-upcasep (letter) + (eq letter (upcase letter))) + +(defun oremacs/capitalize-word-toggle () + (interactive) + (let ((start + (car + (save-excursion + (backward-word) + (bounds-of-thing-at-point 'symbol))))) + (if start + (save-excursion + (goto-char start) + (funcall + (if (oremacs/char-upcasep (char-after)) + 'downcase-region + 'upcase-region) + start (1+ start))) + (capitalize-word -1)))) +;; (bind-key "M-c" 'oremacs/capitalize-word-toggle) + +(defun oremacs/upcase-word-toggle () + (interactive) + (let ((bounds (bounds-of-thing-at-point 'symbol)) + beg end + (regionp + (if (eq this-command last-command) + (get this-command 'regionp) + (put this-command 'regionp nil)))) + (cond + ((or (region-active-p) regionp) + (setq beg (region-beginning) + end (region-end)) + (put this-command 'regionp t)) + (bounds + (setq beg (car bounds) + end (cdr bounds))) + (t + (setq beg (point) + end (1+ beg)))) + (save-excursion + (goto-char (1- beg)) + (and (re-search-forward "[A-Za-z]" end t) + (funcall (if (oremacs/char-upcasep (char-before)) + 'downcase-region + 'upcase-region) + beg end))))) +;; (bind-key "M-l" 'oremacs/upcase-word-toggle) + +(use-package fix-word + :bind (("M-u" . fix-word-upcase) + ("M-l" . fix-word-downcase) + ("M-c" . fix-word-capitalize)) + :ensure t) + +;; Zap up to char is more useful than zap-char +(use-package zop-to-char + :bind (("M-z" . zop-up-to-char) + ("M-Z" . zop-to-char)) + :ensure t) + +;; Automatic indentation of yanked text +(dolist (command '(yank yank-pop)) + (eval `(defadvice ,command (after indent-region activate) + (and (not current-prefix-arg) + (member major-mode '(emacs-lisp-mode lisp-mode + clojure-mode scheme-mode + haskell-mode ruby-mode + rspec-mode python-mode + c-mode c++-mode + objc-mode latex-mode + plain-tex-mode)) + (let ((mark-even-if-inactive transient-mark-mode)) + (indent-region (region-beginning) (region-end) nil)))))) + +(defun ravi/erase-from-point (&optional prefix) + "Erase part of buffer after point (or before point with a prefix)" + (interactive "P") + (if (consp prefix) + (delete-region (point-min) (point)) + (delete-region (point) (point-max)))) + +(use-package comment-dwim-2 + :bind (("M-;" . comment-dwim-2)) + :ensure t) + +;; To do: change to different keybinding +(use-package string-inflection + :bind (("C-c c" . hydra-string-inflection/body)) + :config + (progn + (defhydra hydra-string-inflection () + ("c" string-inflection-all-cycle "all") + ("r" string-inflection-ruby-style-cycle "ruby") + ("j" string-inflection-java-style-cycle "java") + ("<return>" nil))) + :ensure t) + +;; Keep my navigation simple +(setq line-move-visual nil) + +;; Represent undo-history as an actual tree (visualize with C-x u) +(use-package undo-tree + :init + (setq undo-tree-mode-lighter "") + :config + (progn + (global-undo-tree-mode) + (setq undo-tree-auto-save-history t) + (setq undo-tree-history-directory-alist + `(("." . ,(expand-file-name "undotree/" (ravi/emacs-file "past"))))) + ) + :ensure t + ) + +;; Discover emacs +;; Since discover.el replaces keymaps wholesale for "C-x r" and "M-s", it overrides +;; our additions to them. So we use guide-key for "C-x r" and "M-s". +(use-package discover + :config + (progn + (add-hook 'dired-mode-hook 'discover-turn-on-in-dired) + ) + :disabled t ;; unstable API and hosing user-provided keybindings + :ensure t + ) + +;; Help for prefix key-bindings not in discover-mode +(use-package guide-key + :config + (progn + (setq guide-key/guide-key-sequence '("C-c p" ;; projectile + "C-c d" ;; doxymacs + "C-x 4" ;; other-window + "C-x r" ;; rectangles/registers + "M-s" ;; isearch + "C-x v" ;; version control + "M-g" ;; movement + "C-x 5" ;; frames + "C-x n" ;; narrowing + )) + (when (and (boundp ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + (add-to-list 'guide-key/guide-key-sequence "<escape>") + (add-to-list 'guide-key/guide-key-sequence "<escape> C-c") + (add-to-list 'guide-key/guide-key-sequence "<escape> C-x") + (add-to-list 'guide-key/guide-key-sequence "<escape> C-x r") + (add-to-list 'guide-key/guide-key-sequence "<escape> ESC")) + + (guide-key-mode 1) + + (use-package guide-key-tip + :config + (progn + (setq guide-key-tip/enabled t)) + :ensure t + :disabled t ;; popups don't always go away; need to file a bug report + ) + ) + :diminish guide-key-mode + :disabled t + :ensure t + ) + +(use-package which-key + :config + (progn + (which-key-mode)) + :diminish which-key-mode + :ensure t) + +(bind-key "C-h a" 'apropos) + +(use-package popwin + :config + (progn + (popwin-mode 1) + (push '("*Pp Eval Output*" :height 15) popwin:special-display-config)) + :ensure t) + +(use-package temp-buffer-browse + :config + (progn + (temp-buffer-browse-mode 1)) + :diminish temp-buffer-browse-mode + :disabled t ; emacs historical issues make this unworkable + :ensure t) + +(use-package import-popwin + :bind (("M-I" . import-popwin)) + :ensure t) + +(use-package ace-window + :bind (("M-o" . ace-window) + ("M-O" . ravi/dispatched-ace-window)) + :config + (progn + (set-face-attribute 'aw-leading-char-face nil :foreground "deep sky blue" :weight 'bold :height 3.0) + (set-face-attribute 'aw-mode-line-face nil :inherit 'mode-line-buffer-id :foreground "lawn green") + (setq aw-keys '(?d ?f ?g ?h ?j ?k ?l ?i ?e) + ;; aw-dispatch-always t + aw-dispatch-alist + '((?x aw-delete-window "Ace - Delete Window") + (?c aw-swap-window "Ace - Swap Window") + (?n aw-flip-window) + (?v aw-split-window-vert "Ace - Split Vert Window") + (?h aw-split-window-horz "Ace - Split Horz Window") + (?m delete-other-windows "Ace - Maximize Window") + (?g delete-other-windows) + (?b balance-windows) + (?u winner-undo) + (?r winner-redo))) + + (defun ravi/dispatched-ace-window (arg) + "Select window with dispatch always present" + (interactive "p") + (let ((aw-dispatch-always t)) + (ace-window arg))) + + (defun ravi/hide-tool-tip (&rest args) + (when (display-graphic-p) + (x-hide-tip))) + (advice-add 'ace-window :before 'ravi/hide-tool-tip) + + (when (package-installed-p 'hydra) + (defhydra hydra-window-size (:color red) + "Windows size" + ("h" shrink-window-horizontally "shrink horizontal") + ("j" shrink-window "shrink vertical") + ("k" enlarge-window "enlarge vertical") + ("l" enlarge-window-horizontally "enlarge horizontal")) + (defhydra hydra-window-frame (:color red) + "Frame" + ("f" make-frame "new frame") + ("x" delete-frame "delete frame")) + (defhydra hydra-window-scroll (:color red) + "Scroll other window" + ("n" joe-scroll-other-window "scroll") + ("p" joe-scroll-other-window-down "scroll down")) + (add-to-list 'aw-dispatch-alist '(?w hydra-window-size/body) t) + (add-to-list 'aw-dispatch-alist '(?o hydra-window-scroll/body) t) + (add-to-list 'aw-dispatch-alist '(?\; hydra-window-frame/body) t))) + :ensure t) + +(defun ravi/split-window-vertically-and-switch (prefix) + (interactive "P") + (split-window-vertically (if (consp prefix) nil prefix)) + (other-window 1) + (unless (consp prefix) (switch-to-next-buffer))) +(bind-key "C-x 2" 'ravi/split-window-vertically-and-switch) + +(defun ravi/split-window-horizontally-and-switch (prefix) + (interactive "P") + (split-window-horizontally (if (consp prefix) nil prefix)) + (other-window 1) + (unless (consp prefix) (switch-to-next-buffer))) +(bind-key "C-x 3" 'ravi/split-window-horizontally-and-switch) + +(use-package pdf-tools + ;; Install this locally; no update from MELPA needed. + ;; :mode (("\\.pdf\\'" . pdf-view-mode)) ;; errors first use; to do. + :config + (progn + (setq-default pdf-view-display-size 'fit-page) + (pdf-tools-install))) + +(provide 'ravi-init-appearance) +;;; ravi-init-appearance.el ends here diff --git a/lisp/ravi-init-cpp.el b/lisp/ravi-init-cpp.el new file mode 100644 index 0000000..ffa9790 --- /dev/null +++ b/lisp/ravi-init-cpp.el @@ -0,0 +1,451 @@ +;;; ravi-init-cpp.el --- C/C++ handling + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; C/C++ initialization + +;;; Code: + +; Generate a random string (of letters and numbers) of a given length +(defun ravi-random-ucn-string (len) + (coerce (loop for i below len for x = (random 36) collect + (+ x + (cond ((< x 10) 48) + ((< x 36) (- 65 10)) + ))) + 'string)) + +(use-package cmake-mode + :mode (("CMakeLists\\.txt\\'" . cmake-mode) + ("\\.cmake\\'" . cmake-mode)) + ;:ensure t + ) + +(defvar get-buffer-compile-command (lambda (file) (cons file 1))) +(make-variable-buffer-local 'get-buffer-compile-command) + +(setq-default compile-command "") + +(defun compile-dwim (&optional arg) + "Compile Do What I Mean. + Compile using `compile-command'. + When `compile-command' is empty prompt for its default value. + With prefix C-u always prompt for the default value of + `compile-command'. + With prefix C-u C-u prompt for buffer local compile command with + suggestion from `get-buffer-compile-command'. An empty input removes + the local compile command for the current buffer." + (interactive "P") + (cond + ((and arg (> (car arg) 4)) + (let ((cmd (read-from-minibuffer + "Buffer local compile command: " + (funcall get-buffer-compile-command + (or (file-relative-name (buffer-file-name)) "")) + nil nil 'compile-history))) + (cond ((equal cmd "") + (kill-local-variable 'compile-command) + (kill-local-variable 'compilation-directory)) + (t + (set (make-local-variable 'compile-command) cmd) + (set (make-local-variable 'compilation-directory) + default-directory)))) + (when (not (equal compile-command "")) + ;; `compile' changes the default value of + ;; compilation-directory but this is a buffer local + ;; compilation + (let ((dirbak (default-value 'compilation-directory))) + (compile compile-command) + (setq-default compilation-directory dirbak)))) + ((or (and arg (<= (car arg) 4)) + (equal compile-command "")) + (setq-default compile-command (read-shell-command + "Compile command: " + (if (equal compile-command "") + "make " compile-command) + 'compile-history)) + (setq-default compilation-directory default-directory) + (when (not (equal (default-value 'compile-command) "")) + (compile (default-value 'compile-command)))) + (t + (recompile)))) + + +(use-package dummy-h-mode + :mode (("\\.h\\'" . dummy-h-mode)) + :config + (progn + ;; Hack to avoid ObjC files since we do not use it + (defun ravi/do-not-allow-objc (mode-val) + (if (eq mode-val 'objc-mode) + nil + mode-val)) + (mapc (lambda (x) (advice-add x :filter-return #'ravi/do-not-allow-objc)) + '(dummy-h-mode-get-major-mode-by-source-file + ;dummy-h-mode-get-major-mode-by-keywords + dummy-h-mode-get-major-mode-by-files-directory)) + + (setq dummy-h-mode-default-major-mode 'c++-mode)) + :ensure t) + +(use-package cc-mode + + :mode (("\\.h\\(h\\|xx\\|pp\\)\\'" . c++-mode) + ("\\.ccfg\\'" . c++-mode) + ("\\.m\\'" . c-mode) + ("\\.mm\\'" . c++-mode)) + :init + (progn + (use-package doxymacs + :load-path (lambda () (ravi/emacs-file "site-lisp/doxymacs/lisp")) + :config + (progn + (doxymacs-mode) + (setq doxymacs-file-comment-template + '("/**" > n + " * " (doxymacs-doxygen-command-char) "file" > n + " * " > n + " * " (doxymacs-doxygen-command-char) "brief " + (p "Brief description of this file: ") > n + " */" > n) + ) + (setq doxymacs-external-xml-parser-executable + (ravi/emacs-file "site-lisp/doxymacs/c/doxymacs_parser")) + (setq doxymacs-use-external-xml-parser t) + (setq doxymacs-command-character "\\") + ) + :diminish doxymacs-mode + ) + + (use-package rtags + :load-path ,(ravi/emacs-file "site-lisp/rtags/src") + :init + (progn + (setq rtags-path (ravi/emacs-file "site-lisp/rtags")) + (rtags-enable-standard-keybindings c-mode-base-map) + + (use-package rtags-ac) + )) + + (defvar printf-index 0) + + (defun insert-counting-printf (arg) + (interactive "P") + (if arg + (setq printf-index 0)) + (if t + (insert (format "std::cerr << \"step %d..\" << std::endl;\n" + (setq printf-index (1+ printf-index)))) + (insert (format "printf(\"step %d..\\n\");\n" + (setq printf-index (1+ printf-index))))) + (forward-line -1) + (indent-according-to-mode) + (forward-line)) + + ) + + :config + (progn + + (defun my-c-mode-common-hook () + (hs-minor-mode 1) + (hs-hide-initial-comment-block) + (hide-ifdef-mode 1) + (which-function-mode 1) + + (diminish 'hs-minor-mode) + (diminish 'hide-ifdef-mode) + + (bind-key "C-c p" 'insert-counting-printf c-mode-base-map) + + (doxymacs-mode 1) + (doxymacs-font-lock) + + ;(define-key c-mode-base-map [return] 'c-context-line-break) + (bind-key "<return>" 'c-context-line-break c-mode-base-map) + + (unbind-key "M-j" c-mode-base-map) + (bind-key "C-c C-i" 'c-includes-current-file c-mode-base-map) + (when (and (featurep 'ravi-ergodox-mode) ravi-ergodox-mode) + (bind-key "H-h" 'compile-dwim c-mode-base-map)) + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("C"))) + + (set (make-local-variable 'parens-require-spaces) t) + (setq fill-column 88) + + (bind-key "M-q" 'c-fill-paragraph c-mode-base-map) + + (c-toggle-electric-state 1) + (c-toggle-auto-newline 1) + (c-toggle-hungry-state 1) + + (c-set-style "stroustrup") + (setq c-basic-offset 2) + (setq c-recognize-knr-p nil) + (modify-syntax-entry ?_ "w" c-mode-syntax-table) + (add-to-list 'c-cleanup-list 'empty-defun-braces) + (add-to-list 'c-cleanup-list 'defun-close-semi) + (add-to-list 'c-cleanup-list 'list-close-comma) + (add-to-list 'c-cleanup-list 'scope-operator) + ;; one-liner-defun and comment-close-slash found to be annoying + + (font-lock-add-keywords 'c++-mode '(("\\<\\(assert\\|DEBUG\\)(" + 1 font-lock-warning-face t)))) + + (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) + + (defun my-c++-mode-hook () + (setq c-offsets-alist + (append '((statement-cont . c-lineup-math) + (inline-open . 0)) + c-offsets-alist)) + (let ((innamespaceindent (if (and (buffer-file-name) + (string-equal "ccfg" (file-name-extension (buffer-file-name)))) + 2 0)) + ) + (setq c-offsets-alist + (append `((innamespace . ,innamespaceindent) + ) + c-offsets-alist)) + ) + + (modify-syntax-entry ?_ "w" c++-mode-syntax-table) + (setq c-macro-cppflags "-x c++") + (setq c-macro-prompt-flag t) + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("C" "C++" "Boost" "Qt"))) + ) + (defun ravi/c++-hook-adder () + (add-hook 'c++-mode-hook 'my-c++-mode-hook)) + (ravi/c++-hook-adder) + + ;; Stuff from kde-emacs + (defvar kde-header-protection-parts-to-show 1 + "Set this variable to the number of parts from the file name you want to +be used for the defined word in the header-protection function.. E.g. setting +this to 3 makes header-protection define KIG_MISC_NEWTYPE_H for a file named +/home/domi/src/kdenonbeta/kig/misc/newtype.h") + + (defun kde-header-protection-definable-string () + (let* ((definablestring (concat "_" (ravi-random-ucn-string 6)) ) + (f (buffer-file-name)) + (parts (nreverse (split-string f "/"))) + (i) + (first-iter t) + (iters (min (length parts) kde-header-protection-parts-to-show))) + (dotimes (i iters) + (let ((part (pop parts))) + (setq definablestring + (concat + (upcase (replace-regexp-in-string "[\\.-]" "_" part)) + (if (not first-iter) "_" "") + definablestring + ) + ) + (setq first-iter nil) + ) + ) + definablestring + ) + ) + + ;; Creates the ifndef/define/endif statements necessary for a header file + (defun header-protection () + (interactive) + (let ((s (kde-header-protection-definable-string))) + (save-excursion + (goto-char (point-min)) + (insert "#ifndef " s "\n#define " s "\n\n") + (goto-char (point-max)) + (insert "\n#endif\n") + ) + ) + ) + + (defun ravi-start-c++-header () + "Start a new C++ header by inserting include guards ( see \ + header-protection function ), inserting a license statement \ + and putting (point) at the correct position" + (interactive) + (header-protection) + (insert "\n") + (beginning-of-buffer) + + (save-excursion + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (setq end (point)) + (comment-region start end) + ) + ) + + (end-of-buffer) + (next-line -3) + (insert "\n") + (doxymacs-insert-file-comment) + ) + + (setq auto-insert-query nil) + (define-auto-insert "\\.\\([Cc]\\|cc\\|cpp\\|cxx\\|tcc\\)\\'" + 'ravi-auto-insert-cpp) + (define-auto-insert "\\.\\([Hh]\\|hh\\|hpp\\)\\'" 'ravi-start-c++-header) + + (defun ravi-license-insert () + (progn + (let ((start (point-min)) + (comment-style 'box) + (end) + ) + (goto-char start) + (insert (ravi-license-header)) + (insert "\n") + (setq end (point)) + (comment-region start end)))) + + (defun ravi-auto-insert-cpp () + (progn + (ravi-license-insert) + (doxymacs-insert-file-comment))) + + (defun ravi/add-space-before-paren-c (&rest ignored) + (message "Handler invoked") + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\)(") + (save-excursion + (backward-char) + (insert-char ?\s) + ) + )) + + (defadvice c-electric-paren (after ravi/add-space-around-parens activate) + (unless (c-in-literal) + (cond + ((looking-back "([[:space:]]*") + (progn + ;; Open parenthesis was the last command; add a space before it if + ;; necessary, and ensure that the point is placed after a space + (save-excursion + (re-search-backward "([[:space:]]*") + (unless (looking-at "(") (message "Logic error; opening paren not found")) + (when (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)") + (insert-char ?\s))) + (if (and (looking-at " ") (not (looking-at " )"))) + (forward-char) + (insert-char ?\s)) + ) + ) + ((looking-back ")[[:space:]]*") + ;; Closing parenthesis was the last command; add spaces if necessary + (progn + ;; Compact empty function calls + (when (looking-back "([[:space:]]+)[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (delete-horizontal-space) + ) + ) + + ;; Add space before closing parenthesis + (unless (looking-back "()[[:space:]]*") + (save-excursion + (re-search-backward ")[[:space:]]*") + (unless (looking-at ")") (message "Logic error; closing paren not found")) + (unless (looking-back " ") (insert-char ?\s))) + ) + + (let (need-to-add-newline) + (save-excursion + (c-backward-sexp) + (c-backward-syntactic-ws) + ;; FIXME: do-while loops are not handled correctly + (setq need-to-add-newline (looking-back "\\b\\(for\\|while\\|if\\|switch\\|catch\\)")) + ) + (when need-to-add-newline (c-newline-and-indent))) + ) + ) + )) + ) + + (defadvice c-electric-semi&comma (after ravi/add-space-after-comma activate) + (cond + ((looking-back ",") + (if (looking-at " [^)]") (forward-char) (insert-char ?\s))) + ((looking-back ") ;[[:space:]\n]*") + (save-excursion + (re-search-backward " ;[[:space:]\n]*") + (delete-char 1))))) + + ;; Do not activate region as it interferes with region-bindings-mode + (defadvice c-electric-brace (after ravi/do-not-activate-region activate) + (deactivate-mark)) + + (defmacro ravi/fake-send-key (key-to-bind char-to-bind) + (let ((command (key-binding key-to-bind))) + (setq last-command-event char-to-bind) + (setq this-command command) + (call-interactively command)) + ) + + (defun ravi/insert-closing-delimiter() + (interactive) + (if (c-in-literal) + (self-insert-command) + (progn + ;; Find nearest unmatched opening delimiter + (let (brace-type) + (save-excursion + (backward-up-list) + (cond + ((looking-at "{") (setq brace-type 'brace-type-brace)) + ((looking-at "(") (setq brace-type 'brace-type-paren)) + ((looking-at "\\[") (setq brace-type 'brace-type-square)) + (t (setq brace-type 'brace-type-none)) + )) + (cond + ((eq brace-type 'brace-type-brace) (ravi/fake-send-key "}" ?\})) + ((eq brace-type 'brace-type-paren) (ravi/fake-send-key ")" ?\))) + ; Uncommenting the line below would lead to infinite recursion + ;((eq 'brace-type 'brace-type-square) (ravi/fake-send-key "]" ?\])) + (t (self-insert-command 1)) + ) + )))) + + (bind-key "]" 'ravi/insert-closing-delimiter c-mode-base-map) + + (bind-key "<M-f8>" 'compile-dwim c-mode-base-map) + + (bind-key "<M-f5>" 'hs-hide-block c-mode-base-map) + (bind-key "<M-f11>" 'hs-show-block c-mode-base-map) + + (setq hide-ifdef-initially nil) + (bind-key "<S-f5>" 'hide-ifdef-block c-mode-base-map) + (bind-key "<S-f11>" 'show-ifdef-block c-mode-base-map) + + ;; (setq c-syntactic-indentation nil) + ) + ) + +(provide 'ravi-init-cpp) +;;; ravi-init-cpp.el ends here diff --git a/lisp/ravi-init-dired.el b/lisp/ravi-init-dired.el new file mode 100644 index 0000000..a82ba6c --- /dev/null +++ b/lisp/ravi-init-dired.el @@ -0,0 +1,149 @@ +;;; ravi-init-dired.el --- dired setup + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Mostly stolen from Fuco's configuration + +;; Dired setup + +;;; Code: + +(use-package dired + :defer t + :config + (progn + (defun ravi/dired-init-hook () + (dired-filter-mode t) + (visual-line-mode -1) + (toggle-truncate-lines 1)) + (add-hook 'dired-mode-hook 'ravi/dired-init-hook) + + (use-package image-dired) + (use-package dired-aux) + (use-package dired-x + :config + (defun dired-virtual-revert (&optional _arg _noconfirm) + "Enable revert for virtual direds." + (let ((m (dired-file-name-at-point)) + (buffer-modified (buffer-modified-p))) + (goto-char 1) + (dired-next-subdir 1) + (dired-do-redisplay nil t) + (while (dired-next-subdir 1 t) + (dired-do-redisplay nil t)) + (when m (dired-goto-file m)) + (set-buffer-modified-p buffer-modified)))) + + (use-package dired-details + :commands dired-details-toggle + :ensure t + ) + (use-package w32-browser + :commands dired-w32-browser + :ensure t + ) + + (use-package dired-subtree + :ensure t + :config + (progn + (bind-keys :map dired-mode-map + :prefix "," + :prefix-map dired-subtree-map + :prefix-docstring "Dired subtree map." + ("/" . dired-subtree-apply-filter) + ("k" . dired-subtree-remove) + ("n" . dired-subtree-next-sibling) + ("p" . dired-subtree-previous-sibling) + ("u" . dired-subtree-up) + ("d" . dired-subtree-down) + ("a" . dired-subtree-beginning) + ("e" . dired-subtree-end) + ("m" . dired-subtree-mark-subtree) + ("u" . dired-subtree-unmark-subtree) + ("C-o C-f" . dired-subtree-only-this-file) + ("C-o C-d" . dired-subtree-only-this-directory)) + (bind-key "e" 'dired-subtree-insert dired-mode-map)) + ) + + (defconst my-dired-media-files-extensions '("mp3" "mp4" "MP3" "MP4" "avi" "mpg" "flv" "ogg") + "Media file extensions that should launch in VLC. + +Also used for highlighting.") + + (use-package dired-rainbow + :config + (progn + (dired-rainbow-define html "#4e9a06" ("htm" "html" "xhtml")) + (dired-rainbow-define xml "DarkGreen" ("xml" "xsd" "xsl" "xslt" "wsdl")) + + (dired-rainbow-define document "#fce94f" ("doc" "docx" "odt" "pdb" "pdf" "ps" "rtf")) + (dired-rainbow-define media "#ce5c00" my-dired-media-files-extensions) + (dired-rainbow-define image "#ff4b4b" ("jpg" "png" "jpeg" "gif")) + + (dired-rainbow-define log "#c17d11" ("log")) + (dired-rainbow-define sourcefile "#fcaf3e" ("py" "c" "cc" "h" "java" "pl" "rb")) + + (dired-rainbow-define executable "#8cc4ff" ("exe" "msi")) + (dired-rainbow-define compressed "#ad7fa8" ("zip" "bz2" "tgz" "txz" "gz" "xz" "z" "Z" "jar" "war" "ear" "rar" "sar" "xpi" "apk" "xz" "tar")) + (dired-rainbow-define packaged "#e6a8df" ("deb" "rpm")) + (dired-rainbow-define encrypted "LightBlue" ("gpg" "pgp"))) + :ensure t) + + (add-to-list 'dired-guess-shell-alist-user (list (regexp-opt my-dired-media-files-extensions) + "vlc")) + + (use-package dired-filter + :ensure t + ) + + (use-package dired-open + :config + (progn + (bind-key "E" 'dired-open-xdg dired-mode-map)) + :ensure t) + + (use-package dired-avfs + :ensure t + :disabled t ; avfs not in Fedora repositories yet + ) + + (require 'dash) + (--each '(dired-do-rename + dired-do-copy + dired-create-directory + wdired-abort-changes) + (eval `(defadvice ,it (after revert-buffer activate) + (revert-buffer)))) + + (defun ravi/dired-guide-key-hook () + (guide-key/add-local-guide-key-sequence "%") + (guide-key/add-local-guide-key-sequence "*") + (guide-key/add-local-guide-key-sequence "/") + (guide-key/add-local-guide-key-sequence ",") + (guide-key/add-local-guide-key-sequence "C-t") + ) + ;; (add-hook 'dired-mode-hook 'ravi/dired-guide-key-hook) + + )) + +(provide 'ravi-init-dired) +;;; ravi-init-dired.el ends here diff --git a/lisp/ravi-init-files.el b/lisp/ravi-init-files.el new file mode 100644 index 0000000..9ac482d --- /dev/null +++ b/lisp/ravi-init-files.el @@ -0,0 +1,159 @@ +;;; ravi-init-files.el --- file-handling + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; File handling + +;;; Code: + +(setq auto-save-list-file-prefix (ravi/emacs-file "past/auto-save-list/.saves-")) +(setq delete-auto-save-files t) +(setq dired-listing-switches "-Flag") +(setq completion-ignored-extensions + (append completion-ignored-extensions + (quote (".bak" ".#*#" ".ps" ".pdf")))) + +;; Auto refresh buffers +(global-auto-revert-mode 1) + +;; Also auto refresh dired, but be quiet about it +(setq global-auto-revert-non-file-buffers t) +(setq global-auto-revert-ignore-modes '(TeX-output-mode)) +(setq auto-revert-verbose nil) + +;; Transparently open compressed files +(auto-compression-mode t) + +;; UTF-8 please +(setq locale-coding-system 'utf-8) ; pretty +(set-terminal-coding-system 'utf-8) ; pretty +(set-keyboard-coding-system 'utf-8) ; pretty +(set-selection-coding-system 'utf-8) ; please +(prefer-coding-system 'utf-8) ; with sugar on top + +(setq history-length 100) +(setq savehist-file (ravi/emacs-file "past/history")) +(savehist-mode 1) +(setq history-delete-duplicates t) + +(require 'saveplace) +(setq-default save-place t) +(setq save-place-file (ravi/emacs-file "past/places")) + +(use-package recentf + :init + (progn + (setq recentf-save-file (ravi/emacs-file "past/recentf")) + (setq recentf-max-saved-items 100) ;; just 20 is too recent + ) + :config + (progn + (add-to-list 'recentf-exclude "/COMMIT_EDITMSG$") + (add-to-list 'recentf-exclude "/kmail[[:alnum:]]*\\.tmp$") + (add-to-list 'recentf-exclude "/elpa/.*/*-autoloads.el$") + )) + +(require 'uniquify) +(setq uniquify-buffer-name-style 'post-forward) +(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified +(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers + +(setq minibuffer-completion-confirm t) +(setq find-file-confirm-nonexistent-file t) +(setq find-file-visit-truename t) + +;; Automatic loading of file trees +(defun ravi-check-dir-accessible-p (name) + "Check whether NAME is accessible as a directory" + (let* ((topname (file-name-as-directory name)) + (name-exists (and (file-exists-p topname) + (file-directory-p topname) + (file-accessible-directory-p topname) + topname))) + name-exists + )) + +(defun ravi-filecache-add-tree (root recursive simple) + "Add list of directories to filecache for easy opening. +ROOT is the root of the tree to be added. RECURSIVE is a list of +relative paths whose subdirectories are added recursively, while +relative paths in SIMPLE are added non-recursively. If a path does +not exist, it is not added to the filecache." + + (let ((topname (ravi-check-dir-accessible-p root)) + (dirval nil)) + (when topname + (dolist (dir recursive) + (setq dirval (ravi-check-dir-accessible-p + (expand-file-name dir topname))) + (and dirval + (file-cache-add-directory-recursively dirval))) + (dolist (dir simple) + (setq dirval (ravi-check-dir-accessible-p + (expand-file-name dir topname))) + (and dirval + (file-cache-add-directory dirval))) + ))) + +;; Write backup files to own directory +(make-directory (ravi/emacs-file "past/backups/") t) +(setq backup-by-copying t) +(setq backup-directory-alist + `(("." . ,(ravi/emacs-file "past/backups/")) + (,tramp-file-name-regexp nil))) + +;; Make backups of files, even when they're in version control +(setq vc-make-backup-files t) + +;; Git/svn/etc. projects +(use-package projectile + :init + (progn + (use-package pkg-info + :ensure t + ) + (setq projectile-known-projects-file + (ravi/emacs-file "past/projectile-bookmarks.eld")) + ) + :config + (progn + (projectile-global-mode) + + (when (and (boundp 'ravi/use-helm-instead-of-ido) ravi/use-helm-instead-of-ido) + + (setq projectile-completion-system 'helm) + + (use-package helm-projectile + :config + (helm-projectile-on) + :ensure t) + )) + :diminish projectile-mode + :ensure t + ) + +;; Use emacsclient as external editor for kmail +(add-to-list 'auto-mode-alist + (cons (concat temporary-file-directory ".*/kmail[[:alnum:]]*.tmp\\'") 'message-mode)) +(setq gnus-message-highlight-citation t) + +(provide 'ravi-init-files) +;;; ravi-init-files.el ends here diff --git a/lisp/ravi-init-function.el b/lisp/ravi-init-function.el new file mode 100644 index 0000000..673031a --- /dev/null +++ b/lisp/ravi-init-function.el @@ -0,0 +1,144 @@ +;;; ravi-init-function.el --- functionality + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Enable functionality + +;;; Code: + +;; Enable emacs functionality that is disabled by default +(setq disabled-command-function nil) +;(setq enable-recursive-minibuffers t) + +;; Use emacsclient from other programs +(require 'server) +(unless (server-running-p) (server-start)) + +;; Stolen from prelude +(defadvice server-visit-files (before parse-numbers-in-lines (files proc &optional nowait) activate) + "Open file with emacsclient with cursors positioned on requested line. +Most of console-based utilities prints filename in format +'filename:linenumber'. So you may wish to open filename in that format. +Just call: +emacsclient filename:linenumber +and file 'filename' will be opened and cursor set on line 'linenumber'" + (ad-set-arg 0 + (mapcar (lambda (fn) + (let ((name (car fn))) + (if (string-match "^\\(.*?\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?$" name) + (cons + (match-string 1 name) + (cons (string-to-number (match-string 2 name)) + (string-to-number (or (match-string 3 name) "")))) + fn))) files))) + +;; Combined launcher and toggle-maps +(defun ravi/setup-toggle-launcher-map () + (bind-keys :map ctl-x-map + :prefix-map ravi/setup-toggle-launcher-map + :prefix-docstring "Launcher/toggle map" + :prefix "t" + + ;; Toggles + ("c" . column-number-mode) + ("e" . toggle-debug-on-error) + ("f" . auto-fill-mode) + ("l" . toggle-truncate-lines) + ("q" . toggle-debug-on-quit) + ;; Generalized version of `read-only-mode'. + ("r" . dired-toggle-read-only) + ("w" . whitespace-mode) + + ;; Launchers + ("P" . package-list-packages) + ("p" . proced) + ("d" . ediff-buffers) + ("F" . find-dired)) + (autoload 'dired-toggle-read-only "dired" nil t) + ;; (add-to-list 'guide-key/guide-key-sequence "C-x t") + ) +(ravi/setup-toggle-launcher-map) + +;; Start something going on saving a file +(use-package firestarter + :config + (progn + (firestarter-mode 1)) + :diminish firestarter-mode + :ensure t) + +(defun ravi/find-path-name-relative-to-project-root () + "Find path of current buffer file relative to project root" + (interactive) + (let* ((root-dir (and (buffer-file-name) + (or (and (fboundp 'magit-get-top-dir) (magit-get-top-dir)) + (and (fboundp 'vc-root-dir) (vc-root-dir)) + (locate-dominating-file (buffer-file-name) ".git") + (locate-dominating-file (buffer-file-name) dir-locals-file)))) + (relative-name (and root-dir + (file-relative-name (buffer-file-name) root-dir)))) + relative-name)) + +(defun ravi/apply-shell-command-relative-to-project (command-template) + "Apply shell command relative to project + +COMMAND-TEMPLATE should be a string with the following substitutions allowed: + +%p: full path to file name + +%r: path relative to project root + +%f: file name + +%N: unquoted relative path name (should be used extremely carefully) +" + (interactive "sEnter command template: ") + (let* ((path (shell-quote-argument (or (buffer-file-name) ""))) + (rel-name (ravi/find-path-name-relative-to-project-root)) + (rel-path (shell-quote-argument (or rel-name ""))) + (file (shell-quote-argument (file-name-nondirectory (or path "")))) + (cmd (and rel-name + (format-spec command-template + (format-spec-make ?p path ?r rel-path ?f file ?N rel-name))))) + (if cmd + (shell-command cmd) + (if (not (buffer-file-name)) + (message "Not in a file buffer") + (message "Unable to find project root"))))) + +(defvar ravi/shell-command-relative nil + "Variable to set in `dir-locals-file' for use with +`ravi/apply-shell-command-relative-to-project-auto'. See +`ravi/apply-shell-command-relative-to-project' for more +details.") + +(defun ravi/apply-shell-command-relative-to-project-auto () + "Apply shell command relative to project from variable +`ravi/shell-command-relative'. See +`ravi/apply-shell-command-relative-to-project' for more details. +" + (interactive) + (when (and (stringp ravi/shell-command-relative) + (> (length ravi/shell-command-relative) 0)) + (ravi/apply-shell-command-relative-to-project ravi/shell-command-relative))) + +(provide 'ravi-init-function) +;;; ravi-init-function.el ends here diff --git a/lisp/ravi-init-helm.el b/lisp/ravi-init-helm.el new file mode 100644 index 0000000..40e32af --- /dev/null +++ b/lisp/ravi-init-helm.el @@ -0,0 +1,118 @@ +;;; ravi-init-helm.el --- helm initialization -*- lexical-binding: t; -*- + +;; Copyright (C) 2015 + +;; Author: <ravi@nero.lan> +;; Keywords: abbrev + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Initialize helm instead of ido. The code in this file may steal +;; global keybindings that are currently used for ido-mode/smex. + +;;; Code: + +(use-package helm + :bind (("<escape>" . helm-command-prefix) + ("M-x" . helm-M-x) + ("<f1>" . helm-multi-files) + ("<f2>" . helm-find-files) + ("M-y" . helm-show-kill-ring) + ("H-`" . helm-all-mark-rings)) + :init + (progn + (require 'helm-config) + (setq helm-candidate-number-limit 100) + + ;; From https://gist.github.com/antifuchs/9238468 + (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't). + helm-input-idle-delay 0.01 ; this actually updates things + helm-quick-update t + helm-M-x-requires-pattern nil + helm-ff-skip-boring-files t) + + (setq helm-ff-file-name-history-use-recentf t) + + (helm-mode)) + :config + (progn + (unbind-key "C-x c") ; default helm prefix key + (bind-key "<tab>" 'helm-execute-persistent-action helm-map) + (bind-key "H-<tab>" 'helm-select-action helm-map) + + (use-package helm-proc + :commands helm-proc + :init + (progn + (bind-key "q" 'helm-proc helm-command-map)) + :ensure t) + + (use-package helm-git-grep + :commands (helm-git-grep-from-isearch helm-git-grep-from-helm) + :init + (progn + (bind-key "C-c g" 'helm-git-grep-from-helm helm-map) + (bind-key "C-c g" 'helm-git-grep-from-isearch isearch-mode-map)) + :ensure t) + + (use-package helm-ls-git + :bind (("C-x v j" . helm-ls-git-ls)) + :ensure t) + + (use-package helm-ag + :config + (progn + (setq helm-ag-insert-at-point 'symbol)) + :ensure t) + + (use-package helm-dash + :commands (helm-dash + helm-dash-at-point + helm-dash-install-docset + helm-dash-install-user-docset) + :init + (progn + (bind-key "d" 'helm-dash-at-point helm-command-map) + (bind-key "D" 'helm-dash helm-command-map)) + :ensure t)) + :if ravi/use-helm-instead-of-ido + :diminish helm-mode + :ensure t) + +(use-package helm-swoop + :bind (("M-i" . helm-swoop)) + :commands helm-swoop-from-isearch + :init + (progn + (bind-key "M-i" 'helm-swoop-from-isearch isearch-mode-map) + ) + :config + (progn + (bind-key "M-i" 'helm-multi-swoop-all-from-helm-swoop helm-swoop-map) + + ;; Save buffer when helm-multi-swoop-edit complete + (setq helm-multi-swoop-edit-save t) + + ;; If this value is t, split window inside the current window + ;; (setq helm-swoop-split-with-multiple-windows nil) + + ;; Split direcion. 'split-window-vertically or 'split-window-horizontally + ;; (setq helm-swoop-split-direction 'split-window-vertically) + ) + :ensure t) + +(provide 'ravi-init-helm) +;;; ravi-init-helm.el ends here diff --git a/lisp/ravi-init-ido.el b/lisp/ravi-init-ido.el new file mode 100644 index 0000000..0997bd4 --- /dev/null +++ b/lisp/ravi-init-ido.el @@ -0,0 +1,176 @@ +;;; ravi-init-ido.el --- ido initialization + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Ido initialization + +;;; Code: + +;; Almost all of the code below is stolen from jwiegley's .emacs.d. + +(use-package ibuffer + :bind ("C-x C-b" . ibuffer) + :config + (progn + + (use-package ibuffer-vc + :commands ibuffer-vc-set-filter-groups-by-vc-root + :ensure t) + + ;; Switching to ibuffer puts the cursor on the most recent past buffer + (defadvice ibuffer (around ibuffer-point-to-most-recent-but-one activate) () + "Open ibuffer with cursor pointed to most recent buffer name" + (let ((recent-buffer-name (buffer-name (other-buffer (current-buffer) t)))) + ad-do-it + (ibuffer-jump-to-buffer recent-buffer-name))) + + ;; Show version control status in ibuffer + (setq ibuffer-formats + '((mark modified read-only vc-status-mini " " + (name 18 18 :left :elide) + " " + (size 9 -1 :right) + " " + (mode 16 16 :left :elide) + " " + (vc-status 16 16 :left) + " " + filename-and-process))) + + (defun ravi/ibuffer-vc-sort-hook () + (ibuffer-vc-set-filter-groups-by-vc-root) + (unless (eq ibuffer-sorting-mode 'alphabetic) + (ibuffer-do-sort-by-alphabetic))) + (add-hook 'ibuffer-hook 'ravi/ibuffer-vc-sort-hook) + ) + ) + +(use-package ace-jump-buffer + :bind (("M-<f1>" . ace-jump-buffer) + ("C-<f1>" . ace-jump-buffer-other-window) + ("S-<f1>" . ace-jump-projectile-buffers)) + ;; :config + ;; (progn + ;; (bind-key "M-<f1>" 'ido-switch-buffer)) + :ensure t) + +;;;_ , ido + +(use-package ido + :defines (ido-cur-item + ido-require-match + ido-selected + ido-final-text + ido-show-confirm-message) + :if (not ravi/use-helm-instead-of-ido) + :init + (ido-mode 1) + + :config + (progn + (use-package ido-hacks + :config + (ido-hacks-mode 1) + :ensure t + ) + + (use-package flx-ido + :config + (progn + (use-package flx + :ensure t) + (flx-ido-mode 1) + ) + :ensure t + ) + (setq ido-use-filename-at-point 'guess) + (setq ido-use-virtual-buffers t) + (setq ido-create-new-buffer 'always) + + (use-package ido-ubiquitous + :config + (ido-ubiquitous-mode t) + :ensure t + ) + + (use-package ido-vertical-mode + :config + (ido-vertical-mode 1) + :ensure t + ) + + (defun ido-smart-select-text () + "Select the current completed item. Do NOT descend into directories." + (interactive) + (when (and (or (not ido-require-match) + (if (memq ido-require-match + '(confirm confirm-after-completion)) + (if (or (eq ido-cur-item 'dir) + (eq last-command this-command)) + t + (setq ido-show-confirm-message t) + nil)) + (ido-existing-item-p)) + (not ido-incomplete-regexp)) + (when ido-current-directory + (setq ido-exit 'takeprompt) + (unless (and ido-text (= 0 (length ido-text))) + (let ((match (ido-name (car ido-matches)))) + (throw 'ido + (setq ido-selected + (if match + (replace-regexp-in-string "/\\'" "" match) + ido-text) + ido-text ido-selected + ido-final-text ido-text))))) + (exit-minibuffer))) + + (add-hook 'ido-minibuffer-setup-hook + #'(lambda () + (bind-key "<return>" 'ido-smart-select-text + ido-file-completion-map))) + + (defun ido-switch-buffer-tiny-frame (buffer) + (interactive (list (ido-read-buffer "Buffer: " nil t))) + (with-selected-frame + (make-frame '((width . 80) + (height . 22) + (left-fringe . 0) + (right-fringe . 0) + (vertical-scroll-bars . nil) + (unsplittable . t) + (has-modeline-p . nil) + ;;(background-color . "grey80") + (minibuffer . nil))) + (switch-to-buffer buffer) + (set (make-local-variable 'mode-line-format) nil))) + + (bind-key "C-x 5 t" 'ido-switch-buffer-tiny-frame))) + +(use-package smex + :init + (global-set-key [remap execute-extended-command] 'smex) + :if (not ravi/use-helm-instead-of-ido) + :ensure t + ) + +(provide 'ravi-init-ido) +;;; ravi-init-ido.el ends here diff --git a/lisp/ravi-init-insertion.el b/lisp/ravi-init-insertion.el new file mode 100644 index 0000000..e75c414 --- /dev/null +++ b/lisp/ravi-init-insertion.el @@ -0,0 +1,155 @@ +;;; ravi-init-insertion.el --- inserting text + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Automatic text insertion + +;;; Code: + +(require 'autoinsert) +(auto-insert-mode) + +(use-package yasnippet + :init + (progn + (setq yas-snippet-dirs + `(,(ravi/emacs-file "snippets") + yas-installed-snippets-dir) + ) + ) + :config + (progn + (yas-global-mode 1) + + ;; No dropdowns + (setq yas/prompt-functions '(yas/ido-prompt yas/completing-prompt)) + + ;; Wrap around region + (setq yas/wrap-around-region t) + + ;; Automatically create throw-away snippets + (use-package auto-yasnippet + :bind (("C-<f4>" . aya-create) + ("<f4>" . aya-expand)) + :ensure t) + ) + :ensure t + :diminish yas-minor-mode + ) + +;; Default completion (some day via "M-/") +(require 'hippie-exp) +(setq hippie-expand-try-functions-list + '(yas/hippie-try-expand + try-expand-dabbrev + try-expand-dabbrev-all-buffers + try-expand-dabbrev-from-kill + try-complete-file-name-partially + try-complete-file-name + try-expand-all-abbrevs + ) + ) + +(use-package company + :init + (progn + (add-hook 'after-init-hook 'global-company-mode)) + :config + (progn + (setq company-tooltip-flip-when-above t + company-idle-delay 0.1 + company-show-numbers t + company-tooltip-align-annotations t + company-require-match nil + company-minimum-prefix-length 2 + company-occurrence-weight-function 'company-occurrence-prefer-any-closest + company-dabbrev-downcase nil) + (defun ravi/complete-or-indent () + (interactive) + (if (company-manual-begin) + (company-complete-common) + (indent-according-to-mode))) + (bind-key "\t" 'ravi/complete-or-indent) + + (bind-keys :map company-active-map + ("C-n" . company-select-next) + ("C-p" . company-select-previous) + ;; Swap filter and search since filter is more useful + ("C-s" . company-filter-candidates) + ("C-M-s" . company-search-candidates)) + (bind-keys :map company-search-map + ("C-n" . company-select-next) + ("C-p" . company-select-previous)) + + (use-package company-c-headers + :init + (progn + (add-to-list 'company-backends 'company-c-headers)) + :config + (progn + (defun ravi/get-default-include-paths () + (let* ((gcc-out (shell-command-to-string "g++ -E -x c++ - -v < /dev/null")) + (gcc-list-match (string-match "#include <...> search starts here:\n\\(.*\\(?:\n.*\\)*?\\)End of search list.\n" gcc-out)) + (combined-list (match-string 1 gcc-out)) + ;; Need the following rigamarole to handle paths with spaces in them + (path-list-with-spaces (and combined-list (split-string combined-list "\n" t))) + (path-list (and path-list-with-spaces (mapcar 's-trim-left path-list-with-spaces)))) + path-list)) + (mapc (lambda (dir) (add-to-list 'company-c-headers-path-system dir)) (ravi/get-default-include-paths)) + ) + :ensure t) + + (use-package company-quickhelp + :config + (progn + (company-quickhelp-mode 1) + ;; Enable company-quickhelp only when company-mode is active + (unbind-key "M-h" company-quickhelp-mode-map) + (bind-key "M-h" 'company-quickhelp-manual-begin company-active-map)) + :ensure t) + + (use-package company-statistics + :init + (setq company-statistics-file (expand-file-name "company-statistics-cache.el" + (ravi/emacs-file "past"))) + :config + (progn + (company-statistics-mode)) + :ensure t) + + ;; Get rid of company-semantic as it interferes with clang-based backends + (setq company-backends (delete 'company-semantic company-backends)) + ;; Get rid of company-clang since it is too noisy at this point + (setq company-backends (delete 'company-clang company-backends)) + + (require 'company-yasnippet) + (defun ravi/company-to-yasnippet () + (interactive) + (company-abort) + (call-interactively 'company-yasnippet)) + (bind-key "<backtab>" 'ravi/company-to-yasnippet company-active-map) + (bind-key "<backtab>" 'company-yasnippet)) + + :diminish company-mode + :ensure t) + +(provide 'ravi-init-insertion) +;;; ravi-init-insertion.el ends here diff --git a/lisp/ravi-init-layouts.el b/lisp/ravi-init-layouts.el new file mode 100644 index 0000000..f6199ce --- /dev/null +++ b/lisp/ravi-init-layouts.el @@ -0,0 +1,57 @@ +;;; ravi-init-layouts.el --- layouts + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Uses undocumented emacs API + +;;; Code: + +(require 'quail) + +(quail-define-package + "english-prog" "English programmer" "EN-P" t + "English programmer's keyboard." + nil t nil nil t nil nil nil nil nil t) + +(quail-define-rules + ("!" ?1) + ("@" ?2) + ("#" ?3) + ("$" ?4) + ("%" ?5) + ("^" ?6) + ("&" ?7) + ("*" ?8) + ("(" ?9) + (")" ?0) + ("1" ?!) + ("2" ?@) + ("3" ?#) + ("4" ?$) + ("5" ?%) + ("6" ?^) + ("7" ?&) + ("8" ?*) + ("9" ?\() + ("0" ?\))) + +(provide 'ravi-init-layouts) +;;; ravi-init-layouts.el ends here diff --git a/lisp/ravi-init-maps.el b/lisp/ravi-init-maps.el new file mode 100644 index 0000000..ae4eac6 --- /dev/null +++ b/lisp/ravi-init-maps.el @@ -0,0 +1,58 @@ +;;; ravi-init-maps.el --- extra keys -*- lexical-binding: t; -*- + +;; Copyright (C) 2015 Ravi R Kiran + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Extra keybindings + +(use-package hydra + :ensure t) + +(use-package operate-on-number + :bind (("M-g M-d" . hydra-operate-on-number/body)) + :config + (progn + (defhydra hydra-operate-on-number () + " + Arithmetic operations: + - * / + Remainder: \\ + Exponent: \\^ + Arithmetic shift: < > + Base conversion: b o x X # + Format: %%%% + " + ("+" apply-operation-to-number-at-point) + ("-" apply-operation-to-number-at-point) + ("*" apply-operation-to-number-at-point) + ("/" apply-operation-to-number-at-point) + ("\\" apply-operation-to-number-at-point) + ("^" apply-operation-to-number-at-point) + ("<" apply-operation-to-number-at-point) + (">" apply-operation-to-number-at-point) + ("b" apply-operation-to-number-at-point :exit t) + ("o" apply-operation-to-number-at-point :exit t) + ("x" apply-operation-to-number-at-point :exit t) + ("X" apply-operation-to-number-at-point :exit t) + ("#" apply-operation-to-number-at-point :exit t) + ("%" apply-operation-to-number-at-point :exit t))) + :ensure t) + +(provide 'ravi-init-maps) +;;; ravi-init-maps.el ends here diff --git a/lisp/ravi-init-marks.el b/lisp/ravi-init-marks.el new file mode 100644 index 0000000..803b2cb --- /dev/null +++ b/lisp/ravi-init-marks.el @@ -0,0 +1,78 @@ +;;; ravi-init-marks.el --- Handling the mark + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Handling the mark + +;;; Code: + +;; Show active region +(transient-mark-mode 1) +(make-variable-buffer-local 'transient-mark-mode) +(put 'transient-mark-mode 'permanent-local t) +(setq-default transient-mark-mode t) + +;; When popping the mark, continue popping until the cursor actually moves +;; Also, if the last command was a copy - skip past all the expand-region cruft. +;; Stolen from Magnar Sveen's emacs.d on github. +(defadvice pop-to-mark-command (around ensure-new-position activate) + (let ((p (point))) + (when (eq last-command 'save-region-or-current-line) + ad-do-it + ad-do-it + ad-do-it) + (dotimes (i 10) + (when (= p (point)) ad-do-it)))) + +;; Allow mark-based navigation even in transient-mark-mode; see +;; http://www.masteringemacs.org/articles/2010/12/22/fixing-mark-commands-transient-mark-mode/ + +(defun ravi/push-mark-no-activate () + "Pushes `point' to `mark-ring' and does not activate the region +Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled" + (interactive) + (push-mark (point) t nil) + (message "Pushed mark to ring")) +(bind-key "C-`" 'ravi/push-mark-no-activate) + +(defun ravi/jump-to-mark () + "Jumps to the local mark, respecting the `mark-ring' order. +This is the same as using \\[set-mark-command] with the prefix argument." + (interactive) + (set-mark-command 1)) +(bind-key "M-`" 'ravi/jump-to-mark) + +; Prevents C-x C-x from highlighting region +(defun ravi/exchange-point-and-mark-no-activate () + "Identical to \\[exchange-point-and-mark] but will not activate the region." + (interactive) + (exchange-point-and-mark) + (deactivate-mark nil)) +(define-key global-map [remap exchange-point-and-mark] 'ravi/exchange-point-and-mark-no-activate) + +(use-package browse-kill-ring + :config (browse-kill-ring-default-keybindings) + :ensure t + :if (not ravi/use-helm-instead-of-ido) + ) + +(provide 'ravi-init-marks) +;;; ravi-init-marks.el ends here diff --git a/lisp/ravi-init-mu.el b/lisp/ravi-init-mu.el new file mode 100644 index 0000000..2f21a0b --- /dev/null +++ b/lisp/ravi-init-mu.el @@ -0,0 +1,218 @@ +;;; ravi-init-mu.el --- mail + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Set up mu4e conditionally +;; - actual account information should be in local.el +;; - requires definitions of ravi/mu4e-account-alist + +;;; Code: + +(defvar ravi/use-mu-for-email nil + "Use mu for email") +(defvar ravi/mu4e-account-alist nil + "An alist containing account information for all accounts") +(defvar ravi/mu4e-update-interval 1800 ; 30 minutes + "Basic update interval; all other update intervals are multiples") + +(setq message-citation-line-format "On %a %Y-%m-%d %l:%M:%S%p %Z, %f wrote:" + message-citation-line-function 'message-insert-formatted-citation-line) + +(when ravi/use-mu-for-email + (use-package mu4e + :load-path (lambda () (ravi/emacs-file "site-lisp/mu/mu4e")) + :commands mu4e + :init + (progn + (add-to-list 'Info-additional-directory-list (ravi/emacs-file "site-lisp/mu/mu4e")) + (unless ravi/mu4e-account-alist (error "Email account list not found")) + (defun ravi/switch-to-mu4e () + (interactive) + (let ((buf (or (and (boundp 'mu4e~headers-buffer-name) + (get-buffer mu4e~headers-buffer-name)) + (get-buffer "*mu4e-main*")))) + (if buf + (if (get-buffer-window buf t) + (select-window (get-buffer-window buf t)) + (switch-to-buffer buf)) + (mu4e)))) + (bind-key "C-'" 'ravi/switch-to-mu4e) + ) + :config + (progn + + ;; Basic identity for sending mail + (require 'smtpmail) + (setq send-mail-function 'smtpmail-send-it) + (setq message-send-mail-function 'smtpmail-send-it) + + ;; Set up defaults from first account on the list + ;; user-full-name + ;; smtp-local-domain + ;; user-mail-address + ;; smtpmail-smtp-user + ;; smtpmail-smtp-server + ;; mu4e-sent-folder + ;; mu4e-trash-folder + ;; mu4e-refile-folder + (let* ((account (caar ravi/mu4e-account-alist)) + (account-vars (cdr (assoc account ravi/mu4e-account-alist)))) + (if account-vars + (mapc #'(lambda (var) + (set (car var) (cadr var))) + account-vars) + (error "No email account found"))) + + ;; Choose correct SMTP identity wisely + (defun ravi/mu4e-set-account () + "Set the account for composing a message." + (let* ((account + (if mu4e-compose-parent-message + (let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir))) + (string-match "/\\(.*?\\)/" maildir) + (match-string 1 maildir)) + (if (= (length ravi/mu4e-account-alist) 1) + (caar ravi/mu4e-account-alist) + (completing-read (format "Compose with account: (%s) " + (mapconcat #'(lambda (var) (car var)) + ravi/mu4e-account-alist "/")) + (mapcar #'(lambda (var) (car var)) ravi/mu4e-account-alist) + nil t nil nil (caar ravi/mu4e-account-alist))))) + (account-vars (cdr (assoc account ravi/mu4e-account-alist)))) + (if account-vars + (mapc #'(lambda (var) + (set (car var) (cadr var))) + account-vars) + (error "No email account found")))) + (add-hook 'mu4e-compose-pre-hook 'ravi/mu4e-set-account) + + (setq mu4e-compose-dont-reply-to-self t) + (defun ravi/set-self-addresses () + (setq mu4e-user-mail-address-list (list user-mail-address))) + (add-hook 'mu4e-compose-pre-hook 'ravi/set-self-addresses) + + ;; Use async method of sending email, if possible + (use-package async + :config + (progn + (require 'smtpmail-async) + (setq send-mail-function 'async-smtpmail-send-it) + (setq message-send-mail-function 'async-smtpmail-send-it) + ) + :ensure t + ) + + ;; Basic mu4e configuration parameters + (setq mu4e-mu-binary (ravi/emacs-file "site-lisp/mu/mu/mu")) + (setq mu4e-maildir "~/.mail") + + ;; Poll accounts only as often as necessary + (defvar ravi/mu4e-get-mail-attempts 0 + "Number of attempts so far to get mail") + (defun ravi/check-whether-to-get-mail-for-account (account-info) + (let* ((account-interval (assq 'ravi/account-update-interval account-info)) + (account-update-interval (if account-interval (cadr account-interval) 1))) + (if (= (% ravi/mu4e-get-mail-attempts account-update-interval) 0) + (concat " " (car account-info)) + ""))) + (defun ravi/get-mu4e-get-mail-command () + "Figure out arguments to mbsync" + (let ((ravi/all-channels (mapconcat 'ravi/check-whether-to-get-mail-for-account + ravi/mu4e-account-alist ""))) + (setq ravi/mu4e-get-mail-attempts (1+ ravi/mu4e-get-mail-attempts)) + (if (= (length ravi/all-channels) 0) + "true" ;; do nothing command + (concat (ravi/emacs-file "site-lisp/isync/src/mbsync") " -q -q" ravi/all-channels) + ))) + (add-hook 'mu4e-update-pre-hook + (lambda () + (setq mu4e-get-mail-command (ravi/get-mu4e-get-mail-command)))) + ;(message "%d: '%s'" ravi/mu4e-get-mail-attempts (ravi/get-mu4e-get-mail-command)) + ;; Default update command if something goes wrong + (setq mu4e-get-mail-command (concat (ravi/emacs-file "site-lisp/isync/src/mbsync") " -a -q -q")) + (setq mu4e-update-interval ravi/mu4e-update-interval) + (setq mu4e-change-filenames-when-moving t) + + ;; User interface + (setq mu4e-html-renderer 'w3m) + (setq mu4e-html2text-command "w3m -T text/html") + (setq mu4e-view-show-images t) + (setq mu4e-view-show-addresses t) + (when (boundp 'ravi/mu4e-maildir-shortcuts) + (setq mu4e-maildir-shortcuts ravi/mu4e-maildir-shortcuts)) + + (add-to-list 'mu4e-view-actions + '("ViewInBrowser" . mu4e-action-view-in-browser) t) + + ;; Show summary of all folders + (use-package mu4e-maildirs-extension + :config + (progn + (setq mu4e-maildirs-extension-count-command-format + (concat mu4e-mu-binary " find %s maildir:%s --fields 'i' | wc -l")) + (mu4e-maildirs-extension)) + :ensure t) + + ;; Display desktop notifications + (use-package mu4e-alert + :config + (progn + (mu4e-alert-set-default-style 'libnotify) + (mu4e-alert-disable-mode-line-display) + (mu4e-alert-enable-notifications)) + :ensure t) + + (setq message-citation-line-function 'message-insert-formatted-citation-line) + (setq message-kill-buffer-on-exit t) + (setq mu4e-compose-signature-auto-include nil) + (bind-key "C-c C-d" 'ravi/erase-from-point mu4e-compose-mode-map) + + ;; Allow attaching files from dired + (require 'gnus-dired) + ;; make the `gnus-dired-mail-buffers' function also work on + ;; message-mode derived modes, such as mu4e-compose-mode + (defun gnus-dired-mail-buffers () + "Return a list of active message buffers." + (let (buffers) + (save-current-buffer + (dolist (buffer (buffer-list t)) + (set-buffer buffer) + (when (and (derived-mode-p 'message-mode) + (null message-sent-message-via)) + (push (buffer-name buffer) buffers)))) + (nreverse buffers))) + (setq gnus-dired-mail-mode 'mu4e-user-agent) + (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) + + (when ravi/use-helm-instead-of-ido + (add-to-list 'helm-find-files-actions + '("Attach files for mu4e" . helm-mu4e-attach) t) + + (defun helm-mu4e-attach (_file) + (gnus-dired-attach (helm-marked-candidates)))) + + (imagemagick-register-types) + ) + ) + ) + +(provide 'ravi-init-mu) +;;; ravi-init-mu.el ends here diff --git a/lisp/ravi-init-navigation.el b/lisp/ravi-init-navigation.el new file mode 100644 index 0000000..569e164 --- /dev/null +++ b/lisp/ravi-init-navigation.el @@ -0,0 +1,404 @@ +;;; ravi-init-navigation.el --- navigation utilities + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Buffer navigation utilities + +;;; Code: + +(use-package region-bindings-mode + :config + (progn + (region-bindings-mode-enable) + (bind-key "f" 'forward-word region-bindings-mode-map) + (bind-key "b" 'backward-word region-bindings-mode-map) + + ;; HJKL cluster to replace arrow keys + (bind-key "h" 'backward-char region-bindings-mode-map) + (bind-key "l" 'forward-char region-bindings-mode-map) + (bind-key "k" 'previous-line region-bindings-mode-map) + (bind-key "j" 'next-line region-bindings-mode-map) + + ;; Most of the time, we mark regions to copy + (bind-key "w" 'kill-ring-save region-bindings-mode-map) + ) + :ensure t + ) + +(use-package avy + :bind (("M-h" . avy-goto-word-1) + ("M-H" . avy-goto-word-0) + ("M-g g" . avy-goto-line) + ("M-g M-g" . avy-goto-line)) + :config + (progn + (setq avy-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l ?r ?u ?t ?y ?w ?o ?e ?i)) + (setq avy-style 'at-full + avy-background t)) + :ensure t) + +(use-package ace-isearch + :config + (progn + (setq ace-isearch-use-ace-jump nil) ; prefer dedicated key for ace-jump + (global-ace-isearch-mode +1)) + :disabled t ; helm-swoop has a dedicated key now + :ensure t) + +(use-package jump-char + :bind (("M-m" . jump-char-forward)) + :ensure t + ) + +(use-package imenu-anywhere + :bind ("s-." . imenu-anywhere) + :ensure t + ) + +(use-package expand-region + :config + (progn + (bind-key "C-=" 'er/expand-region)) + :ensure t + ) + +(use-package multiple-cursors + :bind (("C-S-c C-S-c" . mc/edit-lines) + + ("C->" . mc/mark-next-like-this) + ("C-<" . mc/mark-previous-like-this) + ("C-c C-<" . mc/mark-all-like-this)) + :init + (progn + (setq mc/list-file (ravi/emacs-file "past/mc-lists.el")) + (bind-key "a" 'mc/mark-all-like-this region-bindings-mode-map) + (bind-key "p" 'mc/mark-previous-like-this region-bindings-mode-map) + (bind-key "n" 'mc/mark-next-like-this region-bindings-mode-map) + (bind-key "m" 'mc/mark-more-like-this-extended region-bindings-mode-map) + ) + :ensure t + ) + +(use-package fold-this + :commands fold-this + :config + (progn + (bind-key "t" 'fold-this region-bindings-mode-map)) + :ensure t + ) + +(use-package indirect + :commands indirect-region + :config + (progn + (bind-key "I" 'indirect-region region-bindings-mode-map)) + ) + +(use-package visual-regexp + :bind (("C-c r" . vr/replace) + ("C-c q" . vr/query-replace) + ("C-c m" . vr/mc-mark)) + :ensure t + ) + +(use-package god-mode + :bind (("<escape>" . god-local-mode)) + :disabled t ; less useful than I thought + :ensure t + ) + +(bind-key "<M-f6>" 'ff-find-other-file) + +(setq compilation-scroll-output 'first-error) + +(use-package smartparens + :commands (smartparens-mode show-smartparens-mode) + :init + (show-smartparens-global-mode 1) + :config + (progn + (require 'smartparens-config) + (add-hook 'emacs-lisp-mode-hook 'smartparens-mode) + (add-hook 'emacs-lisp-mode-hook 'sp-use-smartparens-bindings) + (use-package minor-mode-hack :ensure t) + (raise-minor-mode-map-alist 'region-bindings-mode) + ) + :ensure t + ) + +(use-package corral + :bind (("M-9" . corral-parentheses-backward) + ("M-0" . corral-parentheses-forward) + ("M-[" . corral-brackets-backward) + ("M-]" . corral-brackets-forward) + ("M-{" . corral-braces-backward) + ("M-}" . corral-braces-forward) + ("M-\"" . corral-double-quotes-backward)) + :config + (progn + (setq corral-preserve-point t)) + :ensure t) + +;; Marking and moving lines + +(defun ravi/pull-up-a-line() + "Pull up the next line" + (interactive) + (join-line -1) + ) + +(bind-key "M-j" 'ravi/pull-up-a-line) + +(use-package move-lines + :bind (("<S-down>" . move-lines-down) + ("<S-up>" . move-lines-up) + ) + ) + +;; From Kyle Sherman's comment at +;; http://emacs-fu.blogspot.com/2010/01/duplicating-lines-and-commenting-them.html +;; \todo Make this work someday with regions too. +(defun ravi/kyle-sherman-duplicate-line (&optional comment line) + "Duplicate the line containing the point. +\nIf COMMENT is non-nil, also comment out the original line. + If LINE is non-nil, duplicate that line instead." + (interactive "P") + (let ((col (current-column))) + (save-excursion + (when line + (goto-line line)) + (let ((line (buffer-substring (point-at-bol) (point-at-eol)))) + (when comment + (comment-region (point-at-bol) (point-at-eol))) + (goto-char (point-at-eol)) + (if (eobp) + (newline) + (forward-line 1)) + (open-line 1) + (insert line))) + (forward-line 1) + (move-to-column col))) + +;; C-: duplicates line, C-u C-: comments first line +(bind-key "C-:" 'ravi/kyle-sherman-duplicate-line) + +(defun ravi/back-to-indentation-or-beginning () (interactive) + (if (bolp) (back-to-indentation) + (beginning-of-line))) +(bind-key "C-a" 'ravi/back-to-indentation-or-beginning) + +(defun ravi/Fuco-point-in-comment () + "Determine if the point is inside a comment" + (interactive) + (let ((syn (syntax-ppss))) + (and (nth 8 syn) + (not (nth 3 syn))))) + +(defun ravi/Fuco-end-of-code-or-line+ (arg) + "Move to the end of line. If already there, move to the end of code. + + Comments are recognized in any mode that sets syntax-ppss properly." + (interactive "P") + (let ((eoc (save-excursion + (move-end-of-line arg) + (while (ravi/Fuco-point-in-comment) + (backward-char)) + (skip-chars-backward " \t") + (point)))) + (cond ((eolp) + (move-end-of-line arg) + (while (ravi/Fuco-point-in-comment) + (backward-char)) + (skip-chars-backward " \t")) + (t + (move-end-of-line arg))))) +(bind-key "C-e" 'ravi/Fuco-end-of-code-or-line+) + +;; Use current line for region-based commands if no region selected +(use-package whole-line-or-region + :config + (progn + (defun turn-on-whole-line-or-region-mode() + (interactive) + (whole-line-or-region-mode 1) + ) + (add-hook 'prog-mode-hook 'turn-on-whole-line-or-region-mode) + ) + :diminish whole-line-or-region-mode + :ensure t + ) + +;; This must be after enabling whole-line-or-region +(use-package easy-kill + :config + (progn + (global-set-key [remap kill-ring-save] 'easy-kill) + (global-set-key [remap whole-line-or-region-kill-ring-save] 'easy-kill)) + :ensure t) + +;; grep and friends + +(use-package wgrep + :ensure t) + +(if (executable-find "ag") + ;; Prefer the silver-searcher if available + (use-package ag + :bind (("H-g" . ag) + ("H-G" . ag-files) + ("M-s g" . grep)) + :config + (progn + (setq ag-highlight-search t) + (setq ag-reuse-buffers t) + (use-package wgrep-ag + :ensure t)) + :ensure t) + ;; Use grep if ag is not available on the system + (use-package grep + :bind (("H-g" . grep)))) + +(use-package highlight-symbol + :bind (("H-n" . ravi/highlight-symbol-next) + ("H-N" . highlight-symbol-prev) + ("H-s" . highlight-symbol-query-replace)) + :commands highlight-symbol-next + :config + (progn + (defvar ravi/highlight-symbol-overlay-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "k") 'highlight-symbol-prev) + (define-key map (kbd "j") 'highlight-symbol-next) + (define-key map (kbd "s") 'highlight-symbol-query-replace) + (define-key map (kbd "o") 'highlight-symbol-occur) + map)) + (defun ravi/highlight-symbol-next () + (interactive) + (highlight-symbol-next) + (set-temporary-overlay-map ravi/highlight-symbol-overlay-map t)) + ) + :disabled t ; M-s . suffices for my needs + :ensure t + ) + +(let ((ad-redefinition-action 'accept)) + (use-package color-moccur + :commands (isearch-moccur isearch-all) + :bind ("M-s O" . moccur) + :init + (progn + (bind-key "M-o" 'isearch-moccur isearch-mode-map) + (bind-key "M-O" 'isearch-moccur-all isearch-mode-map)) + + :config + (use-package moccur-edit) + + :ensure t + ) + ) + +;; Delete via isearch +(defun zap-to-isearch (rbeg rend) + "Kill the region between the mark and the closest portion of + the isearch match string. The behaviour is meant to be analogous + to zap-to-char; let's call it zap-to-isearch. The deleted region + does not include the isearch word. This is meant to be bound only + in isearch mode. + + The point of this function is that oftentimes you want to delete + some portion of text, one end of which happens to be an active + isearch word. The observation to make is that if you use isearch + a lot to move the cursor around (as you should, it is much more + efficient than using the arrows), it happens a lot that you could + just delete the active region between the mark and the point, not + include the isearch word." + (interactive "r") + (when (not mark-active) + (error "Mark is not active")) + (let* ((isearch-bounds (list isearch-other-end (point))) + (ismin (apply 'min isearch-bounds)) + (ismax (apply 'max isearch-bounds)) + ) + (if (< (mark) ismin) + (kill-region (mark) ismin) + (if (> (mark) ismax) + (kill-region ismax (mark)) + (error "Internal error in isearch kill function."))) + (isearch-exit) + )) +(bind-key "M-z" 'zap-to-isearch isearch-mode-map) + +;; Exit isearch at the beginning +(defun isearch-exit-other-end (rbeg rend) + "Exit isearch, but at the other end of the search string. + This is useful when followed by an immediate kill." + (interactive "r") + (isearch-exit) + (goto-char isearch-other-end)) +(bind-key "<C-return>" 'isearch-exit-other-end isearch-mode-map) + +;; Search the web +(use-package webjump + :bind ("C-x g" . webjump) + :config + (progn + ;; Suggest word at point if possible + (defun webjump-read-string (prompt) + (let* ((prompt (concat prompt (if (word-at-point) (concat " (default: " (word-at-point) ")")) ": ")) + (input (read-string prompt))) + (if (webjump-null-or-blank-string-p input) (word-at-point) input))) + + ;; C++ reference + (add-to-list 'webjump-sites + '("cpp" . [simple-query "en.cppreference.com" + "http://en.cppreference.com/mwiki/index.php?title=Special:Search&search=" + ""])) + ) + ) + +(use-package anzu + :demand t + :bind (("C-%" . anzu-query-replace) + ("C-M-%" . anzu-query-replace-regexp)) + :config + (progn + (global-anzu-mode)) + :diminish anzu-mode + :ensure anzu) + +(use-package swoop + :bind (("M-s s" . hydra-swoop/body)) + :config + (progn + (defhydra hydra-swoop () + "swoop" + ("s" swoop) + ("m" swoop-multi "multi") + ("r" swoop-pcre "pcre") + ("b" swoop-back-to-last-position "back"))) + :ensure t) + +(require 'midnight) + +;; to do: add zeal-at-point + +(provide 'ravi-init-navigation) +;;; ravi-init-navigation.el ends here diff --git a/lisp/ravi-init-org.el b/lisp/ravi-init-org.el new file mode 100644 index 0000000..523f564 --- /dev/null +++ b/lisp/ravi-init-org.el @@ -0,0 +1,62 @@ +;;; ravi-init-org.el --- org initialization + +;; Copyright (C) 2014 + +;; Author: <ravi@nero> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Org mode initialization + +;;; Code: + +(use-package org + :ensure org-plus-contrib + :mode ("\\.org\\'" . org-mode) + + ;; The following lines are always needed. Choose your own keys. + :bind (("C-c l" . org-store-link) + ("H--" . org-agenda)) + :config + (progn + (use-package htmlize :ensure t) + (use-package ox-reveal + :config + (progn + (setq org-reveal-slide-number nil) + (setq org-reveal-theme "night") + (setq org-reveal-transition "linear") + (setq org-reveal-mathjax t) + (setq org-reveal-mathjax-url "./MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML")) + :ensure t) + (use-package ox-rst :ensure t) + (use-package ox-impress-js :ensure t) + + (setq org-src-fontify-natively t) + (setq org-modules (quote (org-bbdb + org-bibtex + org-crypt + org-gnus + org-id + org-info))) + (setq org-use-speed-commands t) + ) + ) + +(provide 'ravi-init-org) +;;; ravi-init-org.el ends here + diff --git a/lisp/ravi-init-python.el b/lisp/ravi-init-python.el new file mode 100644 index 0000000..7993092 --- /dev/null +++ b/lisp/ravi-init-python.el @@ -0,0 +1,164 @@ +;;; ravi-init-python.el --- python support + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Python programming setup + +;;; Code: + +(use-package python + :mode ("\\.py\\'" . python-mode) + :commands python-shell-switch-to-shell + :config + (progn + + (add-hook 'python-mode-hook 'ravi/python-mode-hook) + (defun ravi/python-mode-hook() + ;; Set ipython as our interpreter + (setq python-shell-interpreter "ipython" + python-shell-interpreter-args "--pylab" + python-shell-prompt-regexp "In \\[[0-9]+\\]: " + python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: " + python-shell-completion-setup-code + "from IPython.core.completerlib import module_completion" + python-shell-completion-module-string-code + "';'.join(module_completion('''%s'''))\n" + python-shell-completion-string-code + "';'.join(get_ipython().Completer.all_completions('''%s'''))\n" + ) + + ;; For ipython 0.10, uncomment the following: + ;; (setq python-shell-completion-string-code + ;; "';'.join(__IP.complete('''%s'''))\n" + ;; python-shell-completion-module-string-code "" + ;; ) + + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("Python 2" "NumPy"))) + + ;; I'd really prefer indentation by 2 spaces, but have too much existing + ;; python code with indentation at 4 spaces. + (setq python-indent-offset 4) + ) + + (bind-key "<return>" 'newline-and-indent python-mode-map) + + ;; We no longer use smart-tab-mode + ;(add-to-list 'smart-tab-disabled-major-modes 'inferior-python-mode) + + (define-auto-insert "\\.py\\'" 'ravi/auto-insert-py) + (defun ravi/auto-insert-py () + (progn + (insert "#!/usr/bin/env python\n\n") + ) + ) + + (use-package virtualenvwrapper + :config + (progn + (venv-initialize-interactive-shells) + (venv-initialize-eshell) + (setq venv-location (expand-file-name "~/usr/local/venv/")) + ) + + :ensure t + ) + + ;; Use jedi.el for code completion plus documentation browsing. + ;; The main issue is that this requires both python-side and emacs-side + ;; support, but the python-side support cannot be installed as a package + ;; from MELPA. Fedora does not provide python-epc as an RPM either. We + ;; work around it by adding sexpdata, jedi and python-epc as git submodules. + (use-package jedi-core + :config + (progn + (defun ravi/jedi-setup () + (let ((basic-server-args (list + "--sys-path" (ravi/emacs-file "site-lisp/python-epc") + "--sys-path" (ravi/emacs-file "site-lisp/sexpdata") + "--sys-path" (ravi/emacs-file "site-lisp/jedi")) + )) + (set (make-local-variable 'jedi:server-args) + (if (and (boundp 'extra-jedi-args) + (listp extra-jedi-args)) + (append basic-server-args extra-jedi-args) + basic-server-args)) + (jedi:setup))) + + ;; Override pos-tip support to automatically delete tooltip + (defun ravi/jedi:tooltip-show (string) + (cond + ((and (memq 'pos-tip jedi:tooltip-method) window-system + (featurep 'pos-tip)) + (pos-tip-show (jedi:string-fill-paragraph string) + 'popup-tip-face nil nil 5)) + ((and (memq 'popup jedi:tooltip-method) + (featurep 'popup)) + (popup-tip string)) + (t (when (stringp string) + (let ((message-log-max nil)) + (message string)))))) + (fset 'jedi:tooltip-show 'ravi/jedi:tooltip-show) + + (defun ravi/python-jedi-hook-installer () + ;; (setq jedi:complete-on-dot t) ; needs auto-complete + (add-hook 'hack-local-variables-hook 'ravi/jedi-setup nil t)) + (add-hook 'python-mode-hook 'ravi/python-jedi-hook-installer) + ) + :ensure t + ) + + (use-package company-jedi + :config + (progn + (add-to-list 'company-backends 'company-jedi)) + :ensure t) + + (use-package sphinx-doc + :config + (progn + (defun ravi/sphinx-doc-setup () + (sphinx-doc-mode 1)) + (add-hook 'python-mode-hook 'ravi/sphinx-doc-setup) + ) + :diminish sphinx-doc-mode + :ensure t) + + (use-package python-docstring + :config + (progn + (defun ravi/python-docstring-mode-setup () + (python-docstring-mode 1)) + (add-hook 'python-mode-hook 'ravi/python-docstring-mode-setup)) + :diminish python-docstring-mode + :ensure t) + + (use-package electric-operator + :config + (progn + (add-hook 'python-mode-hook #'electric-operator-mode)) + ;; :diminish electric-operator + :ensure t) + ) + ) + +(provide 'ravi-init-python) + diff --git a/lisp/ravi-init-repl.el b/lisp/ravi-init-repl.el new file mode 100644 index 0000000..3191bb3 --- /dev/null +++ b/lisp/ravi-init-repl.el @@ -0,0 +1,76 @@ +;;; ravi-init-repl.el --- REPL utilities + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Read-eval-print-loop support + +;;; Code: + +(use-package comint + :defer t + :config + (progn + (bind-key "<up>" 'comint-previous-matching-input-from-input comint-mode-map) + (bind-key "<down>" 'comint-next-matching-input-from-input comint-mode-map) + ) + ) + +(use-package octave-mod + :mode ("\\.m\\'" . octave-mode) + :config + (progn + (defun ravi/octave-shell-switch-to-shell () + "Make sure that `inferior-octave-buffer' exists and is displayed." + (interactive) + (if (get-buffer inferior-octave-buffer) + (pop-to-buffer (get-buffer inferior-octave-buffer)) + (inferior-octave nil))) ) + ) + +(use-package repl-toggle + :config + (progn + (setq rtog/mode-repl-alist '((python-mode . python-shell-switch-to-shell) + (octave-mode . ravi/octave-shell-switch-to-shell) + (emacs-lisp-mode . ielm))) + (setq rtog/goto-buffer-fun 'pop-to-buffer) + (add-hook 'python-mode-hook 'rtog/activate) + (add-hook 'octave-mode-hook 'rtog/activate) + (add-hook 'emacs-lisp-mode-hook 'rtog/activate) + + (defun ravi/repl-toggle-or-compile-dwim () + (interactive) + (if (or rtog/--last-buffer (assoc major-mode rtog/mode-repl-alist)) + (call-interactively 'rtog/toggle-repl) + (call-interactively 'compile-dwim))) + + ; The default keybinding is not great + (unbind-key "C-c C-z" repl-toggle-mode-map) + (bind-key "<f5>" 'ravi/repl-toggle-or-compile-dwim repl-toggle-mode-map) + ) + :diminish repl-toggle-mode + :ensure t) + +;; Calc and friends +(bind-key "H-c" 'calc) + +(provide 'ravi-init-repl) +;;; ravi-init-repl.el ends here diff --git a/lisp/ravi-init-tex.el b/lisp/ravi-init-tex.el new file mode 100644 index 0000000..56545e8 --- /dev/null +++ b/lisp/ravi-init-tex.el @@ -0,0 +1,192 @@ +;;; ravi-init-tex.el --- tex and friends + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; TeX and LaTeX support + +;;; Code: + +(use-package tex-site + :ensure auctex + :mode ("\\.tex\\'" . TeX-latex-mode) + :commands (TeX-latex-mode + TeX-mode + tex-mode + LaTeX-mode + latex-mode) + :config + (progn + (use-package latex + :config + (progn + (use-package reftex + :defer t + :diminish reftex-mode) + ;; fix the "bug" in SP regexp wrap that treats ' as "word" + (modify-syntax-entry ?' ".") + + (require 'smartparens-latex) + (sp-local-pair 'latex-mode "\\begin" "\\end") + (sp-local-tag 'latex-mode "\\ba" "\\begin{align*}" "\\end{align*}") + + (use-package preview) + (use-package font-latex) + (fset 'tex-font-lock-subscript 'ignore) + + (sp-with-modes '(tex-mode plain-tex-mode latex-mode) + (sp-local-pair "\\[" nil :post-handlers '(my-latex-math-block-indent))) + + (defun my-latex-math-block-indent (a action c) + (when (eq action 'insert) + (newline-and-indent) + (save-excursion (newline)))) + + (defun my-latex-compile () + (interactive) + (save-buffer) + (TeX-command "LaTeX" 'TeX-master-file nil)) + (bind-key "C-M-x" 'my-latex-compile LaTeX-mode-map) + + (defvar my-latex-wrap-choices '("emph" + "textsc")) + (defvar my-latex-wrap-history nil) + + (defun my-latex-wrap (macro-name) + (interactive (list (ido-completing-read + "Macro> " + my-latex-wrap-choices + nil 'confirm nil my-latex-wrap-history))) + (when (use-region-p) + (let ((b (region-beginning)) + (e (region-end))) + (goto-char e) + (insert "}") + (goto-char b) + (insert "\\" macro-name "{")))) + (bind-key "C-c w" 'my-latex-wrap LaTeX-mode-map) + + (defun my-end-of-environment () + (interactive) + (LaTeX-mark-environment) + (end-of-region)) + + (defun my-beginning-of-environment () + (interactive) + (LaTeX-mark-environment) + (beginning-of-region) + (deactivate-mark)) + + (bind-key "M-n" 'my-end-of-environment LaTeX-mode-map) + (bind-key "M-p" 'my-beginning-of-environment LaTeX-mode-map) + + ;; Use okular rather than evince + (setq TeX-view-program-selection + '((output-dvi "Okular") + (output-pdf "Okular"))) + + ;; fix italian quote highlight + (push '("\"<" "\">") font-latex-quote-list) + + (defun my-latex-remove-command () + "Unwrap the expression that point is in or before, also +removing the command name. By command we understand a symbol +starting with \\ and followed by a block of text enclosed in {}." + (interactive) + (let ((ok (sp-get-enclosing-sexp))) + (cond + ;; we're inside the { } block + (ok + (progn + (save-excursion + (goto-char (sp-get ok :beg)) + (zap-to-char -1 ?\\ )) + (sp-splice-sexp))) + ;; test if we are in looking at the command fromt he front + ((looking-at "\\\\") + (zap-up-to-char 1 ?{) + (sp-unwrap-sexp)) + ;; otherwise we're inside the command name + (t + (zap-to-char -1 ?\\ ) + (zap-up-to-char 1 ?{) + (sp-unwrap-sexp))))) + (bind-key "C-c d" 'my-latex-remove-command LaTeX-mode-map) + (bind-key "M-RET" 'LaTeX-insert-item LaTeX-mode-map) + + (use-package company-math + :config + (progn + (defun ravi/company-math-setup () + (setq-local company-backends + (append '(company-math-symbols-latex company-latex-commands) + company-backends))) + (add-hook 'TeX-mode-hook 'ravi/company-math-setup)) + :ensure t) + + (use-package latex-extra + :config + (progn + (add-hook 'LaTeX-mode-hook 'latex-extra-mode)) + :diminish latex-extra-mode + :ensure t) + + (defun my-LaTeX-preview-math () + (interactive) + (let ((b (save-excursion (while (texmathp) (backward-char 1)) (1- (point)))) + (e (save-excursion (while (texmathp) (forward-char 1)) (point)))) + (preview-region b e))) + (bind-key "C-<m-key>" 'my-LaTeX-preview-math preview-map) + + (defun my-LaTeX-mode-init () + (setq TeX-auto-save t) + (setq TeX-parse-self t) + (TeX-PDF-mode t) + (setq reftex-plug-into-AUCTeX t) + (reftex-mode t) + (TeX-fold-mode t) + + (smartparens-mode 1) + + (LaTeX-add-environments + '("derivation" LaTeX-env-label)) + (TeX-add-symbols '("emph" 1)) + + (setq fill-column 88) + + ;; Add XeLaTeX support to AucTeX + (add-to-list 'TeX-command-list '("XeLaTeX" "%`xelatex%(mode)%' %t" TeX-run-TeX nil t)) + (setq TeX-command-default "XeLaTeX") + (setq TeX-save-query nil) + (setq TeX-show-compilation t) + + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("LaTeX"))) + + (message "LaTeX mode init complete.")) + ;; ACUTeX replaces latex-mode-hook with LaTeX-mode-hook + (add-hook 'LaTeX-mode-hook 'my-LaTeX-mode-init) + + )) + ) + ) + +(provide 'ravi-init-tex) +;;; ravi-init-tex.el ends here diff --git a/lisp/ravi-init-vc.el b/lisp/ravi-init-vc.el new file mode 100644 index 0000000..a28a75a --- /dev/null +++ b/lisp/ravi-init-vc.el @@ -0,0 +1,104 @@ +;;; ravi-init-vc.el --- vc control + +;; Copyright (C) 2013 + +;; Author: <ravi@nero.lan> +;; Keywords: vc + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Version control initialization + +;;; Code: + +;; Git +(use-package magit + :bind (("<M-f3>" . magit-status) + ("C-x v B" . magit-blame) + ("C-x v F" . magit-file-log)) + :config + (progn + (setq-default + magit-process-popup-time 10 + magit-diff-refine-hunk t + magit-completing-read-function (if ravi/use-helm-instead-of-ido + 'helm--completing-read-default + 'magit-ido-completing-read)) + + (setq magit-restore-window-configuration t) + + (use-package magit-svn + :config (add-hook 'magit-mode-hook 'magit-svn-mode) + :ensure t) + ) + :ensure t) +(use-package git-gutter + :config + (progn + (use-package git-gutter-fringe + :ensure t) + (global-git-gutter-mode 1) + ) + :ensure t + :diminish git-gutter-mode + ) +(use-package gitignore-mode + :ensure t) +(use-package gitconfig-mode + :ensure t) +(use-package git-messenger + :bind ("C-x v p" . git-messenger:popup-message) + :ensure t) +(use-package git-timemachine + :bind ("C-x v t" . git-timemachine) + :ensure t) +(use-package vc-git + :bind ("C-x v f" . vc-git-grep)) + +;; Stolen almost entirely from Fuco (Matus Goljer) +(use-package ediff + :config + (progn + (defvar my-ediff-before-config nil "Window configuration before ediff.") + (defvar my-ediff-after-config nil "Window configuration after ediff.") + + (defun my-ediff-before-setup () + "Function to be called before any buffers or window setup for + ediff." + (setq my-ediff-before-config (current-window-configuration)) + (set-register ?b (list my-ediff-before-config (point-marker)))) + + (defun my-ediff-after-setup () + "Function to be called after buffers and window setup for ediff." + (setq my-ediff-after-config (current-window-configuration)) + (set-register ?e (list my-ediff-after-config (point-marker)))) + + (defun my-ediff-quit () + "Function to be called when ediff quits." + (when my-ediff-before-config + (set-window-configuration my-ediff-before-config)) + ;; clean up ediff bullshit + (->> (buffer-list) + (-map 'buffer-name) + (--select (string-match-p "\\*[Ee]diff" it)) + (-map 'kill-buffer))) + + (add-hook 'ediff-before-setup-hook 'my-ediff-before-setup) + (add-hook 'ediff-after-setup-windows-hook 'my-ediff-after-setup 'append) + (add-hook 'ediff-quit-hook 'my-ediff-quit))) + +(provide 'ravi-init-vc) +;;; ravi-init-vc.el ends here diff --git a/lisp/ravi-init-web.el b/lisp/ravi-init-web.el new file mode 100644 index 0000000..85446ef --- /dev/null +++ b/lisp/ravi-init-web.el @@ -0,0 +1,112 @@ +;;; ravi-init-web.el --- Web development -*- lexical-binding: t; -*- + +;; Copyright (C) 2014 + +;; Author: <ravi@nero.lan> +;; Keywords: + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Web development tools + +;;; Code: + +(use-package emmet-mode + :commands (emmet-mode) + :init + (progn + (add-hook 'css-mode-hook 'emmet-mode) + (add-hook 'sgml-mode-hook 'emmet-mode)) + :config + (progn + (unbind-key "C-j" emmet-mode-keymap) + (bind-key "M-r" 'emmet-expand-line emmet-mode-keymap)) + :ensure t + :diminish emmet-mode) + +;; Javascript +(use-package js2-mode + :mode (("\\.js$" . js2-mode) + ("\\.json$" . js2-mode) + ("Jakefile$" . js2-mode)) + ;; :interpreter ("node" . js2-mode) + :config + (progn + + (use-package js2-refactor + :config + (progn + (js2r-add-keybindings-with-prefix "C-c C-m")) + :ensure t) + + (defun ravi/js2-mode-hook () + (emmet-mode) + (setq js2-basic-offset 2) + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("JavaScript" "jQuery" "jQuery UI")))) + (add-hook 'js2-mode-hook 'ravi/js2-mode-hook)) + :ensure t + ) + +;; Interact with the browser +(use-package skewer-mode + :config + (progn + (skewer-setup)) + :ensure t) + +;; HTML with web-mode +(use-package web-mode + :mode (("\\.html" . web-mode)) + :config + (progn + + ;; Make it work with smartparens + (defun ravi/web-mode-sp-hook () + (setq web-mode-enable-auto-pairing nil) + (smartparens-mode) + (sp-use-smartparens-bindings)) + (add-hook 'web-mode-hook 'ravi/web-mode-sp-hook) + (add-hook 'web-mode-hook 'emmet-mode) + (defun sp-web-mode-is-code-context (id action context) + (when (and + (eq action 'insert) + (not (or (get-text-property (point) 'part-side) (get-text-property (point) 'block-side)))) + t)) + (sp-local-pair 'web-mode "<" nil :when '(sp-web-mode-is-code-context)) + + (defun ravi/web-mode-extra-hook () + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("HTML")))) + (add-hook 'web-mode-hook 'ravi/web-mode-extra-hook) + + ;; Customization + (setq web-mode-enable-current-element-highlight t) + (setq web-mode-markup-indent-offset 2) + (setq web-mode-css-indent-offset 2) + (setq web-mode-code-indent-offset 2) + (setq web-mode-enable-part-face t) + ) + + :ensure t) + +(defun ravi/css-mode-extra-hook () + (when (functionp 'helm-dash) + (setq-local helm-dash-docsets '("CSS")))) +(add-hook 'css-mode-hook 'ravi/css-mode-extra-hook) + +(provide 'ravi-init-web) +;;; ravi-init-web.el ends here |
