[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] javaimp_devel 0d6cb9e 2/2: in progress
From: |
Filipp Gunbin |
Subject: |
[elpa] javaimp_devel 0d6cb9e 2/2: in progress |
Date: |
Fri, 08 Apr 2016 19:23:01 +0000 |
branch: javaimp_devel
commit 0d6cb9e7b7d4082408db66df8072e5aac3f4b528
Author: Filipp Gunbin <address@hidden>
Commit: Filipp Gunbin <address@hidden>
in progress
---
packages/javaimp/javaimp.el | 452 +++++++++++++++++++++++--------------------
1 files changed, 241 insertions(+), 211 deletions(-)
diff --git a/packages/javaimp/javaimp.el b/packages/javaimp/javaimp.el
index 3bf11e3..233d7ae 100644
--- a/packages/javaimp/javaimp.el
+++ b/packages/javaimp/javaimp.el
@@ -4,7 +4,7 @@
;; Author: Filipp Gunbin <address@hidden>
;; Maintainer: Filipp Gunbin <address@hidden>
-;; Version: 0.6
+;; Version: 0.7
;; Keywords: java, maven, programming
;;; Commentary:
@@ -46,8 +46,8 @@
;; If you make some changes which change project hierarchy, you should
;; re-visit the parent again with `javaimp-maven-visit-project'.
;;
-;; May work unreliable with inner classes, but you can always import
-;; top-level class and use qualified name.
+;; Currently inner classes are filtered out from completion alternatives.
+;; You can always import top-level class and use qualified name.
;;
;; User options:
;;
@@ -140,6 +140,7 @@
(require 'cl-macs)
(require 'seq)
+(require 'xml)
;; User options
@@ -205,8 +206,9 @@ to the completion alternatives list.")
(defvar javaimp-project-forest nil
"Visited projects")
-(defvar javaimp-jar-cache nil
- "Cache for jar contents")
+(defvar javaimp-cached-jars nil
+ "Alist of cached jars. Each element is of the form (FILE
+ . CACHED-JAR).")
(defconst javaimp-debug-buf-name "*javaimp-debug*")
@@ -216,10 +218,9 @@ to the completion alternatives list.")
parent children contents)
(cl-defstruct javaimp-module
- id parent-id file file-ts final-name packaging
- source-dir test-source-dir build-dir
- modules
- dep-jars)
+ id parent-id file final-name packaging
+ source-dir test-source-dir build-dir modules
+ dep-jars load-ts)
(defun javaimp-print-id (id)
(format "%s:%s:%s"
@@ -231,12 +232,13 @@ to the completion alternatives list.")
(:print-function #'javaimp-print-id))
group artifact version)
-(cl-defstruct javaimp-jar
- file file-ts classes)
+(cl-defstruct javaimp-cached-jar
+ file read-ts classes)
+;; Utilities
-(defun javaimp-xml-child-list (xml-tree child-name)
+(defun javaimp--xml-child-list (xml-tree child-name)
"Returns list of children of XML-TREE filtered by CHILD-NAME"
(let (result)
(dolist (child (cddr xml-tree) result)
@@ -244,18 +246,42 @@ to the completion alternatives list.")
(eq (car child) child-name))
(push child result)))))
-(defun javaimp-xml-child (name el)
+(defun javaimp--xml-child (name el)
"Returns a child of EL named by symbol NAME"
(assq name (cddr el)))
-(defun javaimp-xml-first-child (el)
+(defun javaimp--xml-first-child (el)
"Returns a first child of EL"
(car (cddr el)))
+(defun javaimp--get-file-ts (file)
+ (nth 5 (file-attributes file)))
-(defun javaimp-cygpath-convert-maybe (path)
- (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program "-u" path))
+(defun javaimp--get-jdk-jars ()
+ (if javaimp-jdk-home
+ (let ((jre-lib-dir
+ (concat (file-name-as-directory javaimp-jdk-home)
+ (file-name-as-directory "jre")
+ (file-name-as-directory "lib"))))
+ (directory-files jre-lib-dir t "\\.jar\\'"))))
+
+(defun javaimp-cygpath-convert-maybe (path &optional mode is-really-path)
+ "On Cygwin, converts PATH using cygpath according to MODE and
+IS-REALLY-PATH. If MODE is `unix' (the default), adds -u switch.
+If MODE is `windows', adds -m switch. If `is-really-path' is
+non-nil, adds `-p' switch. On other systems, PATH is returned
+unchanged."
+ (if (eq system-type 'cygwin)
+ (progn
+ (unless mode (setq mode 'unix))
+ (let (args)
+ (push (cond ((eq mode 'unix) "-u")
+ ((eq mode 'windows) "-m")
+ (t (error "Invalid mode: %s" mode)))
+ args)
+ (and is-really-path (push "-p" args))
+ (push path args)
+ (car (apply #'process-lines javaimp-cygpath-program args))))
path))
@@ -280,6 +306,9 @@ directory containing pom.xml."
;; TODO file should start to sink down from there; at each step append
directory
;; from <module> to it
+
+;; Maven XML routines
+
(defun javaimp--maven-xml-load-tree (file)
"Invokes `mvn help:effective-pom' on FILE and using its output
creates a tree of Maven projects starting from FILE. Children
@@ -290,18 +319,18 @@ inheritance are not included."
(cond ((assq 'project xml-tree)
;; no real children
(let ((project-elt (assq 'project xml-tree))
- (submodules (javaimp-xml-child-list
- (javaimp-xml-child 'modules project-elt) 'module)))
+ (submodules (javaimp--xml-child-list
+ (javaimp--xml-child 'modules project-elt) 'module)))
(and submodules
(message "Independent submodules: %s"
- (mapconcat #'javaimp-xml-first-child submodules ",
")))
+ (mapconcat #'javaimp--xml-first-child submodules ",
")))
(let ((module (javaimp--maven-xml-parse-module project-elt)))
(javaimp--maven-build-tree
(javaimp-module-id module) nil (list module) file))))
((assq 'projects xml-tree)
;; we have are inheriting children - they and their children, if
;; any, are listed in a linear list
- (let* ((project-elts (javaimp-xml-child-list
+ (let* ((project-elts (javaimp--xml-child-list
(assq 'projects xml-tree) 'project))
(all-modules (mapcar #'javaimp--maven-xml-parse-module
project-elts)))
(javaimp--maven-build-tree
@@ -332,27 +361,6 @@ inheritance are not included."
(match-end 0)))))
(xml-parse-region xml-start-pos xml-end-pos)))))
-(defun javaimp--maven-call (pom-file target handler)
- "Runs Maven target TARGET on POM-FILE, then calls HANDLER in
-the temporary buffer and returns its result"
- (message "Calling \"mvn %s\" on pom: %s" target pom-file)
- (with-temp-buffer
- (let* ((pom-file (javaimp-cygpath-convert-maybe pom-file))
- (status
- ;; TODO check
in Maven output on Gnu/Linux
- (let ((coding-system-for-read
- (if (eq system-type 'cygwin) 'utf-8-dos)))
- (process-file javaimp-mvn-program nil t nil "-f" pom-file
target)))
- (b (current-buffer)))
- (with-current-buffer (get-buffer-create javaimp-debug-buf-name)
- (erase-buffer)
- (insert-buffer-substring b))
- (or (and (numberp status) (= status 0))
- (error "Maven target \"%s\" failed with status \"%s\"" target status))
- (goto-char (point-min))
- (funcall handler))))
-
-
(defun javaimp--maven-xml-parse-module (elt)
;; we set `file' slot later because raw <project> element does not contain
;; pom file path, so we need to construct it during tree construction
@@ -360,39 +368,65 @@ the temporary buffer and returns its result"
;; TODO javaimp-maven-process-projects
;;
;; TODO set everything immediately
+ ;;
+ ;; dep-jars are initialized lazily on request
)
+;; TODO remove
(defun javaimp-maven-process-projects (projects-elts)
(mapcar
(lambda (project-elt)
- (let ((build-elt (javaimp-xml-child 'build project-elt)))
+ (let ((build-elt (javaimp--xml-child 'build project-elt)))
(javaimp-make-mod
- (javaimp--maven-extract-id project-elt)
+ (javaimp--maven-xml-extract-id project-elt)
nil ;pom-file will be set later
(file-name-as-directory
(javaimp-cygpath-convert-maybe
- (javaimp-xml-first-child (javaimp-xml-child 'sourceDirectory
build-elt))))
+ (javaimp--xml-first-child (javaimp--xml-child 'sourceDirectory
build-elt))))
(file-name-as-directory
(javaimp-cygpath-convert-maybe
- (javaimp-xml-first-child (javaimp-xml-child 'testSourceDirectory
build-elt))))
+ (javaimp--xml-first-child (javaimp--xml-child 'testSourceDirectory
build-elt))))
(file-name-as-directory
(javaimp-cygpath-convert-maybe
- (javaimp-xml-first-child (javaimp-xml-child 'directory build-elt))))
+ (javaimp--xml-first-child (javaimp--xml-child 'directory build-elt))))
nil ;pom-file-mod-ts will be set later
nil ;jar-list will be set later
- (javaimp--maven-extract-id
- (javaimp-xml-child 'parent project-elt))
+ (javaimp--maven-xml-extract-id
+ (javaimp--xml-child 'parent project-elt))
nil ;parent-ts will be set later
- (javaimp-xml-first-child (javaimp-xml-child 'finalName build-elt))
+ (javaimp--xml-first-child (javaimp--xml-child 'finalName build-elt))
)))
projects-elts))
-(defun javaimp--maven-extract-id (elt)
+(defun javaimp--maven-xml-extract-id (elt)
(make-javaimp-id
- (javaimp-xml-first-child (javaimp-xml-child 'groupId elt))
- (javaimp-xml-first-child (javaimp-xml-child 'artifactId elt))
- (javaimp-xml-first-child (javaimp-xml-child 'version elt))))
+ (javaimp--xml-first-child (javaimp--xml-child 'groupId elt))
+ (javaimp--xml-first-child (javaimp--xml-child 'artifactId elt))
+ (javaimp--xml-first-child (javaimp--xml-child 'version elt))))
+
+
+;; Maven routines
+
+(defun javaimp--maven-call (pom-file target handler)
+ "Runs Maven target TARGET on POM-FILE, then calls HANDLER in
+the temporary buffer and returns its result"
+ (message "Calling \"mvn %s\" on pom: %s" target pom-file)
+ (with-temp-buffer
+ (let* ((pom-file (javaimp-cygpath-convert-maybe pom-file))
+ (status
+ ;; TODO check
in Maven output on Gnu/Linux
+ (let ((coding-system-for-read
+ (if (eq system-type 'cygwin) 'utf-8-dos)))
+ (process-file javaimp-mvn-program nil t nil "-f" pom-file
target)))
+ (b (current-buffer)))
+ (with-current-buffer (get-buffer-create javaimp-debug-buf-name)
+ (erase-buffer)
+ (insert-buffer-substring b))
+ (or (and (numberp status) (= status 0))
+ (error "Maven target \"%s\" failed with status \"%s\"" target status))
+ (goto-char (point-min))
+ (funcall handler))))
(defun javaimp--maven-build-tree (id parent-node all-modules file)
(let ((this (or (javaimp--find-by-id id all-modules)
@@ -432,12 +466,13 @@ the temporary buffer and returns its result"
parent-rel-paths)))
(or (seq-find
(lambda (file)
+ ;; TODO move xml subroutine out
(let* ((xml-tree (with-temp-buffer
(insert-file-contents file)
(xml-parse-region (point-min) (point-max))))
(project-elt (assq 'project xml-tree))
- (id (javaimp--maven-extract-id project-elt))
- (parent-id (javaimp--maven-extract-id (assq 'parent
project-elt))))
+ (id (javaimp--maven-xml-extract-id project-elt))
+ (parent-id (javaimp--maven-xml-extract-id (assq 'parent
project-elt))))
;; TODO we need lax matching because some id
;; components may be missing
(and (equal (javaimp-module-id module) id)
@@ -445,137 +480,118 @@ the temporary buffer and returns its result"
files)
(error "Cannot find file for module: %s" (javaimp-module-id module))))
-(defun javaimp--find-by-id (id modules)
- ;; TODO seq-find
- )
+
+;;; Loading dep-jars
+
+(defun javaimp--maven-update-module-maybe (node)
+ (let (need-update)
+ ;; are deps not initialized?
+ (let ((module (javaimp-node-contents node)))
+ (if (null (javaimp-module-dep-jars module))
+ (setq need-update t)))
+ ;; were any pom.xml files updated after last load?
+ (let ((tmp node))
+ (while (and tmp
+ (not need-update))
+ (let ((module (javaimp-node-contents tmp)))
+ (if (> (float-time (javaimp--get-file-ts (javaimp-module-file
module)))
+ (float-time (javaimp-module-load-ts module)))
+ (setq need-update t)))
+ (setq tmp (javaimp-node-parent tmp))))
+ (when need-update
+ ;; update current module
+ (let ((module (javaimp-node-contents node)))
+ ;; reload & update dep-jars
+ (setf (javaimp-module-dep-jars module)
+ (javaimp--maven-fetch-dep-jars module))
+ ;; update load-ts
+ (setf (javaimp-module-load-ts module) (current-time))))))
+
+(defun javaimp--maven-fetch-dep-jars (module)
+ (let ((raw-line
+ (javaimp--maven-call
+ (javaimp-module-file module) "dependency:build-classpath"
+ (lambda ()
+ (goto-char (point-min))
+ (search-forward "Dependencies classpath:")
+ (forward-line 1)
+ (thing-at-point 'line))))
+ (separator-regex (concat "[" path-separator "\n" "]+")))
+ (split-string (javaimp-cygpath-convert-maybe raw-line 'unix t)
separator-regex t)))
+
+
+;; Working with jar classes
+
+(defun javaimp--get-jar-classes (file)
+ (let ((cached (car (assoc file javaimp-cached-jars))))
+ (cond ((null cached)
+ ;; create, load & put into cache
+ (setq cached
+ (make-javaimp-cached-jar
+ file (javaimp--get-file-ts file) (javaimp--fetch-jar-classes
file)))
+ (push (cons file cached) javaimp-cached-jars))
+ ((> (float-time (javaimp--get-file-ts (javaimp-cached-jar-file
cached)))
+ (float-time (javaimp-cached-jar-read-ts cached)))
+ ;; reload
+ (setf (javaimp-cached-jar-classes) (javaimp--fetch-jar-classes file))
+ ;; update read-ts
+ (setf (javaimp-cached-jar-read-ts) (current-time))))
+ ;; return from cached
+ (javaimp-cached-jar-classes cached)))
+
+(defun javaimp--fetch-jar-classes (file)
+ (message "Reading classes in file: %s" file)
+ (with-temp-buffer
+ (let ((coding-system-for-read (and (eq system-type 'cygwin)
+ 'utf-8-dos)))
+ ;; On Cygwin, "jar" is a Windows program, so file path needs to be
+ ;; converted appropriately.
+ (process-file javaimp-jar-program nil t nil
+ "-t" "-f" (javaimp-cygpath-convert-maybe file 'windows))
+ (goto-char (point-min))
+ (keep-lines "^[^$]+\\.class$")
+ (goto-char (point-min))
+ (replace-string "/" ".")
+ (goto-char (point-min))
+ (let (result)
+ (while (not eobp)
+ (push (thing-at-point 'line) result)
+ (forward-line))
+ result))))
+
+;; Searching and navigating through projects
-(defun javaimp--find-by-parent-id (parent-id modules)
- ;; TODO seq-find
+(defun javaimp--find-by-id (id)
+ ;; TODO call javaimp-find-modules; check that 1 result (or return first and
write warning)
)
-
-;;; Working with module dependency JARs
+(defun javaimp--find-by-parent-id (parent-id)
+ ;; TODO call javaimp-find-modules; check that 1 result
+ )
-(defun javaimp-maven-fetch-module-deps (module)
- "Returns list of dependency jars for MODULE"
- (javaimp--maven-call
- (javaimp-mod-pom-file module) "dependency:build-classpath"
- (lambda ()
- (let (deps-line)
- (goto-char (point-min))
- (search-forward "Dependencies classpath:")
- (forward-line 1)
- (setq deps-line (thing-at-point 'line))
- (when (eq system-type 'cygwin)
- (setq deps-line (car (process-lines javaimp-cygpath-program
- "-up"
- deps-line))))
- (split-string deps-line (concat "[" path-separator "\n" "]+") t)))))
-
-(defun javaimp-get-file-ts (file)
- (nth 5 (file-attributes file)))
+(defun javaimp--find-by-source-file (file)
+ ;; todo check that 1 result
+ )
-(defun javaimp-any-file-ts-updated (files)
- (if (null files)
- nil
- (let ((curr-ts (javaimp-get-file-ts (car (car files))))
- (last-ts (cdr (car files))))
- (or (null last-ts) ; reading for the first time?
- (not (equal (float-time curr-ts) (float-time last-ts)))
- (javaimp-any-file-ts-updated (cdr files))))))
-
-(defun javaimp-get-deps-cached (module parent)
- "Returns a list of dependency jar file paths for a MODULE.
-Both MODULE and PARENT poms are checked for updates because
-PARENT pom may have some versions which are inherited by the
-MODULE."
- (when (javaimp-any-file-ts-updated
- (remq nil (list (cons (javaimp-mod-pom-file module)
- (javaimp-mod-pom-mod-ts module))
- (when parent
- (cons
- (javaimp-mod-pom-file parent)
- ;; here we check the saved parent ts because it
- ;; matters what version we had when we were
- ;; reloading this pom the last time
- (javaimp-mod-parent-ts module))))))
- ;; (re-)fetch dependencies
- (javaimp-set-mod-pom-deps
- module (javaimp-maven-fetch-module-deps module))
- ;; update timestamps
- (javaimp-set-mod-pom-mod-ts
- module (javaimp-get-file-ts (javaimp-mod-pom-file module)))
- (when parent
- (javaimp-set-mod-parent-ts
- module (javaimp-get-file-ts (javaimp-mod-pom-file parent)))))
- (javaimp-mod-pom-deps module))
-
-(defun javaimp-get-jdk-jars ()
- (if javaimp-jdk-home
- (let ((jre-lib-dir
- (concat (file-name-as-directory javaimp-jdk-home)
- (file-name-as-directory "jre")
- (file-name-as-directory "lib"))))
- (directory-files jre-lib-dir t "\\.jar\\'"))))
-
-;; Working with jar and its cache
-
-(defun javaimp-fetch-jar-classes (jar)
- (let ((jar-file (javaimp-jar-path jar))
- result)
- (message "Reading classes in jar: %s" jar-file)
- (with-temp-buffer
- (let ((jar-file (if (eq system-type 'cygwin)
- (car (process-lines javaimp-cygpath-program
- "-m" jar-file))
- jar-file))
- (coding-system-for-read (when (eq system-type 'cygwin) 'utf-8-dos)))
- (process-file javaimp-jar-program nil t nil "-tf" jar-file))
- (goto-char (point-min))
- (while (re-search-forward "^\\(.+\\)\\.class$" nil t)
- (push (replace-regexp-in-string "[/$]" "." (match-string 1))
- result))
- result)))
-
-(defun javaimp-get-jar-classes-cached (jar)
- (let ((current-jar-mod-ts
- (nth 5 (file-attributes (javaimp-jar-path jar)))))
- (unless (equal (float-time (javaimp-jar-mod-ts jar))
- (float-time current-jar-mod-ts))
- (javaimp-set-jar-classes-list jar (javaimp-fetch-jar-classes jar))
- (javaimp-set-jar-mod-ts jar current-jar-mod-ts))
- (javaimp-jar-classes-list jar)))
-
-(defun javaimp-collect-classes (jar-paths)
- (let (result jar)
- (dolist (jar-path jar-paths result)
- (setq jar (assoc jar-path javaimp-jar-cache))
- (unless jar
- (setq jar (javaimp-make-jar jar-path nil nil))
- (push jar javaimp-jar-cache))
- (setq result (append (javaimp-get-jar-classes-cached jar) result)))))
+(defun javaimp-find-modules (predicate)
+ (javaimp--find-modules-forest javaimp-project-forest predicate))
-;; Searching and navigating through projects
+(defun javaimp--find-modules-forest (forest predicate)
+ (apply #'seq-concatenate 'list
+ (mapcar (lambda (tree)
+ (javaimp--find-modules-tree tree predicate))
+ forest)))
-(defun javaimp-find-module (predicate)
- (javaimp--find-module javaimp-project-forest predicate))
+(defun javaimp--find-modules-tree (tree predicate)
+ ;; TODO
+ )
-(defun javaimp--find-module (projects predicate)
- (if projects
- (let ((project (car projects)))
- (or (javaimp--get-module (cdr project) predicate)
- (javaimp--find-module (cdr projects) predicate)))))
-(defun javaimp--get-module (modules predicate)
- (if modules
- (let ((module (car modules)))
- (if (funcall predicate module)
- module
- (javaimp--get-module (cdr modules) predicate)))))
;;; Some functions for use in other programs
+;; TODO remove
(defun javaimp-get-source-directories ()
(append
(mapcar (lambda (root)
@@ -583,16 +599,18 @@ MODULE."
javaimp-project-forest)))
(defun javaimp-get-all-modules ()
- "Returns flat list of all child modules."
+ "Returns list of all modules"
(apply #'seq-concatenate 'list
(mapcar #'cdr javaimp-project-forest)))
-;;; Adding and organizing imports
+;;; Adding imports
;; TODO without prefix arg narrow alternatives by local name; with prefix
;; arg - include all classes in alternatives
+;; TODO search only modules with packaging != pom
+
;;;###autoload
(defun javaimp-add-import (classname)
"Imports CLASSNAME in the current file. Interactively,
@@ -608,20 +626,25 @@ module."
(or (string-prefix-p (javaimp-mod-source-dir m) file)
(string-prefix-p (javaimp-mod-test-source-dir m)
file))))
(error "Cannot find module by file: %s" file))))
+ (javaimp--maven-update-module-maybe module)
(list (completing-read
"Import: "
(append
- (let ((jars (append (javaimp-get-deps-cached module)
- (javaimp-get-jdk-jars))))
- (javaimp-collect-classes jars))
+ ;; we're not caching full list of classes coming from module
+ ;; dependencies because jars may change and we need to reload
+ ;; them
+ (let ((jars (append (javaimp-module-dep-jars module)
+ (javaimp--get-jdk-jars))))
+ (apply #'seq-concatenate 'list
+ (mapcar #'javaimp--get-jar-classes jars)))
(and javaimp-include-current-module-classes
- (javaimp-classes-from-source module)))
+ (javaimp--classes-from-source module)))
nil t nil nil (symbol-name (symbol-at-point))))))
(javaimp-organize-imports classname))
-(defun javaimp-classes-from-source (module)
- "Scans current project and returns a list of top-level classes in both the
-source directory and test source directory"
+(defun javaimp--classes-from-source (module)
+ "Scans current project and returns a list of top-level classes
+in both the source directory and test source directory"
(let ((src-dir (javaimp-mod-source-dir module))
(test-src-dir (javaimp-mod-test-source-dir module))
(build-dir (javaimp-mod-build-dir module)))
@@ -658,31 +681,8 @@ initial package prefix."
(push (concat prefix (file-name-sans-extension (car file))) result)))
result))
-(defun javaimp-add-to-import-groups (new-class groups)
- "Subroutine of `javaimp-organize-imports'"
- (let* ((order (or (assoc-default new-class javaimp-import-group-alist
- 'string-match)
- javaimp-import-default-order))
- (group (assoc order groups)))
- (if group
- (progn
- ;; add only if this class is not already there
- (unless (member new-class (cdr group))
- (setcdr group (cons new-class (cdr group))))
- groups)
- (cons (cons order (list new-class)) groups))))
-
-(defun javaimp-insert-import-groups (groups static-p)
- "Inserts all imports in GROUPS. Non-nil STATIC-P means that
- all imports are static."
- (when groups
- (dolist (group (sort groups (lambda (g1 g2)
- (< (car g1) (car g2)))))
- (dolist (class (sort (cdr group) 'string<))
- (insert (concat "import " (when static-p "static ") class ";\n")))
- (insert ?\n))
- ;; remove newline after the last group
- (delete-char -1)))
+
+;; Organizing imports
;;;###autoload
(defun javaimp-organize-imports (&rest new-classes)
@@ -739,18 +739,48 @@ argument is a list of additional classes to import."
(javaimp-insert-import-groups static-import-groups t))
(message "Nothing to organize")))))
+(defun javaimp-add-to-import-groups (new-class groups)
+ "Subroutine of `javaimp-organize-imports'"
+ (let* ((order (or (assoc-default new-class javaimp-import-group-alist
+ 'string-match)
+ javaimp-import-default-order))
+ (group (assoc order groups)))
+ (if group
+ (progn
+ ;; add only if this class is not already there
+ (unless (member new-class (cdr group))
+ (setcdr group (cons new-class (cdr group))))
+ groups)
+ (cons (cons order (list new-class)) groups))))
+
+(defun javaimp-insert-import-groups (groups static-p)
+ "Inserts all imports in GROUPS. Non-nil STATIC-P means that
+ all imports are static."
+ (when groups
+ (dolist (group (sort groups (lambda (g1 g2)
+ (< (car g1) (car g2)))))
+ (dolist (class (sort (cdr group) 'string<))
+ (insert (concat "import " (when static-p "static ") class ";\n")))
+ (insert ?\n))
+ ;; remove newline after the last group
+ (delete-char -1)))
+
+
+
+;; Interactive functions for debugging
+
(defun javaimp-invalidate-jar-classes-cache ()
- "Resets jar classes cache (debugging only)"
+ "Resets jar classes cache"
(interactive)
(setq javaimp-jar-cache nil))
(defun javaimp-forget-all-visited-modules ()
- "Resets `javaimp-project-forest' (debugging only)"
+ "Resets `javaimp-project-forest'"
(interactive)
(setq javaimp-project-forest nil))
(defun javaimp-reset ()
- "Resets all data (debugging only)"
+ "Resets all data"
(interactive)
(javaimp-forget-all-visited-modules)
(javaimp-invalidate-jar-classes-cache))