branch: master commit cb7f8ac75f8895eb13563ef95564927955498b23 Merge: 5859be9 d279b6a Author: Alexey Veretennikov <alexey.veretenni...@gmail.com> Commit: Alexey Veretennikov <alexey.veretenni...@gmail.com>
Merge pull request #1 from picarresursix/master Support for RET in loccur-mode --- README.md | 125 +++++++++++++++++++++++++++++++++++- loccur.el | 214 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 249 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 3636994..a047bc1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,60 @@ -There is a minor mode for Emacs acting like occur but w/o creating a new window. It just hides all the text excepting lines containing matches. To use it, add the following to your .emacs file: +Functionalities +=============== + + +Provides is a minor mode for Emacs acting like occur but without +creating a new window. It just hides all the text except lines +containing matches for a given regexp. The following functions are +provided: + + + `loccur` Prompts for a regexp and hides all the lines not containing + matches. If the given regexp is empty, defaults to the current + selection and, if the selection is also empty, defaults to the word + at point. + + `loccur-previous-match` Repeats the last `loccur` search. + + `loccur-toggle-highlight` Disables or enables highlighting of the + matches. + +After `loccur` is ran, hit `RET` to move to the line where the cursor +is and display everything again. + +The good thing about this mode is that you can navigate through the +buffer easily. In particular, hopefully useful functions using +`loccur` are suggested in Section +[Quick Navigation](#quick-navigation). + + +Example +======= + +If you run `loccur` on regexp `[0-9]+` (finding any decimal number) on +the following buffer, + + + Lorem ipsum dolor 100 sit amet, consectetur adipisicing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut + enim ad minim veniam, quis 20090 nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure + dolor in reprehenderit in voluptate velit esse cillum dolore eu + fugiat nulla pariatur. Excepteur sint occaecat 3 cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + +we obtain + + Lorem ipsum dolor 100 sit amet, consectetur adipisicing elit, sed + enim ad minim veniam, quis 20090 nostrud exercitation ullamco + fugiat nulla pariatur. Excepteur sint occaecat 3 cupidatat non + + +and, if we hit `RET` on the third line of this display, the first +content is displayed again and the cursor is placed on the 6th line. + + +Suggested settings +================= + +You can add the following to your .emacs file: ```scheme (require 'loccur) @@ -10,4 +66,69 @@ There is a minor mode for Emacs acting like occur but w/o creating a new window. (define-key global-map [(control shift o)] 'loccur-previous-match) ``` -Now you can point the cursor to the word and press "Ctrl+o" to hide all lines except those containing this word. Moving cursor to the required line and pressing "Ctrl+o" again will shows all the text. The good thing about this mode is what you can navigate through the buffer easily. "Ctrl+Shift+o" will repeat last search. +Now you can point the cursor to the word and press `C-o` to hide all +lines except those containing this word. Moving cursor to the required +line and pressing `C-o` again or `RET` will shows all the text. +`C-S-o` will repeat the last search. + + +Quick navigation +================ + + +You can also use `loccur` to efficiently navigate in a buffer. For +instance, the following function displays only the declaration of all +the *Python* functions in the current file; making it very easy to +jump to a particular function. + +```scheme +(defun loccur/list-Python-functions() + "Displays only the lines corresponding to a function +declaration in a Python file." + (loccur-no-highlight "^ *def ")) +``` + +In the same way, the following snippet provides a very useful function +for whoever uses +[beamer](http://en.wikipedia.org/wiki/Beamer_%28LaTeX%29): it lists +all the frame titles to easily jump to a particular one. + + +```scheme +(defun loccur/list-beamer-frames() + "Displays only the lines corresponding to a frame title +declaration in a beamer LaTeX file." + (loccur-no-highlight "\\frametitle")) +``` + +When running this command, this buffer + +``` +\begin{frame} + \frametitle{First frame} + + <insert fascinating content here> +\end{frame} + +\begin{frame} + \frametitle{Then let's talk about this} + + <insert some stunning figure here> +\end{frame} + +\begin{frame} + \frametitle{Wrapping up} + + <insert witty and challenging conclusion here> +\end{frame} +``` + +becomes +``` + + \frametitle{First frame} + \frametitle{Then let's talk about this} + \frametitle{Wrapping up} +``` +and hitting `RET` will bring back the first buffer and place the +cursor on the line wanted. diff --git a/loccur.el b/loccur.el index a9aec5a..ae3919f 100644 --- a/loccur.el +++ b/loccur.el @@ -1,13 +1,13 @@ -;;; loccur.el --- Perform an occur-like folding in current buffer +;;; loccur.el --- Performs an occur-like folding in current buffer. -;; Copyright (C) 2009-2012 Alexey Veretennikov +;; Copyright (C) 2009 Alexey Veretennikov ;; ;; Author: Alexey Veretennikov <alexey dot veretennikov at gmail dot com> ;; Created: 2009-09-08 -;; Version: 1.1.3 +;; Version: 1.1.1 ;; Keywords: matching ;; URL: https://github.com/fourier/loccur -;; Compatibility: GNU Emacs 23.x, GNU Emacs 24.x +;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x, GNU Emacs 24.x ;; ;; This file is NOT part of GNU Emacs. ;; @@ -44,14 +44,11 @@ ;; ;;; Change Log: ;; -;; 2012-09-27 (1.1.3) -;; + Recenter on exit from loccur-mode +;; 2013-03-31 (1.2) +;; + Added possibility to desactivate regex highlight, moved +;; function in different sections and added the RET keyboard +;; shortcut in loccur-mode (Leo Perrin). ;; -;; -;; 2012-09-25 (1.1.2) -;; + Removed cl dependency -;; -;; ;; 2010-03-07 (1.1.1) ;; + Default value is taken from prompt instead of an edit area ;; (thanks to Nathaniel Flath) @@ -68,17 +65,56 @@ ;; ;;; Code: +(eval-when-compile (require 'cl)) (defconst loccur-overlay-property-name 'loccur-custom-buffer-grep) -(or (assq 'loccur-mode minor-mode-alist) - (nconc minor-mode-alist - (list '(loccur-mode loccur-mode)))) +; !SECTION! Possible highlighting of the matching regex + +(defvar loccur-highlight-matching-regexp t + "If set to a non-nil value, the part of the line matching the +regex is highlighted. Use loccur-toggle-highlight to modify its +value interactively.") -(defvar loccur-mode nil) ;; name of the minor mode -(make-variable-buffer-local 'loccur-mode) +(defun loccur-toggle-highlight() + "Toggles the highlighting of the part of the line matching the +regex given in the loccur buffer." + (interactive) + (if loccur-highlight-matching-regexp + (setq loccur-highlight-matching-regexp nil) + (setq loccur-highlight-matching-regexp t))) + + +; !SECTION! Defining the minor-mode + +;; Custom Minor Mode +(define-minor-mode loccur-mode + "Performs an occur-like folding in current buffer." + ;; The initial value - Set to 1 to enable by default + nil + ;; The indicator for the mode line. + " Loccur" + ;; The minor mode keymap + `( + (,(kbd "RET") . loccur-current))) + +(defun loccur-toggle-mode (regex) + (if (or loccur-mode + (null regex) + (zerop (length regex))) + (loccur-mode -1) + (loccur-mode 1)) + (force-mode-line-update) + (loccur-remove-overlays) + (if loccur-mode + (loccur-1 regex) + (recenter))) + + +; !SECTION! Utils +; !SUBSECTION! History (defvar loccur-history nil "History of previously searched expressions for the prompt") @@ -89,38 +125,75 @@ (make-variable-buffer-local 'loccur-last-match) +(defun loccur-previous-match () + "Call `loccur' for the previously found word." + (interactive) + (loccur loccur-last-match)) + + +; !SUBSECTION! Functions dealing with overlays + (defvar loccur-overlay-list nil "A list of currently active overlays.") (make-variable-buffer-local 'loccur-overlay-list) +(defun loccur-create-highlighted-overlays(buffer-matches) + (let ((overlays + (map 'list #'(lambda (match) + (make-overlay + (nth 1 match) + (nth 2 match) + (current-buffer) t nil)) + buffer-matches))) + ;; To possibly remove highlighting of the matching regexp + (if loccur-highlight-matching-regexp + (mapcar (lambda (ovl) + (overlay-put ovl loccur-overlay-property-name t) + (overlay-put ovl 'face 'isearch)) + overlays)))) -(defun loccur-mode (regex) - (setq loccur-mode - (if (or loccur-mode - (null regex) - (zerop (length regex))) - nil - " Loccur")) - (force-mode-line-update) - (loccur-remove-overlays) - (if loccur-mode - (loccur-1 regex) - (recenter))) +(defun loccur-create-invisible-overlays (ovl-bounds) + (let ((overlays + (map 'list #'(lambda (bnd) + (make-overlay + (car bnd) + (cadr bnd) + (current-buffer) t nil)) + ovl-bounds))) + (mapcar (lambda (ovl) + (overlay-put ovl loccur-overlay-property-name t) + (overlay-put ovl 'invisible t) + ;; force intangible property if invisible property + ;; does not automatically set it + (overlay-put ovl 'intangible t)) + overlays))) -(defun loccur-current () - "Call `loccur' for the current word." - (interactive) - (loccur (current-word))) + +(defun loccur-remove-overlays () + (remove-overlays (point-min) (point-max) loccur-overlay-property-name t) + (setq loccur-overlay-list nil)) -(defun loccur-previous-match () - "Call `loccur' for the previously found word." - (interactive) - (loccur loccur-last-match)) +(defun loccur-create-overlay-bounds-btw-lines (buffer-matches) + (let ((prev-end (point-min)) + (overlays (list))) + (when buffer-matches + (mapcar (lambda (line) + (let ((beginning (car line))) + (unless ( = (- beginning prev-end) 1) + (let ((ovl-start (if (= prev-end 1) 1 prev-end)) + (ovl-end (1- beginning))) + (push (list ovl-start ovl-end) overlays))) + (setq prev-end (nth 3 line)))) + buffer-matches) + (push (list (1+ prev-end) (point-max)) overlays) + (setq overlays (nreverse overlays))))) +; !SECTION! Main functions, those actually performing the loccur + (defun loccur (regex) "Perform a simple grep in current buffer for the regular expression REGEX @@ -134,9 +207,16 @@ unhides lines again" (list (read-string (concat "Regexp<" (loccur-prompt) ">: ") "" 'loccur-history )))) (if (string-equal "" regex) (setq regex (loccur-prompt))) - (loccur-mode regex)) + (loccur-toggle-mode regex) + (beginning-of-line)) ; Handier to be at the beginning of line + +(defun loccur-current () + "Call `loccur' for the current word." + (interactive) + (loccur (current-word))) + (defun loccur-prompt () "Returns the default value of the prompt. @@ -167,57 +247,6 @@ if its size is 1 line" (setq loccur-last-match regex) (recenter))) -(defun loccur-create-highlighted-overlays(buffer-matches) - (let ((overlays - (mapcar (lambda (match) - (make-overlay - (nth 1 match) - (nth 2 match) - (current-buffer) t nil)) - buffer-matches))) - (mapcar (lambda (ovl) - (overlay-put ovl loccur-overlay-property-name t) - (overlay-put ovl 'face 'isearch)) - overlays))) - - -(defun loccur-create-invisible-overlays (ovl-bounds) - (let ((overlays - (mapcar (lambda (bnd) - (make-overlay - (car bnd) - (cadr bnd) - (current-buffer) t nil)) - ovl-bounds))) - (mapcar (lambda (ovl) - (overlay-put ovl loccur-overlay-property-name t) - (overlay-put ovl 'invisible t) - ;; force intangible property if invisible property - ;; does not automatically set it - (overlay-put ovl 'intangible t)) - overlays))) - - -(defun loccur-remove-overlays () - (remove-overlays (point-min) (point-max) loccur-overlay-property-name t) - (setq loccur-overlay-list nil)) - - -(defun loccur-create-overlay-bounds-btw-lines (buffer-matches) - (let ((prev-end (point-min)) - (overlays (list))) - (when buffer-matches - (mapcar (lambda (line) - (let ((beginning (car line))) - (unless ( = (- beginning prev-end) 1) - (let ((ovl-start (if (= prev-end 1) 1 prev-end)) - (ovl-end (1- beginning))) - (push (list ovl-start ovl-end) overlays))) - (setq prev-end (nth 3 line)))) - buffer-matches) - (push (list (1+ prev-end) (point-max)) overlays) - (setq overlays (nreverse overlays))))) - (defun loccur-find-matches (regex) "Returns a list of 4-number tuples, specifying begnning of the line, @@ -250,6 +279,15 @@ containing match" (forward-line 1)) (setq lines (nreverse lines))))) +(defun loccur-no-highlight(regex) + "Displays only the lines matching a given regex with no +highlithing of any part of the lines." + (let (old-highlighting) + (setq old-highlighting loccur-highlight-matching-regexp) + (setq loccur-highlight-matching-regexp nil) + (loccur regex) + (setq loccur-highlight-matching-regexp old-highlighting))) + (provide 'loccur) ;;; loccur.el ends here