Mercurial > hg > xemacs-beta
diff lisp/oobr/br-ftr.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/oobr/br-ftr.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,422 @@ +;;!emacs +;; +;; FILE: br-ftr.el +;; SUMMARY: OO-Browser feature browsing support. +;; USAGE: GNU Emacs Lisp Library +;; KEYWORDS: oop, tools +;; +;; AUTHOR: Bob Weiner +;; ORG: Motorola Inc. +;; +;; ORIG-DATE: 20-Aug-91 at 18:16:36 +;; LAST-MOD: 25-Aug-95 at 16:54:53 by Bob Weiner +;; +;; Copyright (C) 1991-1995, Free Software Foundation, Inc. +;; See the file BR-COPY for license information. +;; +;; This file is part of the OO-Browser. +;; +;; DESCRIPTION: +;; DESCRIP-END. + +;;; ************************************************************************ +;;; Public variables +;;; ************************************************************************ + +(defconst br-feature-type-regexp "[-+=@%>1/]" + "Regular expression which matches the first non-whitespace characters in an OO-Browser feature listing.") + +;;; ************************************************************************ +;;; Public functions +;;; ************************************************************************ + +(defun br-find-feature (&optional feature-entry view-only other-win) + "Display feature definition for FEATURE-ENTRY in VIEW-ONLY mode if non-nil. +Return feature path if FEATURE-ENTRY is successfully displayed, nil +otherwise. Can also signal an error when called interactively." + (interactive) + (and (interactive-p) (setq view-only current-prefix-arg)) + (let ((feature-path)) + (setq feature-entry + (br-feature-signature-and-file + (or feature-entry + (br-feature-complete 'must-match "Show feature definition:"))) + feature-path (cdr feature-entry) + feature-entry (car feature-entry)) + (br-edit-feature feature-entry feature-path other-win view-only))) + +(defun br-edit-feature (tag-entry feature-path &optional other-win view-only) + "Edit feature for OO-Browser TAG-ENTRY of file FEATURE-PATH, optionally in OTHER-WIN. +With optional VIEW-ONLY, view feature definition instead of editing it. +Return FEATURE-PATH if feature definition is found, else nil." + (let ((err)) + (cond ((and feature-path (file-readable-p feature-path)) + (cond ((br-feature-found-p feature-path tag-entry nil other-win) + (br-major-mode) + (if view-only + (setq buffer-read-only t) + ;; Handle case of already existing buffer in + ;; read only mode. + (and buffer-read-only + (file-writable-p feature-path) + (setq buffer-read-only nil))) + ;; Force mode-line redisplay + (set-buffer-modified-p (buffer-modified-p))) + ((interactive-p) + (setq err + (format + "(OO-Browser): No '%s' feature defined in Environment." + tag-entry) + feature-path nil)))) + ((interactive-p) + (setq err + (format + "(OO-Browser): '%s' - src file not found or not readable, %s" + tag-entry feature-path) + feature-path nil))) + (if err (error err)) + feature-path)) + +(defun br-find-feature-entry () + "Return feature entry that point is within or nil." + (if (= (point) (point-max)) (skip-chars-backward " \t\n")) + (save-excursion + (beginning-of-line) + (if (or + (progn (skip-chars-forward " \t") + (looking-at br-feature-entry)) + ;; Get current feature signature, if any. + (br-feature-get-signature)) + (let ((feature (buffer-substring + (point) + (progn (skip-chars-forward "^\t\n\r") (point))))) + (if (and (equal br-lang-prefix "objc-") + ;; Remove any trailing class from a category entry. + (string-match "@ ([^\)]+)" feature)) + (substring feature 0 (match-end 0)) + feature))))) + +(defun br-feature-complete (&optional must-match prompt) + "Interactively completes feature entry if possible, and returns it. +Optional MUST-MATCH means must match a completion table entry. +Optional PROMPT is intial prompt string for user." + (interactive) + (let ((default (br-find-feature-entry)) + (completion-ignore-case t) + completions + ftr-entry) + ;; Prompt with possible completions of ftr-entry. + (setq prompt (or prompt "Feature entry:") + completions (br-feature-completions) + ftr-entry + (if completions + (completing-read + (format "%s (default %s) " prompt default) + completions nil must-match) + (read-string + (format "%s (default %s) " prompt default)))) + (if (equal ftr-entry "") default ftr-entry))) + +(defun br-feature-completions () + "Return completion alist of all current Environment elements." + (cond ((not (and br-feature-tags-file (file-exists-p br-feature-tags-file) + (file-readable-p br-feature-tags-file))) + nil) + ((and br-feature-tags-completions + (eq + (car (cdr br-feature-tags-completions)) ;; tags last mod time + (apply '+ (nth 5 (file-attributes br-feature-tags-file)))) + (equal br-env-file (car br-feature-tags-completions))) + (car (cdr (cdr br-feature-tags-completions)))) + (t + (let ((ftr-buf (get-buffer-create "*ftr-buf*")) + (ftr-alist)) + (save-excursion + (br-feature-tags-init) + (copy-to-buffer ftr-buf 1 (point-max)) + (set-buffer ftr-buf) + (goto-char 1) + (while (search-forward "\^L" nil t) + (forward-line 1) + ;; Skip past pathname where features are defined. + (while (and (= (forward-line 1) 0) + (not (looking-at "\^L\\|\\'"))) + (setq ftr-alist (cons (cons (br-feature-signature-to-name + (br-feature-current) + t) + nil) + ftr-alist))))) + (kill-buffer ftr-buf) + (setq br-feature-tags-completions + (list br-env-file + ;; tags last mod time + (apply '+ (nth 5 (file-attributes + br-feature-tags-file))) + ftr-alist)) + ftr-alist)))) + +(defun br-feature-def-file (feature-regexp) + "Return file name in which feature matching FEATURE-REGEXP is, if any. +Assume feature tags file is current buffer and leave point at the start of +matching feature tag, if any." + (goto-char 1) + (and (re-search-forward feature-regexp nil t) + ;; This ensures that point is left on the same line as the feature tag + ;; which is found. + (goto-char (match-beginning 0)) + (br-feature-file-of-tag))) + +(defun br-feature-file (feature-sig) + "Return file name in which feature matching FEATURE-SIG is, if any." + (let ((obuf (current-buffer)) + (file)) + (set-buffer (funcall br-find-file-noselect-function br-feature-tags-file)) + (goto-char 1) + (if (search-forward feature-sig nil t) + (setq file (br-feature-file-of-tag))) + (set-buffer obuf) + file)) + +(defun br-feature-found-p (buf-file feature-tag + &optional deferred-class other-win regexp-flag) + "Search BUF-FILE for FEATURE-TAG. +Return nil if not found, otherwise display it and return non-nil." + (if buf-file + (let ((found-def) + (opoint (point)) + (prev-buf) + (prev-point) + (config (current-window-configuration))) + (setq prev-buf (get-file-buffer buf-file)) + (funcall br-edit-file-function buf-file other-win) + (setq prev-point (point)) + (widen) + (goto-char (point-min)) + (setq found-def + (cond (deferred-class + (br-feature-locate-p feature-tag deferred-class)) + (regexp-flag + (br-feature-locate-p feature-tag regexp-flag)) + (t (br-feature-locate-p feature-tag)))) + (if found-def + ;; Set appropriate mode for file. + (br-major-mode) + (setq buf-file (get-file-buffer buf-file)) + (if prev-buf + (goto-char prev-point) + (if buf-file + (kill-buffer buf-file) + (goto-char prev-point))) + (set-window-configuration config) + (goto-char opoint)) + found-def))) + +(defun br-feature-name (ftr-entry) + "Return name part of FTR-ENTRY." + (if (equal (string-match br-feature-entry ftr-entry) 0) + (substring ftr-entry (match-beginning 1)) + "")) + +(defun br-feature-signature-and-file (class-and-feature-name) + "Return (feature signature . feature-def-file-name) of CLASS-AND-FEATURE-NAME." + (let ((obuf (current-buffer)) + ;; Find only exact matches + (name-regexp (br-feature-name-to-regexp class-and-feature-name)) + (result)) + (set-buffer (funcall br-find-file-noselect-function br-feature-tags-file)) + (goto-char 1) + (if (re-search-forward name-regexp nil t) + (progn (goto-char (match-beginning 0)) + (setq result (cons (br-feature-current) + (br-feature-file-of-tag))))) + (set-buffer obuf) + result)) + +(defun br-feature-signature (&optional arg) + "Show full feature signature in the view window. +With optional prefix ARG, display signatures of all features from the current +buffer." + (interactive "P") + (let* ((buf (buffer-name)) + (owind (selected-window)) + (features (delq nil (if arg (br-feature-get-tags) + (list (br-feature-get-signature)))))) + (if (null features) + (progn (beep) (message "No elements.")) + (br-to-view-window) + (switch-to-buffer (get-buffer-create (concat buf "-Elements"))) + (setq buffer-read-only nil) + (erase-buffer) + (mapcar (function (lambda (feature) (insert feature "\n"))) + features) + (br-major-mode) + (goto-char 1) + (select-window owind) + (message "")))) + +;;; ************************************************************************ +;;; Listing buffer entry tag property handling. +;;; ************************************************************************ + +(if (string-match "^19\." emacs-version) + (progn + ;; + ;; Emacs 19 buffer entry tags functions + ;; + + (defun br-feature-clear-signatures (&optional buf-nm) + "Erase any feature signatures saved with current buffer or optional BUF-NM." + (save-excursion + (if buf-nm (set-buffer (get-buffer buf-nm))) + (save-restriction + (widen) + (remove-text-properties (point-min) (point-max) '(tag))))) + + (defun br-feature-get-signature (&optional line-num-minus-one) + (save-excursion + (if (numberp line-num-minus-one) + (goto-line (1+ line-num-minus-one))) + (end-of-line) + (car (cdr (memq 'tag (text-properties-at (1- (point)))))))) + + (defun br-feature-get-tags () + (save-excursion + (goto-char (point-max)) + (let ((found t) + (tags) + tag) + (while found + (setq tag (get-text-property (1- (point)) 'tag)) + (if tag (setq tags (cons tag tags))) + (setq found (= (forward-line -1) 0)) + (end-of-line)) + tags))) + + ;; Tag property is placed at end of line in case leading indent is + ;; removed by an OO-Browser operation. In that case, we don't want to + ;; lose the tag property. + (defun br-feature-put-signatures (ftr-sigs) + (while ftr-sigs + (end-of-line) + (put-text-property (- (point) 2) (point) 'tag (car ftr-sigs)) + (setq ftr-sigs (cdr ftr-sigs)) + (if (and ftr-sigs (/= (forward-line 1) 0)) + (error "(br-feature-put-signatures): Too few lines in this buffer")))) + + ) + + ;; + ;; Emacs 18 buffer entry tags functions + ;; + + (defun br-feature-clear-signatures (&optional buf-nm) + "Erase any feature signatures saved with current buffer or optional BUF-NM." + (put (intern (or buf-nm (buffer-name))) 'features nil)) + + (defun br-feature-get-signature (&optional line-num) + (or (numberp line-num) + (save-excursion + (beginning-of-line) + (setq line-num (count-lines 1 (point))))) + (cdr (assq line-num (get (intern-soft (buffer-name)) 'features)))) + + (defun br-feature-get-tags () + (get (intern-soft (buffer-name)) 'features)) + + (defun br-feature-put-signatures (ftr-sigs) + (beginning-of-line) + (let* ((line (count-lines 1 (point))) + (meth-alist (mapcar (function + (lambda (meth) + (prog1 (cons line meth) + (setq line (1+ line))))) + ftr-sigs)) + (buf-sym (intern (buffer-name)))) + (put buf-sym 'features + (nconc (get buf-sym 'features) meth-alist)))) + ) + +;;; ************************************************************************ +;;; END - Listing buffer entry tag property handling. +;;; ************************************************************************ + +(defun br-feature-tags-init () + "Set up 'br-feature-tags-file' for writing." + (setq br-feature-tags-completions nil + br-feature-tags-file (br-feature-tags-file-name br-env-file) + br-tags-file (concat br-env-file "-TAGS")) + (set-buffer (funcall br-find-file-noselect-function br-feature-tags-file)) + (setq buffer-read-only nil)) + +(defun br-feature-tags-file-name (env-file) + (concat env-file "-FTR")) + +(defun br-feature-tags-save () + "Filter out extraneous lines and save 'br-feature-tags-file'." + (let ((obuf (current-buffer))) + (set-buffer (funcall br-find-file-noselect-function br-feature-tags-file)) + (goto-char (point-min)) + (delete-matching-lines "^[ \t]*$") + (goto-char (point-min)) + (replace-regexp "^[ \t]+\\|[ \t]+$" "") + (and br-c-tags-flag + (br-member br-lang-prefix '("c++-" "objc-")) + (progn (c-build-element-tags) + (goto-char (point-min)) + (replace-regexp "[ \t]*//.*" ""))) + (goto-char (point-min)) + (delete-matching-lines "^$") + (save-buffer) + (set-buffer obuf))) + +(defun br-insert-features (feature-tag-list &optional indent) + "Insert feature names from FEATURE-TAG-LIST in current buffer indented INDENT columns." + (let ((start (point))) + (mapcar (function + (lambda (feature-tag) + (if indent (indent-to indent)) + (if feature-tag + (insert (br-feature-signature-to-name feature-tag nil t) + "\n")))) + feature-tag-list) + (save-excursion + (goto-char start) + (br-feature-put-signatures feature-tag-list)))) + +;;; ************************************************************************ +;;; Private functions +;;; ************************************************************************ + +(defun br-feature-current () + "Extract current feature from tags file and leave point at the end of line." + (beginning-of-line) + (buffer-substring (point) (progn (end-of-line) (point)))) + +(defun br-feature-file-of-tag () + "Return the file name of the file whose tag point is within. +Assumes the tag table is the current buffer." + (save-excursion + (search-backward "" nil t) + (forward-line 1) + (let ((start (point))) + (end-of-line) + (buffer-substring start (point))))) + +;;; ************************************************************************ +;;; Private variables +;;; ************************************************************************ + +(defconst br-feature-entry + (concat br-feature-type-regexp " \\([^\t\n\r]*[^ \t\n\r]\\)") + "Regexp matching a feature entry in a browser listing buffer.") + +(defvar br-feature-tags-completions nil + "List of (envir-name tags-file-last-mod-time tags-completion-alist).") + +(defvar br-feature-tags-file nil + "Pathname where current object-oriented feature tags are stored.") + +(defvar br-tags-file nil + "Pathname where current non-object-oriented feature tags are stored.") + +(provide 'br-ftr)