1 ;; jde-complete.el -- Smart completion for the JDE
5 ;; Author: Rodrigo Reyes <reyes@chez.com>
6 ;; Maintainers: Rodrigo Reyes
7 ;; Paul Kinnucan <pkinnucan@mediaone.net>
10 ;; Stephane Nicolas <s.nicolas@videotron.ca>,
11 ;; Javier Lopez <jlopez@forumsys.com>
13 ;; Keywords: java, intellisense, completion
15 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Rodrigo Reyes, Paul Kinnucan,
16 ;; Stephane Nicolas, David Ponce, Javier Lopez
18 ;; This package follows the GNU General Public Licence (GPL), see the
19 ;; COPYING file that comes along with GNU Emacs. This is free software,
20 ;; you can redistribute it and/or modify it under the GNU GPL terms.
22 ;; Java is a registered trademark of Sun Microsystem, Inc.
26 ;; This is one of a set of packages that make up the
27 ;; Java Development Environment for Emacs (JDEE). See the
28 ;; JDEE User's Guide for more information.
31 ;; This package adds smart completion to the JDE. How it works is
32 ;; simple : put the cursor at the end of a statement "under
33 ;; construction", eg. "myVariable.rem<CURSOR HERE> and call the
34 ;; jde-complete-at-point emacs-lisp function (this is by default
35 ;; C-.). A completion is then inserted. If multiple completions are
36 ;; possible, calling the completion function again will cycle through
37 ;; all the possibilities (as dabbrev-mode does).
39 ;; To retrieve all the possible completions, it uses the java code in
40 ;; jde.util.Completion.getClassInfo(), called by beanshell. That
41 ;; need the class to be compiled (but that's not worst than an etag
44 ;; Known bugs/problems :
47 ;; Move all the strings manipulation to the java side so that
48 ;; class info can be loaded in the background.
50 ;; The latest version of the JDEE is available at
51 ;; <URL:http://jde.sunsite.dk>.
53 ;; Please send any comments, bugs, or upgrade requests to
54 ;; Paul Kinnucan at pkinnucan@attbi.com
56 ;;jde-eldoc for completion signatures
59 (require 'semantic-idle)
61 (defgroup jde-complete nil
64 :prefix "jde-complete-")
66 (defconst jde-complete-public 0 "Represent a public java modifiers")
68 (defconst jde-complete-protected 1 "Represent a protected java modifiers")
70 (defconst jde-complete-package 2 "Represent a package java modifiers")
72 (defconst jde-complete-private 3 "Represent a private java modifiers")
74 (defconst jde-complete-fields 0 "Represents the positions
75 where the fields are placed.")
77 (defconst jde-complete-constructors 1 "Represents the positions
78 where the constructors are placed.")
80 (defconst jde-complete-methods 2 "Represents the positions
81 where the methods are placed.")
83 (defconst jde-complete-classes 3 "Represents the positions
84 where the classes are placed.")
86 (defvar jde-complete-temp-process "*Temp*"
87 "Used as the name of a temporary process")
89 (defvar jde-complete-last-compiled-class nil
90 "Contains the name of the class that was compiled last")
92 (defvar jde-complete-current-signature nil
93 "Contains the signature of the last method inserted by
94 either `jde-complete-in-line' or `jde-complete-menu'")
96 (defconst jde-complete-signature-buffer "*Signature*"
97 "Buffer to display signatures")
99 (defvar jde-complete-display-signature nil
100 "If non nil it displays the `jde-complete-current-signaure' in
103 (defcustom jde-complete-signature-display (list "Eldoc")
104 "Display modes used to show the method signature after a completion.
105 The display modes choices are using eldoc-mode(the signature shows in the
106 minibuffer), a buffer(a one line buffer shows the signature and then
107 dissapears), or none."
115 (defcustom jde-complete-signature-display-time 5
116 "Amount of time in seconds to display the method signature
117 in the minibuffer after a completion."
121 (defcustom jde-complete-add-space-after-method nil
122 "*If non nil it will add a space between the method
123 name and the first parenthesis. i.e foo () instead of foo() when using
124 the completion methods `jde-complete-in-line' and `jde-complete-menu'
125 After customizing this variable, be sure to use
126 `jde-complete-flush-classinfo-cache', any class information that was
127 previously cache is not going to be affected by this setting."
131 (defcustom jde-complete-unique-method-names nil
132 "If non nil it will display methods with the same name
133 but with different signature only once, the signature for ths methods
134 will be the signature of the first method in the list of completions
135 The list of completion is sorted in alphabetical order.
136 This variable modifies the completion for `jde-complete-menu'
137 and `jde-complete-in-line'. After customizing this variable,
138 be sure to use `jde-complete-flush-classinfo-cache',
139 any class information that was previously cache is not going to be affected by
144 (defcustom jde-complete-insert-method-signature t
145 "If non nil it will insert the method signature when using
146 `jde-complete-in-line' and `jde-complete-menu'
147 i.e. v.get(int, java.lang.String). If `jde-complete-unique-method-names'
148 is non nil methods with the same name will get the signature of the first one
149 in the completion list. After customizing this variable, be sure to use
150 `jde-complete-flush-classinfo-cache', any class information that was
151 previously cache is not going to be affected by this setting"
155 (defcustom jde-complete-display-qualified-types t
156 "If non nil use fully qualified types when displaying methods for selection,
157 i.e. v.get(int, java.lang.String). If nil, use unqualified types, i.e.
158 v.get(int, String). After customizing this variable, be sure to use
159 `jde-complete-flush-classinfo-cache', any class information that was
160 previously cache is not going to be affected by this setting."
164 (defcustom jde-complete-display-result-type t
165 "If non nil include result type when displaying methods for selection.
166 After customizing this variable, be sure to use
167 `jde-complete-flush-classinfo-cache', any class information that was
168 previously cache is not going to be affected by this setting."
172 (defcustom jde-complete-display-throws t
173 "If non nil include thrown exceptions when displaying methods for selection.
174 After customizing this variable, be sure to use
175 `jde-complete-flush-classinfo-cache', any class information that was
176 previously cache is not going to be affected by this setting."
180 ;; (makunbound 'jde-complete-function)
181 (defcustom jde-complete-function 'jde-complete-menu
182 "*Function that will be invoked by the `jde-complete-select' command.
183 The `jde-complete-menu' function displays completions for
184 the symbol at point in a popup menu. The `jde-complete-minibuf' function
185 displays completions in the minibuffer. You may also
186 specify a custom function to use. The custom function must
187 be an interactive function that can be called by
188 `call-interactively'."
191 (function-item jde-complete-menu)
192 (function-item jde-complete-minibuf)
193 (function-item jde-complete-in-line)
194 (function :format "%t %v" :tag "Custom:")))
196 (defvar jde-complete-current-list nil
197 "The list of all the completion. Each element of the list is a list
198 which car is the possible completion, and the cdr is an additional
199 information about this completion.")
201 (defvar jde-complete-current-list-index nil
202 "An index to an element in jde-complete-current-list. This is used to
205 (defun jde-complete-valid-java-declaration-at (point varname)
206 "Verify that a POINT starts a valid java declaration
207 for the VARNAME variable."
211 (concat "\\([A-Za-z0-9_.\177-\377]+\\)[ \t\n\r]+"
212 (jde-complete-double-backquotes varname)
217 (defun jde-complete-double-backquotes (varname)
218 "Build a new string identical to VARNAME, except that every backquote
219 `\' is doubled, so that it can be used in a regex expression"
220 (let (result (idx 0) (len (length varname)) curcar)
222 (setq curcar (elt varname idx))
223 (setq result (concat result (if (eq curcar ?\\)
225 (make-string 1 curcar))))
229 (defun jde-complete-declared-type-of (name)
230 "Find in the current buffer the java type of the variable NAME. The
231 function returns a string containing the name of the class, or nil
232 otherwise. This function does not give the fully-qualified java class
233 name, it just returns the type as it is declared."
235 (let (found res pos orgpt resname)
236 (while (and (not found)
237 (search-backward name nil t))
240 (setq resname (jde-complete-valid-java-declaration-at (point) name))
244 (progn (setq res resname)
248 (defun jde-complete-filter-fqn (importlist)
249 "Filter all the fully-qualified classnames in the import list. It uses
250 the knowledge that those classnames are at the beginning of the list,
251 so that it can stops at the first package import (with a star `*' at
252 the end of the declaration)."
254 (if (string= "*" (car (cdr (car importlist))))
256 (jde-complete-filter-fqn (cdr importlist)))))
258 (defun jde-complete-guess-type-of (name)
259 "Guess the fully qualified name of the class NAME, using the import
260 list. It returns a string if the fqn was found, or a list of possible
262 (let ((importlist (jde-parse-import-list)) shortname fullname tmp result)
263 (while (and importlist (null result))
264 (setq tmp (car importlist))
265 (setq shortname (car (cdr tmp)))
266 (setq fullname (concat (car tmp) name))
268 ((string= "*" shortname)
269 (setq result importlist))
270 ((string= name shortname)
271 (setq result fullname))
273 (setq importlist (cdr importlist)))))
277 (defvar jde-complete-classinfo-cache nil)
279 (defcustom jde-complete-classinfo-cache-size 50
280 "The max size of completion's cache.")
282 (defun jde-complete-flush-classinfo-cache ()
283 "Flushes all entries in the completion cache"
285 (setq jde-complete-classinfo-cache nil))
287 (defun jde-complete-flush-classes-in-cache (class-list)
288 "Flushes all the classes in CLASS-LIST as entries of cache."
289 (let ((temp (nth 0 jde-complete-classinfo-cache))
292 (class (car class-list)))
294 (while (and temp (not found))
295 (setq index (1+ index))
296 (setq temp (nth index jde-complete-classinfo-cache))
297 (if (string= (car temp) class)
300 (setq jde-complete-classinfo-cache
301 (nthcdr (1+ index) jde-complete-classinfo-cache)))
302 (setq class-list (cdr class-list))
303 (setq class (car class-list))
306 (defun jde-complete-add-to-classinfo-cache (name classinfo)
307 (let (new-entry new-list)
308 (if (nth jde-complete-classinfo-cache-size jde-complete-classinfo-cache)
310 (setq new-entry (list name classinfo))
311 (setq new-list (list new-entry nil))
312 (setcdr new-list (cdr jde-complete-classinfo-cache))
313 (setq jde-complete-classinfo-cache new-list)
314 (message "cache is full"))
316 (setq jde-complete-classinfo-cache
318 jde-complete-classinfo-cache
319 (list (list name classinfo)))))))
321 (defun jde-complete-get-from-cache (name)
322 (let ((temp (nth 0 jde-complete-classinfo-cache)) (index -1) (found nil))
323 (while (and temp (not found))
324 (setq index (1+ index))
325 (setq temp (nth index jde-complete-classinfo-cache))
326 (if (string= (car temp) name)
332 (defun jde-complete-get-classinfo (name &optional access-level)
333 "Return the class info list for the class NAME and the ACCESS-LEVEL.
334 Allowed values for access level are 0 for protected 1 for private. This
335 function first checks to see if the class info is cached. If so, it returns the
336 cached class info. Otherwise, it creates the class info list. Each
337 element of the list returned by this function is itself a list whose
338 car is a possible completion and whose cdr gives additional
339 informations on the completion."
340 ;;replacing double quotes by empty strings double quotes seems to break the
342 (while (string-match "\"" name)
343 (setq name (replace-match "" nil nil name)))
345 ;;replacing back slaches by empty strings backlashes causes beanshell problem
346 (while (string-match "\\\\" name)
347 (setq name (replace-match "" nil nil name)))
349 ;;checking that access-level is not nil
350 (if (not access-level)
351 (setq access-level jde-complete-public))
353 (let ((class-info (jde-complete-get-from-cache name))
354 public-methods protected-methods private-methods
356 (when (not class-info)
357 ;;Getting public class info
359 (jde-complete-invoke-get-class-info
360 name jde-complete-public))
362 ;;Getting protected class info
363 (setq protected-methods
364 (jde-complete-invoke-get-class-info
365 name jde-complete-protected))
367 ;;Getting package class info
368 (setq package-methods
369 (jde-complete-invoke-get-class-info
370 name jde-complete-package))
372 ;;Getting private class info
373 (setq private-methods
374 (jde-complete-invoke-get-class-info
375 name jde-complete-private))
376 (setq class-info (append public-methods
381 (jde-complete-add-to-classinfo-cache name class-info)))
383 ;;Getting the class info depending on the access level
385 (jde-complete-get-accessible-info class-info access-level name))
386 (setq class-info (jde-complete-build-completion-list class-info))
388 ;;Removing duplicates
389 (setq class-info (jde-complete-remove-duplicates class-info))
392 (setq class-info (sort class-info 'jde-complete-sort-comparison))
395 (defun jde-complete-remove-duplicates (class-list)
396 "Removes duplicates from class-list"
399 (setq temp (car class-list))
400 (if (not (jde-complete-memberp (car temp) answer))
401 (setq answer (append answer (list temp))))
402 (setq class-list (cdr class-list)))
405 (defun jde-complete-memberp (elt lst)
406 "Returns t if elt is a memver of lst"
409 (setq tmp (caar lst))
410 (if (string= tmp elt)
414 (setq lst (cdr lst))))
417 (defun jde-complete-get-accessible-info (class-info access name)
418 "Takes a list of class info in this format \(list \(list public
419 info\) \(list protected info\) \(list package info\) \(list private
420 info\)\). Each info list is in the format \(list \(list fields\)
421 \(list constructors\) \(list methods\) \(list inner classes\)\). This
422 method will return a list concatenating the fields, methods, and inner
423 classes for the access level."
424 (let* ((public (nth jde-complete-public class-info))
425 (protected (nth jde-complete-protected class-info))
426 (package (nth jde-complete-package class-info))
427 (private (nth jde-complete-private class-info))
428 (package-name (jde-parse-get-package-name))
429 (this (concat (if package-name
430 (concat package-name "." ))
431 (jde-parse-get-class-at-point)))
432 answer fields constructors methods classes packagep)
433 (if (null package-name)
434 (setq package-name ""))
436 (setq packagep (string-match package-name name)))
437 (setq fields (append (nth jde-complete-fields public)
438 (if (>= access jde-complete-protected)
439 (nth jde-complete-fields protected))
441 (nth jde-complete-fields package))
442 (if (or (>= access jde-complete-private)
444 (nth jde-complete-fields private))))
445 (setq constructors (append (nth jde-complete-constructors public)
446 (if (>= access jde-complete-protected)
447 (nth jde-complete-constructors protected))
449 (nth jde-complete-constructors package))
450 (if (or (>= access jde-complete-private)
452 (nth jde-complete-constructors private))))
453 (setq methods (append (nth jde-complete-methods public)
454 (if (>= access jde-complete-protected)
455 (nth jde-complete-methods protected))
457 (nth jde-complete-methods package))
458 (if (or (>= access jde-complete-private)
460 (nth jde-complete-methods private))))
461 (setq classes (append (nth jde-complete-classes public)
462 (if (>= access jde-complete-protected)
463 (nth jde-complete-classes protected))
465 (nth jde-complete-classes package))
466 (if (or (>= access jde-complete-private)
468 (nth jde-complete-classes private))))
469 (setq answer (list fields constructors methods classes))
472 (defun jde-complete-invoke-get-class-info (name access)
473 "Invoke the method jde.util.Completion.getClassInfo(String, int)"
475 (format "jde.util.Completion.getClassInfo(\"%s\",%d);" name access)))
478 (defun jde-complete-get-classinfo-javacode (name import access-level)
479 "Return the java code that calls the
480 jde.util.Completion.getClassInfo function with the short java class
481 name NAME and the package list IMPORT where to look at."
485 "String[] lst = new String[" (number-to-string (length import)) "];\n"
490 (setq count (+ 1 count))
491 (concat "lst[" (int-to-string count) "]=\""
492 (car (nth count import)) "\";\n")))
495 "jde.util.Completion.getClassInfo(\"" name "\",lst,"
496 (number-to-string access-level) ");\n"
500 (defun jde-complete-sort-comparison (first second)
501 (string< (car first) (car second)))
503 (defun jde-complete-get-variables (variables)
504 "Transform a list of the type (\"var\" \"java.lang.String\")
505 into (\"var\" \"java.lang.String\ var\")"
506 (let (result current prev)
507 (if (null jde-complete-unique-method-names)
509 (setq current (car (car variables)))
512 (list (cons (concat current
513 (if jde-complete-display-result-type
516 (jde-complete-maybe-unqualify
517 (nth 1 (car variables))))))
520 (setq variables (cdr variables)))
522 (if (not (string= prev current))
527 (list (cons (concat current
528 (if jde-complete-display-result-type
530 (jde-complete-maybe-unqualify
531 (nth 1 (car variables))))))
534 (setq variables (cdr variables))))
537 (defun jde-complete-build-completion-list (classinfo)
538 "Build a completion list from the CLASSINFO list, as returned by the
539 jde.util.Completion.getClassInfo function."
541 ;; get the variable fields
542 (setq tmp (nth jde-complete-fields classinfo))
543 (setq result (jde-complete-get-variables tmp))
545 ;;get the constructors
546 (setq tmp (jde-complete-get-methods
547 (nth jde-complete-constructors classinfo) t))
548 (if tmp (setq result (append tmp result)))
551 (setq tmp (jde-complete-get-methods (nth jde-complete-methods classinfo)))
552 (if tmp (setq result (append tmp result)))
555 (setq tmp (jde-complete-get-inner-classes
556 (nth jde-complete-classes classinfo)))
557 (if tmp (setq result (append tmp result)))
561 (defun jde-complete-get-methods (classinfo &optional constructor)
562 (let ((end-paren (if (null jde-complete-add-space-after-method) "(" " ("))
563 (end-parens (if (null jde-complete-insert-method-signature)
564 (if (null jde-complete-add-space-after-method)
569 (let* ((type (car (cdr (car classinfo))));;method type i.e. boolean
570 (exceptions (jde-get-exceptions (car (last (car classinfo)))))
571 (method (jde-complete-build-information-for-completion
572 (car classinfo) end-paren))
573 (display (jde-complete-build-display-for-completion
574 (car classinfo) end-paren constructor)))
575 (setq current (jde-parse-get-unqualified-name (car (car classinfo))))
576 (if (not (and jde-complete-unique-method-names
577 (string= prev current)))
585 (if (null jde-complete-insert-method-signature)
590 (setq classinfo (cdr classinfo))))
593 (defun jde-complete-get-inner-classes(class-info)
594 "Takes as an argument a list of inner classes an return a string of
596 (let (tmp fullname pos name)
599 (let* ((fullname (caar class-info))
600 (pos (string-match "\\$" fullname))
601 (name (substring fullname (+ 1 pos))))
604 (list (cons (concat name " : " fullname)
607 (setq class-info (cdr class-info))))
610 (defun jde-get-exceptions (exceptions)
611 "Takes as an argument a list of EXCEPTIONS and return a string of them
613 (if (and (listp exceptions) (car exceptions))
616 (setq exs (concat exs (car exceptions)))
617 (setq exceptions (cdr exceptions))
618 (if exceptions (setq exs (concat exs ", "))))
622 (defun jde-complete-maybe-unqualify (type)
623 (if jde-complete-display-qualified-types
625 (jde-parse-get-unqualified-name type)))
627 (defun jde-complete-build-display-for-completion (lst
629 &optional constructor)
630 "Builds the string that describes a method in a menu for selecting a completion."
631 (let ((result (concat
632 (jde-parse-get-unqualified-name (car lst))
634 (rettype (car (cdr lst)))
635 (exceptions (if (and (listp (last lst)) (car (last lst)))
639 (setq lst (cdr (cdr lst))))
641 (not (listp (car lst))))
642 (setq result (concat result (jde-complete-maybe-unqualify (car lst))))
645 (not (listp (car lst))))
646 (setq result (concat result ", "))))
647 (setq result (concat result ")"))
649 (if (or (and (not constructor) rettype jde-complete-display-result-type)
650 (and exceptions jde-complete-display-throws)) " : ")
651 (if (and (not constructor) rettype jde-complete-display-result-type)
652 (jde-complete-maybe-unqualify rettype))
653 (if (and exceptions jde-complete-display-throws)
656 (mapcar 'jde-complete-maybe-unqualify exceptions)))))))
658 (defun jde-complete-build-information-for-completion (lst
660 &optional constructor)
661 "Builds the text that is inserted in the code for a particular completion."
662 (let ((result (concat
663 (jde-parse-get-unqualified-name (car lst))
667 (setq lst (cdr (cdr lst))))
669 (not (listp (car lst))))
670 (setq result (concat result (car lst)))
673 (not (listp (car lst))))
674 (setq result (concat result ", "))))
675 (setq result (concat result ")"))
678 (defun jde-complete-complete-cycle ()
679 "Replace the previous completion by the next one in the list."
681 (setq jde-complete-current-list-index (1+ jde-complete-current-list-index))
682 (if (>= jde-complete-current-list-index (length jde-complete-current-list))
683 (setq jde-complete-current-list-index 0))
684 (setq elem (nth jde-complete-current-list-index jde-complete-current-list))
685 (setq tmp (cdr elem))
688 (delete-region jde-parse-current-beginning
689 jde-parse-current-end)
691 (setq jde-complete-current-signature (car elem))
692 (jde-complete-place-cursor)
693 (set-marker jde-parse-current-end
694 (+ (marker-position jde-parse-current-beginning)
696 (jde-complete-display-current-signature));;displaying the signature
697 (message (format "No completion at this point!(cycle)")))
698 ;; (goto-char (marker-position jde-complete-current-end))
701 (defun jde-complete-insert-completion (item)
704 (delete-region jde-parse-current-beginning
705 jde-parse-current-end)
707 (jde-complete-place-cursor)
708 (jde-complete-display-current-signature)
709 (set-marker jde-parse-current-end
710 (+ (marker-position jde-parse-current-beginning)
713 (defun jde-complete-find-all-completions (pair lst &optional exact-match)
719 (first-char (substring pat 0 1)))
722 (setq exact-match nil)
723 (setq pat (concat pat args)))
725 (if (string= pat "$")
729 (setq tmp (car (car lst)))
730 (setq chop-pos (string-match " : " tmp))
731 (setq tmp (substring tmp 0 chop-pos))
734 (equal 0 (string-match pat tmp)))
735 (setq result (append result (list (car lst)))))
736 (setq lst (cdr lst)))
740 (defun jde-complete-find-completion-for-pair (pair &optional exact-completion
742 (let ((type (jde-parse-eval-type-of (car pair))))
744 (cond ((member type jde-parse-primitive-types)
745 (error "Cannot complete primitive type: %s" type))
746 ((string= type "void")
747 (error "Cannot complete return type of %s is void." (car pair)))
749 (let ((classinfo (jde-complete-get-classinfo
752 (if (and (string= (nth 1 pair) "")
753 (not exact-completion))
754 (setq jde-complete-current-list classinfo)
755 (setq jde-complete-current-list
756 (jde-complete-find-all-completions
757 pair classinfo exact-completion))))))
759 (let ((classinfo (jde-complete-get-classinfo type)))
761 (if (and (string= (nth 1 pair) "")
762 (not exact-completion))
763 (setq jde-complete-current-list classinfo)
764 (setq jde-complete-current-list
765 (jde-complete-find-all-completions
766 pair classinfo exact-completion)))))))
769 (defun jde-complete-in-line ()
770 "Completes the method or field name at point. Repeating the command
771 cycles through all potential completions for the name. This function
772 displays the signature of a method completion as specified by
773 `jde-complete-display-current-signature' This command uses the
774 Beanshell to run Java code that in turn uses Java reflection to
775 determine the methods and fields defined by the class of the object at
776 point. This command starts the Beanshell if necessary. Hence, you may
777 experience a slight delay when using this command for the first time
778 in a session or when completing a field or method of an object that
779 has many methods and fields. See `jde-complete-menu' for a version of
780 this command that lets you select the desired completion from a popup
784 jde-complete-current-list
785 (markerp jde-parse-current-beginning)
786 (markerp jde-parse-current-end)
787 (marker-position jde-parse-current-beginning)
788 (marker-position jde-parse-current-end)
789 (>= (point) (marker-position jde-parse-current-beginning))
790 (<= (point) (marker-position jde-parse-current-end))
791 (eq last-command this-command))
792 (jde-complete-complete-cycle)
794 (jde-complete-generic "in-line")))
796 (defun jde-complete-choose-completion (&optional title initial-input use-menu)
797 "Display completions for the object at point in a menu if USE-MENU
798 is nonil, otherwise in the minibuffer. The display comprises all of
799 the possible completions for the object it was invoked on. To
800 automatically split large menus this function use `imenu--mouse-menu'
801 to handle the popup menu. initial-input, whatever the user typed
802 before invoking the completion"
803 (let (index-alist pair name)
804 (setq index-alist jde-complete-current-list)
806 (if (= (length index-alist) 1)
807 ;; if only one item match, return it
810 ;; delegates menu handling to imenu :-)
813 ;; Popup window at text cursor
814 (jde-cursor-posn-as-event)
815 (or title "Completion"))
816 (assoc (completing-read (or title "Completion: ")
820 initial-input) ;;initial-input
822 (setq name (cdr pair))
823 (setq jde-complete-current-signature (car pair))
824 (jde-complete-insert-completion name)))
826 (defun jde-cursor-posn-as-event()
827 "Returns the text cursor position as an EVENT on Emacs and the mouse
828 cursor position on XEmacs."
830 (let* ((mouse-pos (mouse-pixel-position))
831 (x (car (cdr mouse-pos)))
832 (y (cdr (cdr mouse-pos))))
833 (make-event 'button-press `(button 1 modifiers nil x ,x y ,y)))
834 (let ((x (* (if jde-xemacsp (frame-width) (frame-char-width))
836 (boundp 'hscroll-mode)
837 (fboundp 'hscroll-window-column))
838 (hscroll-window-column)
839 (mod (current-column) (window-width)))))
840 (y (* (if jde-xemacsp (frame-height) (frame-char-height))
841 (- (count-lines (point-min) (point))
842 (count-lines (point-min) (window-start)))))
843 (window (get-buffer-window (current-buffer))))
844 (list (list x y) window))))
846 (defun jde-complete-menu ()
847 "Completes the method or field name at point. This command displays
848 a popup menu listing the potential completions for the name at
849 point. Selecting a completion causes the command to use the completion
850 to complete the name at point. See `jde-complete-in-line' for a
851 version of this command that lets you cycle throught the potential
852 completions at point."
854 (jde-complete-generic t))
856 (defun jde-complete-minibuf ()
857 "Completes the method or field name at point. This command displays
858 a popup menu listing the potential completions for the name at
859 point. Selecting a completion causes the command to use the completion
860 to complete the name at point. See `jde-complete-in-line' for a
861 version of this command that lets you cycle throught the potential
862 completions at point."
864 (jde-complete-generic nil))
866 (defun jde-complete-generic (completion-type)
867 "Generic implementation for jde-complete methods"
868 (let* ((pair (jde-parse-java-variable-at-point))
869 jde-parse-attempted-to-import)
870 ;;resetting jde-complete-current-list
871 (setq jde-complete-current-list nil)
874 (jde-complete-pair (jde-complete-get-pair pair nil) completion-type)
875 (error (condition-case err
876 (jde-complete-pair (jde-complete-get-pair pair t)
878 (error (message "%s" (error-message-string err)))))
879 (message "No completion at this point"))))
881 (defun jde-complete-pair (pair completion-type)
882 (let ((access (jde-complete-get-access pair))
886 (setq completion-list
887 (jde-complete-find-completion-for-pair pair nil access))
888 (setq completion-list (jde-complete-find-completion-for-pair pair)))
889 ;;if the completion list is nil check if the method is in the current
891 (if (null completion-list)
892 (setq completion-list (jde-complete-find-completion-for-pair
893 (list (concat "this." (car pair)) "")
894 nil jde-complete-private)))
895 ;;if completions is still null check if the method is in the
897 (if (null completion-list)
898 (setq completion-list (jde-complete-find-completion-for-pair
899 (list (concat "super." (car pair)) "")
900 nil jde-complete-protected)))
903 (let ((title (concat (car pair) "."
904 (car (cdr pair)) "[...]")))
905 (if (null completion-type)
906 (jde-complete-choose-completion title (car (cdr pair)))
907 (if (string= completion-type "in-line")
909 (setq jde-complete-current-list-index -1)
910 (jde-complete-complete-cycle))
911 (jde-complete-choose-completion title (car (cdr pair)) t))))
912 (error "No completion at this point")))))
914 (defun jde-complete-get-access (pair)
916 (if (string= (car pair) "this")
917 (setq access jde-complete-private)
918 (if (string= (car pair) "super")
919 (setq access jde-complete-protected)))
922 (defun jde-complete-get-pair (pair op)
923 (let ((tmp (list (car pair) (cadr pair))))
925 (string= (car tmp) "" )
926 (not (string= (cadr tmp) "")))
927 (setcar tmp (cadr tmp)))
928 (if (string= (car tmp) "" )
932 (defun jde-complete ()
933 "Displays completions for the Java symbol at point. This command
934 delegates the task of displaying completions to the function specified
935 by `jde-complete-function'. This allows you to select or specify the
936 default method for displaying completions."
938 (call-interactively jde-complete-function))
940 (define-mode-overload-implementation
941 semantic-idle-summary-current-symbol-info jde-mode ()
942 "Collect information on current symbol."
943 (or jde-complete-display-signature
944 (semantic-idle-summary-current-symbol-info-default)))
946 (defun jde-complete-popup-message (message buffer-or-name)
947 "Split up the current window horizontally, the new buffer is exactly
948 2 lines in height. Message is inserted in the new buffer. Succesive
949 calls to this method with the same buffer-or-name will delete the text
950 inside the buffer and replace it with message. Message should not be
953 (let* ((popup (get-buffer-window buffer-or-name));;last popup window
954 (new (get-buffer-create buffer-or-name));;new popup window
955 (current (current-buffer));;current buffer
956 (min window-min-height);;current window-min-height
957 (w (selected-window));;selected window
958 (height (window-height w));;window height
960 (if popup (delete-window popup));;deleting previous windows
961 (set-window-buffer w new);;set buffer of current window to be the new
963 (insert message);;insert message
964 (setq window-min-height 2);;set the minimum height
965 (setq w2 (split-window w (- height 2)));;split windows
966 (set-window-buffer w current);;restore the buffer in the current window
967 (if (> (window-height w2) 2);;if the popup window is larger than 2
968 (enlarge-window (- (window-height w2) 2)));;resize it to 2
969 (setq window-min-height min);; restore window-min-height
970 (run-at-time jde-complete-signature-display-time
971 nil 'delete-window w2)));;set timer to delete popup window
973 (defun jde-complete-display-current-signature()
974 "Displays the current signature: `jde-complete-current-signature'. The
975 display mode will depend on the variable `jde-complete-signature-display'"
977 (if jde-complete-current-signature
978 (let ((display (car jde-complete-signature-display)))
979 (cond ((string= display "Eldoc") ;;eldoc
980 (setq jde-complete-display-signature t)
981 (run-at-time jde-complete-signature-display-time
983 `jde-complete-display-signature nil)
984 (eldoc-message jde-complete-current-signature))
986 ((string= display "Buffer")
987 (jde-complete-popup-message jde-complete-current-signature
988 jde-complete-signature-buffer))
992 (defun jde-complete-place-cursor ()
993 "Places the cursor in between the parenthesis after a
994 completion. This is only done for methods that contain parameters, for
995 all the other completions the cursor is place at the end."
996 (let ((end-paren (string-match ")" jde-complete-current-signature))
997 (start-paren (string-match "(" jde-complete-current-signature)))
998 (if (and end-paren start-paren (not (= start-paren (- end-paren 1))))
999 (goto-char (- (point) 1)))))
1001 (provide 'jde-complete)
1003 ;; $Log: jde-complete.el,v $
1004 ;; Revision 1.84 2004/08/23 12:13:00 paulk
1005 ;; Change name of jde-complete-invoke-getClassInfo to
1006 ;; jde-complete-invoke-get-class-info to conform to Lisp naming
1007 ;; conventions. Have this function invoke jde-jeval-r instead of
1008 ;; bsh-eval-r to ensure that class info is updated when starting
1011 ;; Revision 1.83 2004/06/13 05:02:14 paulk
1012 ;; Update to use semantic-idle-summary mode to display signature of symbol at point. TThanks to David Ponce.
1014 ;; Revision 1.82 2004/06/06 04:55:47 paulk
1015 ;; Remove references to obsolete (i.e., pre-cedet 1.0) semantic symbols in eldoc
1016 ;; display code. These are no longer necessary because the JDEE now
1017 ;; requires cedet and they cause distracting compile warnings.
1019 ;; Revision 1.81 2004/04/29 02:55:53 paulk
1020 ;; Patch from David Ponce to to make eldoc-like stuff compatible with Semantic version 2 (cedet 1.0).
1022 ;; Revision 1.80 2003/06/07 04:03:01 paulk
1023 ;; Prevent jde-mode from disabling the eldoc facility as
1024 ;; soon as eldoc delays display of a message, which made semantic eldoc
1025 ;; extensions practically unusable in Java buffers. Thanks to David Ponce.
1027 ;; Revision 1.79 2003/02/25 05:32:32 paulk
1028 ;; Fixes defadvice bug that disables eldoc-print-current-symbol-info
1029 ;; in all modes but emacs-lisp-mode and jde-mode. Thanks to ABE Yasushi.
1031 ;; Revision 1.78 2003/02/18 02:09:40 jslopez
1032 ;; Fixes regression bugs.
1034 ;; Revision 1.77 2002/10/04 02:06:47 jslopez
1035 ;; Fixes logic building completion.
1037 ;; Revision 1.76 2002/09/11 03:26:49 paulk
1038 ;; Unconditionalize requires for eldoc and senator so the using completion does not require compiling completion.el.
1040 ;; Revision 1.75 2002/08/07 06:36:19 paulk
1041 ;; Removed code intended to eliminate spurious warnings when byte-compiling the JDEE. The
1042 ;; removed code now resides in a separate package, jde-compat.el. Thanks to Andy Piper
1043 ;; for suggesting this restructuring. Also fixed a number of compiler warnings caused
1046 ;; Revision 1.74 2002/07/13 16:53:35 jslopez
1047 ;; Fixes bug that was causing completion to fail.
1049 ;; Revision 1.73 2002/07/13 16:36:21 jslopez
1050 ;; Fixes bug in completion that was not appending all exceptions to the
1051 ;; possible completions.
1053 ;; Revision 1.72 2002/06/26 04:54:58 paulk
1054 ;; Reimplemented jde-complete-function as a choice widget so that it's value can
1055 ;; be a function symbol rather than a function symbol wrapped in a list.
1057 ;; Revision 1.71 2002/06/23 17:29:35 jslopez
1058 ;; Integrates all the common functionality from jde-complete-in-line,
1059 ;; jde-complete-minibuffer, and jde-complete-menu into a method
1060 ;; jde-complete-generic.
1062 ;; Fixes regresion bug. Caused when trying to complete member within this.
1063 ;; i.e. get (trying to complete methods starting with get was failing)
1065 ;; Revision 1.70 2002/05/31 18:57:42 mnl
1066 ;; The possible completions displayed in popup menus can get quite long
1067 ;; (fully qualified parameter types, return type and throw
1068 ;; clauses). Added new customization variables jde-display-... that allow
1069 ;; omitting some of the details.
1071 ;; Revision 1.69 2002/05/25 19:54:24 jslopez
1072 ;; Fixes bug displaying constructor information.
1074 ;; Revision 1.68 2002/05/25 19:42:11 jslopez
1075 ;; Fixes bug in completion.
1076 ;; Now you can complete String
1078 ;; And the possible constructor will show up.
1080 ;; Revision 1.67 2002/05/25 19:00:49 jslopez
1081 ;; Removes package information from the constructor completion.
1083 ;; Revision 1.66 2002/05/25 18:37:40 jslopez
1084 ;; Adds constructors to completion.
1086 ;; Revision 1.65 2002/05/25 18:26:37 jslopez
1087 ;; Moves routine to get the methods from
1088 ;; jde-complete-build-completion-list into jde-complete-get-methods.
1090 ;; Revision 1.64 2002/05/25 18:03:37 jslopez
1091 ;; Moves routing to get the inner classes from
1092 ;; jde-complete-build-completion-list into jde-complete-get-inner-classes.
1094 ;; Revision 1.63 2002/05/25 17:54:38 jslopez
1095 ;; More formatting changes.
1097 ;; Revision 1.62 2002/05/25 17:18:42 jslopez
1098 ;; Formatting changes.
1100 ;; Revision 1.61 2002/05/12 06:32:42 paulk
1101 ;; - Removed jde-complete-find-type (never used).
1102 ;; - Moved jde-complete-convert-args-to-types to jde-parse package as
1103 ;; jde-parse-convert-args-to-types
1104 ;; - Moved jde-complete-get-name-of-this-class to jde-parse package as
1105 ;; jde-parse-get-buffer-class
1107 ;; Revision 1.60 2002/04/16 03:17:07 jslopez
1108 ;; Integrates jde-open-source.
1110 ;; Revision 1.59 2002/04/15 15:45:36 jslopez
1111 ;; Fixes method signature for jde-complete-find-completion-for-pair.
1113 ;; Revision 1.58 2002/04/14 13:59:24 paulk
1114 ;; Minor improvements to jde-complete-function customization prompts.
1116 ;; Revision 1.57 2002/04/11 04:31:11 paulk
1117 ;; Turns out the JDEE already supported completion in the minibuffer.
1118 ;; Seems Stuart Popejoy was using an old version of the JDEE and used
1119 ;; an outdated version of jde-complete-menu as the based for his
1120 ;; version of jde-complete-minbuf. I've now replaced his version
1121 ;; with a new version based on Javier's latest version. I've
1122 ;; also eliminated the variable jde-complete-use-menu as
1123 ;; jde-complete-function provides the same functionality.
1125 ;; Revision 1.56 2002/04/02 06:43:20 paulk
1126 ;; Minor docstring tweak.
1128 ;; Revision 1.55 2002/04/02 06:41:11 paulk
1129 ;; - Added jde-complete-minibuf command contributed by Stuart Popejoy <stuart@pinksheets.com>.
1130 ;; - Added jde-complete-select command and jde-complete-select-function variable.
1132 ;; Revision 1.54 2002/02/14 01:52:50 jslopez
1133 ;; Fixes bug handling brackets i.e. array[
1136 ;; Revision 1.53 2001/11/30 18:09:44 jslopez
1137 ;; Updates constant jde-emacs21-p to jde-emacs21p
1139 ;; Revision 1.52 2001/11/30 04:11:01 jslopez
1140 ;; Fixes compiler warnings.
1142 ;; Revision 1.51 2001/11/30 02:50:02 jslopez
1143 ;; Improves error handling in the methods
1144 ;; jde-complete-at-point and jde-complete-at-point-menu
1146 ;; Revision 1.50 2001/11/29 01:44:39 jslopez
1147 ;; Fixes bug in completion. Private members were not
1148 ;; being included when trying to complete an instance
1149 ;; of this in the same class.
1151 ;; Revision 1.49 2001/10/28 16:07:49 jslopez
1152 ;; Updated documentation for jde-complete-use-menu.
1154 ;; Revision 1.48 2001/10/24 03:12:28 jslopez
1155 ;; Modified the jde-complete-popup-completion-menu to add
1156 ;; the initial user input when using the buffer for completion.
1157 ;; Fixed bug that did not complete methods for variables names
1158 ;; that start with the '$' character.
1160 ;; Revision 1.47 2001/10/21 14:32:05 jslopez
1161 ;; Added customization group jde-complete
1162 ;; and moved all the jde-complete customization under
1165 ;; Revision 1.46 2001/10/21 13:12:25 jslopez
1166 ;; Adds customization variable jde-complete-use-menu. Modifies
1167 ;; jde-complete-popup-completion-menu to use the emacs completion buffer when
1168 ;; jde-complete-use-menu is nil.
1170 ;; Revision 1.45 2001/10/08 13:08:21 paulk
1171 ;; Fixed bug that caused the in-buffer verion of completion to throw
1172 ;; an error for the first completion. Thanks to Jason Rumney.
1174 ;; Revision 1.44 2001/10/03 13:43:25 jslopez
1175 ;; Fixed function `jde-complete-invoke-getClassInfo\' which failed on getting the class info from Completion.java because the class variable was not inside double quotes\.
1177 ;; Revision 1.43 2001/10/03 05:26:14 paulk
1178 ;; Fixed function `jde-complete-invoke-getClassInfo' which failed on concat because ACCESS variable is an integer. Thanks to David Ponce.
1180 ;; Revision 1.42 2001/10/02 23:27:44 jslopez
1181 ;; Updating the access level. It was still using 1 for private, and 0 for
1182 ;; protected. Now 3 is for private, 2 for default, 1 for protected, and 0 for
1185 ;; Revision 1.41 2001/09/28 21:18:13 jslopez
1186 ;; Updated my email address.
1187 ;; Fix bug that produce duplicates in the completion list
1188 ;; when class A has a protected method x and class be that
1189 ;; extends B overwrites method x and makes it public.
1191 ;; Revision 1.40 2001/09/28 13:43:59 jslopez
1194 ;; Revision 1.39 2001/09/28 13:31:36 jslopez
1195 ;; The completion code now has a notion of package protection.
1196 ;; Completion cache modified, now it store the public, protected,
1197 ;; package and private methods for each class.
1199 ;; Revision 1.38 2001/09/07 14:07:21 jslopez
1200 ;; Added method jde-complete-place-cursor. This method is call after any
1201 ;; completion insertion to place the cursor in the right spot. i.e. in between
1202 ;; the parenthesis when the method have parameters and at the end in all other
1205 ;; Revision 1.37 2001/09/02 03:38:23 jslopez
1206 ;; Added support to show exceptions when using the completion methods.
1208 ;; Revision 1.36 2001/08/30 03:01:35 jslopez
1211 ;; Revision 1.35 2001/08/30 02:34:50 jslopez
1212 ;; Added customization variable jde-complete-signature-display.
1213 ;; Changed the jde-complete-signature-display-time from 60 to 5.
1214 ;; Added methods jde-complete-popup-message and
1215 ;; jde-complete-display-current-signagute.
1216 ;; Modified the completion method to show the completion signature by using
1217 ;; jde-complete-display-current-signature.
1219 ;; Revision 1.34 2001/08/15 05:15:38 paulk
1220 ;; Fixed bug that cause completion to return the wrong name when the class does not have
1221 ;; a package, e.g., .Test for Test.java. Thanks to Javier Lopez.
1223 ;; Revision 1.33 2001/07/31 05:09:03 paulk
1224 ;; Fixes bug that prevented completion of variables in inner classes. Thanks to Javier Lopez.
1226 ;; Revision 1.32 2001/07/21 03:49:17 paulk
1227 ;; Fixed missing first line. Fix for handling static inner classes was contributed by Javier Lopez.
1229 ;; Revision 1.31 2001/07/21 03:46:12 paulk
1230 ;; Now handles completion for methods and fields of static inner classes.
1232 ;; Revision 1.30 2001/07/18 01:45:38 paulk
1233 ;; Fixes bug in completion of inner classes. Thanks to Javier Lopez.
1235 ;; Revision 1.29 2001/07/17 05:37:46 paulk
1236 ;; Bug fixes from Javier Lopez.
1238 ;; Revision 1.28 2001/07/13 04:59:06 paulk
1239 ;; Bug fixes from Javier Lopez.
1241 ;; Revision 1.27 2001/07/06 02:09:33 paulk
1242 ;; Many improvements. Thanks to Javier Lopez.
1244 ;; Revision 1.26 2001/06/12 07:22:05 paulk
1245 ;; Completion now works for instances of inner classes in many cases.
1246 ;; The inner class must be declared before it is referenced for completion to work.
1247 ;; Future releases will fix this and other deficiencies in inner class handling.
1248 ;; Thanks to "Evan Easton" <evan@eeaston.com>.
1250 ;; Revision 1.25 2001/06/12 06:03:14 paulk
1251 ;; * Completion list now includes private methods of the current class and protected methods of
1254 ;; * Now sorts the possible completions in alphabetical order.
1256 ;; * Fixes bug that prevented completion of super class methods, i.e. super.ge...
1258 ;; Thanks to Javier Lopez <jlopez@cellexchange.com>
1260 ;; Revision 1.24 2001/05/31 05:14:39 paulk
1261 ;; Provide support for per-project caching of class data in the Beanshell. Thanks to Matt Conway.
1263 ;; Revision 1.23 2001/04/02 02:45:04 paulk
1264 ;; Add some comments.
1266 ;; Revision 1.22 2001/03/15 19:47:07 paulk
1267 ;; Now pops up the completion menu at the text cursor position on Emacs and at the mouse cursor position on XEmacs. I will change this to popup at the text cursor position on XEmacs as well as soon as I can figure out how to do it. Thanks to Matt_Conway@i2.com for providing the Emacs version of this enhancement.
1269 ;; Revision 1.21 2001/01/25 04:31:01 paulk
1270 ;; Completion now asks user whether to import a class that it cannot find. Thanks to Phillip Lord.
1272 ;; Revision 1.20 2000/12/19 04:33:34 paulk
1273 ;; Fixed popup completion menu to work on XEmacs. Thanks to David Ponce for providing this fix.
1275 ;; Revision 1.19 2000/10/25 02:52:16 paulk
1276 ;; Fixed bug where the completion function was completing symbols that it could not find with the results of the previous completion.
1278 ;; Revision 1.18 2000/10/20 04:02:10 paulk
1279 ;; Now uses semantic for some functions. Thanks to David Ponce.
1281 ;; Revision 1.17 2000/10/08 12:55:39 paulk
1282 ;; *** empty log message ***
1284 ;; Revision 1.16 2000/09/30 17:00:20 paulk
1285 ;; Use imenu to display completion choices. Thanks to David Ponce.
1287 ;; Revision 1.15 2000/08/19 07:07:05 paulk
1288 ;; Flushes cache at end of compilation.
1290 ;; Revision 1.14 2000/08/11 05:15:05 paulk
1291 ;; Now flushes the classinfo cache at the end of a compilation.
1293 ;; Revision 1.13 2000/08/10 08:48:49 paulk
1294 ;; Now handles primitive arrays correctly.
1296 ;; Revision 1.12 2000/08/09 02:04:26 paulk
1297 ;; Adds support for completion of array instances. Thanks to Steff.
1299 ;; Revision 1.11 2000/08/01 07:37:40 paulk
1300 ;; Now caches methods and fields for each class referenced in a session. Now completes private and protected methods and fields. Thanks to Stephane <s.nicolas@videotron.ca>.
1302 ;; Revision 1.10 2000/07/30 20:06:12 paulk
1303 ;; Updated doc for jde-complete-at-point and jde-complete-at-point-menu commands.
1305 ;; Revision 1.9 2000/07/27 04:54:00 paulk
1306 ;; Now completes object fields to any depth and completes variables declared in method argument lists. Thanks to Stephane Nicolas <s.nicolas@videotron.ca>.
1308 ;; Revision 1.8 2000/07/26 14:42:23 paulk
1309 ;; Adds support for static fields and methods and completion of fields and methods of this
1310 ;; and super objects. Thanks to Stephane Nicolas <s.nicolas@videotron.ca> for this enhancement.
1312 ;; Revision 1.7 2000/06/01 05:52:25 paulk
1313 ;; Completion menu now works on XEmacs.
1315 ;; Revision 1.6 2000/05/16 04:41:28 paulk
1316 ;; *** empty log message ***
1319 ;; end of jde-complete.el