├── .gitignore ├── HISTORY.org ├── README.md ├── navi-mode.el └── old └── old-readme.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled 2 | *.elc 3 | -------------------------------------------------------------------------------- /HISTORY.org: -------------------------------------------------------------------------------- 1 | * TODO Version 2.1 2 | 3 | ** TODO set and push v2.1 tag 4 | ** TODO update README 5 | ** TODO set version number 6 | ** TODO announce in org-mode mailing-list 7 | ** TODO announce in emacs-user mailing-list 8 | 9 | 10 | * TODO Version 2.0 11 | 12 | ** TODO improve MELPA-package 13 | ** DONE set and push v2.0 tag 14 | - State "DONE" from "TODO" [2014-09-21 So 13:06] 15 | ** TODO delete tj-navi branch 16 | ** DONE Merge trunk in master 17 | - State "DONE" from "TODO" [2014-09-20 Sa 22:39] 18 | ** DONE quite byte-compiler 19 | - State "DONE" from "TODO" [2014-09-20 Sa 21:31] 20 | ** DONE update README 21 | - State "DONE" from "TODO" [2014-09-20 Sa 19:20] 22 | ** DONE set version number 23 | - State "DONE" from "TODO" [2014-09-20 Sa 19:17] 24 | ** DONE announce in org-mode mailing-list 25 | - State "DONE" from "TODO" [2014-09-21 So 13:07] 26 | ** DONE announce in emacs-user mailing-list 27 | - State "DONE" from "TODO" [2014-09-21 So 13:07] 28 | 29 | * DONE Version 1.0 30 | CLOSED: [2013-05-03 Fr 19:21] 31 | :LOGBOOK: 32 | - State "DONE" from "TODO" [2013-05-03 Fr 19:21] 33 | :END: 34 | [2013-02-21 Do 01:24] 35 | 36 | ** DONE change version number 37 | CLOSED: [2013-05-03 Fr 19:21] 38 | :LOGBOOK: 39 | - State "DONE" from "TODO" [2013-05-03 Fr 19:21] 40 | :END: 41 | [2013-02-21 Do 01:27] 42 | ** CANCELLED announce in org-mode mailing-list :CANCELLED: 43 | CLOSED: [2013-05-03 Fr 19:20] 44 | :LOGBOOK: 45 | - State "CANCELLED" from "TODO" [2013-05-03 Fr 19:20] \\ 46 | enough publicity 47 | :END: 48 | [2013-02-21 Do 01:28] 49 | ** CANCELLED announce in emacs mailing-list :CANCELLED: 50 | CLOSED: [2013-05-03 Fr 19:20] 51 | :LOGBOOK: 52 | - State "CANCELLED" from "TODO" [2013-05-03 Fr 19:20] \\ 53 | enough publicity 54 | :END: 55 | [2013-02-21 Do 01:24] 56 | 57 | 58 | * DONE Version 0.9 59 | CLOSED: [2013-05-03 Fr 19:20] 60 | :LOGBOOK: 61 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 62 | :END: 63 | [2013-02-21 Do 01:24] 64 | 65 | ** DONE fix navi-edit-mode ("e") 66 | CLOSED: [2013-05-03 Fr 19:20] 67 | :LOGBOOK: 68 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 69 | :END: 70 | [2013-03-10 So 01:54] 71 | ** DONE fix not revieves keys 72 | CLOSED: [2013-05-03 Fr 19:20] 73 | :LOGBOOK: 74 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 75 | :END: 76 | [2013-03-10 So 01:54] 77 | ** DONE finish keybindings 78 | CLOSED: [2013-03-09 Sa 23:12] 79 | :LOGBOOK: 80 | - State "DONE" from "TODO" [2013-03-09 Sa 23:12] 81 | :END: 82 | [2013-03-08 Fr 12:01] 83 | ** DONE write 'navi-quit-and-switch' 84 | CLOSED: [2013-05-03 Fr 19:20] 85 | :LOGBOOK: 86 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 87 | :END: 88 | [2013-03-08 Fr 12:00] 89 | ** DONE make '?' and 'h' show C-h b 90 | CLOSED: [2013-05-03 Fr 19:20] 91 | :LOGBOOK: 92 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 93 | :END: 94 | [2013-03-08 Fr 11:58] 95 | ** DONE implement 'remote control' functions 96 | CLOSED: [2013-05-03 Fr 19:20] 97 | :LOGBOOK: 98 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 99 | :END: 100 | [2013-03-08 Fr 11:58] 101 | ** DONE write Worg article 102 | CLOSED: [2013-05-03 Fr 19:20] 103 | :LOGBOOK: 104 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 105 | :END: 106 | [2013-03-08 Fr 11:50] 107 | ** DONE ask about keybindings for functions with args. 108 | CLOSED: [2013-03-09 Sa 23:13] 109 | :LOGBOOK: 110 | - State "DONE" from "TODO" [2013-03-09 Sa 23:13] 111 | :END: 112 | [2013-03-08 Fr 11:49] 113 | ** DONE fix wrong point location (always 1st match) after excursion to other buffers 114 | CLOSED: [2013-05-03 Fr 19:20] 115 | :LOGBOOK: 116 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 117 | :END: 118 | [2013-03-08 Fr 11:44] 119 | 120 | When switching between the twin-buffers, automatic point-location seems to 121 | work, but when switching to other, non-related buffers in between, and then 122 | back to the original-buffer and then to the navi-buffer, point always ends up 123 | at the first match. 124 | 125 | ** DONE make navi derived major-mode 126 | CLOSED: [2013-03-08 Fr 11:42] 127 | :LOGBOOK: 128 | - State "DONE" from "TODO" [2013-03-08 Fr 11:42] 129 | :END: 130 | [2013-02-25 Mo 09:33] 131 | ** CANCELLED turn off fontification of matches??? :CANCELLED: 132 | CLOSED: [2013-03-08 Fr 11:41] 133 | :LOGBOOK: 134 | - State "CANCELLED" from "TODO" [2013-03-08 Fr 11:41] \\ 135 | in the end, the fontification is not so bad, maybe even useful. 136 | :END: 137 | [2013-02-21 Do 01:32] 138 | ** DONE global command: go-back-to-navi-buffer (at marker-position) 139 | CLOSED: [2013-02-25 Mo 09:33] 140 | :LOGBOOK: 141 | - State "DONE" from "TODO" [2013-02-25 Mo 09:33] 142 | :END: 143 | [2013-02-21 Do 01:30] 144 | ** DONE make functions that return from original-buffer to navi-buffer revert navi-buffer 145 | CLOSED: [2013-05-03 Fr 19:20] 146 | :LOGBOOK: 147 | - State "DONE" from "TODO" [2013-05-03 Fr 19:20] 148 | :END: 149 | [2013-03-08 Fr 11:43] 150 | ** CANCELLED implement actualization hook for navi-buffers (always-up-to-date) :CANCELLED: 151 | CLOSED: [2013-03-08 Fr 11:42] 152 | :LOGBOOK: 153 | - State "CANCELLED" from "TODO" [2013-03-08 Fr 11:42] \\ 154 | instead of an actualization-hook-function, each function that returns from 155 | the original-buffer to the navi-buffer reverts the navi-buffer. 156 | :END: 157 | [2013-02-21 Do 01:29] 158 | ** DONE implement narrow/widen 159 | CLOSED: [2013-05-03 Fr 19:19] 160 | :LOGBOOK: 161 | - State "DONE" from "TODO" [2013-05-03 Fr 19:19] 162 | :END: 163 | [2013-02-21 Do 01:27] 164 | ** DONE implement predefined queries with 1key keybindings 165 | CLOSED: [2013-05-03 Fr 19:19] 166 | :LOGBOOK: 167 | - State "DONE" from "NEXT" [2013-05-03 Fr 19:19] 168 | :END: 169 | [2013-02-21 Do 01:27] 170 | ** DONE connect navi-buffer and principal buffer (markers) 171 | CLOSED: [2013-03-08 Fr 11:44] 172 | :LOGBOOK: 173 | - State "DONE" from "TODO" [2013-03-08 Fr 11:44] 174 | :END: 175 | [2013-02-21 Do 01:26] 176 | ** DONE make occur-buffers permanent (-> navi-buffer) 177 | CLOSED: [2013-03-08 Fr 11:44] 178 | :LOGBOOK: 179 | - State "DONE" from "TODO" [2013-03-08 Fr 11:44] 180 | :END: 181 | [2013-02-21 Do 01:26] 182 | ** DONE announce in org-mode mailing-list 183 | CLOSED: [2013-05-03 Fr 19:19] 184 | :LOGBOOK: 185 | - State "DONE" from "TODO" [2013-05-03 Fr 19:19] 186 | :END: 187 | [2013-02-21 Do 01:25] 188 | ** DONE announce in emacs mailing-list 189 | CLOSED: [2013-05-03 Fr 19:19] 190 | :LOGBOOK: 191 | - State "DONE" from "TODO" [2013-05-03 Fr 19:19] 192 | :END: 193 | [2013-02-21 Do 01:24] 194 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Navi-mode 2 | 3 | I no longer maintain this package, but @alphapapa has graciously agreed to take over maintainership. His fork should be considered authoritative and can be found here: 4 | 5 | https://github.com/alphapapa/navi 6 | -------------------------------------------------------------------------------- /navi-mode.el: -------------------------------------------------------------------------------- 1 | ;;; navi-mode.el --- major-mode for easy buffer-navigation 2 | 3 | ;; Author: Thorsten Jolitz 4 | ;; Version: 2.0 5 | ;; URL: https://github.com/tj64/navi 6 | ;; Package-Requires: ((outshine "2.0") (outorg "2.0")) 7 | 8 | ;;;; MetaData 9 | ;; :PROPERTIES: 10 | ;; :copyright: Thorsten Jolitz 11 | ;; :copyright-years: 2013+ 12 | ;; :version: 2.0 13 | ;; :licence: GPL 2 or later (free software) 14 | ;; :licence-url: http://www.gnu.org/licenses/ 15 | ;; :part-of-emacs: no 16 | ;; :author: Thorsten Jolitz 17 | ;; :author_email: tjolitz AT gmail DOT com 18 | ;; :git-repo: https://github.com/tj64/navi.git 19 | ;; :git-clone: git://github.com/tj64/navi.git 20 | ;; :inspiration: occur-mode org-mode 21 | ;; :keywords: emacs navigation remote-buffer-control 22 | ;; :END: 23 | 24 | ;;;; Commentary 25 | 26 | ;;;;; About navi-mode 27 | 28 | ;; Navi-mode, as its name suggests, enables super-fast navigation and 29 | ;; easy structure-editing in Outshine or Org buffers via one-key 30 | ;; bindings in associated read-only *Navi* buffers. 31 | 32 | ;; You can think of a navi-buffer as a kind of 'remote-control' for an 33 | ;; (adecuately) outline-structured original-buffer. Besides navigation 34 | ;; and structure-editing, many common commands can be executed in the 35 | ;; original-buffer without (necessarily) leaving the navi-buffer. When 36 | ;; switching to the original-buffer and coming back after some 37 | ;; modifications, the navi-buffer is always reverted (thus 38 | ;; up-to-date). 39 | 40 | ;; Besides the many things that can be done from a navi-buffer, its 41 | ;; main benefit is to offer a flexible but persistent and rock-solid 42 | ;; overview side-by-side to the details of the original buffer. There 43 | ;; can be many different navi-buffers alive at the same time, each one 44 | ;; of them firmly connected to its associated original 45 | ;; buffer. Switching between the 'twin-buffers' is easy and 46 | ;; fast. Typically, an outline-structured original buffer in 47 | ;; 'show-all' visibility state shares a splitted window with its 48 | ;; associated navi-buffer that either shows headlines, keywords, or a 49 | ;; combination of both. Instead of cycling visibility in the original 50 | ;; buffer itself it is often more convenient to quickly switch to its 51 | ;; navi-buffer and use its many different (over-)views. 52 | 53 | ;; Navi-mode is implemented on top of occur-mode and thus uses occur 54 | ;; as its 'search-engine'. It does not aim to replace occur-mode or to 55 | ;; compete with it, it rather specializes occur-mode for a certain 56 | ;; use-case. Using navi-mode for remotely controlling Outshine and Org 57 | ;; buffers does in no way interfere with occasionally calling 'M-x 58 | ;; occur' on these buffers. 59 | 60 | ;; Navi-mode is part of the Outshine project, consisting of the three 61 | ;; libraries outshine.el, outorg.el and navi-mode.el. For navi-mode to 62 | ;; work, the original buffer must be either an org-mode buffer or have 63 | ;; outline-minor-mode with outshine extensions activated (and be 64 | ;; structured with outshine headers, i.e. outcommented Org headers). 65 | 66 | ;;;;; Usage 67 | 68 | ;; Navi-mode is a special read-only mode (line e.g. occur-mode and 69 | ;; dired-mode), thus all its core commands have one-key 70 | ;; bindings. However, the command `navi-edit-mode' makes the 71 | ;; navi-buffer editable. The edits are directly applied in the 72 | ;; associated original buffer. With command `navi-cease-edit' the 73 | ;; default read-only mode is turned on again. 74 | 75 | ;; Navi-mode's functionality can be divided into the following 76 | ;; categories: 77 | 78 | ;; - headline searches :: keys '1' to '8' show all headlines up to that level 79 | 80 | ;; - keyword searches :: e.g. key 'f' shows functions in many major-modes 81 | 82 | ;; - combined headline and keyword searches :: e.g. 'C-3 v' shows 83 | ;; variables and headlines up to level 3 84 | 85 | ;; - navigation commands :: e.g. keys 'n' and 'p' move to the 86 | ;; next/previous line in the navi-buffer. These commands are 87 | ;; especially useful in combination with keys 'd', 'o' and 's' that 88 | ;; show the current position in the original buffer (or switch to 89 | ;; it). 90 | 91 | ;; - action commands :: call functions on the thing-at-point in the 92 | ;; navi-buffer, to be executed in the 'twin-buffer'. 93 | 94 | ;; Besides the mentioned fundamental outline-heading-searches (8 95 | ;; outline-levels) and the 5 basic keyword-searches (:FUN, :VAR, :DB, 96 | ;; :OBJ and :ALL), all languages can have their own set of searches 97 | ;; and keybindings (see customizable variables `navi-key-mappings' and 98 | ;; `navi-keywords'). 99 | 100 | ;; Use 'M-s n' (`navi-search-and-switch') to open a navi-buffer and 101 | ;; immediately switch to it. The new navi-buffer will show the 102 | ;; first-level headings of the original-buffer, with point at the 103 | ;; first entry. Here is an overview over the available commands in the 104 | ;; navi-buffer: 105 | 106 | ;; - Show headlines (up-to) different levels: 107 | 108 | ;; | key | command | function-name | 109 | ;; |---------+--------------------+----------------------| 110 | ;; | 1 ... 8 | show levels 1 to 8 | navi-generic-command | 111 | 112 | ;; - Navigate up and down in the search results shown in the navi-buffer: 113 | 114 | ;; | key | command | function-name | 115 | ;; |-----+-----------+---------------------| 116 | ;; | p | previous | occur-prev | 117 | ;; | n | next | occur-next | 118 | ;; | DEL | down page | scroll-down-command | 119 | ;; | SPC | up page | scroll-up-command | 120 | 121 | ;; - Revert the navi-buffer (seldom necessary), show help for the 122 | ;; user-defined keyword-searches, and quit the navi-buffer and switch-back 123 | ;; to the original-buffer: 124 | 125 | ;; | key | command | function-name | 126 | ;; |-----+---------------------------+----------------------| 127 | ;; | g | revert buffer | navi-revert-function | 128 | ;; | h | show help | navi-show-help | 129 | ;; | q | quit navi-mode and switch | navi-quit-and-switch | 130 | 131 | ;; - Switch to the original-buffer and back to the navi-buffer, display an 132 | ;; occurence in the original-buffer or go to the occurence: 133 | 134 | ;; | key | command | function-name | 135 | ;; |---------+------------------------+-----------------------------------| 136 | ;; | M-s n | launch navi-buffer | navi-search-and-switch | 137 | ;; | M-s s | switch to other buffer | navi-switch-to-twin-buffer | 138 | ;; | M-s M-s | | | 139 | ;; | s | | | 140 | ;; | d | display occurrence | occur-mode-display-occurrence | 141 | ;; | o | goto occurrence | navi-goto-occurrence-other-window | 142 | 143 | ;; - Structure editing on subtrees and visibility cycling 144 | 145 | ;; | key | command | function-name | 146 | ;; |-----------+--------------------------------+------------------------| 147 | ;; | TAB | cycle subtrees | navi-cycle-subtree | 148 | ;; | | cycle buffer | navi-cycle-buffer | 149 | ;; | + | Demote Subtree | navi-demote-subtree | 150 | ;; | - | promote subtree | navi-promote-subtree | 151 | ;; | ^ | move up subtree (same level) | navi-move-up-subtree | 152 | ;; | < | move down subtree (same level) | navi-move-down-subtree | 153 | 154 | ;; - Miscancellous actions on subtrees (there are more ...) 155 | 156 | ;; | key | command | function-name | 157 | ;; |-----+----------------------------+------------------------------------------| 158 | ;; | m | mark thing at point | navi-mark-thing-at-point-and-switch | 159 | ;; | c | copy thing at point | navi-copy-thing-at-point-to-register-s | 160 | ;; | k | kill thing at point | navi-kill-thing-at-point | 161 | ;; | y | yank killed/copied thing | navi-yank-thing-at-point-from-register-s | 162 | ;; | u | undo last change | navi-undo | 163 | ;; | r | narrow to thing at point | navi-narrow-to-thing-at-point | 164 | ;; | w | widen | navi-widen | 165 | ;; | l | query-replace | navi-query-replace | 166 | ;; | i | isearch | navi-isearch | 167 | ;; | e | edit as org (outorg) | navi-edit-as-org | 168 | ;; | . | call fun on thing at point | navi-act-on-thing-at-point | 169 | 170 | ;; - Furthermore, there are five (semantically) predefined keyword-searches: 171 | 172 | ;; | key | keyword-symbol | searches for | 173 | ;; |-----+----------------+----------------------------| 174 | ;; | f | :FUN | functions, macros etc. | 175 | ;; | v | :VAR | vars, consts, customs etc. | 176 | ;; | x | :OBJ | OOP (classes, methods etc) | 177 | ;; | b | :DB | DB (store and select) | 178 | ;; | a | :ALL | all | 179 | 180 | 181 | ;; - And (potentially) many more user-defined keyword-searches 182 | ;; (example Emacs Lisp): 183 | 184 | ;; #+begin_example 185 | ;; [KEY] : [SEARCH] 186 | ;; ================ 187 | ;; a : ALL 188 | ;; f : FUN 189 | ;; v : VAR 190 | ;; x : OBJ 191 | ;; b : DB 192 | ;; F : defun 193 | ;; V : defvar 194 | ;; C : defconst 195 | ;; G : defgroup 196 | ;; U : defcustom 197 | ;; A : defadvice 198 | ;; W : defalias 199 | ;; M : defmarcro 200 | ;; D : defface 201 | ;; S : defstruct 202 | ;; B : defsubst 203 | ;; L : defclass 204 | ;; I : define 205 | ;; J : declare 206 | ;; K : global-set-key 207 | ;; T : add-to-list 208 | ;; Q : setq 209 | ;; H : add-hook 210 | ;; O : hook 211 | ;; X : lambda 212 | ;; Z : ert 213 | ;; R : require 214 | 215 | ;; #+end_example 216 | 217 | ;; - Headline-searches and keyword-searches can be combined, e.g. 218 | 219 | ;; #+begin_example 220 | ;; C-2 f 221 | ;; #+end_example 222 | 223 | ;; in an Emacs Lisp (outshine-)buffer shows all headlines up-to level 2 as 224 | ;; well as all function, macro and advice definitions in the original-buffer, 225 | 226 | ;; #+begin_example 227 | ;; C-5 a 228 | ;; #+end_example 229 | 230 | ;; shows all headlines up-to level 5 as well as all functions, variables, 231 | ;; classes, methods, objects, and database-related definitions. The exact 232 | ;; meaning of the standard keyword-searches 'f' and 'a' must be defined with a 233 | ;; regexp in the customizable variable `navi-keywords' (just like the 234 | ;; user-defined keyword-searches). 235 | 236 | ;; When exploring a (potentially big) original buffer via navi-mode, a common 237 | ;; usage pattern is the following: 238 | 239 | ;; 1. type e.g '2' and go to the relevant headline 240 | ;; 2. type 'r' and e.g. '3' in sequence to narrow buffers to the subtree at 241 | ;; point and show one deeper level of headlines 242 | ;; 3. do your thing in the narrowed subtree 243 | ;; 4. type e.g. '2' and 'w' to first reduce the headline levels shown and 244 | ;; then widen the buffers again. 245 | 246 | ;;;;; Installation 247 | 248 | ;; Install the three required libraries: 249 | 250 | ;; | navi-mode.el | [[https://github.com/tj64/navi][navi-mode]] | 251 | ;; | outshine.el | [[https://github.com/tj64/outshine][outshine]] | 252 | ;; | outorg.el | [[https://github.com/tj64/outorg][outorg]] | 253 | 254 | ;; from the package-manager via MELPA or clone their github-repos. Follow 255 | ;; the installation instructions in `outshine.el' and `outorg.el'. 256 | 257 | ;; Then install `navi-mode.el' by adding 258 | 259 | ;; #+begin_example 260 | ;; (require 'navi-mode) 261 | ;; #+end_example 262 | 263 | ;; to your .emacs file. 264 | 265 | ;;;;; Emacs Version 266 | 267 | ;; `navi-mode.el' works with [GNU Emacs 24.2.1 (x86_64-unknown-linux-gnu, 268 | ;; GTK+ Version 3.6.4) of 2013-01-20 on eric]. No attempts of testing 269 | ;; with older versions or other types of Emacs have been made (yet). 270 | 271 | ;;;; ChangeLog 272 | 273 | ;; | date | author(s) | version | 274 | ;; |-----------------+-----------------+---------| 275 | ;; | <2014-09-20 Sa> | Thorsten Jolitz | 2.0 | 276 | ;; | <2013-05-03 Fr> | Thorsten Jolitz | 1.0 | 277 | ;; | <2013-03-11 Mo> | Thorsten Jolitz | 0.9 | 278 | 279 | ;;; Requires 280 | 281 | (require 'outshine) 282 | (require 'outorg) 283 | (require 'thingatpt) 284 | 285 | ;;; Mode Definitions 286 | 287 | (define-derived-mode navi-mode 288 | occur-mode "Navi" 289 | "Major mode for easy buffer-navigation. 290 | In this mode (derived from `occur-mode') you can easily navigate 291 | in an associated original-buffer via one-key commands in the 292 | navi-buffer. You can alter the displayed document structure in 293 | the navi-buffer by sending one-key commands that execute 294 | predefined occur searches in the original buffer. `navi-mode' is 295 | especially useful in buffers with outline structure, e.g. buffers 296 | with `outline-minor-mode' activated and `outshine' extensions 297 | loaded. 298 | \\{navi-mode-map}" 299 | (set (make-local-variable 'revert-buffer-function) 'navi-revert-function) 300 | ;; (setq case-fold-search nil) 301 | ) 302 | 303 | (define-derived-mode navi-edit-mode navi-mode "Navi-Edit" 304 | "Major mode for editing *Navi* buffers. 305 | In this mode, changes to the *Navi* buffer are also applied to 306 | the originating buffer. 307 | 308 | To return to ordinary Navi mode, use \\[navi-cease-edit]. 309 | \\{navi-edit-mode-map}" 310 | (setq buffer-read-only nil) 311 | (add-hook 'after-change-functions 'occur-after-change-function nil t) 312 | (message (substitute-command-keys 313 | "Editing: Type \\[navi-cease-edit] to return to Occur mode."))) 314 | 315 | 316 | ;;; Variables 317 | ;;;; Consts 318 | ;;;; Vars 319 | 320 | (defvar navi-mode-version 2.0 321 | "Version number of `navi-mode.el'") 322 | 323 | (defvar navi "navi" 324 | "Symbol that holds pairs of buffer-marker names in its plist. 325 | Keys are buffernames as keyword-symbols, values are markers that 326 | point to original-buffers") 327 | 328 | (defvar navi-regexp-quoted-line-at-point "" 329 | "Regexp that matches the line at point in navi-buffer.") 330 | 331 | (defvar navi-regexp-quoted-line-before-narrowing "" 332 | "Regexp that matched the line at point in navi-buffer before narrowing.") 333 | 334 | (defvar navi-tmp-buffer-marker (make-marker) 335 | "Marker for navi-tmp-buffer.") 336 | 337 | ;;;; Hooks 338 | 339 | ;; (defvar navi-mode-hook nil 340 | ;; "Hook run after navi-mode is called.") 341 | 342 | ;;;; Fonts 343 | ;;;; Customs 344 | ;;;;; Custom Groups 345 | 346 | (defgroup navi-mode nil 347 | "Library for outline navigation and Org-mode editing in Lisp buffers." 348 | :prefix "navi-" 349 | :group 'lisp) 350 | 351 | ;;;;; Custom Vars 352 | 353 | (defcustom navi-key-mappings 354 | '(("emacs-lisp" . ((:ALL . "a") 355 | (:FUN . "f") 356 | (:VAR . "v") 357 | (:OBJ . "x") 358 | (:DB . "b") 359 | (:defun . "F") 360 | (:defvar . "V") 361 | (:defconst . "C") 362 | (:defgroup . "G") 363 | (:defcustom . "U") 364 | (:defadvice . "A") 365 | (:defalias . "W") 366 | (:defmarcro . "M") 367 | (:defface . "D") 368 | (:defstruct . "S") 369 | (:defsubst . "B") 370 | (:defclass . "L") 371 | (:define . "I") 372 | (:declare . "J") 373 | (:global-set-key . "K") 374 | (:add-to-list . "T") 375 | (:setq . "Q") 376 | (:add-hook . "H") 377 | (:hook . "O") 378 | (:lambda . "X") 379 | (:ert . "Z") 380 | (:marker . "P") 381 | (:require . "R") 382 | (:eval-after-load . "N"))) 383 | ("ess" . ((:ALL . "a") 384 | (:FUN . "f") 385 | (:VAR . "v") 386 | (:OBJ . "x") 387 | (:DB . "b") 388 | (:objects . "X") 389 | (:methods . "Y") 390 | (:inout . "R") 391 | (:datacreation . "C") 392 | (:slicing . "[") 393 | (:varconversion . "A") 394 | (:varinfo . "I") 395 | (:dataselection . "W") 396 | (:math . "M") 397 | (:matrices . "]") 398 | (:advdataprocessing . "O") 399 | (:strings . "_") 400 | (:datestimes . ":") 401 | (:plotting . "P") 402 | (:lowlevelplotting . "L") 403 | (:trellisgraphics . "T") 404 | (:modelfitting . "~") 405 | (:statistics . "S") 406 | (:distributions . "D") 407 | (:programming . "{") 408 | (:assignment . "=") 409 | (:environment . "U"))) 410 | ("picolisp" . ((:ALL . "a") 411 | (:FUN . "f") 412 | (:VAR . "v") 413 | (:OBJ . "x") 414 | (:DB . "b") 415 | (:de . "D") 416 | (:def . "F") 417 | (:class . "C") 418 | (:dm . "M") 419 | (:rel . "R") 420 | (:var . "V") 421 | (:extend . "X") 422 | (:obj . "O") 423 | (:object . "J") 424 | (:new . "N") 425 | (:symbols . "S") 426 | (:pool . "L") 427 | (:tree . "T") 428 | (:clause . "U") 429 | (:goal . "K") 430 | (:be . "B") 431 | (:prove . "P") 432 | (:gui . "G") 433 | (:grid . "I") 434 | (:table . "A") 435 | (:spread . "Z") 436 | (:form . "Y") 437 | (:action . "W") 438 | (:html . "H"))) 439 | ("org" . (;; (:ALL . "a") 440 | ;; (:FUN . "f") 441 | ;; (:VAR . "v") 442 | ;; (:OBJ . "x") 443 | 444 | (:srcblock . "b") 445 | (:time . "x") 446 | (:inline-srcblock . "I") 447 | ;; (:affkeywords . "k") 448 | ;; (:table . "t") 449 | (:srcname-w-name . "W") 450 | (:multilineheader . "M") 451 | (:priority . "Y") 452 | (:target . "T") 453 | (:radiotarget . "R") 454 | (:drawer . "D") 455 | (:timestamp . "S") 456 | (:srcname . "N") 457 | (:result . "U") 458 | (:result-w-name . "Z") 459 | (:options . "O") 460 | (:propertydrawer . "P") 461 | (:deadline . "A") 462 | (:scheduled-time-hour . "H") 463 | ;; (:checkbox . "B") 464 | ;; (:list . "L") 465 | ;; (:propertydrawer . "P") 466 | ;; (:attr . "A") 467 | ;; (:caption . "C") 468 | ;; (:header . "H") 469 | ;; (:plot . "O") 470 | ;; (:footnotedef . "F") 471 | ;; (:latex . "X") 472 | )) 473 | ("latex" . ((:ALL . "a") 474 | (:FUN . "f") 475 | (:VAR . "v") 476 | (:OBJ . "x") 477 | (:figure . "F") 478 | (:table . "T") 479 | (:listing . "L") 480 | (:index . "I") 481 | (:ref . "R") 482 | (:refrange . "A") 483 | (:refall . "V")))) 484 | 485 | "Mappings between keybindings and keyword-symbols used in `navi-keywords'. 486 | 487 | All ASCII printing characters (see 488 | http://www.csgnetwork.com/asciiset.html) are available as keys, 489 | except those used for the core commands of 'navi-mode' itself: 490 | 491 | | key | command | 492 | |-----+--------------------------------| 493 | | p | previous | 494 | | n | next | 495 | | DEL | page up | 496 | | SPC | page down | 497 | | g | revert buffer | 498 | | d | display occurrence | 499 | | o | goto occurrence | 500 | | c | copy subtree | 501 | | e | edit subtree as org | 502 | | E | make navi-buffer editable | 503 | | m | mark subtree | 504 | | u | undo last change | 505 | | z | mail subtree | 506 | | r | narrow to subtree | 507 | | w | widen | 508 | | s | switch (to original buffer) | 509 | | k | kill subtree | 510 | | i | isearch in subtree | 511 | | l | query-replace in subtree | 512 | | y | yank killed/copied subtree | 513 | | q | quit navi-mode and switch | 514 | | h | show help | 515 | | + | demote subtree | 516 | | - | promote subtree | 517 | | \^ | move up subtree (same level) | 518 | | < | move down subtree (same level) | 519 | 520 | 521 | And you should not use the following keys and (uppercase) 522 | keyword-symbols for other than the (semantically) predefined 523 | keywords-searches. They define the 5 standard occur-searches that 524 | should be available for every programming language, with the same 525 | keybindings and similar semantics: 526 | 527 | | key | keyword-symbol | command | 528 | |-----+----------------+----------------------------| 529 | | f | :FUN | functions, macros etc. | 530 | | v | :VAR | vars, consts, customs etc. | 531 | | x | :OBJ | OOP (classes, methods etc) | 532 | | b | :DB | DB (store and select) | 533 | | a | :ALL | all | 534 | 535 | All other ASCII printing characters are free and can be used as 536 | one-key keybindings for occur-searches for a programming 537 | language. The keybindings are independent for different 538 | programming languages, so while it would be a good thing to have 539 | similar bindings in different languages, it is by no means 540 | necessary. 541 | 542 | Defining occur-searches for a programming language is a two-step 543 | process: 544 | 545 | 1. Customize `navi-key-mappings', i.e. add a new language-alist 546 | and populate it with pairs of keyword-symbols (that should 547 | represent the language keywords searched for) and ASCII 548 | characters (as strings of length 1). 549 | 550 | 2. Customize `navi-keywords', i.e. add a new language alist and 551 | populate it with pairs of keyword-symbols (that should 552 | represent the language keywords searched for) and regexps, 553 | using exactly the same keyword-symbols as in 554 | `navi-key-mappings'. 555 | 556 | Thus, the following two entries together will map the keybinding 557 | 'a' to an occur-search with the regexp: 558 | 559 | \"^[[:space:]]*(def[a-z]+\": 560 | 561 | ;; #+begin_src emacs-lisp 562 | ;; (defcustom navi-key-mappings 563 | ;; '((\"emacs-lisp\" . ((:ALL . \"a\") ... )))) 564 | 565 | ;; (defcustom navi-keywords 566 | ;; '((\"emacs-lisp\" . ((:ALL . \"^[[:space:]]*(def[a-z]+ \") ...)))) 567 | ;; #+end_src 568 | 569 | There is no need for a third step - defining the keybindings. In 570 | `navi-mode', there are by default keybindings defined for all 571 | ASCII printing characters. Conditional on the programming 572 | language major-mode of the original-buffer, navi-mode checks the 573 | customizable variables `navi-key-mappings' and `navi-keywords' 574 | for an entry with a key pressed by the user. If it doesn't find 575 | one, nothing happens, if it finds one, it looks up the associated 576 | regexp and performs an occur-search with it." 577 | :group 'navi-mode 578 | :type '(alist :key-type string 579 | :value-type alist)) 580 | 581 | (defcustom navi-keywords 582 | '(("emacs-lisp" . ((:ALL . "^[[:space:]]*(\\(use-package[[:space:]]+\\|\\(cl-\\)\\{0,1\\}def[a-z]+\\)\\*? ") 583 | (:OBJ . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}def[smc][^auo][a-z]+ ") 584 | (:VAR . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}def[vcgf][^l][a-z]+ ") 585 | (:FUN 586 | . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}*def[maus][^eltu][a-z]*\\*? ") 587 | (:defun . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}*defun\\*? ") 588 | (:defvar . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defvar ") 589 | (:defconst . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defconst ") 590 | (:defgroup . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defgroup ") 591 | (:defcustom . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defcustom ") 592 | (:defadvice . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defadvice ") 593 | (:defalias . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defalias ") 594 | (:defmarcro . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defmacro\\*? ") 595 | (:defface . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defface ") 596 | (:defstruct . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defstruct ") 597 | (:defsubst . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defsubst ") 598 | (:defclass . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defclass ") 599 | (:defmethod . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}defmethod ") 600 | (:declare . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}declare-") 601 | (:define . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}define-") 602 | (:global-set-key 603 | . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}global-set-key ") 604 | (:add-to-list . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}add-to-list ") 605 | (:setq . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}setq ") 606 | (:add-hook . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}add-hook ") 607 | (:hook . "-hook-?") 608 | (:lambda . "(lambda (") 609 | (:ert . "^[[:space:]]*(ert-") 610 | (:marker . "^[[:space:]]*([a-z]+-marker") 611 | (:require . "^[[:space:]]*([a-z-]*require ") 612 | (:eval-after-load 613 | . "^[[:space:]]*(\\(cl-\\)\\{0,1\\}eval-after-load ") 614 | (:use-package . (rx bol (0+ space) "(" (0+ space) (group "use-package" (1+ space) (1+ not-newline)))))) 615 | ("ess" . ((:ALL . (concat 616 | "\\(" 617 | "[^\s\t\n]* ? ?") 778 | (:table . "^[[:space:]]*( ?") 779 | (:spread . "^[[:space:]]*( ?") 780 | (:form . "^[[:space:]]*([^ ]*form ?") 781 | (:action . "^[[:space:]]*(action ?") 782 | (:html . "^[[:space:]]*(html ?") 783 | (:ALL . (concat 784 | "^[[:space:]]*(" 785 | "\\(de \\|" 786 | "def \\|" 787 | "symbols \\|" 788 | "var \\|" 789 | "class \\|" 790 | "extend \\|" 791 | "dm \\|" 792 | "var \\|" 793 | "rel \\|" 794 | "pool \\|" 795 | "obj \\|" 796 | "object \\|" 797 | "tree \\|" 798 | "new \\|" 799 | "prove \\|" 800 | "clause \\|" 801 | "goal \\|" 802 | "be \\)")) 803 | (:VAR . (concat 804 | "^[[:space:]]*(" 805 | "\\(var \\|" 806 | "rel \\)")) 807 | (:OBJ . (concat 808 | "^[[:space:]]*(" 809 | "\\(class \\|" 810 | "extend \\|" 811 | "dm \\|" 812 | "var \\|" 813 | "rel \\)")) 814 | (:DB . (concat 815 | "^[[:space:]]*(" 816 | "\\(pool \\|" 817 | "obj \\|" 818 | "object \\|" 819 | "tree \\|" 820 | "new \\|" 821 | "prove \\|" 822 | "clause \\|" 823 | "goal \\|" 824 | "be \\)")) 825 | (:FUN . (concat 826 | "^[[:space:]]*(" 827 | "\\(de \\|" 828 | "def \\|" 829 | "symbols \\)")))) 830 | ("org" . ((:srcblock 831 | . (concat 832 | ;; (1) indentation (2) lang 833 | "^\\([ \t]*\\)#\\+begin_src[ \t]+\\([^ \f\t\n\r\v]+\\)[ \t]*" 834 | ;; (3) switches 835 | "\\([^\":\n]*\"[^\"\n*]*\"[^\":\n]*\\|[^\":\n]*\\)" 836 | ;; (4) header arguments 837 | "\\([^\n]*\\)")) 838 | ;; ;; (5) body 839 | ;; "\n\\([^\000]*?\n\\)?[ \t]*#\\+end_src") 840 | (:inline-srcblock 841 | . (concat 842 | ;; (1) replacement target (2) lang 843 | "\\(?:^\\|[^-[:alnum:]]\\)\\(src_\\([^ \f\t\n\r\v]+\\)" 844 | ;; (3,4) (unused, headers) 845 | "\\(\\|\\[\\(.*?\\)\\]\\)" 846 | ;; (5) body 847 | "{\\([^\f\n\r\v]+?\\)}\\)")) 848 | ;; (:affkeywords . "k") 849 | ;; (:table . "t") 850 | (:srcname-w-name 851 | . (concat "^[ \t]*#\\+name:[ \t]*" 852 | "\\(" 853 | "^[ \t]*#\\+headers?:[ \t]*\\([^\n]*\\)$" 854 | "\\)*" 855 | "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)")) 856 | (:multilineheader 857 | . "^[ \t]*#\\+headers?:[ \t]*\\([^\n]*\\)$") 858 | (:srcname . "^[ \t]*#\\+name:[ \t]*") 859 | (:priority . ".*?\\(\\[#\\([A-Z0-9]\\)\\] ?\\)") 860 | (:radiotarget . "<<<\\([^<>\n\r]+\\)>>>") 861 | (:target . "<<\\([^<>\n\r]+\\)>>") 862 | (:propertydrawer 863 | . (concat "\\(^[ \\t]*:PROPERTIES:[ \\t]*$\\)[^\\000]*?" 864 | "\\(^[ \\t]*:END:[ \\t]*$\\)\\n?")) 865 | (:timestamp 866 | . (concat "<\\([0-9]\\{4\\}-[0-9]\\{2\\}" 867 | "-[0-9]\\{2\\} ?[^\r\n>]*?\\)>")) 868 | (:result 869 | . (concat "^[ \t]*#\\+" 870 | (regexp-opt org-babel-data-names t) 871 | "\\(\\[\\(" 872 | ;; FIXME The string below is `org-ts-regexp' 873 | "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?" 874 | "[^\r\n>]*?\\)>" 875 | " \\)?\\([[:alnum:]]+\\)\\]\\)?\\:[ \t]*")) 876 | 877 | (:result-w-name 878 | . (concat "\\(" 879 | "^[ \t]*#\\+" 880 | (regexp-opt org-babel-data-names t) 881 | "\\(\\[\\(" 882 | ;; FIXME The string below is `org-ts-regexp' 883 | "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ?" 884 | "[^\r\n>]*?\\)>" 885 | " \\)?\\([[:alnum:]]+\\)\\]\\)?\\:[ \t]*" 886 | "\\([^ ()\f\t\n\r\v]+\\)\\(\(\\(.*\\)\)\\|\\)" 887 | "\\)")) 888 | (:options 889 | . (concat 890 | "^#\\+\\(CATEGORY\\|TODO\\|COLUMNS\\|STARTUP\\|ARCHIVE\\|" 891 | "LINK\\|PRIORITIES\\|CONSTANTS\\|PROPERTY\\|DRAWERS\\|" 892 | "SETUPFILE\\|OPTIONS\\|\\(?:[a-zA-Z][0-9a-zA-Z_]*_TODO\\)" 893 | "\\):[ ]*\\(.*\\)")) 894 | (:drawer . "^[ ]*:\\(PROPERTIES\\|LOGBOOK\\):[ ]*$") 895 | (:deadline . "\\<\\(DEADLINE:\\).*") 896 | (:scheduled-time-hour 897 | . "\\]*\\)>") 898 | (:time 899 | . (conat "\\(\\<\\(SCHEDULED:\\|DEADLINE:\\|CLOSED:\\|" 900 | "CLOCK:\\)\\)? *\\([[<][0-9]\\{4\\}-[0-9]\\{2\\}" 901 | "-[0-9]\\{2\\} ?[^]\r\n>]*?[]>]\\|<%%([^\r\n>]*>\\)")) 902 | ;; (:checkbox . "B") 903 | ;; (:list . "L") 904 | 905 | ;; (:attr . "A") 906 | ;; (:caption . "C") 907 | ;; (:header . "H") 908 | ;; (:name . "N") 909 | ;; (:plot . "O") 910 | ;; (:footnotedef . "F") 911 | ;; (:latex . "X") 912 | )) 913 | ("latex" . ((:ALL . (concat 914 | "^[[:space:]]*\\\\[[:word:]]+" 915 | "\\(?:\\[.*]\\)?\\(?:{.+}\\)?")) 916 | (:FUN . (concat 917 | "^[[:space:]]*\\\\[[:word:]]+" 918 | "\\(?:\\[.*]\\)[^{]")) 919 | (:VAR . (concat 920 | "^[[:space:]]*\\\\[[:word:]]+" 921 | "\\(?:\\[.*]\\)\\(?:{.+}\\)")) 922 | (:OBJ . (concat 923 | "^[[:space:]]*\\\\[[:word:]]+" 924 | "\\(?:{.*}\\)")) 925 | (:figure . (concat 926 | "^[[:space:]]*\\\\begin{figure}" 927 | "[^^\000]+?\\\\end{figure}")) 928 | (:table . (concat 929 | "^[[:space:]]*\\\\begin{table}" 930 | "[^^\000]+?\\\\end{table}")) 931 | (:listing . (concat 932 | "^[[:space:]]*\\\\begin{listing}" 933 | "[^^\000]+?\\\\end{listing}")) 934 | (:index . "\\\\index{[^^\000]+?}") 935 | (:ref . "\\\\v?ref{[^^\000]+?}") 936 | (:refrange . (concat 937 | "\\\\vrefrange{[^^\000]+?}" 938 | "{[^^\000]+?}")) 939 | (:refall . "\\\\v?ref")))) 940 | 941 | "Alist of language-specific keywords for occur-searches in 942 | navi-mode. 943 | 944 | This customization variable holds a nested alist with 2 levels: 945 | 946 | 1st level: 947 | 948 | The name of the language (key-string) should be the associated 949 | major-mode name without the '-mode' suffix. Run 'M-x major-mode' 950 | in a buffer to find out about the name, in an Emacs Lisp buffer 951 | you get 'emacs-lisp-mode', in a PicoLisp buffer you get 952 | 'picolisp-mode', thus the alist keys for these two languages 953 | should be 'emacs-lisp' and 'picolisp'. 954 | 955 | 2nd level: 956 | 957 | The keys of each language-alist are keywords-symbols used for 958 | selecting the regexp, the value is the regexp itself" 959 | :group 'navi-mode 960 | :type '(alist :key-type string 961 | :value-type alist)) 962 | 963 | ;;; Defuns 964 | ;;;; Functions 965 | ;;;;; Hook Function 966 | 967 | ;; (defun navi-mode-hook-function () 968 | ;; "Function to be run after `navi-mode' is loaded.") 969 | 970 | ;;;;; Utility Functions 971 | 972 | ;; copied from http://www.emacswiki.org/emacs/basic-edit-toolkit.el 973 | (defun navi-underline-line-with (char) 974 | "Insert some char below at current line." 975 | (interactive "cType one char: ") 976 | (save-excursion 977 | (let ((length (- (point-at-eol) (point-at-bol)))) 978 | (end-of-line) 979 | (insert "\n") 980 | (insert (make-string length char))))) 981 | 982 | (defun navi-non-empty-string-p (str) 983 | "Return t if function argument STR is a string of length > 0, nil otherwise." 984 | (if (and (stringp str) (> (length str) 0)) 985 | str 986 | nil)) 987 | 988 | ;;;;; Navi Generic Command 989 | 990 | (defun navi-map-keyboard-to-key (language kbd-key) 991 | "Map pressed keyboard-key KBD-KEY to key in `navi-keywords'." 992 | (let ((mappings (navi-get-language-alist language 'MAPPINGS))) 993 | (and (rassoc kbd-key mappings) 994 | (car (rassoc kbd-key mappings))))) 995 | 996 | (defun navi-msg (key language) 997 | "Tell user that key is not defined for language." 998 | (message "Key %s is not defined for language %s" key language)) 999 | 1000 | ;;;;; Occur Search 1001 | 1002 | ;; modified `occur-1' from `replace.el' 1003 | (defun navi-1 (regexp nlines bufs &optional buf-name) 1004 | (unless (and regexp (not (equal regexp ""))) 1005 | (error "Occur doesn't work with the empty regexp")) 1006 | (unless buf-name 1007 | (setq buf-name "*Navi*")) 1008 | (let (occur-buf 1009 | (active-bufs (delq nil (mapcar #'(lambda (buf) 1010 | (when (buffer-live-p buf) buf)) 1011 | bufs)))) 1012 | ;; Handle the case where one of the buffers we're searching is the 1013 | ;; output buffer. Just rename it. 1014 | (when (member buf-name (mapcar 'buffer-name active-bufs)) 1015 | (with-current-buffer (get-buffer buf-name) 1016 | (rename-uniquely))) 1017 | 1018 | ;; Now find or create the output buffer. 1019 | ;; If we just renamed that buffer, we will make a new one here. 1020 | (setq occur-buf (get-buffer-create buf-name)) 1021 | 1022 | (with-temp-buffer 1023 | (move-marker navi-tmp-buffer-marker (point)) 1024 | (if (stringp nlines) 1025 | (fundamental-mode) ;; This is for collect operation. 1026 | (navi-mode)) 1027 | (let ((inhibit-read-only t) 1028 | ;; Don't generate undo entries for creation of the initial contents. 1029 | (buffer-undo-list t)) 1030 | (let ((count 1031 | (if (stringp nlines) 1032 | ;; Treat nlines as a regexp to collect. 1033 | (let ((bufs active-bufs) 1034 | (count 0)) 1035 | (while bufs 1036 | (with-current-buffer (car bufs) 1037 | (save-excursion 1038 | (goto-char (point-min)) 1039 | (while (re-search-forward regexp nil t) 1040 | ;; Insert the replacement regexp. 1041 | (let ((str (match-substitute-replacement nlines))) 1042 | (if str 1043 | (with-current-buffer 1044 | (marker-buffer navi-tmp-buffer-marker) 1045 | (insert str) 1046 | (setq count (1+ count)) 1047 | (or (zerop (current-column)) 1048 | (insert "\n")))))))) 1049 | (setq bufs (cdr bufs))) 1050 | count) 1051 | ;; Perform normal occur. 1052 | (occur-engine 1053 | regexp active-bufs (marker-buffer navi-tmp-buffer-marker) 1054 | (or nlines list-matching-lines-default-context-lines) 1055 | (if (and case-fold-search search-upper-case) 1056 | (isearch-no-upper-case-p regexp t) 1057 | case-fold-search) 1058 | list-matching-lines-buffer-name-face 1059 | nil list-matching-lines-face 1060 | (not (eq occur-excluded-properties t)))))) 1061 | (let* ((bufcount (length active-bufs)) 1062 | (diff (- (length bufs) bufcount))) 1063 | (message "Searched %d buffer%s%s; %s match%s%s" 1064 | bufcount (if (= bufcount 1) "" "s") 1065 | (if (zerop diff) "" (format " (%d killed)" diff)) 1066 | (if (zerop count) "no" (format "%d" count)) 1067 | (if (= count 1) "" "es") 1068 | ;; Don't display regexp if with remaining text 1069 | ;; it is longer than window-width. 1070 | (if (> (+ (length regexp) 42) (window-width)) 1071 | "" (format " for `%s'" (query-replace-descr regexp))))) 1072 | (if (= count 0) 1073 | nil 1074 | (with-current-buffer occur-buf 1075 | (setq occur-revert-arguments (list regexp nlines bufs)) 1076 | (erase-buffer) 1077 | (insert-buffer-substring 1078 | (marker-buffer navi-tmp-buffer-marker)) 1079 | (display-buffer occur-buf) 1080 | (setq next-error-last-buffer occur-buf) 1081 | (setq buffer-read-only t) 1082 | (set-buffer-modified-p nil) 1083 | (run-hooks 'occur-hook))))) 1084 | (set-marker navi-tmp-buffer-marker nil)))) 1085 | 1086 | (defun navi-show-headers (level &optional args) 1087 | "Show headers up-to level LEVEL." 1088 | (let ((org-promo-headers 1089 | (and (eq major-mode 'navi-mode) 1090 | (with-current-buffer 1091 | (marker-buffer 1092 | (cadr (navi-get-twin-buffer-markers))) 1093 | (and 1094 | (eq major-mode 'org-mode) 1095 | outline-promotion-headings))))) 1096 | (if args 1097 | (navi-revert-function 1098 | (if org-promo-headers 1099 | (navi-calc-org-mode-headline-regexp 1100 | level 1101 | org-promo-headers 1102 | 'NO-PARENT-LEVELS) 1103 | (navi-calc-headline-regexp level 'NO-PARENT-LEVELS))) 1104 | (navi-revert-function 1105 | (if org-promo-headers 1106 | (navi-calc-org-mode-headline-regexp 1107 | level 1108 | org-promo-headers) 1109 | (navi-calc-headline-regexp level)))))) 1110 | 1111 | 1112 | (defun navi-show-keywords (key) 1113 | "Show matches of occur-search with KEY. 1114 | Language is derived from major-mode." 1115 | (let ((language (navi-get-language-name))) 1116 | (navi-revert-function 1117 | (navi-get-regexp language 1118 | (navi-map-keyboard-to-key language key))))) 1119 | 1120 | (defun navi-show-headers-and-keywords (level key &optional args) 1121 | "Show headers up-to level LEVEL and matches of occur-search with KEY. 1122 | Language is derived from major-mode." 1123 | (let* ((language (navi-get-language-name)) 1124 | (org-promo-headers 1125 | (and (eq major-mode 'navi-mode) 1126 | (with-current-buffer 1127 | (marker-buffer 1128 | (cadr (navi-get-twin-buffer-markers))) 1129 | (and 1130 | (eq major-mode 'org-mode) 1131 | outline-promotion-headings)))) 1132 | (rgxp 1133 | (navi-make-regexp-alternatives 1134 | (if args 1135 | (if org-promo-headers 1136 | (navi-calc-org-mode-headline-regexp 1137 | level 1138 | org-promo-headers 1139 | 'NO-PARENT-LEVELS) 1140 | (navi-calc-headline-regexp level 'NO-PARENT-LEVELS)) 1141 | (if org-promo-headers 1142 | (navi-calc-org-mode-headline-regexp 1143 | level 1144 | org-promo-headers) 1145 | (navi-calc-headline-regexp level))) 1146 | (navi-get-regexp language 1147 | (navi-map-keyboard-to-key language key))))) 1148 | (navi-revert-function rgxp))) 1149 | 1150 | ;;;;; Regexps 1151 | 1152 | (defun navi-get-regexp (language key) 1153 | "Return the value of KEY for LANGUAGE in `navi-keywords'." 1154 | (if (not (and (navi-non-empty-string-p language) 1155 | (assoc language navi-keywords))) 1156 | (progn 1157 | (message 1158 | (format "%s%s%s" 1159 | "Language " 1160 | language 1161 | " not registered in 'navi-keywords'")) 1162 | nil) 1163 | (let* ((result (assoc key (cdr (assoc language navi-keywords)))) 1164 | (rgxp (and result (cdr result)))) 1165 | (cond 1166 | ((stringp rgxp) rgxp) 1167 | ((and (listp rgxp) (functionp (car rgxp)) (eval rgxp))) 1168 | (t nil))))) 1169 | 1170 | ;; TODO deeper test of the results 1171 | (defun navi-make-regexp-alternatives (&rest rgxps) 1172 | "Enclose the set of regexp alternatives. 1173 | The regexps are given as the list of strings RGXPS." 1174 | (and rgxps 1175 | (replace-regexp-in-string 1176 | (regexp-quote "\\|\\)") 1177 | (regexp-quote "\\)") 1178 | (concat 1179 | "\\(" 1180 | (mapconcat 1181 | 'identity rgxps "\\|") 1182 | "\\)")))) 1183 | 1184 | (defun navi-calc-headline-regexp (level &optional NO-PARENT-LEVELS) 1185 | "Calculate regexp to show headers of original-buffer. 1186 | Regexp should result in an occur-search showing up to 1187 | outline-level LEVEL headlines in navi-buffer. If NO-PARENT-LEVELS 1188 | in non-nil, only headers of level LEVEL are shown." 1189 | (let* ((orig-buf (marker-buffer 1190 | (cadr (navi-get-twin-buffer-markers)))) 1191 | (outline-base-string 1192 | (with-current-buffer orig-buf 1193 | (outshine-transform-normalized-outline-regexp-base-to-string))) 1194 | (rgxp-string 1195 | (regexp-quote 1196 | (outshine-chomp 1197 | (format 1198 | "%s" (car (rassoc 1 (with-current-buffer orig-buf 1199 | outline-promotion-headings))))))) 1200 | (rgxp (if (not (and level 1201 | (integer-or-marker-p level) 1202 | (>= level 1) 1203 | (<= level 8))) 1204 | (error "Level must be an integer between 1 and 8") 1205 | (if NO-PARENT-LEVELS 1206 | (regexp-quote 1207 | (format 1208 | "%s" 1209 | (car 1210 | (rassoc level 1211 | (with-current-buffer orig-buf 1212 | outline-promotion-headings))))) 1213 | (concat 1214 | (dotimes (i (1- level) rgxp-string) 1215 | (setq rgxp-string 1216 | (concat rgxp-string 1217 | (regexp-quote 1218 | outline-base-string) 1219 | "?"))) 1220 | " "))))) 1221 | (concat "^" rgxp))) 1222 | 1223 | ;;;;; Keyword Searches 1224 | 1225 | (defun navi-get-language-alist (language &optional MAPPINGS) 1226 | "Return the alist with keys and regexps for LANGUAGE from `navi-keywords'. 1227 | If MAPPINGS is non-nil, return the alist with key-mappings from 1228 | `navi-key-mappings' instead." 1229 | (let ((custom-alist (if MAPPINGS navi-key-mappings navi-keywords))) 1230 | (if (not (and (navi-non-empty-string-p language) 1231 | (assoc language custom-alist))) 1232 | (message "Language not registered in customizable variable `%s'" 1233 | (symbol-name custom-alist)) 1234 | (cdr (assoc language custom-alist))))) 1235 | 1236 | ;;;;; Navi Buffer 1237 | 1238 | (defun navi-set-regexp-quoted-line-at-point () 1239 | "Set `navi-regexp-quoted-line-at-point' to the value calculated by 1240 | `navi-regexp-quote-line-at-point'." 1241 | (setq navi-regexp-quoted-line-at-point 1242 | (navi-regexp-quote-line-at-point)) 1243 | (format "%s" navi-regexp-quoted-line-at-point)) 1244 | 1245 | (defun navi-regexp-quote-line-at-point () 1246 | "Store a quoted regexp for line at point. 1247 | Leading and trailing whitespace is deleted." 1248 | ;; (setq navi-regexp-quoted-line-at-point 1249 | (regexp-quote 1250 | (outshine-chomp 1251 | (substring-no-properties 1252 | (buffer-string) (point-at-bol) (point-at-eol))))) 1253 | ;; (format "%s" navi-regexp-quoted-line-at-point)) 1254 | 1255 | (defun navi-get-line-number-from-regexp-quoted-line-at-point (rgxp) 1256 | "Return as Integer the line number in regexp-quoted-line-at-point." 1257 | (string-to-number 1258 | (car (split-string rgxp ":" 'OMIT-NULLS)))) 1259 | 1260 | (defun navi-in-buffer-headline-p () 1261 | "Return `line-number-at-position' if in first line, nil otherwise." 1262 | (and (eq major-mode 'navi-mode) 1263 | (if (eq (line-number-at-pos) 1) 1 nil))) 1264 | 1265 | (defun navi-search-less-or-equal-line-number (&optional num) 1266 | "Search closest result-line to given line-number. 1267 | This function searches a result-line in a navi-buffer with 1268 | line-number less-or-equal to line-number of 1269 | `navi-regexp-quoted-line-at-point' or NUM. Its not about 1270 | line-numbers in the navi-buffer, but about the line-numbers in 1271 | the original-buffer shown in the occur-search results." 1272 | (let* ((line-num (or 1273 | (and num (integer-or-marker-p num) (>= num 1) num) 1274 | (navi-get-line-number-from-regexp-quoted-line-at-point 1275 | navi-regexp-quoted-line-at-point))) 1276 | (line-num-str (int-to-string line-num)) 1277 | (match-point)) 1278 | (save-excursion 1279 | (goto-char (point-min)) 1280 | (forward-line) 1281 | (unless (< line-num 1282 | (navi-get-line-number-from-regexp-quoted-line-at-point 1283 | (navi-regexp-quote-line-at-point))) 1284 | (forward-line -1) 1285 | (while (and (>= line-num 1) 1286 | (not 1287 | (setq match-point 1288 | (re-search-forward 1289 | (concat "^[[:space:]]*" 1290 | line-num-str 1291 | ":") 1292 | nil 'NO-ERROR)))) 1293 | (goto-char (point-min)) 1294 | (setq line-num (1- line-num)) 1295 | (setq line-num-str (int-to-string line-num))) 1296 | (if match-point 1297 | (goto-char match-point) 1298 | (forward-line))) 1299 | (forward-line) 1300 | (occur-prev) 1301 | (point)))) 1302 | 1303 | 1304 | ;; modified `occur-rename-buffer' from `replace.el' 1305 | (defun navi-rename-buffer (&optional unique-p) 1306 | "Rename the current *Occur* buffer to *Navi:original-buffer-name*. 1307 | Here `original-buffer-name' is the buffer name where Occur was 1308 | originally run. When given the prefix argument, the renaming will 1309 | not clobber the existing buffer(s) of that name, but use 1310 | `generate-new-buffer-name' instead. You can add this to 1311 | `occur-hook' if you always want a separate *Occur* buffer for 1312 | each buffer where you invoke `occur'." 1313 | (let ((orig-buffer-name "")) 1314 | (with-current-buffer 1315 | (if (eq major-mode 'occur-mode) (current-buffer) (get-buffer "*Occur*")) 1316 | (setq orig-buffer-name 1317 | (mapconcat 1318 | #'buffer-name 1319 | (car (cddr occur-revert-arguments)) "/")) 1320 | (rename-buffer (concat "*Navi:" orig-buffer-name "*") unique-p) 1321 | ;; make marker for this navi-buffer 1322 | ;; and store it in `navi''s plist 1323 | (put 'navi 1324 | (navi-make-buffer-key) 1325 | (set 1326 | (intern 1327 | (navi-make-marker-name 1328 | (cadr (split-string (buffer-name) "[*:]" 'OMIT-NULLS)))) 1329 | (point-marker)))))) 1330 | 1331 | ;; (add-to-list 'occur-hook 'navi-rename-buffer) 1332 | 1333 | (defun navi-clean-up () 1334 | "Clean up `navi' plist and left-over markers after killing navi-buffer." 1335 | (setq navi-revert-arguments nil) ; FIXME 1336 | (setq navi-regexp-quoted-line-at-point nil) 1337 | (mapc 1338 | (lambda (marker) (set-marker marker nil)) 1339 | (navi-get-twin-buffer-markers))) 1340 | 1341 | 1342 | ;;;;; Twin Buffers 1343 | 1344 | (defun navi-make-buffer-key (&optional buf) 1345 | "Return the (current) buffer-name or string BUF as interned keyword-symbol" 1346 | (let* ((split-str (split-string (or buf (buffer-name)) "[*]" 'OMIT-NULLS)) 1347 | (buf-name 1348 | (if (> (length split-str) 1) 1349 | (file-name-sans-extension 1350 | (mapconcat 'identity split-str "")) 1351 | (file-name-sans-extension (car split-str))))) 1352 | (intern (concat ":" buf-name)))) 1353 | 1354 | (defun navi-make-marker-name (&optional buf) 1355 | "Return marker-name by expansion of (current) buffer-name or string BUF." 1356 | (let ((buf-name 1357 | (file-name-sans-extension 1358 | (car (split-string (or buf (buffer-name)) 1359 | "[*]" 'OMIT-NULLS))))) 1360 | (concat buf-name "-marker"))) 1361 | 1362 | (defun navi-get-twin-buffer-markers () 1363 | "Return list with two markers pointing to buffer-twins or nil. 1364 | CAR of the return-list is always the marker pointing to 1365 | current-buffer, CADR the marker pointing to its twin-buffer." 1366 | (let* ((curr-buf-split 1367 | (split-string (buffer-name) "[*:]" 'OMIT-NULLS)) 1368 | (is-navi-buffer-p 1369 | (string-equal (car curr-buf-split) "Navi")) 1370 | (twin-of-navi 1371 | (and is-navi-buffer-p 1372 | (get 'navi (navi-make-buffer-key (cadr curr-buf-split))))) 1373 | (self-navi 1374 | (and is-navi-buffer-p 1375 | (get 'navi (navi-make-buffer-key 1376 | (concat 1377 | (car curr-buf-split) 1378 | ":" 1379 | (cadr curr-buf-split)))))) 1380 | (twin-of-orig 1381 | (unless is-navi-buffer-p 1382 | (get 'navi (navi-make-buffer-key 1383 | (concat "Navi:" (car curr-buf-split)))))) 1384 | (self-orig 1385 | (unless is-navi-buffer-p 1386 | (get 'navi (navi-make-buffer-key (car curr-buf-split)))))) 1387 | (if is-navi-buffer-p 1388 | (and self-navi twin-of-navi 1389 | (list self-navi twin-of-navi)) 1390 | (and self-orig twin-of-orig 1391 | (list self-orig twin-of-orig))))) 1392 | 1393 | (defun navi-get-language-name () 1394 | "Return language name for major-mode of original-buffer." 1395 | (with-current-buffer 1396 | (marker-buffer 1397 | (cadr (navi-get-twin-buffer-markers))) 1398 | (car 1399 | (split-string 1400 | (symbol-name major-mode) 1401 | "-mode" 'OMIT-NULLS)))) 1402 | 1403 | ;;;;; Special Case Org-mode 1404 | 1405 | ;; special treatment for Org-mode buffers 1406 | (defun navi-make-org-mode-promotion-headings-list () 1407 | "Make a sorted list of headings used for promotion/demotion commands. 1408 | Set this to a list of MAX-LEVEL headings as they are matched by 1409 | `outline-regexp', top-level heading first." 1410 | (setq outline-promotion-headings 1411 | '(("* " . 1) 1412 | ("** " . 2) 1413 | ("*** " . 3) 1414 | ("**** " . 4) 1415 | ("***** " . 5) 1416 | ("****** " . 6) 1417 | ("******* " . 7) 1418 | ("******** " . 8))) 1419 | (make-variable-buffer-local 'outline-promotion-headings)) 1420 | (org-add-hook 'org-mode-hook 'navi-make-org-mode-promotion-headings-list) 1421 | 1422 | ;; special treatment for Org-mode buffers 1423 | (defun navi-calc-org-mode-headline-regexp 1424 | (level &optional org-promo-headers NO-PARENT-LEVELS) 1425 | "Calculate regexp to show headers of original Org-mode buffer. 1426 | Regexp should result in an occur-search showing up to 1427 | outline-level LEVEL headlines in navi-buffer. If NO-PARENT-LEVELS 1428 | in non-nil, only headers of level LEVEL are shown." 1429 | (if (not (and level 1430 | (integer-or-marker-p level) 1431 | (>= level 1) 1432 | (<= level 8))) 1433 | (error "Level must be an integer between 1 and 8") 1434 | (let ((headline-string 1435 | (car 1436 | (rassoc 1437 | level 1438 | (or org-promo-headers 1439 | outline-promotion-headings))))) 1440 | (concat 1441 | "^" 1442 | (if NO-PARENT-LEVELS 1443 | (regexp-quote headline-string) 1444 | (replace-regexp-in-string 1445 | "\\*" "\\\\*" 1446 | (replace-regexp-in-string 1447 | "\\(\\*\\?\\).*\\'" "*" 1448 | (mapconcat 'identity (split-string headline-string "" t) "?") 1449 | nil nil 1))))))) 1450 | 1451 | ;; (add-to-list 'occur-hook 'navi-rename-buffer) 1452 | 1453 | ;;;;; Use Outorg 1454 | 1455 | (defun navi-use-outorg (fun-no-prefix) 1456 | "Call prefixed FUN-NO-PREFIX from navi-mode. 1457 | If the associated original (twin-) buffer is an Org-mode buffer, 1458 | call the relevant Org command directly, i.e. add `org-' prefix to 1459 | FUN-NO-PREFIX, otherwise add `outshine-' prefix and thus call the 1460 | 'outshine-use-outorg' function." 1461 | (let ((fun (intern 1462 | (format "%s%s" 1463 | (with-current-buffer 1464 | (marker-buffer 1465 | (cadr (navi-get-twin-buffer-markers))) 1466 | (if (eq major-mode 'org-mode) 1467 | "org-" 1468 | "outshine-")) 1469 | fun-no-prefix)))) 1470 | (navi-goto-occurrence-other-window) 1471 | (call-interactively fun) 1472 | (navi-switch-to-twin-buffer))) 1473 | 1474 | ;;;; Commands 1475 | 1476 | ;;;;; Navi Edit Mode 1477 | 1478 | (defun navi-cease-edit () 1479 | "Switch from Navi Edit mode to Navi mode." 1480 | (interactive) 1481 | (when (derived-mode-p 'navi-edit-mode) 1482 | (navi-mode) 1483 | (message "Switching to Navi mode."))) 1484 | 1485 | 1486 | ;;;;; Twin Buffers 1487 | 1488 | (defun navi-goto-occurrence-other-window () 1489 | "Moves navi-buffer marker to point before switching buffers." 1490 | (interactive) 1491 | (move-marker 1492 | (car (navi-get-twin-buffer-markers)) (point)) 1493 | (navi-set-regexp-quoted-line-at-point) 1494 | (occur-mode-goto-occurrence-other-window)) 1495 | 1496 | ;;;###autoload 1497 | (defun navi-search-and-switch () 1498 | "Call `occur' and immediatley switch to `*Navi:original-buffer-name*' buffer" 1499 | (interactive) 1500 | (let ((buf-markers (navi-get-twin-buffer-markers)) 1501 | (orig-buffer-mode major-mode)) 1502 | ;; (with-current-buffer (marker-buffer (car buf-markers)) major-mode))) 1503 | (if (and 1504 | buf-markers 1505 | (buffer-live-p (marker-buffer (car buf-markers))) 1506 | (buffer-live-p (marker-buffer (cadr buf-markers)))) 1507 | (navi-switch-to-twin-buffer) 1508 | (let* ((1st-level-headers 1509 | (if (eq orig-buffer-mode 'org-mode) 1510 | (navi-calc-org-mode-headline-regexp 1) 1511 | (if outshine-enforce-no-comment-padding-p 1512 | "^;;; " 1513 | (regexp-quote 1514 | (car (rassoc 1 outline-promotion-headings))))))) 1515 | ;; (regexp-quote 1516 | ;; (outshine-calc-outline-string-at-level 1)))) 1517 | (put 'navi (navi-make-buffer-key (buffer-name)) 1518 | (set (intern (navi-make-marker-name)) (point-marker))) 1519 | (occur 1st-level-headers) 1520 | (navi-rename-buffer) 1521 | (navi-switch-to-twin-buffer) 1522 | (navi-mode) 1523 | (occur-next) 1524 | (move-marker 1525 | (car (navi-get-twin-buffer-markers)) (point)) 1526 | (navi-set-regexp-quoted-line-at-point))) 1527 | (make-variable-buffer-local 'kill-buffer-hook) 1528 | (add-to-list 'kill-buffer-hook 'navi-clean-up))) 1529 | 1530 | (defun navi-quit-and-switch () 1531 | "Quit navi-buffer and immediatley switch back to original-buffer" 1532 | (interactive) 1533 | (navi-goto-occurrence-other-window) 1534 | (kill-buffer (marker-buffer (cadr (navi-get-twin-buffer-markers)))) 1535 | (navi-clean-up)) 1536 | 1537 | (defun navi-switch-to-twin-buffer () 1538 | "Switch to associated twin-buffer of current buffer or do nothing." 1539 | (interactive) 1540 | (let* ((marker-list (navi-get-twin-buffer-markers)) 1541 | (self-marker (car marker-list)) 1542 | (twin-marker (cadr marker-list))) 1543 | (and marker-list 1544 | (buffer-live-p (marker-buffer self-marker)) 1545 | (buffer-live-p (marker-buffer twin-marker)) 1546 | (move-marker self-marker (point) (marker-buffer self-marker)) 1547 | (if (eq major-mode 'navi-mode) 1548 | (navi-set-regexp-quoted-line-at-point) t) 1549 | (switch-to-buffer-other-window (marker-buffer twin-marker)) 1550 | (goto-char (marker-position twin-marker)) 1551 | (and (eq major-mode 'navi-mode) 1552 | (navi-revert-function))))) 1553 | 1554 | ;;;;; Navi Buffer 1555 | 1556 | ;; adapted from 'replace.el' 1557 | (defun navi-revert-function (&optional regexp) 1558 | "Handle `revert-buffer' for navi-buffers." 1559 | (interactive) 1560 | (let ((navi-revert-arguments 1561 | (if regexp 1562 | (append 1563 | (list regexp) (cdr occur-revert-arguments)) 1564 | occur-revert-arguments))) 1565 | (navi-set-regexp-quoted-line-at-point) 1566 | (apply 'navi-1 (append navi-revert-arguments (list (buffer-name)))) 1567 | ;; FIXME redundant with navi-1 instead of occur-1? 1568 | (unless 1569 | (eq major-mode 'navi-mode) (navi-mode)) 1570 | (goto-char 1571 | (navi-search-less-or-equal-line-number)))) 1572 | 1573 | ;;;;; Navi Generic Command 1574 | 1575 | ;; this command executes all user-defined occur-searches 1576 | (defun navi-generic-command (key prefix) 1577 | "One size fits all (user-defined header and keyword searches)." 1578 | (interactive (list last-command-event current-prefix-arg)) 1579 | (let ((keystrg (format "%c" key)) 1580 | (numval-prefix (and prefix (prefix-numeric-value prefix)))) 1581 | (if prefix 1582 | (cond 1583 | ((memq numval-prefix (number-sequence 1 8)) 1584 | (navi-show-headers-and-keywords numval-prefix keystrg)) 1585 | ((and 1586 | (not (memq numval-prefix (number-sequence 1 8))) 1587 | (not (memq key (number-sequence 49 56)))) 1588 | (navi-show-headers keystrg prefix)) 1589 | (t nil)) 1590 | (cond 1591 | ((memq key (number-sequence 49 56)) 1592 | (navi-show-headers (string-to-number (format "%c" key)))) 1593 | ((memq key (number-sequence 57 126)) 1594 | (navi-show-keywords keystrg)) 1595 | (t nil))))) 1596 | 1597 | ;;;;; Act on thing-at-point 1598 | 1599 | ;; (defun navi-mark-subtree-and-switch() 1600 | ;; "Mark subtree at point in original-buffer." 1601 | ;; (interactive) 1602 | ;; (navi-goto-occurrence-other-window) 1603 | ;; (if (outline-on-heading-p) 1604 | ;; (outline-mark-subtree) 1605 | ;; (message "Only subtrees may be marked via navi-mode"))) 1606 | 1607 | ;; ;; FIXME deactivates region - workaround? 1608 | ;; ;; (navi-switch-to-twin-buffer)) 1609 | 1610 | (defun navi-mark-thing-at-point-and-switch () 1611 | "Mark thing at point in original-buffer." 1612 | (interactive) 1613 | (navi-goto-occurrence-other-window) 1614 | (if (outline-on-heading-p) 1615 | (outline-mark-subtree) 1616 | (mark-sexp))) 1617 | 1618 | ;; (defun navi-copy-subtree-to-register-s () 1619 | ;; "Copy subtree at point in original-buffer." 1620 | ;; (interactive) 1621 | ;; (navi-goto-occurrence-other-window) 1622 | ;; (if (outline-on-heading-p) 1623 | ;; (progn 1624 | ;; (outline-mark-subtree) 1625 | ;; (and 1626 | ;; (use-region-p) 1627 | ;; (copy-to-register ?s (region-beginning) (region-end))) 1628 | ;; (deactivate-mark)) 1629 | ;; (message "Only subtrees may be copied via navi-mode")) 1630 | ;; (navi-switch-to-twin-buffer)) 1631 | 1632 | (defun navi-act-on-thing-at-point (&optional arg) 1633 | "Call a function with function arguments on thing-at-point. 1634 | 1635 | Makes sense only for functions that don't need an active region 1636 | \(ARG is nil\) or that take start and end region markers as first 1637 | arguments \(ARG is non-nil\). In both cases, a list of 1638 | more \(optional\) function arguments can be given \(see 1639 | `navi-act-on-thing'\)." 1640 | (interactive "P") 1641 | (navi-goto-occurrence-other-window) 1642 | (if arg 1643 | (progn 1644 | (deactivate-mark) 1645 | (call-interactively 'navi-act-on-thing)) 1646 | (if (outline-on-heading-p) 1647 | (outline-mark-subtree) 1648 | (mark-sexp)) 1649 | (if (not (use-region-p)) 1650 | (error "No active region") 1651 | (call-interactively 'navi-act-on-thing) 1652 | (deactivate-mark))) 1653 | (navi-switch-to-twin-buffer)) 1654 | 1655 | (defun navi-act-on-thing (fun &optional funargs start end) 1656 | "Call FUN with FUNARGS on thing or region \(from START to END\)." 1657 | (interactive "aFunction: \nxArgument List (arg1 ... argN): \nr") 1658 | (if (and start end (use-region-p)) 1659 | (if funargs 1660 | (funcall fun start end funargs) 1661 | (funcall fun start end)) 1662 | (if funargs 1663 | (funcall fun funargs) 1664 | (funcall fun)))) 1665 | 1666 | 1667 | (defun navi-copy-thing-at-point-to-register-s () 1668 | "Copy thing at point in original-buffer." 1669 | (interactive) 1670 | (navi-goto-occurrence-other-window) 1671 | (if (outline-on-heading-p) 1672 | (outline-mark-subtree) 1673 | (mark-sexp)) 1674 | (and 1675 | (use-region-p) 1676 | (progn 1677 | (copy-to-register ?s (region-beginning) (region-end)) 1678 | (deactivate-mark))) 1679 | (navi-switch-to-twin-buffer)) 1680 | 1681 | ;; (defun navi-narrow-to-subtree () 1682 | ;; "Narrow original buffer to subtree at point." 1683 | ;; (interactive) 1684 | ;; (navi-goto-occurrence-other-window) 1685 | ;; (if (outline-on-heading-p) 1686 | ;; (progn 1687 | ;; (outline-mark-subtree) 1688 | ;; (and 1689 | ;; (use-region-p) 1690 | ;; (narrow-to-region (region-beginning) (region-end))) 1691 | ;; (deactivate-mark)) 1692 | ;; (message "Navi-mode can only narrow to subtrees")) 1693 | ;; (setq navi-regexp-quoted-line-before-narrowing 1694 | ;; navi-regexp-quoted-line-at-point) 1695 | ;; (navi-switch-to-twin-buffer)) 1696 | 1697 | (defun navi-narrow-to-thing-at-point () 1698 | "Narrow original buffer to thing at point." 1699 | (interactive) 1700 | (navi-goto-occurrence-other-window) 1701 | (if (outline-on-heading-p) 1702 | (outline-mark-subtree) 1703 | (mark-sexp)) 1704 | (and 1705 | (use-region-p) 1706 | (progn 1707 | (narrow-to-region (region-beginning) (region-end)) 1708 | (deactivate-mark))) 1709 | (setq navi-regexp-quoted-line-before-narrowing 1710 | navi-regexp-quoted-line-at-point) 1711 | (navi-switch-to-twin-buffer)) 1712 | 1713 | (defun navi-widen () 1714 | "Widen original buffer." 1715 | (interactive) 1716 | (navi-goto-occurrence-other-window) 1717 | (widen) 1718 | (navi-switch-to-twin-buffer) 1719 | (setq navi-regexp-quoted-line-at-point 1720 | navi-regexp-quoted-line-before-narrowing) 1721 | (goto-char 1722 | (navi-search-less-or-equal-line-number))) 1723 | 1724 | (defun navi-kill-thing-at-point () 1725 | "Kill thing at point in original-buffer." 1726 | (interactive) 1727 | (navi-goto-occurrence-other-window) 1728 | (if (outline-on-heading-p) 1729 | (outline-mark-subtree) 1730 | (mark-sexp)) 1731 | (and 1732 | (use-region-p) 1733 | (and (y-or-n-p 1734 | "Really kill the marked region in the original-buffer ") 1735 | (copy-to-register 1736 | ?s (region-beginning) (region-end) 'DELETE-FLAG))) 1737 | (deactivate-mark) 1738 | (navi-switch-to-twin-buffer)) 1739 | 1740 | ;; (defun navi-yank-subtree-from-register-s () 1741 | ;; "Yank in original-buffer." 1742 | ;; (interactive) 1743 | ;; (navi-goto-occurrence-other-window) 1744 | ;; (if (and 1745 | ;; (outline-on-heading-p) 1746 | ;; (get-register ?s)) 1747 | ;; (progn 1748 | ;; (newline) 1749 | ;; (forward-line -1) 1750 | ;; (insert-register ?s)) 1751 | ;; (message "Not on subtree-heading or no subtree to yank.")) 1752 | ;; (navi-switch-to-twin-buffer)) 1753 | 1754 | (defun navi-yank-thing-from-register-s () 1755 | "Yank in original-buffer." 1756 | (interactive) 1757 | (navi-goto-occurrence-other-window) 1758 | (if (and 1759 | (or 1760 | (outline-on-heading-p) 1761 | (progn 1762 | (end-of-sexp) 1763 | (beginning-of-sexp) 1764 | (sexp-at-point))) 1765 | (get-register ?s)) 1766 | (progn 1767 | (newline) 1768 | (forward-line -1) 1769 | (insert-register ?s)) 1770 | (message "Not on subtree/sexp or nothing to yank.")) 1771 | (navi-switch-to-twin-buffer)) 1772 | 1773 | ;; (defun navi-query-replace () 1774 | ;; "Call `query-replace' interactively on subtree at point." 1775 | ;; (interactive) 1776 | ;; (navi-goto-occurrence-other-window) 1777 | ;; (if (outline-on-heading-p) 1778 | ;; (progn 1779 | ;; (outline-mark-subtree) 1780 | ;; (and 1781 | ;; (use-region-p) 1782 | ;; (call-interactively 'query-replace)) 1783 | ;; (deactivate-mark)) 1784 | ;; (message "Navi-mode can perform query-replace only on subtrees")) 1785 | ;; (navi-switch-to-twin-buffer)) 1786 | 1787 | ;;;;; Search and Replace 1788 | 1789 | (defun navi-query-replace () 1790 | "Call `query-replace' interactively on thing at point." 1791 | (interactive) 1792 | (navi-goto-occurrence-other-window) 1793 | (if (outline-on-heading-p) 1794 | (outline-mark-subtree) 1795 | (mark-sexp)) 1796 | (and 1797 | (use-region-p) 1798 | (progn 1799 | (call-interactively 'query-replace) 1800 | (deactivate-mark))) 1801 | (navi-switch-to-twin-buffer)) 1802 | 1803 | ;; (defun navi-isearch () 1804 | ;; "Call `isearch' interactively on subtree at point." 1805 | ;; (interactive) 1806 | ;; (navi-goto-occurrence-other-window) 1807 | ;; (if (outline-on-heading-p) 1808 | ;; (save-restriction 1809 | ;; (outline-mark-subtree) 1810 | ;; (and 1811 | ;; (use-region-p) 1812 | ;; (narrow-to-region (region-beginning) (region-end))) 1813 | ;; (deactivate-mark) 1814 | ;; (isearch-mode t nil nil t nil)) 1815 | ;; (message "Navi-mode can perform isearches only on subtrees")) 1816 | ;; (navi-switch-to-twin-buffer)) 1817 | 1818 | 1819 | (defun navi-isearch () 1820 | "Call `isearch' interactively on thing at point." 1821 | (interactive) 1822 | (navi-goto-occurrence-other-window) 1823 | (save-restriction 1824 | (if (outline-on-heading-p) 1825 | (outline-mark-subtree) 1826 | (mark-sexp)) 1827 | (and 1828 | (use-region-p) 1829 | (progn 1830 | (narrow-to-region (region-beginning) (region-end)) 1831 | (deactivate-mark))) 1832 | (isearch-mode t nil nil t nil)) 1833 | (navi-switch-to-twin-buffer)) 1834 | 1835 | (defun navi-demote-subtree () 1836 | "Demote subtree at point." 1837 | (interactive) 1838 | (navi-goto-occurrence-other-window) 1839 | (if (outline-on-heading-p) 1840 | (outline-demote 1) 1841 | (message "Navi-mode can only demote subtrees")) 1842 | (navi-switch-to-twin-buffer)) 1843 | 1844 | (defun navi-promote-subtree () 1845 | "Promote subtree at point." 1846 | (interactive) 1847 | (navi-goto-occurrence-other-window) 1848 | (if (outline-on-heading-p) 1849 | (outline-promote 1) 1850 | (message "Navi-mode can only promote subtrees")) 1851 | (navi-switch-to-twin-buffer)) 1852 | 1853 | (defun navi-move-up-subtree () 1854 | "Move subtree at point one position up." 1855 | (interactive) 1856 | (navi-goto-occurrence-other-window) 1857 | (if (outline-on-heading-p) 1858 | (outline-move-subtree-up 1) 1859 | (message "Navi-mode can only move subtrees")) 1860 | (navi-switch-to-twin-buffer)) 1861 | 1862 | (defun navi-move-down-subtree () 1863 | "Move subtree at point one position down." 1864 | (interactive) 1865 | (navi-goto-occurrence-other-window) 1866 | (if (outline-on-heading-p) 1867 | (outline-move-subtree-down 1) 1868 | (message "Navi-mode can only move subtrees")) 1869 | (navi-switch-to-twin-buffer)) 1870 | 1871 | ;;;;; Visibility Cycling 1872 | 1873 | (defun navi-cycle-subtree () 1874 | "Cycle the visibility state of subtree at point in the original-buffer." 1875 | (interactive) 1876 | (navi-goto-occurrence-other-window) 1877 | (if (outline-on-heading-p) 1878 | (outline-cycle 1) 1879 | (message "Not on subtree - can't cycle subtree visibility state.")) 1880 | (navi-switch-to-twin-buffer)) 1881 | 1882 | (defun navi-cycle-buffer () 1883 | "Cycle the visibility state of the original-buffer." 1884 | (interactive) 1885 | (navi-goto-occurrence-other-window) 1886 | (outline-cycle '(4)) 1887 | (navi-switch-to-twin-buffer)) 1888 | 1889 | ;;;;; Undo 1890 | 1891 | (defun navi-undo () 1892 | "Undo last (undoable) action in original-buffer." 1893 | (interactive) 1894 | (navi-goto-occurrence-other-window) 1895 | (undo) 1896 | (navi-switch-to-twin-buffer)) 1897 | 1898 | ;;;;; Show Help 1899 | 1900 | (defun navi-show-help () 1901 | "Show navi-keybindings for major-mode of original-buffer." 1902 | (interactive) 1903 | (let ((mappings 1904 | (navi-get-language-alist (navi-get-language-name) 'MAPPINGS)) 1905 | (navi-buf-marker (car (navi-get-twin-buffer-markers)))) 1906 | (switch-to-buffer-other-window 1907 | (get-buffer-create 1908 | (concat "*Navi:" (navi-get-language-name) ":HELP"))) 1909 | (save-restriction 1910 | (widen) 1911 | (when (string-equal 1912 | (buffer-substring-no-properties (point-min) (point-max)) "") 1913 | (insert "[KEY] : [SEARCH]\n") 1914 | (forward-line -1) 1915 | (navi-underline-line-with ?=) 1916 | (forward-line 2) 1917 | (mapc 1918 | (lambda (association) 1919 | (insert 1920 | (format "\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s\s\t%s : %s\n" 1921 | (cdr association) 1922 | (car 1923 | (split-string 1924 | (symbol-name (car association)) 1925 | ":" 'OMIT-NULLS))))) 1926 | mappings)) 1927 | (goto-char (point-min)) 1928 | (view-buffer (current-buffer))))) 1929 | 1930 | ;;;;; Use Outorg 1931 | 1932 | (defun navi-edit-as-org (&optional args) 1933 | "Edit subtree at point with `outorg'. 1934 | 1935 | Edit whole buffer if ARGS are given. Editing takes place in a 1936 | separate temporary Org-mode edit-buffer." 1937 | (interactive "P") 1938 | (navi-goto-occurrence-other-window) 1939 | (if (outline-on-heading-p) 1940 | (if args 1941 | (outorg-edit-as-org args) 1942 | (outorg-edit-as-org)) 1943 | (message "Only subtrees (or the whole buffer) may be edited via navi-mode")) 1944 | (navi-switch-to-twin-buffer)) 1945 | 1946 | ;; TODO improve orderly exit from `message' buffer via `outorg' buffer and 1947 | ;; `original-buffer' to `navi-buffer', best without showing `outorg' 1948 | ;; and `original' buffer to the user (not critical). 1949 | (defun navi-mail-subtree () 1950 | "Send subtree at point as email." 1951 | (interactive) 1952 | (navi-goto-occurrence-other-window) 1953 | (if (outline-on-heading-p) 1954 | (outorg-edit-as-org) 1955 | (message "Only subtrees be send as email via navi-mode")) 1956 | (with-current-buffer 1957 | (get-buffer "*outorg-edit-buffer*") 1958 | (org-mark-subtree) 1959 | (if (require 'org-mime nil t) 1960 | (org-mime-subtree) 1961 | (user-error "%s" "Library `org-mime-subtree' not found")))) 1962 | 1963 | ;;;;; Call outshine-use-outorg functions 1964 | 1965 | (defun navi-deadline () 1966 | "Call `outshine-deadline' from navi-mode." 1967 | (interactive) 1968 | (navi-use-outorg 'deadline)) 1969 | 1970 | (defun navi-export-dispatch () 1971 | "Call `outshine-export-dispatch' from navi-mode." 1972 | (interactive) 1973 | (navi-use-outorg 'export-dispatch)) 1974 | 1975 | (defun navi-insert-link () 1976 | "Call `outshine-insert-link' from navi-mode." 1977 | (interactive) 1978 | (navi-use-outorg 'insert-link)) 1979 | 1980 | (defun navi-open-at-point () 1981 | "Call `outshine-open-at-point' from navi-mode." 1982 | (interactive) 1983 | (navi-use-outorg 'open-at-point)) 1984 | 1985 | (defun navi-set-tags-command () 1986 | "Call `outshine-set-tags-command' from navi-mode." 1987 | (interactive) 1988 | (navi-use-outorg 'set-tags-command)) 1989 | 1990 | (defun navi-schedule () 1991 | "Call `outshine-schedule' from navi-mode." 1992 | (interactive) 1993 | (navi-use-outorg 'schedule)) 1994 | 1995 | (defun navi-todo () 1996 | "Call `outshine-todo' from navi-mode." 1997 | (interactive) 1998 | (navi-use-outorg 'todo)) 1999 | 2000 | (defun navi-time-stamp-inactive () 2001 | "Call `outshine-time-stamp-inactive' from navi-mode." 2002 | (interactive) 2003 | (navi-use-outorg 'time-stamp-inactive)) 2004 | 2005 | (defun navi-priority () 2006 | "Call `outshine-priority' from navi-mode." 2007 | (interactive) 2008 | (navi-use-outorg 'priority)) 2009 | 2010 | (defun navi-time-stamp () 2011 | "Call `outshine-time-stamp' from navi-mode." 2012 | (interactive) 2013 | (navi-use-outorg 'time-stamp)) 2014 | 2015 | (defun navi-toggle-fixed-width () 2016 | "Call `outshine-toggle-fixed-width' from navi-mode." 2017 | (interactive) 2018 | (navi-use-outorg 'toggle-fixed-width)) 2019 | 2020 | (defun navi-toggle-comment () 2021 | "Call `outshine-toggle-comment' from navi-mode." 2022 | (interactive) 2023 | (navi-use-outorg 'toggle-comment)) 2024 | 2025 | (defun navi-sort-entries () 2026 | "Call `outshine-sort-entries' from navi-mode." 2027 | (interactive) 2028 | (navi-use-outorg 'sort-entries)) 2029 | 2030 | (defun navi-previous-block () 2031 | "Call `outshine-previous-block' from navi-mode." 2032 | (interactive) 2033 | (navi-use-outorg 'previous-block)) 2034 | 2035 | (defun navi-next-block () 2036 | "Call `outshine-next-block' from navi-mode." 2037 | (interactive) 2038 | (navi-use-outorg 'next-block)) 2039 | 2040 | (defun navi-insert-last-stored-link () 2041 | "Call `outshine-insert-last-stored-link' from navi-mode." 2042 | (interactive) 2043 | (navi-use-outorg 'insert-last-stored-link)) 2044 | 2045 | (defun navi-toggle-checkbox () 2046 | "Call `outshine-toggle-checkbox' from navi-mode." 2047 | (interactive) 2048 | (navi-use-outorg 'toggle-checkbox)) 2049 | 2050 | (defun navi-clock-in () 2051 | "Call `outshine-clock-in' from navi-mode." 2052 | (interactive) 2053 | (navi-use-outorg 'clock-in)) 2054 | 2055 | (defun navi-clock-goto () 2056 | "Call `outshine-clock-goto' from navi-mode." 2057 | (interactive) 2058 | (navi-use-outorg 'clock-goto)) 2059 | 2060 | (defun navi-next-link () 2061 | "Call `outshine-next-link' from navi-mode." 2062 | (interactive) 2063 | (navi-use-outorg 'next-link)) 2064 | 2065 | (defun navi-clock-out () 2066 | "Call `outshine-clock-out' from navi-mode." 2067 | (interactive) 2068 | (navi-use-outorg 'clock-out)) 2069 | 2070 | (defun navi-previous-link () 2071 | "Call `outshine-previous-link' from navi-mode." 2072 | (interactive) 2073 | (navi-use-outorg 'previous-link)) 2074 | 2075 | (defun navi-clock-cancel () 2076 | "Call `outshine-clock-cancel' from navi-mode." 2077 | (interactive) 2078 | (navi-use-outorg 'clock-cancel)) 2079 | 2080 | (defun navi-clock-report () 2081 | "Call `outshine-clock-report' from navi-mode." 2082 | (interactive) 2083 | (navi-use-outorg 'clock-report)) 2084 | 2085 | (defun navi-timer-pause-or-continue () 2086 | "Call `outshine-timer-pause-or-continue' from navi-mode." 2087 | (interactive) 2088 | (navi-use-outorg 'timer-pause-or-continue)) 2089 | 2090 | (defun navi-timer-item () 2091 | "Call `outshine-timer-item' from navi-mode." 2092 | (interactive) 2093 | (navi-use-outorg 'timer-item)) 2094 | 2095 | (defun navi-timer () 2096 | "Call `outshine-timer' from navi-mode." 2097 | (interactive) 2098 | (navi-use-outorg 'timer)) 2099 | 2100 | (defun navi-timer-start () 2101 | "Call `outshine-timer-start' from navi-mode." 2102 | (interactive) 2103 | (navi-use-outorg 'timer-start)) 2104 | 2105 | (defun navi-timer-cancel-timer () 2106 | "Call `outshine-timer-cancel-timer' from navi-mode." 2107 | (interactive) 2108 | (navi-use-outorg 'timer-cancel-timer)) 2109 | 2110 | (defun navi-timer-set-timer () 2111 | "Call `outshine-timer-set-timer' from navi-mode." 2112 | (interactive) 2113 | (navi-use-outorg 'timer-set-timer)) 2114 | 2115 | (defun navi-agenda-set-restriction-lock () 2116 | "Call `outshine-agenda-set-restriction-lock' from navi-mode." 2117 | (interactive) 2118 | (navi-use-outorg 'agenda-set-restriction-lock)) 2119 | 2120 | (defun navi-agenda-remove-restriction-lock () 2121 | "Call `outshine-agenda-remove-restriction-lock' from navi-mode." 2122 | (interactive) 2123 | (navi-use-outorg 'agenda-remove-restriction-lock)) 2124 | 2125 | (defun navi-inc-effort () 2126 | "Call `outshine-inc-effort' from navi-mode." 2127 | (interactive) 2128 | (navi-use-outorg 'inc-effort)) 2129 | 2130 | (defun navi-set-property-and-value () 2131 | "Call `outshine-set-property-and-value' from navi-mode." 2132 | (interactive) 2133 | (navi-use-outorg 'set-property-and-value)) 2134 | 2135 | (defun navi-toggle-archive-tag () 2136 | "Call `outshine-toggle-archive-tag' from navi-mode." 2137 | (interactive) 2138 | (navi-use-outorg 'toggle-archive-tag)) 2139 | 2140 | (defun navi-insert-drawer () 2141 | "Call `outshine-insert-drawer' from navi-mode." 2142 | (interactive) 2143 | (navi-use-outorg 'insert-drawer)) 2144 | 2145 | (defun navi-set-effort () 2146 | "Call `outshine-set-effort' from navi-mode." 2147 | (interactive) 2148 | (navi-use-outorg 'set-effort)) 2149 | 2150 | (defun navi-footnote-action () 2151 | "Call `outshine-footnote-action' from navi-mode." 2152 | (interactive) 2153 | (navi-use-outorg 'footnote-action)) 2154 | 2155 | (defun navi-set-property () 2156 | "Call `outshine-set-property' from navi-mode." 2157 | (interactive) 2158 | (navi-use-outorg 'set-property)) 2159 | 2160 | ;;; Menus and Keys 2161 | ;;;; Menus 2162 | 2163 | ;; menu map for navi-mode 2164 | (defvar navi-menu-map 2165 | (let ((map (make-sparse-keymap))) 2166 | (define-key map [next-error-follow-minor-mode] 2167 | `(menu-item ,(purecopy "Auto Occurrence Display") 2168 | next-error-follow-minor-mode 2169 | :help ,(purecopy 2170 | "Display another occurrence when moving the cursor") 2171 | :button (:toggle . (and (boundp 'next-error-follow-minor-mode) 2172 | next-error-follow-minor-mode)))) 2173 | 2174 | (define-key map [separator-11] menu-bar-separator) 2175 | (define-key map [navi-quit-and-switch] 2176 | `(menu-item ,(purecopy "Quit") 2177 | navi-quit-and-switch :help ,(purecopy "Quit navi-buffer and switch to 2178 | original-buffer"))) 2179 | 2180 | (define-key map [separator-10] menu-bar-separator) 2181 | (define-key map [kill-this-buffer] 2182 | `(menu-item ,(purecopy "Kill Navi Buffer") kill-this-buffer 2183 | :help ,(purecopy "Kill the current *Navi* buffer"))) 2184 | (define-key map [clone-buffer] 2185 | `(menu-item ,(purecopy "Clone Navi Buffer") clone-buffer 2186 | :help ,(purecopy "Create and return a twin copy 2187 | of the current *Navi* buffer"))) 2188 | 2189 | (define-key map [separator-9] menu-bar-separator) 2190 | (define-key map [navi-show-help] 2191 | `(menu-item ,(purecopy "Show Help") 2192 | navi-show-help :help ,(purecopy "Show help for keyword queries. Use 2193 | \\[describe-mode] to see all navi-mode keybindings."))) 2194 | (define-key map [navi-revert-function] 2195 | `(menu-item ,(purecopy "Revert Navi Buffer") 2196 | navi-revert-function :help ,(purecopy "Revert 2197 | navi-buffer (seldom necessary)"))) 2198 | (define-key map [navi-undo] 2199 | `(menu-item ,(purecopy "Undo Last Change") 2200 | navi-undo :help ,(purecopy "Undo last change in original-buffer"))) 2201 | 2202 | (define-key map [separator-8] menu-bar-separator) 2203 | (define-key map [navi-edit-mode] 2204 | `(menu-item ,(purecopy "Make Navi-Buffer Editable") 2205 | navi-edit-mode :help ,(purecopy "Make navi-buffer editable and apply 2206 | changes to original-buffer"))) 2207 | (define-key map [navi-edit-as-org] 2208 | `(menu-item ,(purecopy "Edit Subtree in Org-mode") 2209 | navi-edit-as-org :help ,(purecopy "Edit Subtree at point in temporary 2210 | Org-mode edit buffer"))) 2211 | 2212 | (define-key map [separator-7] menu-bar-separator) 2213 | (define-key map [navi-query-replace] 2214 | `(menu-item ,(purecopy "Query-Replace in thing-at-point") 2215 | navi-query-replace :help ,(purecopy "Do a query-replace in 2216 | thing at point"))) 2217 | (define-key map [navi-isearch] 2218 | `(menu-item ,(purecopy "iSearch in thing-at-point") 2219 | navi-isearch :help ,(purecopy "Do an isearch in thing at point"))) 2220 | 2221 | (define-key map [separator-6] menu-bar-separator) 2222 | (define-key map [navi-widen] 2223 | `(menu-item ,(purecopy "Widen Original Buffer") 2224 | navi-widen :help ,(purecopy "Widen original-buffer"))) 2225 | (define-key map [navi-narrow-to-thing-at-point] 2226 | `(menu-item ,(purecopy "Narrow to thing-at-point") 2227 | navi-narrow-to-thing-at-point 2228 | :help ,(purecopy "Narrow original-buffer to 2229 | thing at point"))) 2230 | 2231 | (define-key map [separator-5] menu-bar-separator) 2232 | (define-key map [navi-mail-subtree] 2233 | `(menu-item ,(purecopy "Mail Subtree") 2234 | navi-mail-subtree 2235 | :help ,(purecopy "Mail subtree at point"))) 2236 | (define-key map [navi-yank-thing-from-register-s] 2237 | `(menu-item ,(purecopy "Yank killed/copied thing") 2238 | navi-yank-thing-from-register-s 2239 | :help ,(purecopy "Yank (killed/copied) thing 2240 | from register s"))) 2241 | (define-key map [navi-kill-thing-at-point] 2242 | `(menu-item ,(purecopy "Kill thing-at-point") 2243 | navi-kill-thing-at-point 2244 | :help ,(purecopy "Kill thing at point (y-or-n-p)"))) 2245 | (define-key map [navi-copy-thing-at-point-to-register-s] 2246 | `(menu-item ,(purecopy "Copy thing-at-point") 2247 | navi-copy-thing-at-point-to-register-s 2248 | :help ,(purecopy "Copy thing at point to register s"))) 2249 | (define-key map [navi-act-on-thing-at-point] 2250 | `(menu-item ,(purecopy "Act on thing-at-point") 2251 | navi-act-on-thing-at-point 2252 | :help ,(purecopy "Act on thing at point"))) 2253 | (define-key map [navi-mark-thing-at-point-and-switch] 2254 | `(menu-item ,(purecopy "Mark thing-at-point") 2255 | navi-mark-thing-at-point-and-switch 2256 | :help ,(purecopy "Mark thing at point and switch to 2257 | original buffer"))) 2258 | 2259 | (define-key map [separator-4] menu-bar-separator) 2260 | (define-key map [navi-move-up-subtree] 2261 | `(menu-item ,(purecopy "Move Up Subtree") 2262 | navi-move-up-subtree 2263 | :help ,(purecopy "Move subtree at point up 1 position"))) 2264 | (define-key map [navi-move-down-subtree] 2265 | `(menu-item ,(purecopy "Move Down Subtree") 2266 | navi-move-down-subtree 2267 | :help ,(purecopy "Move subtree at point down 1 position"))) 2268 | (define-key map [navi-demote-subtree] 2269 | `(menu-item ,(purecopy "Demote Subtree") 2270 | navi-demote-subtree 2271 | :help ,(purecopy "Demote subtree at point"))) 2272 | (define-key map [navi-promote-subtree] 2273 | `(menu-item ,(purecopy "Promote Subtree") 2274 | navi-promote-subtree 2275 | :help ,(purecopy "Promote subtree at point"))) 2276 | (define-key map [navi-cycle-buffer] 2277 | `(menu-item ,(purecopy "Cycle Buffer") 2278 | navi-cycle-buffer 2279 | :help ,(purecopy "Cycle visibility of original buffer"))) 2280 | (define-key map [navi-cycle-subtree] 2281 | `(menu-item ,(purecopy "Cycle Subtree") 2282 | navi-cycle-subtree 2283 | :help ,(purecopy "Cycle visibility of subtree at point"))) 2284 | 2285 | 2286 | (define-key map [separator-3] menu-bar-separator) 2287 | (define-key map [navi-switch-to-twin-buffer] 2288 | `(menu-item ,(purecopy "Switch to Twin Buffer") 2289 | navi-switch-to-twin-buffer 2290 | :help ,(purecopy "Go to the associated twin buffer"))) 2291 | (define-key map [navi-goto-occurrence-other-window] 2292 | `(menu-item ,(purecopy "Go To Occurrence Other Window") 2293 | navi-goto-occurrence-other-window 2294 | :help ,(purecopy "Go to the occurrence the 2295 | current line describes, in another window"))) 2296 | (define-key map [occur-mode-display-occurrence] 2297 | `(menu-item ,(purecopy "Display Occurrence") 2298 | occur-mode-display-occurrence 2299 | :help ,(purecopy "Display in another window the 2300 | occurrence the current line describes"))) 2301 | 2302 | (define-key map [separator-2] menu-bar-separator) 2303 | (define-key map [scroll-up-command] 2304 | `(menu-item ,(purecopy "Move Page up") scroll-up-command 2305 | :help ,(purecopy "Move 1 page up in buffer"))) 2306 | (define-key map [scroll-down-command] 2307 | `(menu-item ,(purecopy "Move Page down") scroll-down-command 2308 | :help ,(purecopy "Move 1 page down in buffer"))) 2309 | (define-key map [occur-next] 2310 | `(menu-item ,(purecopy "Move to Next Match") occur-next 2311 | :help ,(purecopy "Move to the Nth (default 1) 2312 | next match in a Navi-mode buffer"))) 2313 | (define-key map [occur-prev] 2314 | `(menu-item ,(purecopy "Move to Previous Match") occur-prev 2315 | :help ,(purecopy "Move to the Nth (default 1) 2316 | previous match in a Navi-mode buffer"))) map) 2317 | "Menu keymap for `navi-mode'.") 2318 | 2319 | 2320 | ;; menu map for navi-edit-mode 2321 | (defvar navi-edit-menu-map 2322 | (let ((map (make-sparse-keymap))) 2323 | (define-key map [next-error-follow-minor-mode] 2324 | `(menu-item ,(purecopy "Auto Occurrence Display") 2325 | next-error-follow-minor-mode 2326 | :help ,(purecopy 2327 | "Display another occurrence when moving the cursor") 2328 | :button (:toggle . (and (boundp 'next-error-follow-minor-mode) 2329 | next-error-follow-minor-mode)))) 2330 | 2331 | (define-key map [separator-4] menu-bar-separator) 2332 | (define-key map [navi-cease-edit] 2333 | `(menu-item ,(purecopy "Cease Edit") 2334 | navi-cease-edit :help ,(purecopy "Cease editing in navi-edit-mode and 2335 | return to (read-only) navi-mode"))) 2336 | 2337 | (define-key map [separator-3] menu-bar-separator) 2338 | (define-key map [occur-mode-display-occurrence] 2339 | `(menu-item ,(purecopy "Display Occurrence") 2340 | occur-mode-display-occurrence 2341 | :help ,(purecopy "Display in another window the 2342 | occurrence the current line describes"))) 2343 | 2344 | (define-key map [separator-2] menu-bar-separator) 2345 | (define-key map [scroll-up-command] 2346 | `(menu-item ,(purecopy "Move Page up") scroll-up-command 2347 | :help ,(purecopy "Move 1 page up in buffer"))) 2348 | (define-key map [scroll-down-command] 2349 | `(menu-item ,(purecopy "Move Page down") scroll-down-command 2350 | :help ,(purecopy "Move 1 page down in buffer"))) 2351 | (define-key map [scroll-other-window-up] 2352 | `(menu-item ,(purecopy "Move Page up (other window)") 2353 | scroll-other-window-up 2354 | :help 2355 | ,(purecopy "Move 1 page up in other window"))) 2356 | (define-key map [scroll-other-window] 2357 | `(menu-item ,(purecopy "Move Page down (other window)") 2358 | scroll-other-window 2359 | :help 2360 | ,(purecopy "Move 1 page down in other window"))) 2361 | (define-key map [occur-next] 2362 | `(menu-item ,(purecopy "Move to Next Match") occur-next 2363 | :help ,(purecopy "Move to the Nth (default 1) 2364 | next match in a Navi-mode buffer"))) 2365 | (define-key map [occur-prev] 2366 | `(menu-item ,(purecopy "Move to Previous Match") occur-prev 2367 | :help ,(purecopy "Move to the Nth (default 1) 2368 | previous match in a Navi-mode buffer"))) map) 2369 | "Menu keymap for `navi-edit-mode'.") 2370 | 2371 | 2372 | ;;;; Keys 2373 | 2374 | ;; key-bindings for user-defined occur-searches 2375 | ;; see `navi-key-mappings' and `navi-keywords'. 2376 | ;; reserved keys to be removed from num-seq: 2377 | ;; | ?\s | 32 | 2378 | ;; | ?\+ | 43 | 2379 | ;; | ?\- | 45 | 2380 | ;; | ?\^ | 60 | 2381 | ;; | ?E | 69 | 2382 | ;; | ?\< | 94 | 2383 | ;; | ?c | 99 | 2384 | ;; | ?d | 100 | 2385 | ;; | ?e | 101 | 2386 | ;; | ?g | 103 | 2387 | ;; | ?h | 104 | 2388 | ;; | ?k | 107 | 2389 | ;; | ?l | 108 | 2390 | ;; | ?m | 109 | 2391 | ;; | ?n | 110 | 2392 | ;; | ?o | 111 | 2393 | ;; | ?p | 112 | 2394 | ;; | ?q | 113 | 2395 | ;; | ?r | 114 | 2396 | ;; | ?s | 115 | 2397 | ;; | ?u | 117 | 2398 | ;; | ?w | 119 | 2399 | ;; | ?y | 121 | 2400 | ;; | ?z | 122 | 2401 | ;; | ?\d | 127 | 2402 | (mapc #'(lambda (key) 2403 | (define-key navi-mode-map (format "%c" key) 2404 | 'navi-generic-command)) 2405 | ;; all ascii printing chars 2406 | (let ((num-seq (number-sequence 32 127))) 2407 | (mapc #'(lambda (num) 2408 | (setq num-seq (delq num num-seq))) 2409 | ;; reserved keys defined elsewhere 2410 | '(32 43 45 60 69 94 99 100 101 103 104 107 108 109 2411 | 110 111 112 113 114 115 117 119 121 122 127)) num-seq)) 2412 | 2413 | ;; global keys for (original) twin-buffer of navi-buffer 2414 | (global-set-key (kbd "M-s n") 'navi-search-and-switch) 2415 | (global-set-key (kbd "M-s s") 'navi-switch-to-twin-buffer) 2416 | (global-set-key (kbd "M-s M-s") 'navi-switch-to-twin-buffer) 2417 | ;; keys for navi-mode 2418 | (define-key navi-mode-map (kbd "s") 'navi-switch-to-twin-buffer) 2419 | (define-key navi-mode-map (kbd "d") 'occur-mode-display-occurrence) 2420 | (define-key navi-mode-map (kbd "o") 'navi-goto-occurrence-other-window) 2421 | (define-key navi-mode-map (kbd "n") 'occur-next) 2422 | (define-key navi-mode-map (kbd "p") 'occur-prev) 2423 | (define-key navi-mode-map (kbd "SPC") 'scroll-up-command) 2424 | (define-key navi-mode-map (kbd "DEL") 'scroll-down-command) 2425 | (define-key navi-mode-map (kbd "TAB") 'navi-cycle-subtree) 2426 | (define-key navi-mode-map (kbd "M-TAB") 'navi-cycle-buffer) 2427 | ;; (define-key navi-mode-map (kbd "") 'navi-cycle-buffer) 2428 | (define-key navi-mode-map (kbd "m") 2429 | 'navi-mark-thing-at-point-and-switch) 2430 | (define-key navi-mode-map (kbd "c") 2431 | 'navi-copy-thing-at-point-to-register-s) 2432 | (define-key navi-mode-map (kbd ",") 2433 | 'navi-act-on-thing-at-point) 2434 | (define-key navi-mode-map (kbd "z") 'navi-mail-subtree) 2435 | (define-key navi-mode-map (kbd "r") 'navi-narrow-to-thing-at-point) 2436 | (define-key navi-mode-map (kbd "w") 'navi-widen) 2437 | (define-key navi-mode-map (kbd "l") 'navi-query-replace) 2438 | (define-key navi-mode-map (kbd "i") 'navi-isearch) 2439 | (define-key navi-mode-map (kbd "k") 'navi-kill-thing-at-point) 2440 | (define-key navi-mode-map (kbd "y") 'navi-yank-thing-from-register-s) 2441 | (define-key navi-mode-map (kbd "u") 'navi-undo) 2442 | (define-key navi-mode-map (kbd "e") 'navi-edit-as-org) 2443 | (define-key navi-mode-map (kbd "E") 'navi-edit-mode) 2444 | (define-key navi-mode-map (kbd "h") 'navi-show-help) 2445 | (define-key navi-mode-map (kbd "+") 'navi-demote-subtree) 2446 | (define-key navi-mode-map (kbd "-") 'navi-promote-subtree) 2447 | (define-key navi-mode-map (kbd "^") 'navi-move-up-subtree) 2448 | (define-key navi-mode-map (kbd "<") 'navi-move-down-subtree) 2449 | (define-key navi-mode-map (kbd "g") 'navi-revert-function) 2450 | (define-key navi-mode-map (kbd "q") 'navi-quit-and-switch) 2451 | ;; TODO define navi command that scrolls twin-buffer 2452 | (define-key navi-mode-map (kbd ":") 'scroll-other-window-down) 2453 | (define-key navi-mode-map (kbd ".") 'scroll-other-window) 2454 | ;; ;; original Org-mode keys for `navi-use-outorg' functions 2455 | (define-key navi-mode-map (kbd "C-c C-d") 'navi-deadline) 2456 | (define-key navi-mode-map (kbd "C-c C-e") 'navi-export-dispatch) 2457 | (define-key navi-mode-map (kbd "C-c C-l") 'navi-insert-link) 2458 | (define-key navi-mode-map (kbd "C-c C-o") 'navi-open-at-point) 2459 | (define-key navi-mode-map (kbd "C-c C-q") 'navi-set-tags-command) 2460 | (define-key navi-mode-map (kbd "C-c C-s") 'navi-schedule) 2461 | (define-key navi-mode-map (kbd "C-c C-t") 'navi-todo) 2462 | (define-key navi-mode-map (kbd "C-c !") 'navi-time-stamp-inactive) 2463 | (define-key navi-mode-map (kbd "C-c ,") 'navi-priority) 2464 | (define-key navi-mode-map (kbd "C-c .") 'navi-time-stamp) 2465 | (define-key navi-mode-map (kbd "C-c :") 'navi-toggle-fixed-width) 2466 | (define-key navi-mode-map (kbd "C-c ;") 'navi-toggle-comment) 2467 | (define-key navi-mode-map (kbd "C-c ^") 'navi-sort-entries) 2468 | (define-key navi-mode-map (kbd "C-c M-b") 'navi-previous-block) 2469 | (define-key navi-mode-map (kbd "C-c M-f") 'navi-next-block) 2470 | (define-key navi-mode-map (kbd "C-c C-x C-b") 'navi-toggle-checkbox) 2471 | (define-key navi-mode-map (kbd "C-c C-x TAB") 'navi-clock-in) 2472 | (define-key navi-mode-map (kbd "C-c C-x C-j") 'navi-clock-goto) 2473 | (define-key navi-mode-map (kbd "C-c C-x C-o") 'navi-clock-out) 2474 | (define-key navi-mode-map (kbd "C-c C-x C-q") 'navi-clock-cancel) 2475 | (define-key navi-mode-map (kbd "C-c C-x C-r") 'navi-clock-report) 2476 | (define-key navi-mode-map (kbd "C-c C-x C-n") 'navi-next-link) 2477 | (define-key navi-mode-map (kbd "C-c M-l") 2478 | 'navi-insert-last-stored-link) 2479 | (define-key navi-mode-map (kbd "C-c C-x C-p") 'navi-previous-link) 2480 | (define-key navi-mode-map (kbd "C-c C-x ,") 'navi-timer-pause-or-continue) 2481 | (define-key navi-mode-map (kbd "C-c C-x -") 'navi-timer-item) 2482 | (define-key navi-mode-map (kbd "C-c C-x .") 'navi-timer) 2483 | (define-key navi-mode-map (kbd "C-c C-x 0") 'navi-timer-start) 2484 | (define-key navi-mode-map (kbd "C-c C-x :") 2485 | 'navi-timer-cancel-timer) 2486 | (define-key navi-mode-map (kbd "C-c C-x ;") 'navi-timer-set-timer) 2487 | (define-key navi-mode-map (kbd "C-c C-x <") 2488 | 'navi-agenda-set-restriction-lock) 2489 | (define-key navi-mode-map (kbd "C-c C-x >") 2490 | 'navi-agenda-remove-restriction-lock) 2491 | (define-key navi-mode-map (kbd "C-c C-x E") 'navi-inc-effort) 2492 | (define-key navi-mode-map (kbd "C-c C-x P") 2493 | 'navi-set-property-and-value) 2494 | (define-key navi-mode-map (kbd "C-c C-x a") 2495 | 'navi-toggle-archive-tag) 2496 | (define-key navi-mode-map (kbd "C-c C-x d") 'navi-insert-drawer) 2497 | (define-key navi-mode-map (kbd "C-c C-x e") 'navi-set-effort) 2498 | (define-key navi-mode-map (kbd "C-c C-x f") 'navi-footnote-action) 2499 | (define-key navi-mode-map (kbd "C-c C-x p") 'navi-set-property) 2500 | 2501 | ;; menu for navi-mode 2502 | (define-key navi-mode-map [menu-bar navi] 2503 | (cons (purecopy "Navi") navi-menu-map)) 2504 | (define-key navi-mode-map [menu-bar occur] nil) 2505 | 2506 | ;; keys for navi-edit-mode 2507 | (set-keymap-parent navi-edit-mode-map text-mode-map) 2508 | (define-key navi-edit-mode-map [mouse-2] 'occur-mode-mouse-goto) 2509 | (define-key navi-edit-mode-map "\M-n" 'occur-next) 2510 | (define-key navi-edit-mode-map "\M-p" 'occur-prev) 2511 | (define-key navi-edit-mode-map "\M-o" 'occur-mode-display-occurrence) 2512 | (define-key navi-edit-mode-map "\C-c\C-f" 'next-error-follow-minor-mode) 2513 | (define-key navi-edit-mode-map "\C-c\C-c" 'navi-cease-edit) 2514 | ;; menu for navi-edit-mode 2515 | (define-key navi-edit-mode-map [menu-bar navi] nil) 2516 | (define-key navi-edit-mode-map [menu-bar occur] nil) 2517 | (define-key navi-edit-mode-map [menu-bar navi-edit] 2518 | (cons (purecopy "Navi-Edit") navi-edit-menu-map)) 2519 | 2520 | ;;; Run Hooks and Provide 2521 | 2522 | ;; (add-to-list 'navi-mode-hook 'navi-mode-hook-function) 2523 | ;; (run-mode-hooks) 2524 | 2525 | (provide 'navi-mode) 2526 | 2527 | ;;; navi-mode.el ends here 2528 | -------------------------------------------------------------------------------- /old/old-readme.txt: -------------------------------------------------------------------------------- 1 | Thorsten Jolitz 2 | 3 | 4 | Table of Contents 5 | _________________ 6 | 7 | 1 navi-mode.el --- major-mode for easy buffer-navigation 8 | .. 1.1 Copyright 9 | .. 1.2 Licence 10 | .. 1.3 Credits 11 | .. 1.4 Commentary 12 | ..... 1.4.1 About navi-mode 13 | ..... 1.4.2 Installation 14 | ..... 1.4.3 Usage 15 | ..... 1.4.4 Emacs Version 16 | .. 1.5 ChangeLog 17 | 18 | 19 | 1 navi-mode.el --- major-mode for easy buffer-navigation 20 | ======================================================== 21 | 22 | 1.1 Copyright 23 | ~~~~~~~~~~~~~ 24 | 25 | Copyright (C) 2013 Thorsten Jolitz 26 | 27 | Author: Thorsten Jolitz 28 | Maintainer: Thorsten Jolitz 29 | Version: 1.0 30 | Created: 11th March 2013 31 | Keywords: occur, outlines, navigation 32 | 33 | 34 | 1.2 Licence 35 | ~~~~~~~~~~~ 36 | 37 | This file is NOT (yet) part of GNU Emacs. 38 | 39 | This program is free software; you can redistribute it and/or modify 40 | it under the terms of the GNU General Public License as published by 41 | the Free Software Foundation, either version 3 of the License, or (at 42 | your option) any later version. 43 | 44 | This program is distributed in the hope that it will be useful, but 45 | WITHOUT ANY WARRANTY; without even the implied warranty of 46 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 47 | General Public License for more details. 48 | 49 | You should have received a copy of the GNU General Public License 50 | along with this program. If not, see [http://www.gnu.org/licenses/]. 51 | 52 | 53 | 1.3 Credits 54 | ~~~~~~~~~~~ 55 | 56 | This library is inspired by the Org-mode command `org-goto', which 57 | shows the documemt structure of an Org-mode file in a temporary 58 | buffer, and enables navigation in that buffer without changing the 59 | original-buffer's visibility-level, and by the authors frequent use of 60 | (M-x) `occur' (and the resulting *Occur* buffer) for buffer navigation 61 | purposes. 62 | 63 | 64 | 1.4 Commentary 65 | ~~~~~~~~~~~~~~ 66 | 67 | 1.4.1 About navi-mode 68 | --------------------- 69 | 70 | This file implements extensions for occur-mode. You can think of a 71 | navi-buffer as a kind of 'remote-control' for an (adecuately) 72 | outline-structured original-buffer. It enables quick navigation and 73 | basic structure editing in the original-buffer without (necessarily) 74 | leaving the navi-buffer. When switching to the original-buffer and 75 | coming back after some modifications, the navi-buffer is always 76 | reverted (thus up-to-date). 77 | 78 | Besides the fundamental outline-heading-searches (8 outline-levels) 79 | and the 5 basic keyword-searches (:FUN, :VAR, :DB, :OBJ and :ALL), all 80 | languages can have their own set of searches and keybindings (see 81 | `navi-key-mappings' and `navi-keywords'). Heading-searches and 82 | keyword-searches can be combined, offering a vast amount of possible 83 | 'views' at the original-buffer. 84 | 85 | 86 | 1.4.2 Installation 87 | ------------------ 88 | 89 | Download (or clone the github-repos of) the three required libraries 90 | 91 | `navi-mode.el' ([https://github.com/tj64/navi]) 92 | `outshine.el' ([https://github.com/tj64/outshine]) 93 | `outorg.el' ([https://github.com/tj64/outorg]) 94 | 95 | and put them in a place where Emacs can find them (on the Emacs 96 | 'load-path'). Follow the installation instructions in `outshine.el' 97 | and `outorg.el'. 98 | 99 | Install `navi-mode.el' by adding 100 | 101 | #+begin_src emacs-lisp 102 | (require 'navi-mode) 103 | #+end_src 104 | 105 | to your .emacs file. 106 | 107 | 108 | 1.4.3 Usage 109 | ----------- 110 | 111 | For `navi-mode' to work, the original-buffer must be 112 | outline-structured 'the outshine way', i.e. with the headlines being 113 | proper Org-mode headlines, marked and outcommented with 114 | `comment-region'. As an example, to generate a 3rd level 115 | outshine-headline in an Emacs Lisp file, write down 116 | 117 | ,----------------------- 118 | *** Third Level Header 119 | `----------------------- 120 | 121 | mark the header line, and apply `comment-region' on it: 122 | 123 | ,----------------------- 124 | ;; *** Third Level Header 125 | `----------------------- 126 | 127 | In a LaTeX file, an adecuate header will look like this: 128 | 129 | ,----------------------- 130 | % *** Third Level Header 131 | `----------------------- 132 | 133 | and in a PicoLisp file like this (always depending of the major-mode 134 | specific values of `comment-start', `comment-end', `comment-add' and 135 | `comment-padding'): 136 | 137 | ,----------------------- 138 | ## *** Third Level Header 139 | `----------------------- 140 | 141 | The second assumption is that `outline-minor-mode' is activated in the 142 | original-buffer and `outshine.el' loaded like described in its 143 | installation instructions, i.e. 144 | 145 | #+begin_src emacs-lisp 146 | (require 'outshine) 147 | (add-hook 'outline-minor-mode-hook 'outshine-hook-function) 148 | #+end_src 149 | 150 | When these pre-conditions are fullfilled (`outorg.el' must be loaded 151 | too), you can use 'M-s n' (`navi-search-and-switch') to open a 152 | navi-buffer and immediately switch to it. The new navi-buffer will 153 | show the first-level headings of the original-buffer, with point at 154 | the first entry. 155 | 156 | You can then: 157 | 158 | 1. Show headlines (up-to) different levels: 159 | 160 | key command function-name 161 | --------------------------------------------------- 162 | 1 ... 8 show levels 1 to 8 navi-generic-command 163 | 164 | 2. Navigate up and down in the search results shown in the 165 | navi-buffer: 166 | 167 | key command function-name 168 | ----------------------------------- 169 | p previous occur-prev 170 | n next occur-next 171 | DEL down page scroll-down-command 172 | SPC up page scroll-up-command 173 | 174 | 3. Revert the navi-buffer (seldom necessary), show help for the 175 | user-defined keyword-searches, and quit the navi-buffer and 176 | switch-back to the original-buffer: 177 | 178 | key command function-name 179 | ------------------------------------------------------ 180 | g revert buffer navi-revert-function 181 | h show help navi-show-help 182 | q quit navi-mode and switch navi-quit-and-switch 183 | 184 | 4. Switch to the original-buffer and back to the navi-buffer, display 185 | and occurence in the original-buffer or go to the occurence: 186 | 187 | key command function-name 188 | -------------------------------------------------------------------- 189 | M-s n launch navi-buffer navi-search-and-switch 190 | M-s s switch to other buffer navi-switch-to-twin-buffer 191 | M-s M-s 192 | s 193 | d display occurrence occur-mode-display-occurrence 194 | o goto occurrence navi-goto-occurrence-other-window 195 | 196 | 5. Structure editing on subtrees and visibility cycling 197 | 198 | key command function-name 199 | ------------------------------------------------------------------- 200 | TAB cycle subtrees navi-cycle-subtree 201 | cycle buffer navi-cycle-buffer 202 | + Demote Subtree navi-demote-subtree 203 | - promote subtree navi-promote-subtree 204 | ^ move up subtree (same level) navi-move-up-subtree 205 | < move down subtree (same level) navi-move-down-subtree 206 | 207 | 6. Miscancellous actions on subtrees 208 | 209 | key command function-name 210 | -------------------------------------------------------------------- 211 | m mark subtree navi-mark-subtree-and-switch 212 | c copy subtree navi-copy-subtree-to-register-s 213 | k kill subtree navi-kill-subtree 214 | y yank killed/copied subtree navi-yank-subtree-from-register-s 215 | u undo last change navi-undo 216 | r narrow to subtree navi-narrow-to-subtree 217 | w widen navi-widen 218 | l query-replace navi-query-replace 219 | i isearch navi-isearch 220 | e edit as org (outorg) navi-edit-as-org 221 | 222 | 7. Furthermore, there are five (semantically) predefined 223 | keyword-searches: 224 | 225 | key keyword-symbol searches for 226 | ------------------------------------------------- 227 | f :FUN functions, macros etc. 228 | v :VAR vars, consts, customs etc. 229 | x :OBJ OOP (classes, methods etc) 230 | b :DB DB (store and select) 231 | a :ALL all 232 | 233 | 234 | 8. And (potentially) many more user-defined keyword-searches 235 | (example Emacs Lisp): 236 | 237 | key keyword-symbol searches for 238 | ----------------------------------- 239 | F :defun (defun 240 | V :defvar (defvar 241 | C :defconst (defconst 242 | G :defgroup (defgroup 243 | U :defcustom (defcustom 244 | A :defadvice (defadvice 245 | M :defmacro (defmacro 246 | E :defface (defface 247 | S :defstruct (defstruct 248 | L :defclass (defclass 249 | 250 | 9. Headline-searches and keyword-searches can be combined, e.g. 251 | 252 | ,------ 253 | C-2 f 254 | `------ 255 | 256 | in an Emacs Lisp (outshine-)buffer shows all headlines up-to level 2 257 | as well as all function, macro and advice definitions in the 258 | original-buffer, 259 | 260 | ,------ 261 | C-5 a 262 | `------ 263 | 264 | shows all headlines up-to level 5 as well as all functions, variables, 265 | classes, methods, objects, and database-related definitions. The exact 266 | meaning of the standard keyword-searches 'f' and 'a' must be defined 267 | with a regexp in the customizable variable `navi-keywords' (just like 268 | the user-defined keyword-searches). 269 | 270 | When exploring a (potentially big) original buffer via navi-mode, a 271 | common usage pattern is the following: 272 | 273 | 1. type e.g '2' and go to the relevant headline 274 | 2. type 'r' and e.g. '3' in sequence to narrow buffers to the subtree 275 | at point and show one deeper level of headlines 276 | 3. do your thing in the narrowed subtree 277 | 4. type e.g. '2' and 'w' to first reduce the headline levels shown and 278 | then widen the buffers again. 279 | 280 | 281 | 1.4.4 Emacs Version 282 | ------------------- 283 | 284 | `navi-mode.el' works with [GNU Emacs 24.2.1 (x86_64-unknown-linux-gnu, 285 | GTK+ Version 3.6.4) of 2013-01-20 on eric]. No attempts of testing 286 | with older versions or other types of Emacs have been made (yet). 287 | 288 | 289 | 1.5 ChangeLog 290 | ~~~~~~~~~~~~~ 291 | 292 | date author(s) version 293 | ------------------------------------------------- 294 | 2013-05-03 Fr Thorsten Jolitz 1.0 295 | 2013-03-11 Mo Thorsten Jolitz 0.9 296 | --------------------------------------------------------------------------------