1 ;;; idlw-complete-structtag.el --- Completion of structure tags.
2 ;; Copyright (c) 2001,2002 Free Software Foundation
4 ;; Author: Carsten Dominik <dominik@astro.uva.nl>
5 ;; Maintainer: J.D. Smith <jdsmith@as.arizona.edu
7 ;; Date: $Date: 2003-08-12 12:26:17 $
10 ;; This file is part of GNU Emacs.
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
29 ;; Completion of structure tags is highly ambiguous since you never
30 ;; know what kind of structure a variable will hold at runtime.
31 ;; However, in some applications there is one main structure which
32 ;; contains a large amount of information. For example, in many
33 ;; widget applications, a "state" structure contains all important
34 ;; data about the application is stored in the main widget. The
35 ;; different routines called by the event handler then use this
36 ;; structure for their actions. If you use the same variable name for
37 ;; this structure throughout your application (a good idea for many
38 ;; reasons), IDLWAVE can support completion for its tags.
40 ;; This file is a completion plugin which implements this kind of
41 ;; completion. It is also an example which shows how completion
42 ;; plugins should be programmed.
44 ;; New versions of IDLWAVE, documentation, and more information
50 ;; Put this file on the emacs load path and load it with the following
51 ;; line in your .emacs file:
53 ;; (add-hook 'idlwave-load-hook
54 ;; (lambda () (require 'idlw-complete-structtag)))
58 ;; Suppose your IDL program contains something like
62 ;; where the star marks the cursor position. If you now press the
63 ;; completion key M-TAB, IDLWAVE searches the current file for a
64 ;; structure definition
66 ;; state = {tag1:val1, tag2:val2, ...}
68 ;; and offers the tags for completion.
72 ;; - The structure definition assignment "state = {...}" must use the
73 ;; same variable name as the the completion location "state.*".
74 ;; - The structure definition must be in the same file.
75 ;; - The structure definition is searched backwards from the end of
76 ;; the file, until a definition with tags is found.
77 ;; - The file is parsed again for the definition only if the variable
78 ;; name (like "state") of the current completion differs from the
79 ;; previous tag completion.
80 ;; - You can force and update of the tag list with the usual command
81 ;; to update routine info in IDLWAVE: C-c C-i
84 (defvar idlwave-current-tags-var nil)
85 (defvar idlwave-current-tags-buffer nil)
86 (defvar idlwave-current-struct-tags nil)
87 (defvar idlwave-sint-structtags nil)
88 (idlwave-new-sintern-type 'structtag)
89 (add-to-list 'idlwave-complete-special 'idlwave-complete-structure-tag)
90 (add-hook 'idlwave-update-rinfo-hook 'idlwave-structtag-reset)
92 (defun idlwave-complete-structure-tag ()
93 "Complete a structure tag.
94 This works by looking in the current file for a structure assignment to a
95 variable with the same name and takes the tags from there. Quite useful
96 for big structures like the state variables of a widget application."
101 ;; Check if the context is right
102 (skip-chars-backward "[a-zA-Z0-9._$]")
104 (not (equal (char-before) ?!)) ; no sysvars
105 (looking-at "\\([a-zA-Z][a-zA-Z0-9_]*\\)\\.")
106 (>= pos (match-end 0))
107 (not (string= (downcase (match-string 1)) "self")))) ;; FIXME: Can we avoid checking for self here?
108 (let* ((var (downcase (match-string 1))))
109 ;; Check if we need to update the "current" structure
110 (if (or (not (string= var (or idlwave-current-tags-var "@")))
111 (not (eq (current-buffer) idlwave-current-tags-buffer)))
112 (idlwave-prepare-structure-tag-completion var))
113 (setq idlwave-completion-help-info
114 (list 'idlwave-complete-structure-tag-help))
115 (idlwave-complete-in-buffer 'structtag 'structtag
116 idlwave-current-struct-tags nil
117 "Select a structure tag" "structure tag")
118 t) ; return t to skip other completions
121 (defun idlwave-structtag-reset ()
122 (setq idlwave-current-tags-buffer nil))
124 (defvar idlwave-structtag-struct-location nil)
125 (defun idlwave-prepare-structure-tag-completion (var)
126 "Find and parse the necessary class definitions for class structure tags."
127 ;; (message "switching to var %s" var) ; FIXME: take this out.
132 (goto-char (point-max))
133 (while (idlwave-find-structure-definition var nil 'back)
134 (let ((tags (idlwave-struct-tags)))
136 (setq idlwave-sint-structtags nil
137 idlwave-current-tags-buffer (current-buffer)
138 idlwave-current-tags-var var
139 idlwave-structtag-struct-location (point)
140 idlwave-current-struct-tags
142 (list (idlwave-sintern-structtag x 'set)))
145 (error "Cannot complete structure tags of variable %s" var)))
147 ;; Fake help in the source buffer for structure tags.
148 ;; kwd and name are global-variables here.
149 (defvar idlwave-help-do-struct-tag)
150 (defun idlwave-complete-structure-tag-help (mode word)
152 ((eq mode 'test) ; nothing gets fontified for class tags
156 idlwave-help-do-struct-tag idlwave-structtag-struct-location))
157 (t (error "This should not happen"))))
159 (provide 'idlw-complete-structtag)
161 ;;; idlw-complete-structtag.el ends here