Mercurial > hg > xemacs-beta
diff lisp/oobr/br-compl.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-compl.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,284 @@ +;;!emacs +;; +;; FILE: br-compl.el +;; SUMMARY: Most functions for performing completion on OO constructs. +;; USAGE: GNU Emacs Lisp Library +;; KEYWORDS: matching, oop, tools +;; +;; AUTHOR: Bob Weiner +;; ORG: Motorola Inc. +;; +;; ORIG-DATE: 27-Mar-90 +;; LAST-MOD: 4-May-95 at 17:08:48 by Bob Weiner +;; +;; Copyright (C) 1990-1995 Free Software Foundation, Inc. +;; See the file BR-COPY for license information. +;; +;; This file is part of the OO-Browser. +;; +;; DESCRIPTION: +;; DESCRIP-END. + +(global-set-key "\M-\C-i" 'br-complete-symbol) + +;; ************************************************************************ +;; Other required Elisp libraries +;; ************************************************************************ + +;; Requires a number of functions from "br-lib.el", part of the OO-Browser +;; package. See the code for functions called but not defined within this +;; file. + +;; ************************************************************************ +;; Public functions +;; ************************************************************************ + +(defun br-buffer-menu () + "Display list of buffers for current browser language in the viewer window." + (interactive) + (or (br-in-view-window-p) + (setq *br-prev-listing-window* (selected-window))) + (let ((owind (selected-window)) + (ovbuf (save-window-excursion + (br-to-view-window) + (current-buffer)))) + (buffer-menu 'files-only) + (narrow-to-region (point) (point-max)) + (let ((buffer-read-only nil) + (buf-name)) + (while (setq buf-name (br-buffer-menu-buffer-name)) + (if (not (string-match br-src-file-regexp buf-name)) + (delete-region (point) (progn (forward-line 1) (point))) + (forward-line 1)))) + (goto-char (point-min)) + (widen) + (if (looking-at "^$") ;; No matching buffers + (progn + (switch-to-buffer ovbuf) + (select-window owind) + (beep) + (message + "(OO-Browser): No appropriate buffers available for selection.")) + (set-window-start nil 1) + (substitute-key-definition 'Buffer-menu-select 'br-buffer-menu-select + Buffer-menu-mode-map) + (message "(OO-Browser): Select a buffer for display.")))) + +(defun br-buffer-menu-buffer-name () + "Return name of buffer on curren buffer menu line or nil. +Leaves point at the beginning of the current line." + (if (= (point) (point-max)) + nil + (beginning-of-line) + (forward-char Buffer-menu-buffer-column) + (let ((start (point))) + ;; End of buffer name marked by tab or two spaces. + (if (not (re-search-forward "\t\\| ")) + nil + (skip-chars-backward " \t") + (prog1 + (buffer-substring start (point)) + (beginning-of-line)))))) + +(defun br-buffer-menu-select () + "Display buffer associated with the line that point is on." + (interactive) + (substitute-key-definition 'br-buffer-menu-select 'Buffer-menu-select + Buffer-menu-mode-map) + (let ((buff (Buffer-menu-buffer t)) + (menu (current-buffer))) + (if buff + (progn (switch-to-buffer buff) + (or (eq menu buff) + (bury-buffer menu))) + (beep)))) + +(defun br-complete-entry (&optional prompt) + "Interactively completes class or feature name and returns it or nil. +Optional PROMPT is initial prompt string for user." + (interactive) + (let ((default (and (br-in-browser) + (not (br-in-view-window-p)) + (br-find-class-name))) + (completion-ignore-case t) + completions + element-name) + (if (not (br-class-path default)) (setq default nil)) + ;; Prompt with possible completions of element-name. + (setq prompt (or prompt "Class/Element name:") + completions (append (br-class-completions) + (br-feature-completions)) + element-name + (if completions + (completing-read + (format "%s (default %s) " prompt (or default "<None>")) + completions nil 'must-match) + (read-string + (format "%s (default %s) " prompt (or default "<None>"))))) + (if (equal element-name "") (setq element-name default)) + element-name)) + +(defun br-complete-symbol () + "Complete symbol preceding point." + (interactive) + (cond ((and (fboundp 'br-lang-mode) + (eq major-mode (symbol-function 'br-lang-mode))) + (br-complete-type)) + (t + (lisp-complete-symbol)))) + +(defun br-complete-class-name (&optional must-match prompt) + "Interactively completes class name if possible, and returns class name. +Optional MUST-MATCH means class name must match a completion table entry. +Optional PROMPT is intial prompt string for user." + (interactive) + (let ((default (br-find-class-name)) + (completion-ignore-case t) + completions + class-name) + ;; Prompt with possible completions of class-name. + (setq prompt (or prompt "Class name:") + completions (br-class-completions) + class-name + (if completions + (completing-read + (format "%s (default %s) " prompt default) + completions nil must-match) + (read-string + (format "%s (default %s) " prompt default)))) + (if (equal class-name "") default class-name))) + +(defun br-lisp-mode-p () + (or (eq major-mode 'lisp-mode) + (eq major-mode 'emacs-lisp-mode) + (eq major-mode 'scheme-mode) + (eq major-mode 'lisp-interaction-mode))) + +(defun br-complete-type () + "Perform in-buffer completion of a type or element identifier before point. +That symbol is compared against current Environment entries and any needed +characters are inserted." + (interactive) + (let* ((completion-ignore-case nil) + (end (point)) + (beg (save-excursion + (if (br-lisp-mode-p) + nil + (skip-chars-backward "^()") + (if (eq (preceding-char) ?\() + (skip-chars-backward " \t\(") + (goto-char end)) + ) + (skip-chars-backward (concat br-identifier-chars ":")) + (point))) + (pattern (br-set-case (buffer-substring beg end))) + (type-p) + (completion-alist (if (string-match br-feature-signature-regexp + pattern) + (br-feature-completions) + (setq type-p t) + (br-class-completions))) + (completion (try-completion pattern completion-alist))) + (cond ((eq completion t)) + ((null completion) + (message "Can't find completion for '%s'" pattern) + (ding)) + ((not (string-equal pattern completion)) + (delete-region beg end) + (insert (if type-p + (br-set-case-type completion) + completion))) + (t + (message "Making completion list...") + (let ((list (sort (all-completions pattern completion-alist) + 'string-lessp))) + (let (new) + (while list + (setq new (cons (car list) new) + list (cdr list))) + (setq list (nreverse new))) + (with-output-to-temp-buffer "*Completions*" + (display-completion-list list))) + (message "Making completion list...%s" "done"))))) + +;; Derived from saveconf.el. +(defun br-window-list () + "Returns a list of Lisp window objects for all Emacs windows. +Do not count the minibuffer window even if it is active." + (let* ((first-window (next-window (previous-window (selected-window)))) + (windows (cons first-window nil)) + (current-cons windows) + (w (next-window first-window))) + (while (not (eq w first-window)) + (setq current-cons (setcdr current-cons (cons w nil))) + (setq w (next-window w))) + windows)) + +;; ************************************************************************ +;; Private functions +;; ************************************************************************ + +(defun br-all-classes (&optional htable-type duplicates-flag) + "Return list of class names in Environment or optional HTABLE-TYPE. +HTABLE-TYPE may be \"sys\" or \"lib\" or an actual hash table. +List is not sorted unless optional DUPLICATES-FLAG is non-nil, which means cons +the the sorted list of duplicate classes onto the front of the unique class +names list." + (let ((classes + (apply 'append + (hash-map + (function (lambda (val-key-cons) + ;; Copy so that hash-table values are not + ;; disturbed. + (copy-sequence (car val-key-cons)))) + (cond ((and (stringp htable-type) + (not (string-equal htable-type ""))) + (br-get-htable (concat htable-type "-paths"))) + ((hashp htable-type) htable-type) + (t (br-get-paths-htable))))))) + (if duplicates-flag + (br-duplicate-and-unique-strings (sort classes 'string-lessp)) + classes))) + +(defun br-class-completions () + "Return alist of elements whose cars are all class names in lookup table." + (mapcar (function (lambda (elt) (cons elt nil))) + (br-class-list-filter (sort (br-all-classes) 'string-lessp)))) + +(defun br-find-class-name (&optional keep-indent) + "Return class name that point is within in a listing buffer, else nil. +Optional KEEP-INDENT non-nil means keep indentation preceding class name." + (if (= (point) (point-max)) (skip-chars-backward " \t\n")) + (save-excursion + (if (looking-at (concat "[ \t]*" br-feature-type-regexp "?[ \t]+")) + (goto-char (match-end 0))) + (let ((objc (string-equal br-lang-prefix "objc-")) + (class)) + (if objc + ;; Include [] characters for default classes, <> for Objective-C + ;; protocols and () for Objective-C class categories. + (skip-chars-backward (concat "\]\[()<>" br-identifier-chars)) + (skip-chars-backward (concat "\]\[" br-identifier-chars))) + (if (or (and objc + (or + ;; Objective-C protocol + (looking-at (concat "<" br-identifier ">")) + ;; Objective-C class(category) + (looking-at (concat br-identifier "(" br-identifier ")")) + ;; Objective-C class(category) + (if (looking-at + (concat "\\((" br-identifier ")\\)" br-identifier)) + (setq class (concat (buffer-substring (match-end 1) + (match-end 0)) + (buffer-substring + (match-beginning 1) + (match-end 1))))))) + (looking-at br-identifier) + ;; default class + (looking-at (concat "\\[" br-identifier "\\]"))) + (progn (if keep-indent (beginning-of-line)) + (br-set-case (or class + (buffer-substring (point) + (match-end 0))))))))) + +(provide 'br-compl)