diff options
Diffstat (limited to 'lisp/ravi-init-navigation.el')
| -rw-r--r-- | lisp/ravi-init-navigation.el | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/lisp/ravi-init-navigation.el b/lisp/ravi-init-navigation.el new file mode 100644 index 0000000..5a6054d --- /dev/null +++ b/lisp/ravi-init-navigation.el @@ -0,0 +1,350 @@ +;;; 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 ace-jump-mode + :bind (("M-h" . ace-jump-mode) + ("M-H" . ace-jump-line-mode)) + :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)) + :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)) + :config + (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 + ) + +;; 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 + ) + +;; 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)) + :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 "j") 'highlight-symbol-prev) + (define-key map (kbd "k") '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)) + ) + :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=" + ""])) + ) + ) + +;; to do: add zeal-at-point + +(provide 'ravi-init-navigation) +;;; ravi-init-navigation.el ends here |
