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