This looks like something I would use a lot, although I haven't tried it
yet. I'll give it a shot when I have the time.

Love the comment to jde-import-all-kill-extra-imports :)

/ Petter

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On 
> Behalf Of Phillip Lord
> Sent: den 12 mars 2004 11:41
> To: [EMAIL PROTECTED]
> Subject: Re: jde-import-all
> 
> 
> 
> Here is the latest version of jde-import-all, which works with
> jde-2.3.3.
> 
> 
> 
> Cheers
> 
> Phil
> 
> 
> ;;; jde-import-all.el --- Import everything at once.
> 
> ;; Copyright (C) 2004 Phillip Lord
> 
> ;; Author: Phillip Lord <[EMAIL PROTECTED]>
> 
> ;; COPYRIGHT NOTICE
> ;;
> ;; This program is free software; you can redistribute it 
> and/or modify
> ;; it under the terms of the GNU General Public License as 
> published by
> ;; the Free Software Foundation; either version 2, or (at your option)
> ;; any later version.
> 
> ;; This program is distributed in the hope that it will be useful,
> ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
> ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> ;; GNU General Public License for more details.
> 
> ;; You should have received a copy of the GNU General Public License
> ;; along with this program; see the file COPYING.  If not, 
> write to the
> ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> ;; Boston, MA 02111-1307, USA.
> 
> ;;; Commentary:
> ;;
> ;; Build imports for all types in the buffer.  This package has two
> ;; entry points.  `jde-import-all' finds all declared types in the
> ;; buffer, then presents the user with a nice dialog which they can
> ;; then choose as many as they wish.  `jde-import-all-unambiguous'
> ;; finds all the declared types in the buffer, and then imports
> ;; without asking the user any imports which identify a class
> ;; unambigiously.
> ;;
> ;; There are not user options other than those in `jde-import' which
> ;; this respects.
> ;;
> ;; This package is really meant for rolling into jde-import.  There's
> ;; also a dialog near the end which uses the efc namespace, because it
> ;; probably belongs there.
> ;; 
> ;; This package uses regexp searching to find all the types, as the
> ;; semantic grammar doesn't appear to go deep enough for use
> ;; here.  Like other parts of JDE it depends on use of coding 
> standards
> ;; (upper case for types).  It will miss types not conforming to this.
> 
> ;;; Bugs:
> ;;
> ;; This does not correctly identifer InnerClasses which need to be
> ;; imported via their parent. Probably requires both lisp and
> ;; beanshell support.
> ;; 
> 
> ;;; History:
> ;; 
> ;; - fixed bug with regexp, which failed to pick up "implements"
> ;; types, or multiple types after extends
> ;; 
> 
> ;;; Code:
> 
> 
> (require 'sregex)
> (require 'jde-import)
> 
> (defun jde-import-all-regexp()
>   "Get the regexp set to find all types."
>   (let ((white-nl
>          '(1+ (or (syntax ?-) "\n")))
>         (white-nl-0
>          '(0+ (or (syntax ?-) "\n")))
>         (non-identifier
>          '(1+ wordchar))
>         ;; match an upper case begining word, which we will take as a
>         ;; type.
>         (identifier
>          '(group
>            (char (?A . ?Z))
>            (1+ wordchar))))
>     (list
>      (cons
>       ;; match anything following instanceof, new, or extends. These
>       ;; are keywords, so are guarenteed to be classes
>       (sregex '(or "new" "instanceof" "throws")
>               white-nl
>               '(group (1+ wordchar)))
>       1)
>      (cons
>       ;; match anything following extends or implements. This will
>       ;; then be split on commas. Both extends and implements can
>       ;; carry multiple Class names after them, as Interfaces can
>       ;; extend multiple other interfaces.
>       (sregex '(or "extends" "implements")
>               white-nl-0
>               `(group
>                 (1+ (or ,identifier "," (syntax ?-)))))
>       'jde-import-match-comma-split)
>      (cons
>       ;; match anything in between parens and starting with upper
>       ;; case. This picks up casts. This will also pick up things like
>       ;; debugGraphics.setDebugOptions(FLASH_OPTIONS); where
>       ;; FLASH_OPTIONS is actually a static. Generally this won't be a
>       ;; problem because it shouldn't resolve as a class. `
>       (sregex '(char ?( )
>                      identifier
>                      '(char ?)))
>       1)
>      ;; match an .class type thing..
>      (cons
>       (sregex identifier ".class")
>       1)
>      ;; match variable declaration
>      (cons
>       (sregex white-nl
>               identifier
>               white-nl
>               non-identifier
>               white-nl-0
>               '(or ";" "="))
>       1)
>      ;; match formal parameters
>      (cons
>       (sregex '(or "(" ",")
>               white-nl-0
>               identifier
>               white-nl
>               non-identifier
>               white-nl-0
>               '(or "," ")"))
>       1)
>      )))
> 
> 
> (defun jde-import-all-get-types()
>   "Return all the types in the current buffer.
> 
> The result is a list with no duplicates."
>   (let ((elements))
>     (mapcar
>      (lambda(matcher)
>        (let ((matches
>               (jde-import-all-gather matcher)))
>          (mapcar
>           (lambda(match)
>             (add-to-list 'elements match))
>           matches)))
>      (jde-import-all-regexp))
>     elements))
> 
> (defun jde-import-all-gather(matcher)
>   "Get all matches in the current buffer.
> 
> MATCHER is a cons (regexp . group). Looks for matches to the regexp
> and stores the match in the group. Only matches not in strings are
> accepted. This list can contain duplicates."
>   (let ((regexp (car matcher))
>         (group (cdr matcher))
>         (case-fold-search nil)
>         (retn))
>     (save-excursion
>       (goto-char (point-min))
>       (while (re-search-forward
>               regexp
>               (point-max) t)
>         (setq retn
>               (append
>                (if (numberp group)
>                    (jde-import-default-match group)
>                  (funcall group))
>                retn))))
>     retn))
>   
> (defun jde-import-default-match(group)
>   (goto-char (match-end group))
>   (unless
>       (jde-parse-comment-or-quoted-p)
>     (list
>      (match-string-no-properties group))))
> 
> (defun jde-import-match-comma-split()
>   (goto-char (match-end 1))
>   (unless
>       (jde-parse-comment-or-quoted-p)
>     (split-string
>      (match-string-no-properties 1)
>      "[ ,]+")))
> 
> (defun jde-import-all-import-types(list)
>   "Import all types.
> 
> Accepts a list of Strings of unqualified classes"
>   ;; we have a list of strings
>   (setq list
>         (jde-import-all-expand-strip-exclude list))
>   ;; so we now have a list of lists of strings. We want to over a
>   ;; dialog showing all of these one after the other..
>   (let ((dialog
>          (jde-import-all-dialog
>           "Multi Classes Option"
>           :options list
>           :text "Select imports to insert."))
>         (selection))
>     (efc-dialog-show dialog)
>     (setq selection
>           (delq nil (oref dialog selection)))
>     (if (and selection
>              (< 0 (length selection)))
>         (jde-import-insert-imports-into-buffer selection))))
>         
> (defun jde-import-all-expand-strip-exclude(list)
>   "Qualifies, strips and excludes imports.
> 
> This function takes in a list of imports. It removes all the existing
> imports, qualifies them and then strips excluded imports. It returns a
> list of lists of strings. And all in one function."
>   (delq nil
>         (mapcar
>          (lambda(unqualified-class)
>            ;; we want to remove any imports which already exists
>            (if (jde-import-get-existing-import unqualified-class)
>                nil
>              (jde-import-exclude-imports
>               ;; we want to kill of the java.lang
>               ;; packges. exclude-imports will probably do this for
>               ;; us. But this is not good as it will leave the other
>               ;; possibilities. So "String" will be imported as
>               ;; "apache.xpath.String" (on my machine) which is almost
>               ;; exactly the wrong behaviour
>               ;;
>               ;; I'm not really happy with this but what can you do.
>               (jde-import-all-kill-lang-classes
>                ;; we want to expand any unqualified names, 
> this returns
>                ;; a list of string possibilities
>                (jde-jeval-r
>                 (concat  "jde.util.JdeUtilities.getQualifiedName(\""
>                          unqualified-class "\");"))))))
>          list)))
> 
> (defun jde-import-all-kill-lang-classes(list)
>   (let ((ismatch nil))
>     (mapc
>      (lambda(item)
>        (if (string-match "^java\\.lang\\.[^.]*$" item)
>            (setq ismatch t)))
>      list)
>     (if ismatch
>         nil
>       list)))
> 
> (defun jde-import-all-unambiguous()
>   "Import all unambigious imports.
> 
> This function imports all imports for which the name identifies a
> unique class in the classpath. This avoids presenting the user with a
> large dialog, which can take a while to build if there are many
> imports."
>   (interactive)
>   (let ((list
>          (jde-import-all-expand-strip-exclude 
> (jde-import-all-get-types)))
>         (retn))
>     (delq nil
>           ;; take single length sublists, and return item..
>           (mapcar
>            (lambda(item)
>              (if (= 1 (length item))
>                  (add-to-list 'retn
>                               (car item))))
>            list))
>     (if (< 0 (length retn))
>         (jde-import-insert-imports-into-buffer retn))))
>                    
> 
> (defun jde-import-all()
>   "Attempt to import all types in the current buffer.
> 
> The user will be prompted with an interactive dialog, prompting
> for alternatives."
>   (interactive)
>   (jde-import-all-import-types
>    (jde-import-all-get-types)))
> 
> 
> 
> ;; define a nifty option dialog for asking for multiple options.
> ;; I've never used eieio before. Very cute...
> (defclass efc-multi-option-dialog (efc-option-dialog)
>   ((options :initarg :options
>             :documentation
>             "Option of options from which to choose")
>    (radio-buttons :initarg :radio-buttons
>                   :documentation
>                   "Buttons for selecting options")
>    (text :initarg :text
>          :type string
>          :initform "Select option."
>          :documentation
>          "Text at top")
>    (build-message :initarg :text
>                   :type string
>                   :initform "Building Dialog"
>                   :documentation
>                   "Warning message while building dialog, as 
> this can be slow")
>    (selection :initarg :selection
>               :documentation
>               "Options choosen."))
>   "Provides a dialog with several sets of OPTIONS.
> The dialog sets SELECTION to the options selected by the user.")
> 
> (defmethod initialize-instance ((this 
> efc-multi-option-dialog) &rest fields)
>   "Dialog constructor."
>   (call-next-method))
> 
> (defmethod efc-dialog-create ((this efc-multi-option-dialog))
>   (message "%s..." (oref this build-message))
>   (widget-insert (oref this text))
>   (widget-insert "\n\n")
>   ;; use radio buttons slot as list of radio buttons rather than.
>   (oset this radio-buttons
>       (mapcar
>          (lambda(list)
>            (prog1
>                (widget-create
>                 (list
>                  'radio-button-choice
>                  :value
>                  (efc-multi-option-dialog-default this list)
>                  :args (mapcar
>                         (lambda (x)
>                           (list 'item x))
>                         list)))
>              (widget-insert "\n")))
>          (efc-multi-option-dialog-sort this
>                                        (oref this options))))
>   (widget-insert "\n")
>   (message "%s...done" (oref this text)))
> 
> (defmethod efc-dialog-ok((this efc-multi-option-dialog))
>   ;; set the selection up as a list rather a simple result
>   (oset this selection
>         (mapcar
>          (lambda(widget)
>            (widget-value widget))
>          (oref this radio-buttons)))
>   (delete-window)
>   (set-buffer (oref this initbuf))
>   (pop-to-buffer (oref this initbuf))
>   (kill-buffer (oref this buf))
>   (exit-recursive-edit))
> 
> (defmethod efc-multi-option-dialog-default ((this 
> efc-multi-option-dialog) list)
>   "Pick the default from a collection of options."
>   (if (= 1 (length list))
>       (car list)))
> 
> (defmethod efc-multi-option-dialog-sort ((this 
> efc-multi-option-dialog) list)
>   "Sort the options."
>   ;; sort the ones with the most options first...
>   (sort list
>         (lambda(a b)
>           (> (length a)
>              (length b)))))
> 
> 
> ;; define a more specific dialog, which searches things differently.
> 
> (defclass jde-import-all-dialog(efc-multi-option-dialog) nil)
> 
> (defmethod initialize-instance ((this jde-import-all-dialog) 
> &rest fields)
>   "Dialog constructor."
>   (call-next-method))
> 
> (defmethod efc-multi-option-dialog-sort ((this 
> jde-import-all-dialog) list)
>   "Sort the options."
>   ;; sort the ones with the most options first...
>   (sort list
>         (lambda(a b)
>           ;; sort lexically
>           (if (= (length a)
>                  (length b))
>               (string< (car a)
>                        (car b))
>             ;; or by length
>             (> (length a)
>                (length b))))))
> 
> 
> ;;; code to kill lots of extra imports in many different buffers. This
>  ;;; is a bit of a hack at the moment. 
> (defun jde-import-all-search-path()
>   "Find source root directories.
> This code is chopped straight from `jde-find' which is a little
> unfortunate."
>   (read-from-minibuffer 
>    "Search directories: "
>    (cons 
>     (mapconcat 
>      (lambda (x) x)
>      (cond
>       (jde-sourcepath
>        (mapcar 
>         (lambda (path)
>           (jde-normalize-path path 'jde-sourcepath))
>         jde-sourcepath))
>       (jde-compile-option-sourcepath 
>        (mapcar 
>         (lambda (path)
>           (jde-normalize-path path 'jde-compile-option-sourcepath))
>         jde-compile-option-sourcepath))
>       (jde-compile-option-classpath 
>        (mapcar 
>         (lambda (path)
>           (jde-normalize-path path 'jde-compile-option-classpath))
>         jde-compile-option-classpath))
>       (jde-global-classpath 
>        (mapcar 
>         (lambda (path)
>           (jde-normalize-path path 'jde-global-classpath))
>         jde-global-classpath))
>       (t
>        (list default-directory)))     
>      " ")
>     0)
>    nil nil 'jde-find-root-history))
> 
> (defun jde-import-all-find-internal (buffer &optional dirs)
>   (if (not (executable-find 
>           (if (eq system-type 'windows-nt) "find.exe" "find")))
>       (error (list "This command requires the Unix find utility.")))
>   (let* ((directories-option
>         (if dirs dirs "."))
>          (cmd 
>           (format "find %s -type f -name \"%s\""
>                   directories-option
>                   (car jde-find-file-regexp))))
>     (shell-command cmd buffer)))
> 
> (put 'jde-import-all-kill-extra-imports 'disabled
>      "It is not possible to undo this action")
> 
> (defun jde-import-all-kill-extra-imports()
>   "Kill extraneous imports in many buffers.
> 
> This function uses the unix find command to discover all java files 
> in the current project and then removes all extranous import 
> statements
> from them. 
> 
> This function is a little bit scary and may not behave correctly.
> Even if it does it can't be undone. And even if you don't want to
> undo it, its user interface is very poor as it's very noisy telling
> you lots of things you don't want to know, and nothing that you 
> actually want to know. In short its a hack."
>   (interactive)
>   (save-some-buffers)
>   (with-temp-buffer
>     (let ((files-buffer (current-buffer))
>           (current-buffers (buffer-list))
>           (total-files)
>           (onfile 0))
>       (message "Discovering files...")
>       (jde-import-all-find-internal
>        files-buffer
>        (jde-import-all-search-path))
>       (message "Discovering files...done")
>       (setq total-files 
>             (count-lines (point-min) (point-max)))
>       (dolist (file (split-string (buffer-string)))
>         (message "On %s from %s file %s"
>                  (incf onfile) total-files
>                  file)
>         (jde-import-all-kill-imports file current-buffers)))))
> 
> (defun jde-import-all-kill-imports(file current-buffers)
>   (let ((file-buffer (find-file-noselect file)))
>     (save-excursion
>       (set-buffer file-buffer)
>       (jde-import-kill-extra-imports)
>       (save-buffer)
>       (if (not (member file-buffer current-buffers))
>           (kill-buffer (current-buffer))))))
> 
> 
> 
> ;; test functions...
> (defun jde-import-find-all-java()
>   (interactive)
>   (jde-import-all-find-internal
>    (jde-import-all-search-path)))
> 
> (defun jde-import-all-search-path-test()
>   (interactive)
>   (message "search path is %s" 
>            (jde-import-all-search-path)))
> 
> 
> (defun jde-import-all-show-gather()
>   "Show all of the type declarations shown in a special buffer"
>   (interactive)
>   (save-excursion
>     (set-buffer (get-buffer-create "*jde import*"))
>     (erase-buffer))
>   (mapcar
>    (lambda(matcher)
>      (let ((matches
>             (jde-import-all-gather matcher)))
>        (save-excursion
>          (set-buffer "*jde import*")
>          (insert (format "Matching %s" matcher))
>          (insert "\n")
>          (mapcar
>           (lambda(match)
>             (insert (concat match "\n")))
>           matches))))
>    (jde-import-all-regexp))
>   (switch-to-buffer-other-window "*jde import*"))
> 
> (defun jde-import-all-show()
>   "Show all of the type declarations"
>   (interactive)
>   (let ((import
>          (jde-import-all-get-types)))
>     (save-excursion
>       (set-buffer (get-buffer-create "*jde import*"))
>       (erase-buffer)
>       (mapcar
>        (lambda(match)
>          (insert match)
>          (insert "\n"))
>        import))))
>      
> 
> 
> (provide 'jde-import-all)
> 
> ;;; jde-import-all.el ends here
> 
> 

Reply via email to