├── Readme.org └── hide-lines.el /Readme.org: -------------------------------------------------------------------------------- 1 | * Library Information 2 | Readme.org --- Commands for hiding lines based on a regexp 3 | 4 | - Filename :: [[file:hide-lines.el][hide-lines.el]] 5 | - Description :: Commands for hiding lines based on a regexp 6 | - Author :: Mark Hulme-Jones 7 | - Maintainer :: Joe Bloggs 8 | - Version :: 20130623.1701 9 | - Last-Updated :: 2013-06-22 22:38:04 10 | - By :: Joe Bloggs 11 | - URL :: https://github.com/vapniks/hide-lines 12 | - Keywords :: convenience 13 | - Compatibility :: GNU Emacs 24.3.1 14 | 15 | * Commentary 16 | 17 | The simplest way to make hide-lines work is to add the following 18 | lines to your .emacs file: 19 | 20 | =(autoload 'hide-lines "hide-lines" "Hide lines based on a regexp" t) 21 | (global-set-key "\C-ch" 'hide-lines)= 22 | 23 | Now, when you type C-c h, you will be prompted for a regexp 24 | (regular expression). All lines matching this regexp will be 25 | hidden in the buffer. 26 | 27 | Alternatively, you can type C-u C-c h (ie. provide a prefix 28 | argument to the hide-lines command) to hide all lines that *do not* 29 | match the specified regexp. 30 | 31 | If you want to make all of the hidden areas re-appear again, type: 32 | M-x hide-lines-show-all 33 | Or you can bind show-all-invisible to a key and use that to show 34 | all the hidden areas again. 35 | 36 | If you prefer the opposite behaviour either use =hide-lines-not-matching= 37 | or set =hide-lines-reverse-prefix= to t. 38 | 39 | =hide-lines= is useful in the *Messages* buffer or *Packages* buffer (M-x list-packages). 40 | In the *Packages* buffer the following regular expression can be used to 41 | limit the display to all packages marked for installation/uninstallation 42 | 43 | * Installation 44 | Put hide-lines.el in a directory in your load-path, e.g. ~/.emacs.d/ 45 | You can add a directory to your load-path with the following line in ~/.emacs 46 | (add-to-list 'load-path (expand-file-name "~/elisp")) 47 | where ~/elisp is the directory you want to add 48 | (you don't need to do this for ~/.emacs.d - it's added by default). 49 | 50 | Add the following to your ~/.emacs startup file. 51 | 52 | (require 'hide-lines) 53 | * Commands & keybindings 54 | 55 | Below is a complete list of commands: 56 | 57 | - *hide-lines* : 58 | Hide lines matching the specified regexp.\\ 59 | Keybinding: =M-x hide-lines= 60 | - *hide-lines-not-matching* : 61 | Hide lines that don't match the specified regexp.\\ 62 | Keybinding: =M-x hide-lines-not-matching= 63 | - *hide-lines-matching* : 64 | Hide lines matching the specified regexp.\\ 65 | Keybinding: =M-x hide-lines-matching= 66 | - *hide-lines-show-all* : 67 | Show all areas hidden by the filter-buffer command.\\ 68 | Keybinding: =M-x hide-lines-show-all= 69 | - *hide-blocks-not-matching* 70 | Hide text that is not between lines matching START-TEXT and END-TEXT. 71 | Keybinding: =M-x hide-blocks-not-matching= 72 | - *hide-blocks-matching* 73 | Hide text that is between lines matching START-TEXT and END-TEXT. 74 | Keybinding: =M-x hide-blocks-matching= 75 | - *hide-lines-kill-hidden* 76 | Kill or delete all hidden areas. 77 | Keybinding =M-x hide-lines-kill-hidden= 78 | * Customizable Options 79 | 80 | Below is a list of customizable options: 81 | 82 | - *hide-lines-reverse-prefix* : 83 | If non-nil then - *hide-lines* : will call - *hide-lines-matching* : by default, and - *hide-lines-not-matching* : with a single prefix.\\ 84 | default value: =nil= 85 | -------------------------------------------------------------------------------- /hide-lines.el: -------------------------------------------------------------------------------- 1 | ;;; hide-lines.el --- Commands for hiding lines based on a regexp -*- lexical-binding: nil; -*- 2 | 3 | ;; Filename: hide-lines.el 4 | ;; Description: Commands for hiding lines based on a regexp 5 | ;; Author: Mark Hulme-Jones 6 | ;; Maintainer: Joe Bloggs 7 | ;; Version: 20130623.1701 8 | ;; Last-Updated: Fri Nov 27 19:10:05 2015 9 | ;; By: Joe Bloggs 10 | ;; URL: https://github.com/vapniks/hide-lines 11 | ;; Keywords: convenience 12 | ;; Compatibility: GNU Emacs 24.3.1 13 | ;; Package-Requires: 14 | ;; 15 | ;; Features that might be required by this library: 16 | ;; 17 | ;; 18 | ;; 19 | 20 | ;;; This file is NOT part of GNU Emacs 21 | 22 | ;;; License 23 | ;; 24 | ;; This program is free software; you can redistribute it and/or modify 25 | ;; it under the terms of the GNU General Public License as published by 26 | ;; the Free Software Foundation; either version 3, or (at your option) 27 | ;; any later version. 28 | 29 | ;; This program is distributed in the hope that it will be useful, 30 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | ;; GNU General Public License for more details. 33 | 34 | ;; You should have received a copy of the GNU General Public License 35 | ;; along with this program; see the file COPYING. 36 | ;; If not, see . 37 | 38 | ;;; Commentary: 39 | ;; 40 | ;; The simplest way to make hide-lines work is to add the following 41 | ;; lines to your .emacs file: 42 | ;; 43 | ;; (autoload 'hide-lines "hide-lines" "Hide lines based on a regexp" t) 44 | ;; (global-set-key (kbd "C-c /") 'hide-lines) 45 | ;; 46 | ;; Now, when you type C-c /, you will be prompted for a regexp 47 | ;; (regular expression). All lines matching this regexp will be 48 | ;; hidden in the buffer. 49 | ;; 50 | ;; Alternatively, you can type C-u C-c / (ie. provide a prefix 51 | ;; argument to the hide-lines command) to hide all lines that *do not* 52 | ;; match the specified regexp. If you want to reveal previously hidden 53 | ;; lines you can use any other prefix, e.g. C-u C-u C-c / 54 | ;; 55 | 56 | 57 | 58 | ;;; Commands: 59 | ;; 60 | ;; Below is a complete list of commands: 61 | ;; 62 | ;; `hide-lines' 63 | ;; Hide lines matching the specified regexp. 64 | ;; Keybinding: M-x hide-lines 65 | ;; `hide-lines-not-matching' 66 | ;; Hide lines that don't match the specified regexp. 67 | ;; Keybinding: M-x hide-lines-not-matching 68 | ;; `hide-lines-matching' 69 | ;; Hide lines matching the specified regexp. 70 | ;; Keybinding: M-x hide-lines-matching 71 | ;; `hide-lines-show-all' 72 | ;; Show all areas hidden by the filter-buffer command. 73 | ;; Keybinding: M-x hide-lines-show-all 74 | ;; `hide-blocks-not-matching' 75 | ;; Hide text that is not between lines matching START-TEXT and END-TEXT. 76 | ;; Keybinding: M-x hide-blocks-not-matching 77 | ;; `hide-blocks-matching' 78 | ;; Hide text that is between lines matching START-TEXT and END-TEXT. 79 | ;; Keybinding: M-x hide-blocks-matching 80 | ;; 81 | ;;; Customizable Options: 82 | ;; 83 | ;; Below is a list of customizable options: 84 | ;; 85 | ;; `hide-lines-reverse-prefix' 86 | ;; If non-nil then `hide-lines' will call `hide-lines-matching' by default, and `hide-lines-not-matching' with a single prefix. 87 | ;; default = nil 88 | 89 | ;;; Installation: 90 | ;; 91 | ;; Put hide-lines.el in a directory in your load-path, e.g. ~/.emacs.d/ 92 | ;; You can add a directory to your load-path with the following line in ~/.emacs 93 | ;; (add-to-list 'load-path (expand-file-name "~/elisp")) 94 | ;; where ~/elisp is the directory you want to add 95 | ;; (you don't need to do this for ~/.emacs.d - it's added by default). 96 | ;; 97 | ;; Add the following to your ~/.emacs startup file. 98 | ;; 99 | ;; (require 'hide-lines) 100 | 101 | ;;; Change log: 102 | ;; 103 | ;; 2013/06/22 - Add namespace prefixes to functions and variables. 104 | ;; Add licence and add to Marmalade repo. 105 | ;; Alter hide-lines so that it can also show all lines 106 | ;; 107 | ;; 24/03/2004 - Incorporate fix for infinite loop bug from David Hansen. 108 | ;; 2021/01/17 - PRouleau: set hide-lines group parent to convenience, 109 | ;; matching what packages states. Fixed checkdoc warnings. 110 | 111 | ;;; Acknowledgements: 112 | ;; 113 | ;; David Hansen. 114 | ;; 115 | 116 | ;;; TODO 117 | ;; 118 | ;; 119 | ;; 120 | 121 | ;;; Require 122 | 123 | 124 | ;;; Code: 125 | 126 | (defgroup hide-lines nil 127 | "Commands for hiding lines based on a regexp." 128 | :group 'convenience) 129 | 130 | (defvar-local hide-lines-invisible-areas () 131 | "List of invisible overlays used by hidelines") 132 | 133 | (defcustom hide-lines-reverse-prefix nil 134 | "Control what command `hide-lines' calls by default. 135 | 136 | - If non-nil then `hide-lines' will call `hide-lines-matching' by default, 137 | and `hide-lines-not-matching' with a single prefix. 138 | - Otherwise it's the other way round. 139 | 140 | In either case a prefix arg with any value apart from 1 or 4 will 141 | call `hide-lines-show-all'." 142 | :type 'boolean 143 | :group 'hide-lines) 144 | 145 | (make-variable-buffer-local 'hide-lines-reverse-prefix) 146 | 147 | (add-to-invisibility-spec 'hl) 148 | 149 | ;;;###autoload 150 | (defun hide-lines (&optional arg) 151 | "Hide lines matching the specified regexp. 152 | With prefix ARG of 4 (\\[universal-argument]) hide lines that do not match the 153 | specified regexp. With any other prefix arg, reveal all hidden lines." 154 | (interactive "p") 155 | (cond ((= arg 4) (call-interactively 156 | (if hide-lines-reverse-prefix 'hide-lines-matching 157 | 'hide-lines-not-matching))) 158 | ((= arg 1) (call-interactively 159 | (if hide-lines-reverse-prefix 'hide-lines-not-matching 160 | 'hide-lines-matching))) 161 | (t (call-interactively 'hide-lines-show-all)))) 162 | 163 | ;;;###autoload 164 | (defun hide-blocks (&optional arg) 165 | "Hide blocks of lines between matching regexps. 166 | With prefix ARG of 4 (\\[universal-argument]) hide blocks that do not match the 167 | specified regexps. With any other prefix arg, reveal all hidden blocks." 168 | (interactive "p") 169 | (cond ((= arg 4) (call-interactively 170 | (if hide-lines-reverse-prefix 'hide-blocks-matching 171 | 'hide-blocks-not-matching))) 172 | ((= arg 1) (call-interactively 173 | (if hide-lines-reverse-prefix 'hide-blocks-not-matching 174 | 'hide-blocks-matching))) 175 | (t (call-interactively 'hide-lines-show-all)))) 176 | 177 | (defun hide-lines-invisible-p (start end) 178 | "Return non-nil if region between START and END is already hidden." 179 | (remove nil (mapcar (lambda (ov) 180 | (and (<= (overlay-start ov) start) 181 | (>= (overlay-end ov) end))) 182 | hide-lines-invisible-areas))) 183 | 184 | (defun hide-lines-add-overlay (start end) 185 | "Add an overlay from `START' to `END' in the current buffer. 186 | Push the overlay onto the `hide-lines-invisible-areas' list" 187 | (unless (hide-lines-invisible-p start end) 188 | (let ((overlay (make-overlay start end))) 189 | (push overlay hide-lines-invisible-areas) 190 | (unless (and (consp buffer-invisibility-spec) 191 | (member 'hl buffer-invisibility-spec)) 192 | (add-to-invisibility-spec 'hl)) 193 | (overlay-put overlay 'invisible 'hl)))) 194 | 195 | ;;;###autoload 196 | (defun hide-lines-not-matching (search-text) 197 | "Hide lines that don't match the regexp SEARCH-TEXT." 198 | (interactive "MHide lines not matched by regexp: ") 199 | (set (make-local-variable 'line-move-ignore-invisible) t) 200 | (save-excursion 201 | (goto-char (point-min)) 202 | (let ((start-position (point-min)) 203 | (pos (re-search-forward search-text nil t))) 204 | (while pos 205 | (beginning-of-line) 206 | (hide-lines-add-overlay start-position (point)) 207 | (forward-line 1) 208 | (setq start-position (point)) 209 | (if (eq (point) (point-max)) 210 | (setq pos nil) 211 | (setq pos (re-search-forward search-text nil t)))) 212 | (hide-lines-add-overlay start-position (point-max))))) 213 | 214 | ;;;###autoload 215 | (defun hide-lines-matching (search-text) 216 | "Hide lines matching the regexp SEARCH-TEXT." 217 | (interactive "MHide lines matching regexp: ") 218 | (set (make-local-variable 'line-move-ignore-invisible) t) 219 | (save-excursion 220 | (goto-char (point-min)) 221 | (let ((pos (re-search-forward search-text nil t)) 222 | start-position) 223 | (while pos 224 | (beginning-of-line) 225 | (setq start-position (point)) 226 | (end-of-line) 227 | (hide-lines-add-overlay start-position (+ 1 (point))) 228 | (forward-line 1) 229 | (if (eq (point) (point-max)) 230 | (setq pos nil) 231 | (setq pos (re-search-forward search-text nil t))))))) 232 | 233 | ;;;###autoload 234 | (defun hide-blocks-not-matching (start-text end-text) 235 | "Hide text that is not between lines matching START-TEXT and END-TEXT." 236 | (interactive (list (read-regexp "Regexp matching start lines of blocks: ") 237 | (read-regexp "Regexp matching end lines of blocks: "))) 238 | (set (make-local-variable 'line-move-ignore-invisible) t) 239 | (save-excursion 240 | (goto-char (point-min)) 241 | (let ((start-position (point-min)) 242 | (pos (re-search-forward start-text nil t))) 243 | (while pos 244 | (beginning-of-line) 245 | (hide-lines-add-overlay start-position (point)) 246 | (forward-line 1) 247 | (if (re-search-forward end-text nil t) 248 | (beginning-of-line) 249 | (goto-char (point-max))) 250 | (setq start-position (point)) 251 | (if (eq (point) (point-max)) 252 | (setq pos nil) 253 | (setq pos (re-search-forward start-text nil t)))) 254 | (hide-lines-add-overlay start-position (point-max))))) 255 | 256 | ;;;###autoload 257 | (defun hide-blocks-matching (start-text end-text) 258 | "Hide text that is between lines matching START-TEXT and END-TEXT." 259 | (interactive (list (read-regexp "Regexp matching start lines of blocks: ") 260 | (read-regexp "Regexp matching end lines of blocks: "))) 261 | (set (make-local-variable 'line-move-ignore-invisible) t) 262 | (save-excursion 263 | (goto-char (point-min)) 264 | (let ((pos (re-search-forward start-text nil t)) 265 | start-position) 266 | (while pos 267 | (beginning-of-line) 268 | (setq start-position (point)) 269 | (forward-line 1) 270 | (if (re-search-forward end-text nil t) 271 | (beginning-of-line) 272 | (goto-char (point-max))) 273 | (hide-lines-add-overlay start-position (point)) 274 | (if (eq (point) (point-max)) 275 | (setq pos nil) 276 | (setq pos (re-search-forward start-text nil t))))))) 277 | 278 | ;;;###autoload 279 | (defun hide-lines-show-all () 280 | "Unhide all hidden areas." 281 | (interactive) 282 | (mapc (lambda (overlay) (delete-overlay overlay)) 283 | hide-lines-invisible-areas) 284 | (setq hide-lines-invisible-areas ()) 285 | (remove-from-invisibility-spec 'hl)) 286 | 287 | (defun hide-lines-kill-hidden (&optional deletep) 288 | "Kill all hidden areas. 289 | If called with prefix arg (or DELETEP is non-nil) dont save the 290 | text to the kill ring (this is faster, but you can't retrieve the hidden text)." 291 | (interactive "P") 292 | (mapc (lambda (overlay) 293 | (funcall (if deletep 'delete-region 'kill-region) 294 | (overlay-start overlay) 295 | (overlay-end overlay)) 296 | (delete-overlay overlay)) 297 | hide-lines-invisible-areas) 298 | (setq hide-lines-invisible-areas ()) 299 | (remove-from-invisibility-spec 'hl)) 300 | 301 | (provide 'hide-lines) 302 | 303 | ;; (magit-push) 304 | ;; (yaoddmuse-post "EmacsWiki" "hide-lines.el" (buffer-name) (buffer-string) "update") 305 | 306 | ;;; hide-lines.el ends here 307 | --------------------------------------------------------------------------------