Mercurial > hg > xemacs-beta
diff lisp/hyperbole/kotl/kvspec.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 4103f0995bd7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/hyperbole/kotl/kvspec.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,366 @@ +;;!emacs +;; +;; FILE: kvspec.el +;; SUMMARY: Koutline view specification. +;; USAGE: GNU Emacs Lisp Library +;; KEYWORDS: outlines, wp +;; +;; AUTHOR: Bob Weiner +;; +;; ORIG-DATE: 21-Oct-95 at 15:17:07 +;; LAST-MOD: 3-Nov-95 at 19:44:10 by Bob Weiner +;; +;; This file is part of Hyperbole. +;; Available for use and distribution under the same terms as GNU Emacs. +;; +;; Copyright (C) 1995, Free Software Foundation, Inc. +;; Developed with support from Motorola Inc. +;; +;; DESCRIPTION: +;; +;;; Koutliner view specs +;; + means support code has been written already. +;; +;; + all: Show all lines of cells and all cells in the outline. +;; + blank: Blank lines are on. +;; b - on +;; + cutoff: Show only NUM lines per cell, 0 = all +;; c - set default cutoff lines +;; cNUM - set cutoff lines to NUM +;; descend: Only entries below this entry +;; + elide: Ellipses are on. +;; e - ellipses on +;; filter: Regexp or filter program to select entries for view, +;; off=select non-matching entries +;; glue: Freeze any group of entries selected to stay at top of +;; window, off=freeze those not-in-group. +;; include: Include an entry referenced by a link. +;; + level: Some levels are hidden. +;; l - set default level clipping +;; lNUM - set level clipping to NUM +;; name: Display leading names within cells. +;; m - show names +;; + number: Cell numbers are on +;; n - set default labels +;; n0 - display idstamp labels +;; n1 - display alpha labels +;; n2 - display partial alpha labels +;; n. - display legal labels +;; n* - display star labels +;; n~ - turn off labels +;; rest: Only following cells. +;; synthesize: Use a named generator function to generate entries for +;; view. +;; view: Turn koutliner view mode on. Standard insertion keys then +;; can be used for browsing and view setting. +;; +;; DESCRIP-END. + +;;; ************************************************************************ +;;; Other required Elisp libraries +;;; ************************************************************************ + +(require 'kview) + +;;; ************************************************************************ +;;; Public variables +;;; ************************************************************************ + +(defvar kvspec:current nil + "String that represents the current view spec. +It is local to each koutline. Nil value means it has not been set yet.") + +;;; ************************************************************************ +;;; Public functions +;;; ************************************************************************ + +(defun kvspec:activate (&optional view-spec) + "Activate optional VIEW-SPEC or existing view spec in the current koutline. +VIEW-SPEC is a string or t, which means recompute the current view spec. See +<${hyperb:dir}/kotl/EXAMPLE.kotl, 2b17=048> for details on valid view specs." + (interactive (list (read-string "Set view spec: " kvspec:current))) + (kotl-mode:is-p) + (if (or (equal view-spec "") (equal view-spec kvspec:current)) + (setq view-spec nil)) + (kvspec:initialize) + (kvspec:update view-spec) + (kvspec:update-view)) + +(defun kvspec:initialize () + "Ensure that view spec settings will be local to the current buffer." + (if (and (fboundp 'local-variable-p) + (local-variable-p 'kvspec:current (current-buffer))) + nil + (make-local-variable 'kvspec:current) + (make-local-variable 'kvspec:string))) + +(defun kvspec:levels-to-show (levels-to-keep) + "Hide all cells in outline at levels deeper than LEVELS-TO-KEEP (a number). +Shows any hidden cells within LEVELS-TO-KEEP. 1 is the first level. 0 means +display all levels of cells." + (if (null levels-to-keep) + (setq levels-to-keep + (read-from-minibuffer "Show cells down to level (0 = show all levels): " + nil nil t))) + (setq levels-to-keep (prefix-numeric-value levels-to-keep)) + (if (< levels-to-keep 0) + (error "(kvspec:levels-to-show): Must display at least one level.")) + (kview:map-tree + (function (lambda (kview) + (if (/= (kcell-view:level) levels-to-keep) + (kotl-mode:show-tree) + (kotl-mode:hide-subtree) + ;; Move to last cell in hidden subtree, to skip further + ;; processing of these cells. + (if (kcell-view:next t) + (kcell-view:previous) + (goto-char (point-max)))))) + kview t) + (kview:set-attr kview 'levels-to-show levels-to-keep)) + +(defun kvspec:show-lines-per-cell (num) + "Show NUM lines per cell." + (if (and (integerp num) (>= num 0)) + nil + (error "(kvspec:show-lines-per-cell): Invalid lines per cell, '%d'" num)) + (kview:set-attr kview 'lines-to-show num) + (let (start end count) + (if (zerop num) + ;; Show all lines in cells. + (kview:map-tree + (function + (lambda (kview) + ;; Use free variable label-sep-len bound in kview:map-tree for + ;; speed. + (setq start (goto-char (kcell-view:start nil label-sep-len)) + end (kcell-view:end-contents)) + ;; Show all lines in cell. + (subst-char-in-region start end ?\r ?\n t))) + kview t t) + ;; Show NUM lines in cells. + (kview:map-tree + (function + (lambda (kview) + ;; Use free variable label-sep-len bound in kview:map-tree for speed. + (setq start (goto-char (kcell-view:start nil label-sep-len)) + end (kcell-view:end-contents) + count (1- num)) + ;; Hide all lines in cell. + (subst-char-in-region start end ?\n ?\r t) + ;; Expand num - 1 newlines to show num lines. + (while (and (> count 0) (search-forward "\r" end t)) + (replace-match "\n") (setq count (1- count))))) + kview t t)))) + +(defun kvspec:toggle-blank-lines () + "Toggle blank lines between cells on or off." + (interactive) + (setq kvspec:current + (if (string-match "b" kvspec:current) + (hypb:replace-match-string "b" kvspec:current "" t) + (concat "b" kvspec:current))) + (kvspec:blank-lines) + (kvspec:update-modeline)) + +(defun kvspec:update (view-spec) + "Update current view spec according to VIEW-SPEC but don't change the view. +VIEW-SPEC is a string or t, which means recompute the current view spec. See +<${hyperb:dir}/kotl/EXAMPLE.kotl, 2b17=048> for details on valid view specs." + (cond ((stringp view-spec) + ;; Use given view-spec after removing extraneous characters. + (setq kvspec:current + (hypb:replace-match-string + "[^.*~0-9abcdefgilnrsv]+" view-spec "" t))) + ((or (eq view-spec t) (null kvspec:current)) + (setq kvspec:current (kvspec:compute)))) + ;; Update display using current specs. + (kvspec:update-modeline)) + +;;; ************************************************************************ +;;; Private functions +;;; ************************************************************************ + +(defun kvspec:blank-lines () + "Turn blank lines on or off according to 'kvspec:current'." + (let ((modified-p (buffer-modified-p)) + (buffer-read-only)) + (if (string-match "b" kvspec:current) + ;; On + (progn (kview:set-attr kview 'blank-lines t) + (kproperty:remove (point-min) (point-max) '(invisible t))) + ;; Off + (kview:set-attr kview 'blank-lines nil) + (save-excursion + (goto-char (point-max)) + (while (re-search-backward "[\n\r][\n\r]" nil t) + ;; Make blank lines invisible. + (kproperty:put (1+ (point)) (min (+ (point) 2) (point-max)) + '(invisible t))))) + (set-buffer-modified-p modified-p))) + +(defun kvspec:compute () + "Compute and return current view spec string." + (concat + + ;; a - Show all cells and cell lines. + ;; Never compute this setting (use it only within links) since it will + ;; expose all carefully hidden outline items if the user forgets to turn + ;; it off when he resets the view specs. + + ;; b - blank separator lines + (if (kview:get-attr kview 'blank-lines) "b") + + ;; c - cutoff lines per cell + (let ((lines (kview:get-attr kview 'lines-to-show))) + (if (zerop lines) + nil + (concat "c" (int-to-string lines)))) + + ;; e - ellipses on + (if selective-display-ellipses "e") + + ;; l - hide some levels + (let ((levels (kview:get-attr kview 'levels-to-show))) + (if (zerop levels) + nil + (concat "l" (int-to-string levels)))) + + ;; n - numbering type + (let ((type (kview:label-type kview))) + (cond ((eq type 'no) nil) + ((eq type kview:default-label-type) "n") + (t (concat "n" (char-to-string + (car (rassq (kview:label-type kview) + kvspec:label-type-alist))))))))) + +(defun kvspec:elide () + "Turn ellipses display following clipped cells on or off according to 'kvspec:current'." + (setq selective-display-ellipses + (if (string-match "e" kvspec:current) t))) + +(defun kvspec:hide-levels () + "Show a set number of cell levels according to 'kvspec:current'." + ;; "l" means use value of kview:default-levels-to-show. + ;; "l0" means show all levels. + (let (levels) + (if (not (string-match "l\\([0-9]+\\)?" kvspec:current)) + ;; Don't change the view if no view spec is given but note that + ;; all levels should be shown in the future. + (kview:set-attr kview 'levels-to-show 0) + (if (match-beginning 1) + (setq levels (string-to-int + (substring kvspec:current (match-beginning 1) + (match-end 1)))) + (setq levels kview:default-levels-to-show)) + (kview:set-attr kview 'levels-to-show levels) + (kvspec:levels-to-show levels)))) + +(defun kvspec:lines-to-show () + "Show a set number of lines per cell according to 'kvspec:current'." + ;; "c" means use value of kview:default-lines-to-show. + ;; "c0" means show all lines. + (cond ((not (string-match "c\\([0-9]+\\)?" kvspec:current)) + ;; Don't change the view if no view spec is given but note that all + ;; lines should be shown in the future. + (kview:set-attr kview 'lines-to-show 0)) + ((match-beginning 1) + (kvspec:show-lines-per-cell + (string-to-int (substring kvspec:current (match-beginning 1) + (match-end 1))))) + (t (kvspec:show-lines-per-cell kview:default-lines-to-show)))) + +(defun kvspec:numbering () + "Set the type of numbering (label) display according to 'kvspec:current'." + (if (not (string-match "n\\([.*~0-2]\\)?" kvspec:current)) + nil + ;; "n" means use value of kview:default-label-type. + ;; "n0" means display idstamps. + ;; "n1" means display alpha labels. + ;; "n2" means display partial alpha labels. + ;; "n." means display legal labels. + ;; "n*" means star labels. + ;; "n~" means no labels. + (let (spec type) + (if (match-beginning 1) + (setq spec (string-to-char + (substring kvspec:current + (match-beginning 1) (match-end 1))) + type (cdr (assq spec kvspec:label-type-alist))) + (setq type kview:default-label-type)) + (kview:set-label-type kview type)))) + +(defun kvspec:update-modeline () + "Setup or update display of the current kview spec in the modeline." + (if (stringp kvspec:current) + (setq kvspec:string (format kvspec:string-format kvspec:current))) + (if (memq 'kvspec:string mode-line-format) + nil + (setq mode-line-format (copy-sequence mode-line-format)) + (let ((elt (or (memq 'mode-line-buffer-identification mode-line-format) + (memq 'modeline-buffer-identification mode-line-format)))) + (setcdr elt (cons 'kvspec:string (cdr elt)))))) + +(defun kvspec:update-view () + "Update view according to current setting of local 'kvspec:current' variable." + (let ((modified-p (buffer-modified-p)) + (buffer-read-only)) + (save-excursion + + (if (string-match "a" kvspec:current) + (kotl-mode:show-all)) + + (kvspec:blank-lines) ;; b + + ;; This must come before kvspec:lines-to-show or else it could show + ;; lines that should be hidden. + (kvspec:hide-levels) ;; l + + (kvspec:lines-to-show) ;; c + + (if (string-match "d" kvspec:current) + nil) + + (kvspec:elide) ;; e + + (if (string-match "f" kvspec:current) + nil) + + (if (string-match "g" kvspec:current) + nil) + + (if (string-match "i" kvspec:current) + nil) + + (if (string-match "r" kvspec:current) + nil) + + (if (string-match "s" kvspec:current) + nil) + + ;; Do this last since it can trigger an error if partial alpha is + ;; selected. + (kvspec:numbering) ;; n + + ) + (set-buffer-modified-p modified-p))) + +;;; ************************************************************************ +;;; Private variables +;;; ************************************************************************ + +(defvar kvspec:label-type-alist + '((?0 . idstamp) (?1 . alpha) (?2 . partial-alpha) + (?. . legal) (?* . star) (?~ . no)) + "Alist of (view-spec-character . label-type) pairs.") + +(defvar kvspec:string "" + "String displayed in koutline modelines to reflect the current view spec. +It is local to each koutline. Set this to nil to disable modeline display of +the view spec settings.") + +(defvar kvspec:string-format " <|%s>" + "Format of the kview spec modeline display. +It must contain a '%s' which is replaced with the current set of view spec +characters at run-time.") + +(provide 'kvspec)