help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Creating Custom Occur Mode Buffers


From: Thorsten Jolitz
Subject: Re: Creating Custom Occur Mode Buffers
Date: Thu, 27 Feb 2014 10:08:01 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Eric James Michael Ritz <address@hidden> writes:

> I am working on a mode where I want the user to take some user input,
> run it through an external program which will return all lines in a
> file matching that input, and then show those lines in an *Occur*
> buffer so that the user can easily navigate them.  What is the best
> way to create and populate a buffer to work with Occur Mode?  Or is
> there a better approach which I should consider?

You might want to have a look at navi-mode.el (you can get it from MELPA
via the package manager or from github: https://github.com/tj64/navi
and see it in action on
[[http://www.youtube.com/watch?v%3DnqE6YxlY0rw][Youtube]])

Its a specialised *Occur* mode designed to work with Org-mode and
Outshine buffers (outshine.el). Since outshine should (in theory) work
with all kinds of Emacs major-modes, navi-mode should too - as long as
the files are structured the 'outshine way' (which is actually the
Org-mode way, but with outcommented Org-mode headers). 

Navi-mode is extensible, I defined sets of keyword searches for Emacs
Lisp, PicoLisp, Org-mode and ESS/R-mode so far, but anyone can define
his/her own keyword-searches via the two customizable variables

  ,------------------
  | navi-key-mappings
  | navi-keywords
  `------------------

using M-x customize-variable.

Here is what I came up with for Emacs Lisp buffers:

,---------------------------------------------
| (defcustom navi-key-mappings
|   '(("emacs-lisp" . ((:ALL . "a")
|                      (:FUN . "f")
|                      (:VAR . "v")
|                      (:OBJ . "x")
|                      (:DB . "b")
|                      (:defun . "F")
|                      (:defvar . "V")
|                      (:defconst . "C")
|                      (:defgroup . "G")
|                      (:defcustom . "U")
|                      (:defadvice . "A")
|                      (:defalias . "W")
|                      (:defmarcro . "M")
|                      (:defface . "D")
|                      (:defstruct . "S")
|                      (:defsubst . "B")
|                      (:defclass . "L")
|                      (:define . "I")
|                      (:declare . "J")
|                      (:global-set-key . "K")
|                      (:add-to-list . "T")
|                      (:setq . "Q")
|                      (:add-hook . "H")
|                      (:hook . "O")
|                      (:lambda . "X")
|                      (:require . "R")))
`---------------------------------------------
  
,---------------------------------------------------------------------
| (defcustom navi-keywords
|   '(("emacs-lisp" . ((:ALL . "^[[:space:]]*(def[a-z]+ ")
|                      (:OBJ . "^[[:space:]]*(def[smc][^auo][a-z]+ ")
|                      (:VAR . "^[[:space:]]*(def[vcgf][^l][a-z]+ ")
|                      (:FUN
|                       . "^[[:space:]]*(def[maus][^elt][a-z]*\\*? ")
|                      (:defun . "^[[:space:]]*(defun\\*? ")
|                      (:defvar . "^[[:space:]]*(defvar ")
|                      (:defconst . "^[[:space:]]*(defconst ")
|                      (:defgroup . "^[[:space:]]*(defgroup ")
|                      (:defcustom . "^[[:space:]]*(defcustom ")
|                      (:defadvice . "^[[:space:]]*(defadvice ")
|                      (:defalias . "^[[:space:]]*(defalias ")
|                      (:defmarcro . "^[[:space:]]*(defmacro ")
|                      (:defface . "^[[:space:]]*(defface ")
|                      (:defstruct . "^[[:space:]]*(defstruct ")
|                      (:defsubst . "^[[:space:]]*(defsubst ")
|                      (:defclass . "^[[:space:]]*(defclass ")
|                      (:defmethod . "^[[:space:]]*(defmethod ")
|                      (:declare . "^[[:space:]]*(declare-")
|                      (:define . "^[[:space:]]*(define-")
|                      (:global-set-key . "^[[:space:]]*(global-set-key ")
|                      (:add-to-list . "^[[:space:]]*(add-to-list ")
|                      (:setq . "^[[:space:]]*(setq ")
|                      (:add-hook . "^[[:space:]]*(add-hook ")
|                      (:hook . "-hook-?")
|                      (:lambda . "(lambda (")
|                      (:require . "^[[:space:]]*([a-z-]*require ")))
`---------------------------------------------------------------------


so you define a key first:

   ,---------------
   | (:defun . "F")
   `---------------

and then associate it with a regexp:

   ,----------------------------------
   | (:defun . "^[[:space:]]*(defun\\*? ")
   `----------------------------------

Then when you type F in the *Navi* buffer (a specialized *Occur*
buffer) it shows all (defun ...) in your Emacs Lisp source-code
buffer. The nice thing is you can type C-3 F and it shows you all
(outshine = outcommented Org-mode) headlines from level 1 to level 3
AND all defuns, giving a good overview. 

Navi-mode can do many other things, its not only for navigation but a
kind of 'remote-control' for the associated source-code buffer. Here
are the principal keybindings to give you an idea:

,------------------------------------------------------------------------
| (define-key navi-mode-map (kbd "s") 'navi-switch-to-twin-buffer)
| (define-key navi-mode-map (kbd "d") 'occur-mode-display-occurrence)
| (define-key navi-mode-map (kbd "o") 'navi-goto-occurrence-other-window)
| (define-key navi-mode-map (kbd "n") 'occur-next)
| (define-key navi-mode-map (kbd "p") 'occur-prev)
| (define-key navi-mode-map (kbd "SPC") 'scroll-up-command)
| (define-key navi-mode-map (kbd "DEL") 'scroll-down-command)
| (define-key navi-mode-map (kbd "TAB") 'navi-cycle-subtree)
| (define-key navi-mode-map (kbd "<backtab>") 'navi-cycle-buffer)
| (define-key navi-mode-map (kbd "m")
|   'navi-mark-thing-at-point-and-switch)
| (define-key navi-mode-map (kbd "c")
|   'navi-copy-thing-at-point-to-register-s)
| (define-key navi-mode-map (kbd ".")
|   'navi-act-on-thing-at-point)
| (define-key navi-mode-map (kbd "z") 'navi-mail-subtree)
| (define-key navi-mode-map (kbd "r") 'navi-narrow-to-thing-at-point)
| (define-key navi-mode-map (kbd "w") 'navi-widen)
| (define-key navi-mode-map (kbd "l") 'navi-query-replace)
| (define-key navi-mode-map (kbd "i") 'navi-isearch)
| (define-key navi-mode-map (kbd "k") 'navi-kill-thing-at-point)
| (define-key navi-mode-map (kbd "y") 'navi-yank-thing-from-register-s)
| (define-key navi-mode-map (kbd "u") 'navi-undo)
| (define-key navi-mode-map (kbd "e") 'navi-edit-as-org)
| (define-key navi-mode-map (kbd "E") 'navi-edit-mode)
| (define-key navi-mode-map (kbd "h") 'navi-show-help)
| (define-key navi-mode-map (kbd "+") 'navi-demote-subtree)
| (define-key navi-mode-map (kbd "-") 'navi-promote-subtree)
| (define-key navi-mode-map (kbd "^") 'navi-move-up-subtree)
| (define-key navi-mode-map (kbd "<") 'navi-move-down-subtree)
| (define-key navi-mode-map (kbd "g") 'navi-revert-function)
| (define-key navi-mode-map (kbd "q") 'navi-quit-and-switch)
`------------------------------------------------------------------------

so maybe you can build you mode on top of navi-mode.el or use it as an
example.

-- 
cheers,
Thorsten




reply via email to

[Prev in Thread] Current Thread [Next in Thread]