From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Thorsten Jolitz Newsgroups: gmane.emacs.help Subject: Re: Creating Custom Occur Mode Buffers Date: Thu, 27 Feb 2014 10:08:01 +0100 Message-ID: <87lhwwkjny.fsf@gmail.com> References: <530E99B2.6090608@yahoo.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1393492054 5408 80.91.229.3 (27 Feb 2014 09:07:34 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 27 Feb 2014 09:07:34 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Feb 27 10:07:44 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WIwwR-0003yY-8g for geh-help-gnu-emacs@m.gmane.org; Thu, 27 Feb 2014 10:07:43 +0100 Original-Received: from localhost ([::1]:44988 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIwwQ-0004NI-P9 for geh-help-gnu-emacs@m.gmane.org; Thu, 27 Feb 2014 04:07:42 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50744) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIwwA-0004N1-QF for help-gnu-emacs@gnu.org; Thu, 27 Feb 2014 04:07:32 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WIww4-0001dK-Hl for help-gnu-emacs@gnu.org; Thu, 27 Feb 2014 04:07:26 -0500 Original-Received: from plane.gmane.org ([80.91.229.3]:38290) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WIww4-0001d9-6q for help-gnu-emacs@gnu.org; Thu, 27 Feb 2014 04:07:20 -0500 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1WIww2-0002Cd-8I for help-gnu-emacs@gnu.org; Thu, 27 Feb 2014 10:07:18 +0100 Original-Received: from g231232051.adsl.alicedsl.de ([92.231.232.51]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 27 Feb 2014 10:07:18 +0100 Original-Received: from tjolitz by g231232051.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 27 Feb 2014 10:07:18 +0100 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 158 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: g231232051.adsl.alicedsl.de User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:ma1IDaSeuxQaMV1qwbPpU0kp14o= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:96212 Archived-At: Eric James Michael Ritz 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 "") '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