From 85cd0b5e671215509a52d7371ea1556b1faaf5b3 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Fri, 30 Oct 2015 13:19:47 -0600 Subject: [PATCH 01/57] Added eclim-run-configuartion. Fixes #244. Runs a configuration in the compilation buffer. --- History.txt | 2 ++ eclim-java-run.el | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/History.txt b/History.txt index 9732142..6821409 100644 --- a/History.txt +++ b/History.txt @@ -4,6 +4,8 @@ === New features * company mode completion can be case insensitive + * added eclim-run-configuartion which runs a run configuration in the + compilation buffer. == 0.3 diff --git a/eclim-java-run.el b/eclim-java-run.el index 5626239..f390229 100644 --- a/eclim-java-run.el +++ b/eclim-java-run.el @@ -146,5 +146,19 @@ classpath project-dir)))) +(defun eclim-run-configuartion (configuration-name) + "Runs the configuration given in CONFIGURATION-NAME in the compilation buffer." + (interactive (list (eclim-java-run--ask-which-configuration))) + (let* ((current-directory default-directory) + (configurations (eclim-java-run--load-configurations (eclim-project-name))) + (configuration (eclim-java-run--configuration configuration-name configurations)) + (project-dir (eclim-java-run--project-dir (eclim-project-name))) + (classpath (eclim/java-classpath (eclim-project-name))) + (command (eclim-java-run--command configuration (eclim-java-run--java-vm-args classpath)))) + (setq default-directory project-dir) + (compile command) + (setq default-directory current-directory) + )) + (provide 'eclim-java-run) ;;; eclim-java-run.el ends here From dcc59ca7a6cde15a09bb7ba5bfe7b885c3b9bf63 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sun, 8 Nov 2015 13:33:10 -0700 Subject: [PATCH 02/57] added eclim-java-generate-getter eclim-java-generate-getter generates a getter method for the symbol at point. --- History.txt | 2 ++ eclim-java.el | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/History.txt b/History.txt index 9732142..8b6404f 100644 --- a/History.txt +++ b/History.txt @@ -4,6 +4,8 @@ === New features * company mode completion can be case insensitive + * added eclim-java-generate-getter which generates a getter method + for the symbol at point. == 0.3 diff --git a/eclim-java.el b/eclim-java.el index 1ddd205..da03cc2 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -174,6 +174,17 @@ declaration has been found. TYPE may be either 'class', has been found." (eclim--java-current-type-name "\\(class\\)")) +(defun eclim--java-generate-bean-properties (project file offset encoding type) + "Generates a bean property for the symbol at point. TYPE specifies the property to generate." + (eclim--call-process "java_bean_properties" + "-p" project + "-f" file + "-o" (number-to-string offset) + "-e" encoding + "-r" (cdr (eclim--java-identifier-at-point t)) + "-t" type) + (revert-buffer t t t)) + (defun eclim/java-classpath (project) (eclim--check-project project) (eclim--call-process "java_classpath" "-p" project)) @@ -215,15 +226,15 @@ has been found." (eclim--project-current-file) (eclim--byte-offset) (eclim--current-encoding))) + (eclim--java-generate-bean-properties project file offset encoding "gettersetter")) - (eclim--call-process "java_bean_properties" - "-p" project - "-f" file - "-o" (number-to-string offset) - "-e" encoding - "-r" (cdr (eclim--java-identifier-at-point t)) - "-t" "gettersetter") - (revert-buffer t t t)) +(defun eclim-java-generate-getter (project file offset encoding) + "Generates a getter method for the symbol at point." + (interactive (list (eclim-project-name) + (eclim--project-current-file) + (eclim--byte-offset) + (eclim--current-encoding))) + (eclim--java-generate-bean-properties project file offset encoding "getter")) (defun eclim-java-constructor () (interactive) From 48af1bec80c2b9ef95dd7eb2299febd781f57c2f Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 7 Nov 2015 14:32:07 -0700 Subject: [PATCH 03/57] Added eclim-java-refactor-move-class Allows moving a top level class or interface from one package to another. --- History.txt | 2 ++ eclim-java.el | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/History.txt b/History.txt index 5e907af..c00bc38 100644 --- a/History.txt +++ b/History.txt @@ -8,6 +8,8 @@ compilation buffer. * added eclim-java-generate-getter which generates a getter method for the symbol at point. + * added eclim-java-refactor-move-class which allows moving a top level + class or interface from one package to another. == 0.3 diff --git a/eclim-java.el b/eclim-java.el index da03cc2..44f39fe 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -185,6 +185,23 @@ has been found." "-t" type) (revert-buffer t t t)) +(defun eclim--java-refactor (result) + "Processes the resulst of a refactor command. RESULT is the + results of invoking eclim/execute-command." + (if (stringp res) (error res)) + (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) + do (when (and from to) + (kill-buffer (find-buffer-visiting from)) + (find-file to))) + (save-excursion + (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) + do (when file + (let ((buf (get-file-buffer (file-name-nondirectory file)))) + (when buf + (switch-to-buffer buf) + (revert-buffer t t t)))))) + (message "Done")) + (defun eclim/java-classpath (project) (eclim--check-project project) (eclim--call-process "java_classpath" "-p" project)) @@ -262,19 +279,17 @@ has been found." (n (read-string (concat "Rename " (cdr i) " to: ") (cdr i)))) (eclim/with-results res ("java_refactor_rename" "-p" "-e" "-f" ("-n" n) ("-o" (car i)) ("-l" (length (cdr i)))) - (if (stringp res) (error res)) - (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) - do (when (and from to) - (kill-buffer (find-buffer-visiting from)) - (find-file to))) - (save-excursion - (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) - do (when file - (let ((buf (get-file-buffer (file-name-nondirectory file)))) - (when buf - (switch-to-buffer buf) - (revert-buffer t t t)))))) - (message "Done")))) + (eclim--java-refactor res)))) + +(defun eclim-java-refactor-move-class () + "Renames the java class. Searches backward in the current buffer +until a class declaration has been found." + (interactive) + (let* ((class-name (eclim--java-current-class-name)) + (package-name (eclim--java-current-package)) + (n (read-string (concat "Move " class-name " to: ") package-name))) + (eclim/with-results res ("java_refactor_move" "-p" "-f" ("-n" n)) + (eclim--java-refactor res)))) (defun eclim-java-call-hierarchy (project file encoding) (interactive (list (eclim-project-name) From 0cf5e19f2add3717c13b8e3c58ffcc831b2c135c Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 7 Nov 2015 17:39:47 -0700 Subject: [PATCH 04/57] Can assign Eclim project settings. Added eclim-project-setting-set which can assign an Eclim project setting. --- History.txt | 2 ++ eclim-project.el | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/History.txt b/History.txt index c00bc38..b721679 100644 --- a/History.txt +++ b/History.txt @@ -10,6 +10,8 @@ for the symbol at point. * added eclim-java-refactor-move-class which allows moving a top level class or interface from one package to another. + * added eclim-project-setting-set which can assign an Eclim project + setting. == 0.3 diff --git a/eclim-project.el b/eclim-project.el index 326191f..fb17634 100644 --- a/eclim-project.el +++ b/eclim-project.el @@ -1,4 +1,4 @@ -;; eclim-project.el --- an interface to the Eclipse IDE. +; eclim-project.el --- an interface to the Eclipse IDE. ;; ;; Copyright (C) 2009 Yves Senn ;; @@ -185,6 +185,10 @@ ;; TODO: make the output useable (eclim--call-process "project_setting" "-p" project "-s" setting)) +(defun eclim/project-setting-set (project setting value) + (eclim--check-project project) + (eclim--call-process "project_setting" "-p" project "-s" setting "-v" (concat "[\"" value "\"]"))) + (defun eclim/project-nature-add (project nature) (eclim--check-project project) (eclim--check-nature nature) @@ -218,6 +222,20 @@ (eclim--check-project project) (eclim--call-process "project_rename" "-p" project "-n" new-name)) +(defun eclim--ask-which-project-setting () + (completing-read "Which project setting do you wish to set? " + (--map (cdr (assoc 'name it)) + (eclim/project-settings (eclim-project-name))) + nil t)) + +(defun eclim-project-setting-set (setting) + "Assigns the Eclim project setting given in SETTING." + (interactive (list (eclim--ask-which-project-setting))) + (let* ((project (eclim-project-name)) + (prev-value (eclim/project-setting project setting)) + (value (read-string (concat "value " prev-value ": ")))) + (eclim/project-setting-set project setting value))) + (defun eclim/project-classpath (&optional delimiter) "return project classpath for the current buffer." (eclim/execute-command "java_classpath" "-p" ("-d" delimiter))) From 6810921288811aa152bd45434aa3f9bda80801c3 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Wed, 2 Sep 2015 18:13:25 -0700 Subject: [PATCH 05/57] Ignore errors when deciding whether to handle a file in global-eclim-mode. Otherwise a bad Eclipse state can cause an Emacs session to get very unpleasant. I'm not sure exactly what the mechanism is, but basic stuff like find-file, switch-buffer and *the M-x prompt* (of all things) stop working with the Eclipse error. To reproduce, define eclim--project-dir to (error something), then open a managed Java file not already open. Have the real eclim--project-dir ready; fortunately, eval-expression still works. The user can run eclim-mode manually if they want to investigate the error, or try to do anything that needs project-dir. I think even printing a message would still be too unpleasant in that state, hence ignore. --- eclim.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eclim.el b/eclim.el index 76ea3a5..0537d67 100644 --- a/eclim.el +++ b/eclim.el @@ -529,10 +529,12 @@ the use of eclim to java and ant files." ;;;###autoload (define-globalized-minor-mode global-eclim-mode eclim-mode (lambda () - (if (and buffer-file-name - (eclim--accepted-p buffer-file-name) - (eclim--project-dir)) - (eclim-mode 1)))) + ;; Errors here can REALLY MESS UP AN EMACS SESSION. Can't emphasize enough. + (ignore-errors + (if (and buffer-file-name + (eclim--accepted-p buffer-file-name) + (eclim--project-dir)) + (eclim-mode 1))))) (require 'eclim-project) (require 'eclim-java) From 612eb4fbe933c76ed959e40ffcffffebd109f757 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 2 Aug 2015 11:17:00 -0700 Subject: [PATCH 06/57] Make `eclim-problems' correct work properly from the problems buffer. It was not selecting the source code buffer. --- eclim-problems.el | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/eclim-problems.el b/eclim-problems.el index b25124a..d614996 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -201,10 +201,19 @@ (eclim--problem-goto-pos p))) (defun eclim-problems-correct () + "Pops up a suggestion for the current correction. This can be +invoked in either the problems buffer or a source code buffer." (interactive) (let ((p (eclim--problems-get-current-problem))) - (if (not (string-match "\\.\\(groovy\\|java\\)$" (cdr (assoc 'filename p)))) - (error "Not a Java or Groovy file. Corrections are currently supported only for Java or Groovy") + (unless (string-match "\\.\\(groovy\\|java\\)$" (cdr (assoc 'filename p))) + (error "Not a Java or Groovy file. Corrections are currently supported only for Java or Groovy")) + (if (eq major-mode 'eclim-problems-mode) + (let ((p-buffer (find-file-other-window (assoc-default 'filename p)))) + (with-selected-window (get-buffer-window p-buffer t) + ;; Intentionally DON'T save excursion. Often times we need edits. + (eclim--problem-goto-pos p) + (eclim-java-correct (cdr (assoc 'line p)) (eclim--byte-offset)))) + ;; source code buffer (eclim-java-correct (cdr (assoc 'line p)) (eclim--byte-offset))))) (defmacro eclim--with-problems-list (problems &rest body) From acb91835ce6b817a6eccba783764dc3b4c990789 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 2 Aug 2015 11:29:24 -0700 Subject: [PATCH 07/57] Replace distracting "refreshing File" message with small modeline indicator. When we save, a lot of different messages zip by in the minibuffer and create a distraction. Instead, a '*' in the modeline right by the error counts that are about to be updated is discreet but noticeable. Removed an extraneous space. --- eclim-problems.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eclim-problems.el b/eclim-problems.el index d614996..d6de590 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -68,6 +68,7 @@ (define-key eclim-mode-map (kbd "C-c C-e o") 'eclim-problems-open) (defvar eclim--problems-list nil) +(defvar eclim--problems-refreshing nil) ;; Set to true while refreshing probs. (defvar eclim--problems-filter nil) ;; nil -> all problems, w -> warnings, e -> errors (defvar eclim--problems-filefilter nil) ;; should filter by file name @@ -222,14 +223,14 @@ invoked in either the problems buffer or a source code buffer." it asynchronously." (let ((res (gensym))) `(when eclim--problems-project - (when (not (minibuffer-window-active-p (minibuffer-window))) - (message "refreshing... %s " (current-buffer))) + (setq eclim--problems-refreshing t) (eclim/with-results-async ,res ("problems" ("-p" eclim--problems-project) (when (string= "e" eclim--problems-filter) '("-e" "true"))) (loop for problem across ,res do (let ((filecell (assq 'filename problem))) (when filecell (setcdr filecell (file-truename (cdr filecell)))))) (setq eclim--problems-list ,res) (let ((,problems ,res)) + (setq eclim--problems-refreshing nil) ,@body))))) (defun eclim-problems-buffer-refresh () @@ -489,8 +490,9 @@ is convenient as it lets the user navigate between errors using (defun eclim-problems-modeline-string () "Returns modeline string with additional info about problems for current file" - (concat (format " : %s/%s" + (concat (format ": %s/%s" (eclim--count-current-errors) - (eclim--count-current-warnings)))) + (eclim--count-current-warnings)) + (when eclim--problems-refreshing "*"))) (provide 'eclim-problems) From 03c352b23fd598a8e430179be9571e205b6f5860 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 2 Aug 2015 11:58:30 -0700 Subject: [PATCH 08/57] Some love for the compilation-problems buffer. This version fits my typical compilation-based workflow better than the problems buffer. * Fix an errant call to eclim--project-dir. * Fix the counting of errors/warnings. Errors apparently get 'warning = ":json-false", not nil. * Store the project-name in the buffer. This allows it to be called from within itself ("refreshed") easily. * Bind the standard "g" key to do just that. Otherwise compilation-mode will happily start a new shell make that confuses eclipse (in my config). * Use the standard "process status" part of the modeline to display "refreshing" / results, the latter in red if there are errors. * The local variables header text is unnecessary if we set it programatically. * Instead, put the result text at beginning as well and tag with time. * Try to not reposition the buffer upon refresh if possible. Note that I don't think we should make compilation-buffer refresh automatically when we get an updated list, even though it's quite easy. Other compilations stay unchanged until manually refreshed and uniformity is nice. --- eclim-problems.el | 70 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/eclim-problems.el b/eclim-problems.el index d6de590..c7123d8 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -449,27 +449,57 @@ is convenient as it lets the user navigate between errors using `next-error' (\\[next-error])." (interactive) (lexical-let ((filecol-size (eclim--problems-filecol-size)) - (project-directory (concat (eclim--project-dir buffer-file-name) "/")) - (compil-buffer (get-buffer-create eclim--problems-compilation-buffer-name))) + (project-directory (concat (eclim--project-dir) "/")) + (compil-buffer (get-buffer-create eclim--problems-compilation-buffer-name)) + (project-name (eclim-project-name))) ; To store it in buffer. + + (with-current-buffer compil-buffer + (setq default-directory project-directory) + (setq mode-line-process + (concat ": " (propertize "refreshing" + 'face 'compilation-mode-line-run)))) + ;; Remember that the part below is asynchronous. This can be tricky. (eclim--with-problems-list problems - (with-current-buffer compil-buffer - (setq default-directory project-directory) - (setq buffer-read-only nil) - (erase-buffer) - (insert (concat "-*- mode: compilation; default-directory: " - project-directory - " -*-\n\n")) - (let ((errors 0) (warnings 0)) - (loop for problem across (eclim--problems-filtered) - do (eclim--insert-problem-compilation problem filecol-size project-directory) - (cond ((assoc-default 'warning problem) - (setq warnings (1+ warnings))) - (t - (setq errors (1+ errors))))) - (insert (format "\nCompilation results: %d errors and %d warnings." - errors warnings))) - (compilation-mode)) - (display-buffer compil-buffer 'other-window)))) + (let (saved-user-pos) + (with-current-buffer compil-buffer + (buffer-disable-undo) + (setq buffer-read-only nil) + (setq saved-user-pos (point)) + (erase-buffer) + (let ((errors 0) (warnings 0)) + (loop for problem across (eclim--problems-filtered) do + (eclim--insert-problem-compilation + problem filecol-size project-directory) + (if (eq t (assoc-default 'warning problem)) ; :json-false, WTH + (setq warnings (1+ warnings)) + (setq errors (1+ errors)))) + (let ((msg (format + "Compilation results: %d errors, %d warnings [%s].\n" + errors warnings (current-time-string)))) + (insert "\n" msg) + (goto-char (point-min)) + (insert msg "\n")) + (compilation-mode) + ;; The above killed local variables, so recover our lexical-lets + (setq default-directory project-directory) + (setq eclim-project-name project-name) + ;; Remap the very dangerous "g" command :) A make -k in some of + ;; my projects would throw Eclipse off-balance by cleaning .classes. + ;; May look funky, but it's safe. + (local-set-key "g" 'eclim-problems-compilation-buffer) + + (setq mode-line-process + (concat ": " + (propertize (format "%d/%d" errors warnings) + 'face (when (> errors 0) + 'compilation-mode-line-fail)))))) + ;; Sometimes, buffer was already current. Note outside with-current-buf. + (unless (eq compil-buffer (current-buffer)) + (display-buffer compil-buffer 'other-window)) + (with-selected-window (get-buffer-window compil-buffer t) + (when (< saved-user-pos (point-max)) + (goto-char saved-user-pos))))))) + (defun eclim--insert-problem-compilation (problem filecol-size project-directory) (let ((filename (first (split-string (assoc-default 'filename problem) project-directory t))) From 9c4ea63b8528209245add4507a2f6c980d9fe816 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 2 Aug 2015 12:13:21 -0700 Subject: [PATCH 09/57] Add simple commands to move back and forth between problems in current file. These are entirely cursor based rather than dependent on position in the problems-buffer. They are intended to be navigational aids in the absence of Eclipse's scroll bar indicators, which we can't do in emacs. Otherwise, errors in long files can be hard to find. --- eclim-problems.el | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/eclim-problems.el b/eclim-problems.el index c7123d8..14b1112 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -517,6 +517,40 @@ is convenient as it lets the user navigate between errors using (length (eclim--filter-problems "w" t (buffer-file-name (current-buffer)) eclim--problems-list))) +(defun eclim-problems-next-same-file (&optional up) + "Moves to the next problem in the current file, with wraparound. If UP +or prefix arg, moves to previous instead; see `eclim-problems-prev-same-file'." + (interactive "P") + ;; This seems pretty inefficient, but it's fast enough. Would be even + ;; more inefficient if we didn't assume problems were sorted. + (let ((problems-file + (eclim--filter-problems nil t (buffer-file-name (current-buffer)) + eclim--problems-list)) + (pass-line (line-number-at-pos)) + (pass-col (+ (current-column) (if up 0 1))) + (first-passed nil) (last-not-passed nil)) + (when (= 0 (length problems-file)) (error "No problems in this file")) + (loop for p across problems-file until first-passed do + (let ((line (assoc-default 'line p)) + (col (assoc-default 'column p))) + (if (or (> line pass-line) + (and (= line pass-line) (> col pass-col))) + (setq first-passed p) + (setq last-not-passed p)))) + (eclim--problem-goto-pos + (or + (if up last-not-passed first-passed) + (when up (message "Moved past first error, continuing to last") + (elt problems-file (- (length problems-file) 1))) ; Ugh, vector + (progn (message "Moved past last error, continuing to first") + (elt problems-file 0)))))) + +(defun eclim-problems-prev-same-file () + "Moves to the previous problem in the same file, with wraparound." + (interactive) + (eclim-problems-next-same-file t)) + + (defun eclim-problems-modeline-string () "Returns modeline string with additional info about problems for current file" From c0de8ca2a2374dc81cb9eadcaca9413f380eb78c Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 2 Aug 2015 14:32:52 -0700 Subject: [PATCH 10/57] Minor: add follow-link=t to javadoc text buttons, allowing left click. This helps on Macbook. It's consistent with help-mode, for example. --- eclim-java.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eclim-java.el b/eclim-java.el index 44f39fe..2c276ec 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -675,13 +675,14 @@ much faster than running mvn test -Dtest=TestClass#method." (replace-match text) (make-text-button (match-beginning 0) (+ (match-beginning 0) (length text)) + 'follow-link t 'action 'eclim-java-show-documentation-follow-link 'url href)))) (when add-to-history (goto-char (point-max)) (insert "\n\n") - (insert-text-button "back" 'action 'eclim--java-show-documentation-go-back)) + (insert-text-button "back" 'follow-link t 'action 'eclim--java-show-documentation-go-back)) (goto-char (point-min))) From 38b41d73c77a68fa31c76d8dcfea227793bf20ff Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Fri, 7 Aug 2015 10:11:37 -0700 Subject: [PATCH 11/57] company-eclim: make ignore-case=nil filter candidates to match prefix. Eclipse changed the relevant option to apply to camelCase only, and when completing a variable we get a *huge* selection of all classes that begin with that prefix. Try completing a variable that starts with "re" for example. Eclimd's sorting is not particularly good, either -- in Eclipse at least we get the lowercase matches first. Company-mode's view is that the backend is responsible for ensuring the prefix matches properly. --- company-emacs-eclim.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/company-emacs-eclim.el b/company-emacs-eclim.el index 27c9d9b..0cf2fb2 100644 --- a/company-emacs-eclim.el +++ b/company-emacs-eclim.el @@ -80,7 +80,11 @@ (mapcar (lambda (candidate) (annotate (without-redundant-prefix candidate))) - (eclim--completion-candidates))))) + ;; Company says backend is responsible for filtering prefix case. + (if company-emacs-eclim-ignore-case + (eclim--completion-candidates) + (remove-if-not #'(lambda(str) (string-prefix-p prefix str)) + (eclim--completion-candidates))))))) (defun company-emacs-eclim--annotation (candidate) (let ((str (get-text-property 0 'eclim-meta candidate))) From d5a3b205c681cfb530c10dd07fd0a4afba27cf69 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 9 Aug 2015 13:39:14 -0700 Subject: [PATCH 12/57] Allow completion after an open bracket or template bracket. This matches the way it works in Eclipse -- complete the open call / type rather than going for a new identifier. beginning-of-thing does not by itself cross the open bracket. --- eclim-completion.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/eclim-completion.el b/eclim-completion.el index 7e7f65e..060caf1 100644 --- a/eclim-completion.el +++ b/eclim-completion.el @@ -161,6 +161,15 @@ buffer." (case major-mode ((java-mode javascript-mode js-mode ruby-mode groovy-mode php-mode c-mode c++-mode scala-mode) (progn + ;; Allow completion after open bracket. Eclipse/eclim do. + (when (or (eq ?\( (char-before)) + ;; Template? Technically it could be a less-than sign + ;; but it's unlikely the user completes there and + ;; no particular harm done. + (and (eq ?\< (char-before)) + (memq major-mode + '(java-mode c++-mode goovy-mode)))) + (backward-char 1)) (ignore-errors (beginning-of-thing 'symbol)) ;; Completion candidates for annotations don't include '@'. (when (eq ?@ (char-after)) From 9392755ca2324f821e00c4c7706adb5295cbaf91 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Fri, 14 Aug 2015 17:18:33 -0700 Subject: [PATCH 13/57] Make problems refresh after an automated correction. Otherwise it's strange to accept a correction, see the buffer save & refresh, but the error highlight persist. I don't like automatic problem updates always (tried it!), but in this case I'm actively expecting Eclipse to fix one. Minor: remove an extraneous space from Eclim modeline. "Eclim: 0/13" looks nicer to me than "Eclim : 0/13", and modeline space is precious. --- eclim-java.el | 5 ++++- eclim.el | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index 2c276ec..5adaeaf 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -621,7 +621,10 @@ much faster than running mvn test -Dtest=TestClass#method." "-f" ("-l" line) ("-o" offset) - ("-a" choice))) + ("-a" choice)) + ;; Problem updates can be distracting, but here the user was + ;; actively trying to fix one. + (eclim--problems-update-maybe)) (message "No automatic corrections found. Sorry"))))) (defun eclim-java-show-documentation-for-current-element () diff --git a/eclim.el b/eclim.el index 0537d67..3e8e28a 100644 --- a/eclim.el +++ b/eclim.el @@ -546,6 +546,6 @@ the use of eclim to java and ant files." (defun eclim-modeline-string () (when eclim-mode - (concat " Eclim " (eclim-problems-modeline-string)))) + (concat " Eclim" (eclim-problems-modeline-string)))) (provide 'eclim) From 9aab07c0a4c85d06ef016af2b0b9b5f74e33199e Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Mon, 17 Aug 2015 21:56:07 -0700 Subject: [PATCH 14/57] Fix eclim-java-implement; it now uses Eclipse rather than emacs insertion. Eclipse is much better at it than we can hope to be. For example: * It imports the return type correctly, which eclim doesn't give us fully * It imports in the right place syntactically, even when called from within a method * It looks up argument names in javadoc if available [note] * Is much less fragile [note] which means that many times the reason we used yasnippet at all becomes unnecessary, since the javadoc names are something the user typically wants to keep in overrides. This whole thing started as a quest to expunge yasnippet which was being used unconditionally. --- eclim-java.el | 200 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 139 insertions(+), 61 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index 5adaeaf..4a9a9d0 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -188,19 +188,19 @@ has been found." (defun eclim--java-refactor (result) "Processes the resulst of a refactor command. RESULT is the results of invoking eclim/execute-command." - (if (stringp res) (error res)) - (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) - do (when (and from to) - (kill-buffer (find-buffer-visiting from)) - (find-file to))) - (save-excursion - (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) - do (when file - (let ((buf (get-file-buffer (file-name-nondirectory file)))) - (when buf - (switch-to-buffer buf) - (revert-buffer t t t)))))) - (message "Done")) + (if (stringp res) (error "%s" res)) + (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) + do (when (and from to) + (kill-buffer (find-buffer-visiting from)) + (find-file to))) + (save-excursion + (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) + do (when file + (let ((buf (get-file-buffer (file-name-nondirectory file)))) + (when buf + (switch-to-buffer buf) + (revert-buffer t t t)))))) + (message "Done")))) (defun eclim/java-classpath (project) (eclim--check-project project) @@ -496,57 +496,135 @@ sorts import statements. " (eclim-java-import-organize (mapcar (lambda (imports) (eclim--completing-read "Import: " (append imports '()))) res))))))) -(defun format-type (type) - (cond ((null type) nil) - ((listp (first type)) - (append (list "<") (rest (mapcan (lambda (type) (append (list ", ") (format-type type))) (first type))) (list ">") - (format-type (rest type)))) - (t (cons (let ((type-name (symbol-name (first type)))) - (when (string-match "\\(.*\\.\\)?\\(.*\\)" type-name) - (match-string 2 type-name))) - (format-type (rest type)))))) + +(defun eclim--signature-has-keyword (sig java-keyword) + "Returns true if a method signature SIG has the keyword JAVA-KEYWORD." + ;; \_< is beginning of identifier E.g. don't match do_abstract". + (string-match-p (format "\\_<%s\\_>" java-keyword) sig)) + + +(defun eclim--colorize-signature (sig) + "Minimal colorization for a method signature that we offer for completion, +so the essential bits stand out from the block of text that ido presents. +Keep this minimal: more highlighting could easily make things worse not better." + (save-match-data + (mapc #'(lambda(re-g-f) ;; expecting single match per RE + (when (string-match (elt re-g-f 0) sig) + (setq sig (replace-match + (propertize (match-string (elt re-g-f 1) sig) + 'face (elt re-g-f 2)) + nil nil sig (elt re-g-f 1))))) + '(("\\_<\\(class\\|interface\\)\\s +\\([[:alnum:]_]+\\_>\\)" + 2 font-lock-type-face) + ("\\_<\\([[:alnum:]_]+\\)(" 1 font-lock-function-name-face) + ("all [[:digit:]]+ \\w+ methods" 0 font-lock-function-name-face)))) + sig) + (defun eclim-java-implement (&optional name) - "Lets the user select from a list of methods to -implemnt/override, then inserts a skeleton for the chosen -method." + "Implement or override methods from parents of the class, prompting the +user to select with a completing read (even if one, as confirmation). If +NAME was specified programmatically, filters for that name (strict, +although only on method name not arguments) and if only one choice +implement it without prompting. The actual change is done by Eclipse +and will be close to point although not necessarily at it (e.g. if in a +sub block)." (interactive) - (eclim/with-results response ("java_impl" "-p" "-f" "-o") - (cl-flet ((join (glue items) - (cond ((null items) "") - ((= 1 (length items)) (format "%s" (first items))) - (t (reduce (lambda (a b) (format "%s%s%s" a glue b)) items)))) - (format-type (type) - (cond ((null type) nil) - ((listp (first type)) - (append (list "<") (rest (mapcan (lambda (type) (append (list ", ") (format-type type))) (first type))) (list ">") - (format-type (rest type)))) - (t (cons (let ((type-name (symbol-name (first type)))) - (when (string-match "\\(.*\\.\\)?\\(.*\\)" type-name) - (let ((package (match-string 1 type-name)) - (class (match-string 2 type-name))) - (eclim-java-import (concat package class)) - class))) - (format-type (rest type))))))) - (let* ((methods (remove-if-not (lambda (m) (or (null name) - (string-match name m))) - (mapcar (lambda (x) (replace-regexp-in-string "[ \n\t]+" " " x)) - (apply 'append - (mapcar (lambda (x) (append (assoc-default 'methods x) nil)) - (assoc-default 'superTypes response)))))) - (method (if (= 1 (length methods)) (first methods) - (eclim--completing-read "Signature: " methods))) - (sig (eclim--java-parse-method-signature method)) - (ret (assoc-default :return sig))) - (yas/expand-snippet (format "@Override\n%s %s(%s) {$0}" - (apply #'concat - (join " " (remove-if-not (lambda (m) (find m '(public protected private void))) (subseq ret 0 (1- (length ret))))) - " " - (format-type (remove-if (lambda (m) (find m '(abstract public protected private ))) ret))) - (assoc-default :name sig) - (join ", " (loop for arg in (remove-if #'null (assoc-default :arglist sig)) - for i from 0 - collect (format "%s ${arg%s}" (apply #'concat (format-type (assoc-default :type arg))) i))))))))) + (eclim/with-results list-response ("java_impl" "-p" "-f" "-o") + (let* ((supertypes (assoc-default 'superTypes list-response)) + ;; "Choices" are lists of user-friendly method names. We want to + ;; present interfaces/abstract first, otherwise Object can barge in. + (choices nil) (choices-opt nil) (choices-last nil) + ;; Maps a choice to a (supertype method1 method2...), needed + ;; when we request eclim to implement that method. + (choice-data (make-hash-table :test 'equal))) + (loop + for super-entry across supertypes do + (let* ((package (assoc-default 'packageName super-entry)) + (super-sig (assoc-default 'signature super-entry)) + ;; Erase type arguments. This looks like "class List". + (friendly-super (replace-regexp-in-string "<[^<]*>" "" super-sig)) + (full-super (concat package "." + (replace-regexp-in-string "^\\w+ " "" + friendly-super))) + (is-interface (eclim--signature-has-keyword + super-sig "interface")) + (methods (assoc-default 'methods super-entry)) + (required-methods nil)) ;; Eclim names here + (loop + for method across methods + ;; Skip if specified name doesn't match. + if (or (null name) + (string-match-p (format "\\_<%s(" (regexp-quote name)) method)) + do + ;; This regexp stuff is how vim (and thus eclim) does it. Nothing + ;; fancy. If it breaks, Google eclim/java/impl.vim for changes. + (let ((name-for-eclim + ;; Remove keywords and return type. \_< begins identifier. + (replace-regexp-in-string "^\\s *[^(]*\\(\\_<[[:alnum:]_]+(\\)" + "\\1" + ;; Remove any and all type parameters. + (replace-regexp-in-string "<[^<]*>" "" method))) + ;; For the user, we have very different requirements. I like + ;; knowing public and abstract, and the return type. I hate + ;; packages -- I'm already implementing this class so I know. + (friendly-name + ;; Packages are non-trivial to find (think Map.Entry) but + ;; if we stop at the first capitalized portion we're okay. + (replace-regexp-in-string "\\_<[[:lower:]][[:alnum:]_]+\\." + "" method)) + (is-required (or is-interface (eclim--signature-has-keyword + method "abstract")))) + (let ((choice (format "%s [%s]" friendly-name friendly-super)) + (data (list full-super name-for-eclim))) + ;; This is probably overkill but what if our package erasing + ;; resulted in duplicates? Use full name then. As in, really full. + (when (gethash choice choice-data) + (setq choice (format "%s [%s]" name-for-eclim full-super))) + (cond (is-required (push choice choices)) + ((member full-super '("java.lang.Object")) ; others like it? + (push choice choices-last)) + (t (push choice choices-opt))) + (puthash choice (list full-super name-for-eclim) choice-data) + (when is-required (push name-for-eclim required-methods))))) + ;; Since we don't allow multiple selection like Eclipse / vim, let's + ;; provide for the cases that matter. Note that full non-abstract + ;; overrides are typically a use case for *delegates*. + (when (> (length required-methods) 1) ;; 1 method already there + (let ((choice + (format "" + (length required-methods) + (cond (is-interface "missing") (name) (t "abstract")) + friendly-super)) + (data (cons full-super (reverse required-methods)))) + (push choice choices) ;; I'll not worry about conflict here. + (puthash choice data choice-data))))) + ;; Keep inital order, except for our tweaks. + (setq choices (append (nreverse choices) (reverse choices-opt) + (reverse choices-last))) + (unless choices + (if name (error "No such unimplemented method: %s" name) ;most likely + (error "No candidates to implement"))) ;; Rare, given Object ancestor. + + ;; Ask user even if only one choice, for confirmation. Otherwise it's + ;; possible to not even notice the change from a bad key combo. Unless + ;; we were called programmatically a for specific method. + (let ((choice + (if (and name (eq 1 (length choices))) + (first choices) + (funcall eclim-interactive-completion-function + "Implement: " + (mapcar #'eclim--colorize-signature choices) + nil t)))) ; require match + (setq choice (substring-no-properties choice)) ; uncolorize + (let* ((eclim-data (gethash choice choice-data)) + (super (car eclim-data)) (methods (cdr eclim-data)) + (methods-str (json-encode methods))) + (eclim/with-results impl-result ("java_impl" "-p" "-f" "-o" + ("-s" super) ("-m" methods-str)) + ;; eclim should give us a smaller list if it did something. But + ;; it's probably not worth an error in case this changes. + (revert-buffer t t t))))))) (defun eclim-package-and-class () (let ((package-name (eclim--java-current-package)) From f19c4b4a862eb0d95b178b334e18110a880fc7ee Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Mon, 24 Aug 2015 23:05:43 -0700 Subject: [PATCH 15/57] Problem highlights: add variable that causes highlights to be suppressed. This allows the user to easily set up commands that disable highlights (e.g. temporarily, while writing a bunch of new code), globally or buffer-local (more common in my usage). Unlike a problem filter, the problem counts remain and the problems are navigable. Rename eclim--problems-clear-highlights to indicate it's not private. --- eclim-problems.el | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/eclim-problems.el b/eclim-problems.el index 14b1112..85c78b8 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -33,6 +33,17 @@ :type '(choice (const :tag "Off" nil) (const :tag "On" t))) +(defcustom eclim-problems-suppress-highlights nil + "When set, error and warning highlights are disabled in source files, +although counts are printed and they remain navigable. This is +designed to be made buffer-local (by user, not eclim) most of the +time, but it also works globally." + :group 'eclim-problems + :type '(choice (const :tag "Allow" nil) + (const :tag "Suppress" t) + (sexp :tag "Suppress when" + :value (lambda() 'for-example buffer-read-only)))) + (defface eclim-problems-highlight-error-face '((t (:underline "red"))) "Face used for highlighting errors in code" @@ -152,17 +163,27 @@ (overlay-put highlight 'category 'eclim-problem) (overlay-put highlight 'kbd-help (assoc-default 'message problem)))))) -(defun eclim--problems-clear-highlights () + +(defun eclim-problems-clear-highlights () + "Clears all eclim problem highlights in the current buffer. This is temporary +until the next refresh." + (interactive) (remove-overlays nil nil 'category 'eclim-problem)) + (defun eclim-problems-highlight () + "Inserts the currently active problem highlights in the current buffer, +if `eclim-problems-suppress-highlights' allows it." (interactive) (when (eclim--accepted-p (buffer-file-name)) (save-restriction (widen) - (eclim--problems-clear-highlights) - (loop for problem across (remove-if-not (lambda (p) (string= (assoc-default 'filename p) (buffer-file-name))) eclim--problems-list) - do (eclim--problems-insert-highlight problem))))) + (eclim-problems-clear-highlights) + (unless (if (functionp eclim-problems-suppress-highlights) + (funcall eclim-problems-suppress-highlights) + eclim-problems-suppress-highlights) + (loop for problem across (remove-if-not (lambda (p) (string= (assoc-default 'filename p) (buffer-file-name))) eclim--problems-list) + do (eclim--problems-insert-highlight problem)))))) (defadvice find-file (after eclim-problems-highlight-on-find-file activate) (eclim-problems-highlight)) From 45268809e2b815769b72251811e6ecf73e183080 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Mon, 24 Aug 2015 23:16:14 -0700 Subject: [PATCH 16/57] Add a function to find files by name. I'm using this to help Emacs find the file from stack traces, which are basename only, via compilation-find-file advice. --- eclim-java.el | 50 +++++++++++++++++++++++++------------------------- eclim.el | 22 +++++++++++++++++++++- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index 4a9a9d0..a8a3ac2 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -142,9 +142,9 @@ in eclim when appropriate." (replace-regexp-in-string "[<>(),?]" (lambda (m) (assoc-default m '(("<" . "((") (">" . "))") - ("(" . "((") (")" ."))") - ("," . ")(") - ("?" . "\\\\?")))) + ("(" . "((") (")" ."))") + ("," . ")(") + ("?" . "\\\\?")))) str))))) (defun eclim--java-parse-method-signature (signature) @@ -189,18 +189,18 @@ has been found." "Processes the resulst of a refactor command. RESULT is the results of invoking eclim/execute-command." (if (stringp res) (error "%s" res)) - (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) - do (when (and from to) - (kill-buffer (find-buffer-visiting from)) - (find-file to))) - (save-excursion - (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) - do (when file - (let ((buf (get-file-buffer (file-name-nondirectory file)))) - (when buf - (switch-to-buffer buf) - (revert-buffer t t t)))))) - (message "Done")))) + (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) + do (when (and from to) + (kill-buffer (find-buffer-visiting from)) + (find-file to))) + (save-excursion + (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) + do (when file + (let ((buf (get-file-buffer (file-name-nondirectory file)))) + (when buf + (switch-to-buffer buf) + (revert-buffer t t t)))))) + (message "Done")) (defun eclim/java-classpath (project) (eclim--check-project project) @@ -563,8 +563,8 @@ sub block)." ;; Remove keywords and return type. \_< begins identifier. (replace-regexp-in-string "^\\s *[^(]*\\(\\_<[[:alnum:]_]+(\\)" "\\1" - ;; Remove any and all type parameters. - (replace-regexp-in-string "<[^<]*>" "" method))) + ;; Remove any and all type parameters. + (replace-regexp-in-string "<[^<]*>" "" method))) ;; For the user, we have very different requirements. I like ;; knowing public and abstract, and the return type. I hate ;; packages -- I'm already implementing this class so I know. @@ -641,16 +641,16 @@ sub block)." " -c " (eclim-package-and-class))))) (defun eclim--java-junit-file (project file offset encoding) - (concat eclim-executable - " -command java_junit -p " project - " -f " file - " -o " (number-to-string offset) - " -e " encoding)) + (concat eclim-executable + " -command java_junit -p " project + " -f " file + " -o " (number-to-string offset) + " -e " encoding)) (defun eclim--java-junit-project (project encoding) - (concat eclim-executable - " -command java_junit -p " project - " -e " encoding)) + (concat eclim-executable + " -command java_junit -p " project + " -e " encoding)) (defun eclim--buffer-contains-substring (string) (save-excursion diff --git a/eclim.el b/eclim.el index 3e8e28a..ce472fc 100644 --- a/eclim.el +++ b/eclim.el @@ -435,6 +435,26 @@ FILENAME is given, return that file's project name instead." hits)) t))) +(defun eclim-find-file-path-strict (filename &optional project directory) + "Locates a file (basename) in Eclipse. If PROJECT is a string, +searches only that project; if nil, the project of the current +file. If t, searches all Eclipse projects. If DIRECTORY is +specified, returns only files that are under that +directory. Returns a list of matching absolute paths; possibly +empty. This can be used to help resolve exception stack traces, +for example." + (let* ((results (apply #'eclim--call-process "locate_file" + "-p" (regexp-quote filename) + (if (eq project t) + (list "-s" "workspace") + (list "-s" "project" "-n" + (or project (eclim-project-name)))))) + (paths (mapcar #'(lambda(hit) (assoc-default 'path hit)) results))) + (if directory + (remove-if-not #'(lambda (f) (file-in-directory-p f directory)) paths) + paths))) + + ;;;###autoload (defun eclim/workspace-dir () (eclim--call-process "workspace_dir")) @@ -474,7 +494,7 @@ FILENAME is given, return that file's project name instead." "List of regular expressions that are matched against filenames to decide if eclim should be automatically started on a particular file. By default all files part of a project managed -by eclim can be accepted (see `eclim--accepted-filename' for more +by eclim can be accepted (see `eclim--accepted-filename-p' for more information). It is nevertheless possible to restrict eclim to some files by changing this variable. For example, a value of (\"\\\\.java\\\\'\" \"build\\\\.xml\\\\'\") can be used to restrict From 0f852e76c32c27b9ce1fc968100b87fd0e01c009 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Thu, 17 Dec 2015 15:31:01 -0700 Subject: [PATCH 17/57] Tweak for eclim-run-configuartion. --- eclim-java-run.el | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/eclim-java-run.el b/eclim-java-run.el index f390229..3487b6b 100644 --- a/eclim-java-run.el +++ b/eclim-java-run.el @@ -149,16 +149,13 @@ (defun eclim-run-configuartion (configuration-name) "Runs the configuration given in CONFIGURATION-NAME in the compilation buffer." (interactive (list (eclim-java-run--ask-which-configuration))) - (let* ((current-directory default-directory) - (configurations (eclim-java-run--load-configurations (eclim-project-name))) + (let* ((configurations (eclim-java-run--load-configurations (eclim-project-name))) (configuration (eclim-java-run--configuration configuration-name configurations)) (project-dir (eclim-java-run--project-dir (eclim-project-name))) (classpath (eclim/java-classpath (eclim-project-name))) + (default-directory project-dir) (command (eclim-java-run--command configuration (eclim-java-run--java-vm-args classpath)))) - (setq default-directory project-dir) - (compile command) - (setq default-directory current-directory) - )) + (compile command))) (provide 'eclim-java-run) ;;; eclim-java-run.el ends here From 35545c68230d22a5867742010c632a2e0551fe8e Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 10:43:12 +0900 Subject: [PATCH 18/57] Correct meta comment for packaging convention --- company-emacs-eclim.el | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/company-emacs-eclim.el b/company-emacs-eclim.el index 0cf2fb2..22bf493 100644 --- a/company-emacs-eclim.el +++ b/company-emacs-eclim.el @@ -1,4 +1,4 @@ -;; company-emacs-eclim.el --- an interface to the Eclipse IDE. +;;; company-emacs-eclim.el --- an interface to the Eclipse IDE. ;; ;; Copyright (C) 2009-2012 Fredrik Appelberg ;; Copyright (C) 2013-2014 Dmitry Gutov @@ -16,7 +16,7 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;; -;;; Description +;;; Commentary: ;; ;; company-emacs-eclim.el -- company-mode backend that replaces company-eclim ;; @@ -26,6 +26,8 @@ ;; ;; Minimum company-mode version required: 0.7. +;;; Code: + ;;* Eclim Company (require 'eclim) @@ -119,3 +121,4 @@ (eclim--completion-action beg end))) (provide 'company-emacs-eclim) +;;; company-emacs-eclim.el ends here From ad931701a666002d6379a05a74f5f3f47d5ce038 Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 10:44:03 +0900 Subject: [PATCH 19/57] Add autoload cookie for lazy loading --- company-emacs-eclim.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/company-emacs-eclim.el b/company-emacs-eclim.el index 22bf493..a5fe392 100644 --- a/company-emacs-eclim.el +++ b/company-emacs-eclim.el @@ -41,6 +41,7 @@ :type '(choice (const :tag "Yes" t) (const :tag "No" nil))) +;;;###autoload (defun company-emacs-eclim-setup () "Convenience function that adds company-emacs-eclim to the list of available company backends." @@ -93,6 +94,7 @@ (when (and str (string-match "(" str)) (substring str (match-beginning 0))))) +;;;###autoload (defun company-emacs-eclim (command &optional arg &rest ignored) "`company-mode' back-end for Eclim completion" (interactive (list 'interactive)) From 5461fa7bfbe32b12b332d25a161473bcb14530fa Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 10:44:27 +0900 Subject: [PATCH 20/57] Use cl-lib macros instead cl.el And load cl-lib explicitly. --- company-emacs-eclim.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/company-emacs-eclim.el b/company-emacs-eclim.el index a5fe392..8854658 100644 --- a/company-emacs-eclim.el +++ b/company-emacs-eclim.el @@ -34,6 +34,7 @@ (require 'eclim-completion) (require 'eclim-java) (require 'company) +(require 'cl-lib) (defcustom company-emacs-eclim-ignore-case t "If t, case is ignored in completion matches." @@ -47,8 +48,8 @@ of available company backends." (setq company-backends (cons 'company-emacs-eclim - (remove-if (lambda (b) (find b '(company-nxml company-eclim))) - company-backends)))) + (cl-remove-if (lambda (b) (cl-find b '(company-nxml company-eclim))) + company-backends)))) (defun company-emacs-eclim--before-prefix-in-buffer (prefix) "Search for the text before prefix that may be included as part of completions" @@ -86,8 +87,8 @@ ;; Company says backend is responsible for filtering prefix case. (if company-emacs-eclim-ignore-case (eclim--completion-candidates) - (remove-if-not #'(lambda(str) (string-prefix-p prefix str)) - (eclim--completion-candidates))))))) + (cl-remove-if-not #'(lambda(str) (string-prefix-p prefix str)) + (eclim--completion-candidates))))))) (defun company-emacs-eclim--annotation (candidate) (let ((str (get-text-property 0 'eclim-meta candidate))) @@ -98,7 +99,7 @@ (defun company-emacs-eclim (command &optional arg &rest ignored) "`company-mode' back-end for Eclim completion" (interactive (list 'interactive)) - (case command + (cl-case command (interactive (company-begin-backend 'company-emacs-eclim)) (prefix (let ((start (and eclim-mode (eclim--accepted-p (buffer-file-name)) From 96ef7c5f8fa8c3379bde8a3e6a683dd68cccd20a Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 10:47:52 +0900 Subject: [PATCH 21/57] Add cl-lib dependency Some files already use cl-lib functions/macros. --- emacs-eclim-pkg.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-eclim-pkg.el b/emacs-eclim-pkg.el index 206c071..07be54c 100644 --- a/emacs-eclim-pkg.el +++ b/emacs-eclim-pkg.el @@ -3,4 +3,5 @@ '((dash "2.11.0") (json "1.2") (popup "0.5.2") - (s "1.9.0"))) + (s "1.9.0") + (cl-lib "0.5"))) From a9ab83e578d37b672d93cb6865bc9325392b8ac0 Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 11:07:38 +0900 Subject: [PATCH 22/57] Correct argument names --- eclim-ant.el | 2 +- eclim-java.el | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eclim-ant.el b/eclim-ant.el index c33a867..b119716 100644 --- a/eclim-ant.el +++ b/eclim-ant.el @@ -67,7 +67,7 @@ stored. It is used globally for all eclim projects." (eclim--check-project project) (mapcar (lambda (line) (split-string line "|")) - (eclim--call-process "ant_validate" "-p" project "-f" file))) + (eclim--call-process "ant_validate" "-p" project "-f" buildfile))) (defun eclim/ant-target-list (project buildfile) (eclim--check-project project) diff --git a/eclim-java.el b/eclim-java.el index a8a3ac2..0e8b587 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -188,13 +188,13 @@ has been found." (defun eclim--java-refactor (result) "Processes the resulst of a refactor command. RESULT is the results of invoking eclim/execute-command." - (if (stringp res) (error "%s" res)) - (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) res) + (if (stringp result) (error "%s" result)) + (loop for (from to) in (mapcar (lambda (x) (list (assoc-default 'from x) (assoc-default 'to x))) result) do (when (and from to) (kill-buffer (find-buffer-visiting from)) (find-file to))) (save-excursion - (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) res) + (loop for file in (mapcar (lambda (x) (assoc-default 'file x)) result) do (when file (let ((buf (get-file-buffer (file-name-nondirectory file)))) (when buf From 32d014fa5f5028a6130aa00ce4f46b97568e5912 Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 11:09:08 +0900 Subject: [PATCH 23/57] Fix for global variable declarations - Global variables should be declared - Use defvar instead of setq for initializing global variable --- eclim-java.el | 1 + eclim.el | 14 +++++++------- eclimd.el | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index 0e8b587..7c020f8 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -104,6 +104,7 @@ Java documentation under Android docs, so don't forget to set "references")) (defvar eclim--is-completing nil) +(defvar eclim-java-show-documentation-history nil) (defun eclim/groovy-src-update (&optional save-others) "If `eclim-auto-save' is non-nil, save the current java diff --git a/eclim.el b/eclim.el index ce472fc..3078db6 100644 --- a/eclim.el +++ b/eclim.el @@ -209,13 +209,13 @@ strings and will be called on completion." (kill-buffer buf))))) (set-process-sentinel proc sentinel))))))) -(setq eclim--default-args - '(("-n" . (eclim-project-name)) - ("-p" . (or (eclim-project-name) (error "Could not find eclipse project for %s" (buffer-name (current-buffer))))) - ("-e" . (eclim--current-encoding)) - ("-f" . (eclim--project-current-file)) - ("-o" . (eclim--byte-offset)) - ("-s" . "project"))) +(defvar eclim--default-args + '(("-n" . (eclim-project-name)) + ("-p" . (or (eclim-project-name) (error "Could not find eclipse project for %s" (buffer-name (current-buffer))))) + ("-e" . (eclim--current-encoding)) + ("-f" . (eclim--project-current-file)) + ("-o" . (eclim--byte-offset)) + ("-s" . "project"))) (defun eclim--args-contains (args flags) "Check if an (unexpanded) ARGS list contains any of the diff --git a/eclimd.el b/eclimd.el index 824e208..8fb4387 100644 --- a/eclimd.el +++ b/eclimd.el @@ -64,6 +64,8 @@ You can freeze emacs until eclimd is ready to accept commands with this variable (defvar eclimd-process nil "The active eclimd process") +(defvar eclimd-port nil) + (defconst eclimd-process-buffer-name "eclimd") (defun eclimd--executable-path () From 4f2df56f87f0651efa9dcca737d5aa6b45f27beb Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 11:10:35 +0900 Subject: [PATCH 24/57] Correct variable name --- eclim-problems.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim-problems.el b/eclim-problems.el index 85c78b8..6b9a63a 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -503,7 +503,7 @@ is convenient as it lets the user navigate between errors using (compilation-mode) ;; The above killed local variables, so recover our lexical-lets (setq default-directory project-directory) - (setq eclim-project-name project-name) + (setq eclim--project-name project-name) ;; Remap the very dangerous "g" command :) A make -k in some of ;; my projects would throw Eclipse off-balance by cleaning .classes. ;; May look funky, but it's safe. From 258d0ae9d6b310b8879ee251ed779c195667c544 Mon Sep 17 00:00:00 2001 From: Syohei YOSHIDA Date: Fri, 18 Dec 2015 11:11:32 +0900 Subject: [PATCH 25/57] Use argument The file name is passed as argument. --- eclim-problems.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim-problems.el b/eclim-problems.el index 6b9a63a..79647ae 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -267,7 +267,7 @@ it asynchronously." (length (remove-if-not (lambda (p) (eq t (assoc-default 'warning p))) problems))))))) (defun eclim--problems-cleanup-filename (filename) - (let ((x (file-name-nondirectory (assoc-default 'filename problem)))) + (let ((x (file-name-nondirectory filename))) (if eclim-problems-show-file-extension x (file-name-sans-extension x)))) (defun eclim--problems-filecol-size () From 21e67c4d600fde709ffa0616106c4830816afa90 Mon Sep 17 00:00:00 2001 From: Daniel Gopar Date: Sat, 19 Dec 2015 20:15:54 -0800 Subject: [PATCH 26/57] Create setter function --- History.txt | 2 ++ eclim-java.el | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/History.txt b/History.txt index b721679..d00a747 100644 --- a/History.txt +++ b/History.txt @@ -8,6 +8,8 @@ compilation buffer. * added eclim-java-generate-getter which generates a getter method for the symbol at point. + * added eclim-java-generate-setter which generates a setter method + for the symbol at point. * added eclim-java-refactor-move-class which allows moving a top level class or interface from one package to another. * added eclim-project-setting-set which can assign an Eclim project diff --git a/eclim-java.el b/eclim-java.el index 7c020f8..3dd72e0 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -254,6 +254,14 @@ has been found." (eclim--current-encoding))) (eclim--java-generate-bean-properties project file offset encoding "getter")) +(defun eclim-java-generate-setter (project file offset encoding) + "Generates a setter method for the symbol at point." + (interactive (list (eclim-project-name) + (eclim--project-current-file) + (eclim--byte-offset) + (eclim--current-encoding))) + (eclim--java-generate-bean-properties project file offset encoding "setter")) + (defun eclim-java-constructor () (interactive) (eclim/execute-command "java_constructor" "-p" "-f" "-o")) From c889b9495bf23d5d5ca8f358a8c81314ba405c78 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 19 Dec 2015 22:12:42 -0700 Subject: [PATCH 27/57] Fixed some compiler warnings. Only fixed compiler warnings in code that could be manually tested. Other compiler warnings, in code that could not be tested, were left as is. --- eclim-ant.el | 2 +- eclim-java.el | 24 ++++++++++++------------ eclim-problems.el | 16 ++++++++-------- eclim-project.el | 26 ++++++++++++++------------ eclim.el | 26 ++++++++++++++------------ tests/company-emacs-eclim-tests.el | 2 +- 6 files changed, 50 insertions(+), 46 deletions(-) diff --git a/eclim-ant.el b/eclim-ant.el index b119716..e563540 100644 --- a/eclim-ant.el +++ b/eclim-ant.el @@ -89,7 +89,7 @@ buffer. The results are displayed in a dedicated compilation buffer." (dolist (line (eclim/ant-validate project file)) (insert (eclim--convert-find-result-to-string line)) (newline))) - (beginning-of-buffer) + (goto-char (point-min)) (compilation-mode)) (defun eclim-ant-run (target) diff --git a/eclim-java.el b/eclim-java.el index 3dd72e0..ab2ff17 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -454,12 +454,12 @@ imports section of a java source file. This will preserve the undo history." (interactive) (cl-flet ((cut-imports () - (beginning-of-buffer) + (goto-char (point-min)) (if (re-search-forward "^import" nil t) (progn (beginning-of-line) (let ((beg (point))) - (end-of-buffer) + (goto-char (point-max)) (re-search-backward "^import") (end-of-line) (let ((imports (buffer-substring-no-properties beg (point)))) @@ -486,7 +486,7 @@ undo history." "Adds an import statement for the given type, if one does not exist already." (save-excursion - (beginning-of-buffer) + (goto-char (point-min)) (let ((revert-buffer-function 'eclim-soft-revert-imports)) (when (not (re-search-forward (format "^import %s;" type) nil t)) (eclim/execute-command "java_import" "-p" "-f" "-o" "-e" ("-t" type)) @@ -789,16 +789,16 @@ much faster than running mvn test -Dtest=TestClass#method." (let* ((doc-root-vars '(eclim-java-documentation-root eclim-java-android-documentation-root)) (path (replace-regexp-in-string "^[./]+" "" url)) - (fullpath (some (lambda (var) - (let ((fullpath (concat (symbol-value var) - "/" - path))) - (if (file-exists-p (replace-regexp-in-string - "#.+" - "" - fullpath)) + (fullpath (cl-some (lambda (var) + (let ((fullpath (concat (symbol-value var) + "/" + path))) + (if (file-exists-p (replace-regexp-in-string + "#.+" + "" + fullpath)) fullpath))) - doc-root-vars))) + doc-root-vars))) (if fullpath (browse-url (concat "file://" fullpath)) diff --git a/eclim-problems.el b/eclim-problems.el index 79647ae..3acda08 100644 --- a/eclim-problems.el +++ b/eclim-problems.el @@ -182,7 +182,7 @@ if `eclim-problems-suppress-highlights' allows it." (unless (if (functionp eclim-problems-suppress-highlights) (funcall eclim-problems-suppress-highlights) eclim-problems-suppress-highlights) - (loop for problem across (remove-if-not (lambda (p) (string= (assoc-default 'filename p) (buffer-file-name))) eclim--problems-list) + (loop for problem across (cl-remove-if-not (lambda (p) (string= (assoc-default 'filename p) (buffer-file-name))) eclim--problems-list) do (eclim--problems-insert-highlight problem)))))) (defadvice find-file (after eclim-problems-highlight-on-find-file activate) @@ -208,7 +208,7 @@ if `eclim-problems-suppress-highlights' allows it." (widen) (let ((line (line-number-at-pos)) (col (current-column))) - (or (find-if (lambda (p) (and (string= (assoc-default 'filename p) (file-truename buffer-file-name)) + (or (cl-find-if (lambda (p) (and (string= (assoc-default 'filename p) (file-truename buffer-file-name)) (= (assoc-default 'line p) line))) eclim--problems-list) (error "No problem on this line"))))))) @@ -242,7 +242,7 @@ invoked in either the problems buffer or a source code buffer." (declare (indent defun)) "Utility macro to refresh the problem list and do operations on it asynchronously." - (let ((res (gensym))) + (let ((res (cl-gensym))) `(when eclim--problems-project (setq eclim--problems-refreshing t) (eclim/with-results-async ,res ("problems" ("-p" eclim--problems-project) (when (string= "e" eclim--problems-filter) '("-e" "true"))) @@ -263,8 +263,8 @@ it asynchronously." (if (string= "e" eclim--problems-filter) (message "Eclim reports %d errors." (length problems)) (message "Eclim reports %d errors, %d warnings." - (length (remove-if-not (lambda (p) (not (eq t (assoc-default 'warning p)))) problems)) - (length (remove-if-not (lambda (p) (eq t (assoc-default 'warning p))) problems))))))) + (length (cl-remove-if-not (lambda (p) (not (eq t (assoc-default 'warning p)))) problems)) + (length (cl-remove-if-not (lambda (p) (eq t (assoc-default 'warning p))) problems))))))) (defun eclim--problems-cleanup-filename (filename) (let ((x (file-name-nondirectory filename))) @@ -292,7 +292,7 @@ it asynchronously." "Draw the problem list on screen." (let ((buf (get-buffer "*eclim: problems*"))) (when buf - (save-excursion + (with-current-buffer (set-buffer buf) (eclim--problems-update-filter-description) (save-excursion @@ -339,11 +339,11 @@ COMPILATION-SKIP-THRESHOLD, implement this feature." (defun eclim--filter-problems (type-filter file-filter file problems) (let ((type-filterp (eclim--choose-type-filter type-filter)) (file-filterp (eclim--choose-file-filter file-filter file))) - (remove-if-not (lambda (x) (and (funcall type-filterp x) (funcall file-filterp x))) problems))) + (cl-remove-if-not (lambda (x) (and (funcall type-filterp x) (funcall file-filterp x))) problems))) (defun eclim--insert-problem (problem filecol-size) (let* ((filecol-format-string (concat "%-" (number-to-string filecol-size) "s")) - (problem-new-line-pos (position ?\n (assoc-default 'message problem))) + (problem-new-line-pos (cl-position ?\n (assoc-default 'message problem))) (problem-message (if problem-new-line-pos (concat (substring (assoc-default 'message problem) diff --git a/eclim-project.el b/eclim-project.el index fb17634..8bfee18 100644 --- a/eclim-project.el +++ b/eclim-project.el @@ -98,7 +98,8 @@ (erase-buffer) (loop for project across (eclim/project-list) do (eclim--insert-project project)) - (goto-line line-number)))) + (goto-char (point-min)) + (forward-line (1- line-number))))) (defun eclim--insert-project (project) (insert (format " | %-6s | %-30s | %s\n" @@ -125,7 +126,7 @@ (interactive) (let ((marked-projects '())) (save-excursion - (beginning-of-buffer) + (goto-char (point-min)) (while (re-search-forward "*" nil t) (push (eclim--project-current-line) marked-projects))) marked-projects)) @@ -260,12 +261,13 @@ (eclim--project-nature-read))) ;;android project is need the vars target,package,application (if (string-equal nature "android") - (progn (setq target (read-string "Target: ")) - (setq package (read-string "Package: ")) - (setq application (read-string "Application: ")) - (message (eclim/project-create path nature name target package application))) - (message (eclim/project-create path nature name)) - (eclim--project-buffer-refresh))) + (progn + (let ((target (read-string "Target: ")) + (package (read-string "Package: ")) + (application (read-string "Application: "))) + (message (eclim/project-create path nature name target package application)))) + (message (eclim/project-create path nature name)) + (eclim--project-buffer-refresh))) (defun eclim-project-import (folder) (interactive "DProject Directory: ") @@ -335,7 +337,7 @@ (defun eclim-project-mark-all () (interactive) (save-excursion - (beginning-of-buffer) + (goto-char (point-min)) (loop do (eclim--project-insert-mark-current 'dired-mark) until (not (forward-line 1))))) @@ -347,7 +349,7 @@ (defun eclim-project-unmark-all () (interactive) (save-excursion - (beginning-of-buffer) + (goto-char (point-min)) (loop do (eclim--project-remove-mark-current) until (not (forward-line 1))))) @@ -355,7 +357,7 @@ (interactive (list (eclim--project-read t))) (ido-find-file-in-dir (assoc-default 'path - (find project (eclim/project-list) + (cl-find project (eclim/project-list) :key (lambda (e) (assoc-default 'name e)) :test #'string=)))) @@ -408,7 +410,7 @@ (use-local-map eclim-project-mode-map) (cd "~") ;; setting a defualt directoy avoids some problems with tramp (eclim--project-buffer-refresh) - (beginning-of-buffer) + (goto-char (point-min)) (run-mode-hooks 'eclim-project-mode-hook)) (defalias 'eclim-manage-projects 'eclim-project-mode) diff --git a/eclim.el b/eclim.el index 3078db6..861f93f 100644 --- a/eclim.el +++ b/eclim.el @@ -143,14 +143,15 @@ operation, and the rest are flags/values to be passed on to eclimd." (when (not eclim-executable) (error "Eclim installation not found. Please set eclim-executable.")) - (reduce (lambda (a b) (format "%s %s" a b)) + (cl-reduce (lambda (a b) (format "%s %s" a b)) (append (list eclim-executable "-command" (first args)) (loop for a = (rest args) then (rest (rest a)) for arg = (first a) for val = (second a) while arg append (if val (list arg (shell-quote-argument val)) (list arg)))))) -(defun eclim--parse-result (result) +(defun ecl + im--parse-result (result) "Parses the result of an eclim operation, raising an error if the result is not valid JSON." (if (string-match (rx string-start (zero-or-more (any " " "\n" "\t")) string-end) result) @@ -193,7 +194,7 @@ asynchronously. CALLBACK is a function that accepts a list of strings and will be called on completion." (lexical-let ((handler callback) (cmd (eclim--make-command args))) - (when (not (find cmd eclim--currently-running-async-calls :test #'string=)) + (when (not (cl-find cmd eclim--currently-running-async-calls :test #'string=)) (lexical-let ((buf (get-buffer-create (generate-new-buffer-name "*eclim-async*")))) (when eclim-print-debug-messages (message "Executing: %s" cmd) @@ -203,7 +204,7 @@ strings and will be called on completion." (let ((sentinel (lambda (process signal) (unwind-protect (save-excursion - (setq eclim--currently-running-async-calls (remove-if (lambda (x) (string= cmd x)) eclim--currently-running-async-calls)) + (setq eclim--currently-running-async-calls (cl-remove-if (lambda (x) (string= cmd x)) eclim--currently-running-async-calls)) (set-buffer (process-buffer process)) (funcall handler (eclim--parse-result (buffer-substring 1 (point-max))))) (kill-buffer buf))))) @@ -221,7 +222,7 @@ strings and will be called on completion." "Check if an (unexpanded) ARGS list contains any of the specified FLAGS." (loop for f in flags - return (find f args :test #'string= :key (lambda (a) (if (listp a) (car a) a))))) + return (cl-find f args :test #'string= :key (lambda (a) (if (listp a) (car a) a))))) (defun eclim--expand-args (args) "Takes a list of command-line arguments with which to call the @@ -341,7 +342,7 @@ argument PROJECTNAME is given, return that project's root directory." (defun eclim-project-name (&optional filename) "Returns this file's project name. If the optional argument FILENAME is given, return that file's project name instead." - (labels ((get-project-name (file) + (cl-labels ((get-project-name (file) (eclim/execute-command "project_by_resource" ("-f" file)))) (if filename (get-project-name filename) @@ -356,7 +357,7 @@ FILENAME is given, return that file's project name instead." (archive-name (replace-regexp-in-string eclim--compressed-urls-regexp "" (first parts))) (file-name (second parts))) (find-file-other-window archive-name) - (beginning-of-buffer) + (goto-char (point-min)) (re-search-forward (replace-regexp-in-string eclim--compressed-file-path-removal-regexp "" (regexp-quote (replace-regexp-in-string @@ -364,11 +365,11 @@ FILENAME is given, return that file's project name instead." "/" file-name)))) (let ((old-buffer (current-buffer))) (archive-extract) - (beginning-of-buffer) + (goto-char (point-min)) (kill-buffer old-buffer))))) (defun eclim--find-display-results (pattern results &optional open-single-file) - (let ((results (remove-if (lambda (result) (string-match (rx bol (or "jar" "zip") ":") (assoc-default 'filename result))) results))) + (let ((results (cl-remove-if (lambda (result) (string-match (rx bol (or "jar" "zip") ":") (assoc-default 'filename result))) results))) (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) (pop-to-buffer (get-buffer-create "*eclim: find")) (let ((buffer-read-only nil)) @@ -395,7 +396,8 @@ FILENAME is given, return that file's project name instead." (defun eclim--visit-declaration (line) (ring-insert find-tag-marker-ring (point-marker)) (eclim--find-file (assoc-default 'filename line)) - (goto-line (assoc-default 'line line)) + (goto-char (point-min)) + (forward-line (1- (assoc-default 'line line))) (move-to-column (1- (assoc-default 'column line)))) (defun eclim--string-strip (content) @@ -451,7 +453,7 @@ for example." (or project (eclim-project-name)))))) (paths (mapcar #'(lambda(hit) (assoc-default 'path hit)) results))) (if directory - (remove-if-not #'(lambda (f) (file-in-directory-p f directory)) paths) + (cl-remove-if-not #'(lambda (f) (file-in-directory-p f directory)) paths) paths))) @@ -505,7 +507,7 @@ the use of eclim to java and ant files." (defun eclim--accepted-filename-p (filename) "Return t if and only one of the regular expressions in `eclim-accepted-file-regexps' matches FILENAME." - (if (member-if + (if (cl-member-if (lambda (regexp) (string-match regexp filename)) eclim-accepted-file-regexps) t)) diff --git a/tests/company-emacs-eclim-tests.el b/tests/company-emacs-eclim-tests.el index 50c1220..f504f19 100644 --- a/tests/company-emacs-eclim-tests.el +++ b/tests/company-emacs-eclim-tests.el @@ -33,5 +33,5 @@ (with-temp-buffer (insert (cdr (assoc 'content arg))) (goto-char (point-max)) - (flet ((eclim--completion-candidates () (cdr (assoc 'mocked-response arg)))) + (cl-flet ((eclim--completion-candidates () (cdr (assoc 'mocked-response arg)))) (company-emacs-eclim--candidates (cdr (assoc 'prefix arg)))))) From 6e0308b42d52da806cec227fcc0c3d1d1f4a0050 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 13:00:05 -0700 Subject: [PATCH 28/57] Small change to trigger Travis CI build --- History.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/History.txt b/History.txt index d00a747..a0e2f61 100644 --- a/History.txt +++ b/History.txt @@ -7,9 +7,9 @@ * added eclim-run-configuartion which runs a run configuration in the compilation buffer. * added eclim-java-generate-getter which generates a getter method - for the symbol at point. + for the symbol at point. * added eclim-java-generate-setter which generates a setter method - for the symbol at point. + for the symbol at point. * added eclim-java-refactor-move-class which allows moving a top level class or interface from one package to another. * added eclim-project-setting-set which can assign an Eclim project From 4d26ff5501109dff8b56a486779c51e1dea79136 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 13:05:05 -0700 Subject: [PATCH 29/57] Small change to trigger Travis CI build --- History.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/History.txt b/History.txt index a0e2f61..1dfc083 100644 --- a/History.txt +++ b/History.txt @@ -14,6 +14,8 @@ class or interface from one package to another. * added eclim-project-setting-set which can assign an Eclim project setting. + * Fixed some compiler warnings. Not all compiler warnings were fixed + since those changes could not be tested. == 0.3 From 86067cb982f7ee6b970104488a444914d127642d Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 13:25:23 -0700 Subject: [PATCH 30/57] Fix for test cases. Test cases need to use "flet" and cannot be replaced with "cl-flet". --- tests/company-emacs-eclim-tests.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/company-emacs-eclim-tests.el b/tests/company-emacs-eclim-tests.el index f504f19..4c79005 100644 --- a/tests/company-emacs-eclim-tests.el +++ b/tests/company-emacs-eclim-tests.el @@ -30,8 +30,9 @@ (should (equal (get-text-property 0 'eclim-meta (first candidates)) "getterWithParams(int x, int y, int z) : int - LibraryA")))) (defun emacs-eclim--candidates-for-temp-buffer (arg) + (message "arg: %s" arg) (with-temp-buffer (insert (cdr (assoc 'content arg))) (goto-char (point-max)) - (cl-flet ((eclim--completion-candidates () (cdr (assoc 'mocked-response arg)))) + (flet ((eclim--completion-candidates () (cdr (assoc 'mocked-response arg)))) (company-emacs-eclim--candidates (cdr (assoc 'prefix arg)))))) From 2fcac97f8a244f44437dbcadb0dddc2ae9e12cea Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 13:29:32 -0700 Subject: [PATCH 31/57] Forgot to remove debug statement in last commit. --- tests/company-emacs-eclim-tests.el | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/company-emacs-eclim-tests.el b/tests/company-emacs-eclim-tests.el index 4c79005..50c1220 100644 --- a/tests/company-emacs-eclim-tests.el +++ b/tests/company-emacs-eclim-tests.el @@ -30,7 +30,6 @@ (should (equal (get-text-property 0 'eclim-meta (first candidates)) "getterWithParams(int x, int y, int z) : int - LibraryA")))) (defun emacs-eclim--candidates-for-temp-buffer (arg) - (message "arg: %s" arg) (with-temp-buffer (insert (cdr (assoc 'content arg))) (goto-char (point-max)) From 4e4adcb80748c950dc12dce77dc3fd82126cbd22 Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 13:43:43 -0700 Subject: [PATCH 32/57] Now points to correct build status page. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a31a296..d0f9b10 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![License GPL 3][badge-license]](http://www.gnu.org/licenses/gpl-3.0.txt) -[![Build Status](https://travis-ci.org/senny/emacs-eclim.svg?branch=master)](https://travis-ci.org/senny/emacs-eclim) +[![Build Status](https://travis-ci.org/emacs-eclim/emacs-eclim.svg?branch=master)](https://travis-ci.org/emacs-eclim/emacs-eclim) [![MELPA](http://melpa.org/packages/emacs-eclim-badge.svg)](http://melpa.org/#/emacs-eclim) [![MELPA Stable](http://stable.melpa.org/packages/emacs-eclim-badge.svg)](http://stable.melpa.org/#/emacs-eclim) From da0648f8067dd70da3f954f1db89e084f4873e81 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Sat, 26 Dec 2015 22:13:07 +0000 Subject: [PATCH 33/57] Added new Gitter badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d0f9b10..be4cf36 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Overview -[![Join the chat at https://gitter.im/senny/emacs-eclim](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/senny/emacs-eclim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Join the chat at https://gitter.im/emacs-eclim/emacs-eclim](https://badges.gitter.im/emacs-eclim/emacs-eclim.svg)](https://gitter.im/emacs-eclim/emacs-eclim?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [Eclim](http://eclim.org) is an Eclipse plugin which exposes Eclipse features through a server interface. When this server is started, the From de6f6d7be1ba4e2d96cdbd05853f07ebbcd091cc Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 26 Dec 2015 15:23:59 -0700 Subject: [PATCH 34/57] Fixed a bad typo introduced earlier. --- eclim.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eclim.el b/eclim.el index 861f93f..e4309de 100644 --- a/eclim.el +++ b/eclim.el @@ -150,8 +150,7 @@ eclimd." for val = (second a) while arg append (if val (list arg (shell-quote-argument val)) (list arg)))))) -(defun ecl - im--parse-result (result) +(defun eclim--parse-result (result) "Parses the result of an eclim operation, raising an error if the result is not valid JSON." (if (string-match (rx string-start (zero-or-more (any " " "\n" "\t")) string-end) result) From 968da3c06d674417a46b2f6db7d0e8277c35141d Mon Sep 17 00:00:00 2001 From: Nelson Loyola Date: Sat, 14 Nov 2015 20:47:26 -0700 Subject: [PATCH 35/57] Fix for eclim-run-java-doc. Added eclim--call-process-no-parse to call the eclim server process and not parse the output it returns. Can be called with a variable number of arguments. --- eclim-java.el | 8 ++++---- eclim.el | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index ab2ff17..ad5c225 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -226,11 +226,11 @@ has been found." (defun eclim-run-java-doc () "Run Javadoc on current or all projects." (interactive) - (let ((project-list (mapcar 'third (eclim/project-list)))) + (let ((proj-list (eclim/project-list))) (if (y-or-n-p "Run Javadoc for all projects?") - (dolist (project project-list) - (eclim/execute-command "javadoc" ("-p" project))) - (eclim/execute-command "javadoc" "-p")) + (dotimes (i (length proj-list)) + (eclim--call-process-no-parse "javadoc" "-p" (rest (assq 'name (elt proj-list i))))) + (eclim--call-process-no-parse "javadoc" "-p")) (message "Javadoc creation finished."))) (defun eclim-java-format () diff --git a/eclim.el b/eclim.el index e4309de..7f2d397 100644 --- a/eclim.el +++ b/eclim.el @@ -177,13 +177,17 @@ where is the corresponding java name for this encoding." e e))) (error (match-string 1 result))) (t (error result))))))) +(defun eclim--call-process-no-parse (&rest args) + "Calls eclim with the supplied arguments but does not attempt to parse the result. " + (let ((cmd (eclim--make-command args))) + (when eclim-print-debug-messages (message "Executing: %s" cmd)) + (shell-command-to-string cmd))) + (defun eclim--call-process (&rest args) "Calls eclim with the supplied arguments. Consider using `eclim/execute-command' instead, as it has argument expansion, error checking, and some other niceties.." - (let ((cmd (eclim--make-command args))) - (when eclim-print-debug-messages (message "Executing: %s" cmd)) - (eclim--parse-result (shell-command-to-string cmd)))) + (eclim--parse-result (apply 'eclim--call-process-no-parse args))) (defvar eclim--currently-running-async-calls nil) From 4dcae5a50a8f636bdc6dcde7bdd2916eb8922c47 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Thu, 25 Feb 2016 21:12:12 +0800 Subject: [PATCH 36/57] add support to read source in jar file. --- eclim.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 76ea3a5..2615e2e 100644 --- a/eclim.el +++ b/eclim.el @@ -367,8 +367,18 @@ FILENAME is given, return that file's project name instead." (beginning-of-buffer) (kill-buffer old-buffer))))) +(defun eclim-java-archive-file (file) + (let ((eclim-auto-save nil)) + (eclim/with-results tmp-file ("archive_read" ("-f" file)) + tmp-file))) + (defun eclim--find-display-results (pattern results &optional open-single-file) - (let ((results (remove-if (lambda (result) (string-match (rx bol (or "jar" "zip") ":") (assoc-default 'filename result))) results))) + (let ((results + (loop for result across results + for file = (cdr (assoc 'filename result)) + if (string-match (rx bol (or "jar" "zip") ":") file) + do (setf (cdr (assoc 'filename result)) (eclim-java-archive-file file)) + collect result))) (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) (pop-to-buffer (get-buffer-create "*eclim: find")) (let ((buffer-read-only nil)) From b1e8af94360eeb620aa75c26d5e5ea7542c76239 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Fri, 26 Feb 2016 09:27:01 +0800 Subject: [PATCH 37/57] bug fix: return type should be array instead of list. --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 2615e2e..b33ac06 100644 --- a/eclim.el +++ b/eclim.el @@ -378,7 +378,7 @@ FILENAME is given, return that file's project name instead." for file = (cdr (assoc 'filename result)) if (string-match (rx bol (or "jar" "zip") ":") file) do (setf (cdr (assoc 'filename result)) (eclim-java-archive-file file)) - collect result))) + finally (return results)))) (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) (pop-to-buffer (get-buffer-create "*eclim: find")) (let ((buffer-read-only nil)) From 20d4000f3465889de3ddc74889141e44062e865d Mon Sep 17 00:00:00 2001 From: Vitalie Spinu Date: Fri, 18 Mar 2016 23:29:53 +0100 Subject: [PATCH 38/57] Enhance 'eclim-run-class' - add optional argument to edit eclim command - track last command per class and save them in buffer local alist - allow format specs (currently %c - class, %p - project, %r - project root) --- eclim-java.el | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index ad5c225..e17c775 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -105,6 +105,10 @@ Java documentation under Android docs, so don't forget to set (defvar eclim--is-completing nil) (defvar eclim-java-show-documentation-history nil) +(defvar eclim--run-class-history nil) +(defvar-local eclim--run-class-commands nil + "Alist of previously ran commands in current buffer. +See `eclim-run-class'.") (defun eclim/groovy-src-update (&optional save-others) "If `eclim-auto-save' is non-nil, save the current java @@ -641,13 +645,37 @@ sub block)." (if package-name (concat package-name "." class-name) class-name))) -(defun eclim-run-class () - "Run the current class." - (interactive) +(defun eclim-run-class (&optional editp) + "Run the current class. +If optional EDITP is non-nil, edit the command before running +it. The following format specs are substituted in the eclim command: + + %p project name + %c fully qualified class name + %r root directory of the current project + +See help string of 'eclim ? java` for available +arguments. Currently available arguments: + + java -p project [-d] [-c classname] [-w workingdir] + [-v vmargs] [-s sysprops] [-e envargs] [-a args] +" + (interactive "P") (if (not (string= major-mode "java-mode")) (message "Sorry cannot run current buffer.") - (compile (concat eclim-executable " -command java -p " (eclim-project-name) - " -c " (eclim-package-and-class))))) + (let* ((class (eclim-package-and-class)) + (hist-command (and eclim--run-class-commands + (assoc class eclim--run-class-commands))) + (command (or (cdr hist-command) + (concat eclim-executable " -command java -p %p -c %c")))) + (when editp + (setq command (read-string "Run command: " command 'eclim--run-class-history)) + (if hist-command + (setf (cdr hist-command) command) + (add-to-list 'eclim--run-class-commands (cons class command)))) + (compile (format-spec command `((?p . ,(eclim-project-name)) + (?c . ,class) + (?r . ,(eclim--project-dir)))))))) (defun eclim--java-junit-file (project file offset encoding) (concat eclim-executable From 241a1a2f97858a53eeee03e3310e9c933699c2b9 Mon Sep 17 00:00:00 2001 From: Vitalie Spinu Date: Thu, 17 Mar 2016 19:16:18 +0100 Subject: [PATCH 39/57] Add `eclim-java-browse-documentation-at-point` --- eclim-java.el | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/eclim-java.el b/eclim-java.el index e17c775..0641152 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -742,6 +742,41 @@ much faster than running mvn test -Dtest=TestClass#method." (eclim--problems-update-maybe)) (message "No automatic corrections found. Sorry"))))) +(defun eclim-java-browse-documentation-at-point (&optional arg) + "Browse the documentation of the element at point. +With the prefix ARG, ask for pattern. Pattern is a shell glob +pattern, not a regexp. Rely on `browse-url' to open user defined +browser." + (interactive "P") + (let ((symbol (if arg + (read-string "Glob Pattern: ") + (symbol-at-point))) + (proj-name (or (eclim-project-name) + (error "Not in Eclim project")))) + (if symbol + (let* ((urls (if arg + (eclim/execute-command "java_docsearch" + ("-n" proj-name) + "-f" + ("-p" symbol)) + (let ((bounds (bounds-of-thing-at-point 'symbol))) + (eclim/execute-command "java_docsearch" + ("-n" proj-name) + "-f" + ("-l" (- (cdr bounds) (car bounds))) + ("-o" (save-excursion + (goto-char (car bounds)) + (eclim--byte-offset))))))) + ;; convert from vector to list + (urls (append urls nil))) + (if urls + (let ((url (if (> (length urls) 1) + (eclim--completing-read "Browse: " (append urls nil)) + (car urls)))) + (browse-url url)) + (message "No documentation for '%s' found" symbol))) + (message "No element at point")))) + (defun eclim-java-show-documentation-for-current-element () "Displays the doc comments for the element at the pointers position." (interactive) @@ -804,7 +839,6 @@ much faster than running mvn test -Dtest=TestClass#method." (goto-char (point-min))) - (defun eclim-java-show-documentation-follow-link (link) (interactive) (let ((url (button-get link 'url))) From a370e86824839d71c1ab846a2a2b401994be0cfe Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sat, 12 Sep 2015 17:23:46 -0700 Subject: [PATCH 40/57] java-import: reorder things to avoid visible excursion to top of buffer. I found this distracting. The biggest culprit was the fact that we were running eclim import with point at the top of the buffer; also soft-revert-imports was reading a file in that state. Add a message to document that we imported, since it's now less noticeable. --- eclim-java.el | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/eclim-java.el b/eclim-java.el index 0641152..89a2b15 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -474,27 +474,29 @@ undo history." (delete-blank-lines) (insert "\n\n\n") (forward-line -2))))) - (save-excursion - (clear-visited-file-modtime) - (cut-imports) - (widen) - (insert - (let ((fname (buffer-file-name))) - (with-temp-buffer - (insert-file-contents fname) - (cut-imports)))) - (not-modified) - (set-visited-file-modtime)))) + (let* ((fname (buffer-file-name)) + (new-imports (with-temp-buffer + (insert-file-contents fname) + (cut-imports)))) + (save-excursion + (clear-visited-file-modtime) + (cut-imports) + (widen) + (insert new-imports) + (not-modified) + (set-visited-file-modtime))))) (defun eclim-java-import (type) "Adds an import statement for the given type, if one does not exist already." - (save-excursion - (goto-char (point-min)) + (unless (save-excursion + (goto-char (point-min)) + (beginning-of-buffer) + (re-search-forward (format "^import %s;" type) nil t)) (let ((revert-buffer-function 'eclim-soft-revert-imports)) - (when (not (re-search-forward (format "^import %s;" type) nil t)) - (eclim/execute-command "java_import" "-p" "-f" "-o" "-e" ("-t" type)) - (eclim--problems-update-maybe))))) + (eclim/execute-command "java_import" "-p" "-f" "-o" "-e" ("-t" type)) + (eclim--problems-update-maybe) + (message "Imported %s" type)))) (defun eclim-java-import-organize (&optional types) "Checks the current file for missing imports, removes unused imports and From 03873c4534ff76181d267e5b3813ba273413a932 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Tue, 29 Mar 2016 14:19:59 -0700 Subject: [PATCH 41/57] Open files in archives. Fixes http://github.com/senny/emacs-eclim/issues/250 The fix was twofold: 1) Fix regexp to allow jar:file:///Users... 2) Remove explicit filtering of results against archives. There was code to handle them, but it had been explicitly disabled presumably because of the problem above, which made it behave rather badly. This works beautifully when source jars if present, including all of the SDK. It also works with class files and autodisass-java-bytecode , though personally I don't find that very useful; better than bytecode, I suppose. --- eclim.el | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/eclim.el b/eclim.el index 7f2d397..9793d86 100644 --- a/eclim.el +++ b/eclim.el @@ -120,7 +120,8 @@ in the current workspace." ("utf-8-unix" . "utf-8") ("utf-8-emacs-unix" . "utf-8"))) -(defvar eclim--compressed-urls-regexp "^\\(\\(?:jar\\|file\\|zip\\)://\\)") +(defvar eclim--compressed-urls-regexp + "^\\(\\(?:jar\\|file\\|zip\\):\\(?:file:\\)?//\\)") (defvar eclim--compressed-file-path-replacement-regexp "\\\\") (defvar eclim--compressed-file-path-removal-regexp "^/") @@ -372,19 +373,19 @@ FILENAME is given, return that file's project name instead." (kill-buffer old-buffer))))) (defun eclim--find-display-results (pattern results &optional open-single-file) - (let ((results (cl-remove-if (lambda (result) (string-match (rx bol (or "jar" "zip") ":") (assoc-default 'filename result))) results))) - (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) - (pop-to-buffer (get-buffer-create "*eclim: find")) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) - (newline 2) - (insert (concat "eclim java_search -p " pattern)) - (newline) - (loop for result across results - do (insert (eclim--format-find-result result default-directory))) - (goto-char 0) - (grep-mode))))) + (if (and (= 1 (length results)) open-single-file) + (eclim--visit-declaration (elt results 0)) + (pop-to-buffer (get-buffer-create "*eclim: find")) + (let ((buffer-read-only nil)) + (erase-buffer) + (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) + (newline 2) + (insert (concat "eclim java_search -p " pattern)) + (newline) + (loop for result across results + do (insert (eclim--format-find-result result default-directory))) + (goto-char 0) + (grep-mode)))) (defun eclim--format-find-result (line &optional directory) (let ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line)))) From ce5b4621767a5a2f36395b570c72f4c260aaf61b Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Thu, 31 Mar 2016 09:22:43 -0700 Subject: [PATCH 42/57] When find returns multiple archive results, location should be the archive. This is not ideal (user has to go find the actual file ), but it's about the best we can do without major compile-mode surgery. There are no hooks for find-file and no archive file handler, and it's overkill to write one for this purpose. Visiting files in archive still works just fine when there's only one result, which IMHO is the major use case. --- eclim.el | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/eclim.el b/eclim.el index 9793d86..3c3598b 100644 --- a/eclim.el +++ b/eclim.el @@ -375,7 +375,7 @@ FILENAME is given, return that file's project name instead." (defun eclim--find-display-results (pattern results &optional open-single-file) (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) - (pop-to-buffer (get-buffer-create "*eclim: find")) + (pop-to-buffer (get-buffer-create "*eclim: find*")) (let ((buffer-read-only nil)) (erase-buffer) (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) @@ -388,14 +388,24 @@ FILENAME is given, return that file's project name instead." (grep-mode)))) (defun eclim--format-find-result (line &optional directory) - (let ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line)))) - (format "%s:%d:%d:%s\n" - (if converted-directory - (replace-regexp-in-string (concat (regexp-quote directory) "/?") "" converted-directory) - converted-directory) - (assoc-default 'line line) - (assoc-default 'column line) - (assoc-default 'message line)))) + (let* ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line))) + (parts (split-string converted-directory "!")) + (filename (replace-regexp-in-string + eclim--compressed-urls-regexp "" (first parts))) + (filename-in-dir (if directory + (replace-regexp-in-string (concat (regexp-quote directory) "/?") + "" filename) + filename))) + (if (cdr parts) + ;; Just put the jar path, since there's no easy way to instruct + ;; compile-mode to go into an archive. Better than nothing. + ;; TODO: revisit when an archive file-handler shows up somewhere. + (format "%s:1: %s\n" filename-in-dir (assoc-default 'message line)) + (format "%s:%d:%d:%s\n" + filename-in-dir + (assoc-default 'line line) + (assoc-default 'column line) + (assoc-default 'message line))))) (defun eclim--visit-declaration (line) (ring-insert find-tag-marker-ring (point-marker)) From 0f8195276d7cb2f02223ffdc2c6fa64e657d96df Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Tue, 29 Mar 2016 13:08:00 -0700 Subject: [PATCH 43/57] Default accepted file regexps should all be extensions (end-of-string). The biggest offender for me was that eclim-accepted would trigger on autosave files (#Foo.java#), which in turn tripped up eclimd with an error. But in general: (eclim--accepted-filename-p "hello.csv") -> t can't be right. --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 3c3598b..c7f749a 100644 --- a/eclim.el +++ b/eclim.el @@ -506,7 +506,7 @@ for example." (remove-hook 'after-save-hook 'eclim--after-save-hook 't))) (defcustom eclim-accepted-file-regexps - '("\\.java" "\\.js" "\\.xml" "\\.rb" "\\.groovy" "\\.php" "\\.c" "\\.cc" "\\.h" "\\.scala") + '("\\.java$" "\\.js$" "\\.xml$" "\\.rb$" "\\.groovy$" "\\.php$" "\\.c$" "\\.cc$" "\\.h$" "\\.scala$") "List of regular expressions that are matched against filenames to decide if eclim should be automatically started on a particular file. By default all files part of a project managed From 357b1bb46b33cb19bbd419ce67f2093a6a81d416 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sat, 12 Sep 2015 10:58:59 -0700 Subject: [PATCH 44/57] Completion: do not refresh problems while inserting the choice. The insertion can result in an import, which is a roundtrip to Eclipse. More often than not, the code is in bad shape at that point and it's annoying to have it underlined as you're writing it. --- eclim-completion.el | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/eclim-completion.el b/eclim-completion.el index 060caf1..0efdcb3 100644 --- a/eclim-completion.el +++ b/eclim-completion.el @@ -221,12 +221,13 @@ buffer." (backward-char))))) (defun eclim--completion-action (beg end) - (case major-mode - ('java-mode (eclim--completion-action-java beg end)) - ('groovy-mode (eclim--completion-action-java beg end)) - ((c-mode c++-mode) (eclim--completion-action-java beg end)) - ('nxml-mode (eclim--completion-action-xml beg end)) - (t (eclim--completion-action-default)))) + (let ((eclim--is-completing t)) ;; an import should not refresh problems + (case major-mode + ('java-mode (eclim--completion-action-java beg end)) + ('groovy-mode (eclim--completion-action-java beg end)) + ((c-mode c++-mode) (eclim--completion-action-java beg end)) + ('nxml-mode (eclim--completion-action-xml beg end)) + (t (eclim--completion-action-default))))) (defun eclim--render-doc (str) "Performs rudimentary rendering of HTML elements in From 3ae5c07ad9a11f6e0effa4e1a4f30975da47b1d6 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Sun, 30 Aug 2015 08:59:45 -0700 Subject: [PATCH 45/57] Completion: fix up corner cases in yas template computation. One was that nested parameters created a nested template, which did not make sense (filling template args before erasing the template altogether); it did not seem intended. The other was an empty arg list. Instead, use replace-regexp-in-string which takes care of some ugly details, and count levels to make sure we replace only on first. Added a test. The previous code fails the first two assertions. --- eclim-completion.el | 27 ++++++++++++++++++--------- tests/completion-tests.el | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 tests/completion-tests.el diff --git a/eclim-completion.el b/eclim-completion.el index 0efdcb3..3445e88 100644 --- a/eclim-completion.el +++ b/eclim-completion.el @@ -142,15 +142,24 @@ buffer." (defun eclim--completion-yasnippet-convert (completion) "Convert a completion string to a yasnippet template" - (apply #' concat - (loop for c across (replace-regexp-in-string ", " "," completion) - collect (case c - (40 "(${") - (60 "<${") - (44 "}, ${") - (41 "})") - (62 "}>") - (t (char-to-string c)))))) + (let ((level 0)) + (replace-regexp-in-string + ;; ORs: 1) avoid empty case; 2) eat spaces sometimes; 3) not when closing. + "()\\|[(<,] *\\|[)>]" + #'(lambda (m) + (let ((c (string-to-char m)) (repl m)) + (unless (string= m "()") + (when (memq c '(?\( ?<)) (incf level)) + (when (<= level 1) (setq repl (case c + (?\( "(${") + (?< "<${") + (?, "}, ${") + (?\) "})") + (?> "}>") + (t (error "RE/case mismatch"))))) + (when (memq c '(?\) ?>)) (decf level))) + repl)) + completion))) (defvar eclim--completion-start) diff --git a/tests/completion-tests.el b/tests/completion-tests.el new file mode 100644 index 0000000..efbec79 --- /dev/null +++ b/tests/completion-tests.el @@ -0,0 +1,18 @@ +(ert-deftest completion-yasnippet-convert () + ;; Nested params should *not* be nested templates. + (should (equal (eclim--completion-yasnippet-convert + "addAll(Collection c, T... elements)") + "addAll(${Collection c}, ${T... elements})")) + ;; Corner case: no argument. + (should (equal (eclim--completion-yasnippet-convert "toString()") + "toString()")) + + ;; Basic cases. + (should (equal (eclim--completion-yasnippet-convert + "printf(Locale l, String format, Object... args)") + "printf(${Locale l}, ${String format}, ${Object... args})")) + (should (equal (eclim--completion-yasnippet-convert "HashMap") + "HashMap<${K}, ${V}>")) + + ) + From de4be90e9b8ee6349e594c42b8889059482b4420 Mon Sep 17 00:00:00 2001 From: Shuai Lin Date: Mon, 4 Apr 2016 14:39:48 +0800 Subject: [PATCH 46/57] Added eclim-scala-find-declaration. Ref senny/emacs-eclim#81 --- eclim-scala.el | 47 +++++++++++++++++++++++++++++++++++++++++++++++ eclim.el | 1 + 2 files changed, 48 insertions(+) create mode 100644 eclim-scala.el diff --git a/eclim-scala.el b/eclim-scala.el new file mode 100644 index 0000000..eb33c46 --- /dev/null +++ b/eclim-scala.el @@ -0,0 +1,47 @@ +;; eclim-scala.el --- an interface to the Eclipse IDE. +;; +;; Copyright (C) 2009 Yves Senn +;; +;; 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 3 of the License, 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. If not, see . +;; +;;; Contributors +;; +;; - Shuai Lin +;; +;;; Conventions +;; +;; Conventions used in this file: Name internal variables and functions +;; "eclim--", and name eclim command invocations +;; "eclim/command-name", like eclim/project-list. + +;;* Eclim Scala + +(require 'eclim-java) + +(defun eclim-scala-find-declaration () + "Find and display the declaration of the scala identifier at point." + (interactive) + (let ((i (eclim--java-identifier-at-point t))) + (eclim/with-results hits + ( + "scala_search" + "-n" + "-f" + ("-o" (car i)) + ("-l" (length (cdr i))) + ("-e" "utf-8") + ) + (eclim--find-display-results (cdr i) hits t)))) + +(provide 'eclim-scala) diff --git a/eclim.el b/eclim.el index c7f749a..d32731c 100644 --- a/eclim.el +++ b/eclim.el @@ -574,6 +574,7 @@ the use of eclim to java and ant files." (require 'eclim-project) (require 'eclim-java) +(require 'eclim-scala) (require 'eclim-ant) (require 'eclim-maven) (require 'eclim-problems) From b6daef5acf3e8cece565f410853ec4eebb4f8925 Mon Sep 17 00:00:00 2001 From: Ovidiu Gheorghioiu Date: Mon, 11 Apr 2016 09:16:35 -0700 Subject: [PATCH 47/57] Completion: allow the user to customize insertion. I think yas is problematic for completion because: * Completion begins by spitting out a potentially long method signature * Aborting from yas can't resume, so you're left with above * The code can be in a non-sensical (for Eclipse) state for quite a long time. This can prevent further coding aids. * Yas is intrusive and wants to be a minor mode everywhere. The default insertion is hardly better. So one should at least have the option to do something different. I put in a simple (and sample) alternative that simply erases arguments, which is already an improvement, but I have something better for the next commit. --- eclim-completion.el | 25 +++++++++++++++++++++++-- tests/completion-tests.el | 13 +++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/eclim-completion.el b/eclim-completion.el index 3445e88..979ddf1 100644 --- a/eclim-completion.el +++ b/eclim-completion.el @@ -50,6 +50,13 @@ (defvar eclim--completion-candidates nil) +(defvar eclim-insertion-functions nil + "Use one of these functons when inserting a completion in +preference to yasnippet or raw insertion. Each will be called +with a yas template and should return nil iff it cannot do the +insertion (e.g. wrong mode). For example, `eclim-completion-insert-empty' +removes all arguments before inserting.") + (defun eclim--complete () (setq eclim--is-completing t) (unwind-protect @@ -75,6 +82,7 @@ (setq eclim--is-completing nil))) (defun eclim--completion-candidates-filter (c) + "Rejects completion candidate C (non-nil return) in certain situations." (case major-mode ((xml-mode nxml-mode) (or (search "XML Schema" c) (search "Namespace" c))) @@ -201,9 +209,12 @@ buffer." (package (if (and rest (string-match "\\w+\\(\\.\\w+\\)*" rest)) rest nil)) (template (eclim--completion-yasnippet-convert insertion))) (delete-region beg end) - (if (and eclim-use-yasnippet template (featurep 'yasnippet) yas-minor-mode) + (unless (loop for f in eclim-insertion-functions thereis + (funcall f template)) + (if (and eclim-use-yasnippet template + (featurep 'yasnippet) yas-minor-mode) (yas/expand-snippet template) - (insert insertion)) + (insert insertion))) (when package (eclim-java-import (concat package "." (substring insertion 0 (or (string-match "[<(]" insertion) @@ -257,4 +268,14 @@ completion candidates list." (when doc (eclim--render-doc doc)))) +(defun eclim-completion-insert-empty (template) + "Insert a completion erasing arguments, leaving point inside argument list +or outside if empty. Meant for `eclim-insertion-functions'." + (save-match-data + (if (not (string-match "${.*}" template)) + (insert template) + (insert (substring template 0 (match-beginning 0))) + (save-excursion (insert (substring template (match-end 0)))))) + t) + (provide 'eclim-completion) diff --git a/tests/completion-tests.el b/tests/completion-tests.el index efbec79..1626e8a 100644 --- a/tests/completion-tests.el +++ b/tests/completion-tests.el @@ -16,3 +16,16 @@ ) +(ert-deftest completion-insert-empty-usable () + (let ((eclim-insertion-functions '(eclim-completion-insert-empty))) + (cl-letf (((symbol-function 'eclim-java-import) #'ignore)) + (with-temp-buffer + (insert "method(String arg1, List arg2) - some.Class") + (eclim--completion-action-java (line-beginning-position) (point)) + (should (equal (thing-at-point 'line) "method()")) + (should (looking-at ")")) + (erase-buffer) + (insert "method2()") + (should (equal (thing-at-point 'line) "method2()")) + (should (eolp)) + )))) From 0c9a492e9a83f7039b59f0b0da5dabc0f4dac083 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Tue, 3 May 2016 10:07:34 +0800 Subject: [PATCH 48/57] merge from https://github.com/emacs-eclim/emacs-eclim/pull/23 --- eclim.el | 65 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/eclim.el b/eclim.el index b33ac06..3c3aa3b 100644 --- a/eclim.el +++ b/eclim.el @@ -120,7 +120,8 @@ in the current workspace." ("utf-8-unix" . "utf-8") ("utf-8-emacs-unix" . "utf-8"))) -(defvar eclim--compressed-urls-regexp "^\\(\\(?:jar\\|file\\|zip\\)://\\)") +(defvar eclim--compressed-urls-regexp + "^\\(\\(?:jar\\|file\\|zip\\):\\(?:file:\\)?//\\)") (defvar eclim--compressed-file-path-replacement-regexp "\\\\") (defvar eclim--compressed-file-path-removal-regexp "^/") @@ -367,40 +368,40 @@ FILENAME is given, return that file's project name instead." (beginning-of-buffer) (kill-buffer old-buffer))))) -(defun eclim-java-archive-file (file) - (let ((eclim-auto-save nil)) - (eclim/with-results tmp-file ("archive_read" ("-f" file)) - tmp-file))) - (defun eclim--find-display-results (pattern results &optional open-single-file) - (let ((results - (loop for result across results - for file = (cdr (assoc 'filename result)) - if (string-match (rx bol (or "jar" "zip") ":") file) - do (setf (cdr (assoc 'filename result)) (eclim-java-archive-file file)) - finally (return results)))) - (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) - (pop-to-buffer (get-buffer-create "*eclim: find")) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) - (newline 2) - (insert (concat "eclim java_search -p " pattern)) - (newline) - (loop for result across results - do (insert (eclim--format-find-result result default-directory))) - (goto-char 0) - (grep-mode))))) + (if (and (= 1 (length results)) open-single-file) + (eclim--visit-declaration (elt results 0)) + (pop-to-buffer (get-buffer-create "*eclim: find*")) + (let ((buffer-read-only nil)) + (erase-buffer) + (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) + (newline 2) + (insert (concat "eclim java_search -p " pattern)) + (newline) + (loop for result across results + do (insert (eclim--format-find-result result default-directory))) + (goto-char 0) + (grep-mode)))) (defun eclim--format-find-result (line &optional directory) - (let ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line)))) - (format "%s:%d:%d:%s\n" - (if converted-directory - (replace-regexp-in-string (concat (regexp-quote directory) "/?") "" converted-directory) - converted-directory) - (assoc-default 'line line) - (assoc-default 'column line) - (assoc-default 'message line)))) + (let* ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line))) + (parts (split-string converted-directory "!")) + (filename (replace-regexp-in-string + eclim--compressed-urls-regexp "" (first parts))) + (filename-in-dir (if directory + (replace-regexp-in-string (concat (regexp-quote directory) "/?") + "" filename) + filename))) + (if (cdr parts) + ;; Just put the jar path, since there's no easy way to instruct + ;; compile-mode to go into an archive. Better than nothing. + ;; TODO: revisit when an archive file-handler shows up somewhere. + (format "%s:1: %s\n" filename-in-dir (assoc-default 'message line)) + (format "%s:%d:%d:%s\n" + filename-in-dir + (assoc-default 'line line) + (assoc-default 'column line) + (assoc-default 'message line))))) (defun eclim--visit-declaration (line) (ring-insert find-tag-marker-ring (point-marker)) From 74c170db9c3bd5dfe65d88c0e9c513a8ba993cae Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Wed, 4 May 2016 10:54:31 +0800 Subject: [PATCH 49/57] update problems after a fix. --- eclim-java.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eclim-java.el b/eclim-java.el index 1ddd205..6bcfe88 100644 --- a/eclim-java.el +++ b/eclim-java.el @@ -595,7 +595,8 @@ much faster than running mvn test -Dtest=TestClass#method." "-f" ("-l" line) ("-o" offset) - ("-a" choice))) + ("-a" choice)) + (eclim--problems-update-maybe)) (message "No automatic corrections found. Sorry"))))) (defun eclim-java-show-documentation-for-current-element () From ed109ff5175968ecf483f73c3fbcc24ba0afacd1 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 17:37:51 +0800 Subject: [PATCH 50/57] make emacs can navigate codes in a jar file. --- eclim.el | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/eclim.el b/eclim.el index 3c3aa3b..1caf20c 100644 --- a/eclim.el +++ b/eclim.el @@ -347,7 +347,8 @@ FILENAME is given, return that file's project name instead." (if filename (get-project-name filename) (or eclim--project-name - (and buffer-file-name (setq eclim--project-name (get-project-name buffer-file-name))))))) + (and buffer-file-name (setq eclim--project-name (get-project-name buffer-file-name))) + (and buffer-file-name (gethash buffer-file-name eclim-projects-for-archive-file)))))) (defun eclim--find-file (path-to-file) (if (not (string-match-p "!" path-to-file)) @@ -368,20 +369,34 @@ FILENAME is given, return that file's project name instead." (beginning-of-buffer) (kill-buffer old-buffer))))) +(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) +(defun eclim-java-archive-file (file) + (let ((eclim-auto-save nil)) + (eclim/with-results tmp-file ("archive_read" ("-f" file)) + ;; archive file's project should be same as current context. + (setf (gethash tmp-file eclim-projects-for-archive-file) (eclim-project-name)) + tmp-file))) + (defun eclim--find-display-results (pattern results &optional open-single-file) - (if (and (= 1 (length results)) open-single-file) + (let ((results + (loop for result across results + for file = (cdr (assoc 'filename result)) + if (string-match (rx bol (or "jar" "zip") ":") file) + do (setf (cdr (assoc 'filename result)) (eclim-java-archive-file file)) + finally (return results)))) + (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) - (pop-to-buffer (get-buffer-create "*eclim: find*")) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) - (newline 2) - (insert (concat "eclim java_search -p " pattern)) - (newline) - (loop for result across results - do (insert (eclim--format-find-result result default-directory))) - (goto-char 0) - (grep-mode)))) + (pop-to-buffer (get-buffer-create "*eclim: find")) + (let ((buffer-read-only nil)) + (erase-buffer) + (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) + (newline 2) + (insert (concat "eclim java_search -p " pattern)) + (newline) + (loop for result across results + do (insert (eclim--format-find-result result default-directory))) + (goto-char 0) + (grep-mode))))) (defun eclim--format-find-result (line &optional directory) (let* ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line))) @@ -415,7 +430,9 @@ FILENAME is given, return that file's project name instead." (defun eclim--project-current-file () (or eclim--project-current-file (setq eclim--project-current-file - (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))))) + (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))) + ;; command archive_read will extract archive file to /tmp directory, which is out of current project directory. + buffer-file-name)) (defun eclim--byte-offset (&optional text) ;; TODO: restricted the ugly newline counting to dos buffers => remove it all the way later From e26323c3156fa900fe28a1ebbee92c7c8dbbefcc Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 17:51:51 +0800 Subject: [PATCH 51/57] make emacs can navigate codes in a jar file. --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 1caf20c..f516c16 100644 --- a/eclim.el +++ b/eclim.el @@ -432,7 +432,7 @@ FILENAME is given, return that file's project name instead." (setq eclim--project-current-file (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))) ;; command archive_read will extract archive file to /tmp directory, which is out of current project directory. - buffer-file-name)) + (and buffer-file-name (gethash buffer-file-name eclim-projects-for-archive-file) buffer-file-name))) (defun eclim--byte-offset (&optional text) ;; TODO: restricted the ugly newline counting to dos buffers => remove it all the way later From 71c23ffffc7d90ce89f444132b6c81962441cb3f Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 18:11:04 +0800 Subject: [PATCH 52/57] fix code style --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index f516c16..091161b 100644 --- a/eclim.el +++ b/eclim.el @@ -369,7 +369,7 @@ FILENAME is given, return that file's project name instead." (beginning-of-buffer) (kill-buffer old-buffer))))) -(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) +(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) (defun eclim-java-archive-file (file) (let ((eclim-auto-save nil)) (eclim/with-results tmp-file ("archive_read" ("-f" file)) From 549dc0a0be17d11122486fbfcada507788e6d80f Mon Sep 17 00:00:00 2001 From: James Chochlinski Date: Thu, 31 Dec 2015 12:59:17 -0500 Subject: [PATCH 53/57] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index be4cf36..dfcd285 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Development has moved to https://github.com/emacs-eclim/emacs-eclim + [![License GPL 3][badge-license]](http://www.gnu.org/licenses/gpl-3.0.txt) [![Build Status](https://travis-ci.org/emacs-eclim/emacs-eclim.svg?branch=master)](https://travis-ci.org/emacs-eclim/emacs-eclim) [![MELPA](http://melpa.org/packages/emacs-eclim-badge.svg)](http://melpa.org/#/emacs-eclim) From 00d0a925e71bf36fdbfb0da7a35f001be92d7c27 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Fri, 17 Jun 2016 11:54:52 +0800 Subject: [PATCH 54/57] fix conflict with upstream. --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index d32731c..04718a9 100644 --- a/eclim.el +++ b/eclim.el @@ -121,7 +121,7 @@ in the current workspace." ("utf-8-emacs-unix" . "utf-8"))) (defvar eclim--compressed-urls-regexp - "^\\(\\(?:jar\\|file\\|zip\\):\\(?:file:\\)?//\\)") + "^\\(\\(?:jar\\|file\\|zip\\):\\(?:file:\\)?//\\)") (defvar eclim--compressed-file-path-replacement-regexp "\\\\") (defvar eclim--compressed-file-path-removal-regexp "^/") From 125384e759b5399a8486f816f1298b76f73cb2c1 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 17:37:51 +0800 Subject: [PATCH 55/57] make emacs can navigate codes in a jar file. --- eclim.el | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/eclim.el b/eclim.el index 04718a9..39e7524 100644 --- a/eclim.el +++ b/eclim.el @@ -351,7 +351,8 @@ FILENAME is given, return that file's project name instead." (if filename (get-project-name filename) (or eclim--project-name - (and buffer-file-name (setq eclim--project-name (get-project-name buffer-file-name))))))) + (and buffer-file-name (setq eclim--project-name (get-project-name buffer-file-name))) + (and buffer-file-name (gethash buffer-file-name eclim-projects-for-archive-file)))))) (defun eclim--find-file (path-to-file) (if (not (string-match-p "!" path-to-file)) @@ -372,20 +373,34 @@ FILENAME is given, return that file's project name instead." (goto-char (point-min)) (kill-buffer old-buffer))))) +(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) +(defun eclim-java-archive-file (file) + (let ((eclim-auto-save nil)) + (eclim/with-results tmp-file ("archive_read" ("-f" file)) + ;; archive file's project should be same as current context. + (setf (gethash tmp-file eclim-projects-for-archive-file) (eclim-project-name)) + tmp-file))) + (defun eclim--find-display-results (pattern results &optional open-single-file) - (if (and (= 1 (length results)) open-single-file) + (let ((results + (loop for result across results + for file = (cdr (assoc 'filename result)) + if (string-match (rx bol (or "jar" "zip") ":") file) + do (setf (cdr (assoc 'filename result)) (eclim-java-archive-file file)) + finally (return results)))) + (if (and (= 1 (length results)) open-single-file) (eclim--visit-declaration (elt results 0)) - (pop-to-buffer (get-buffer-create "*eclim: find*")) - (let ((buffer-read-only nil)) - (erase-buffer) - (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) - (newline 2) - (insert (concat "eclim java_search -p " pattern)) - (newline) - (loop for result across results - do (insert (eclim--format-find-result result default-directory))) - (goto-char 0) - (grep-mode)))) + (pop-to-buffer (get-buffer-create "*eclim: find")) + (let ((buffer-read-only nil)) + (erase-buffer) + (insert (concat "-*- mode: eclim-find; default-directory: " default-directory " -*-")) + (newline 2) + (insert (concat "eclim java_search -p " pattern)) + (newline) + (loop for result across results + do (insert (eclim--format-find-result result default-directory))) + (goto-char 0) + (grep-mode))))) (defun eclim--format-find-result (line &optional directory) (let* ((converted-directory (replace-regexp-in-string "\\\\" "/" (assoc-default 'filename line))) @@ -420,7 +435,9 @@ FILENAME is given, return that file's project name instead." (defun eclim--project-current-file () (or eclim--project-current-file (setq eclim--project-current-file - (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))))) + (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))) + ;; command archive_read will extract archive file to /tmp directory, which is out of current project directory. + buffer-file-name)) (defun eclim--byte-offset (&optional text) ;; TODO: restricted the ugly newline counting to dos buffers => remove it all the way later From c1d141480de6a1f551eb833ef6eb01084a4c1427 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 17:51:51 +0800 Subject: [PATCH 56/57] make emacs can navigate codes in a jar file. --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 39e7524..11e5aa7 100644 --- a/eclim.el +++ b/eclim.el @@ -437,7 +437,7 @@ FILENAME is given, return that file's project name instead." (setq eclim--project-current-file (eclim/execute-command "project_link_resource" ("-f" buffer-file-name))) ;; command archive_read will extract archive file to /tmp directory, which is out of current project directory. - buffer-file-name)) + (and buffer-file-name (gethash buffer-file-name eclim-projects-for-archive-file) buffer-file-name))) (defun eclim--byte-offset (&optional text) ;; TODO: restricted the ugly newline counting to dos buffers => remove it all the way later From 7314476ec738b9d188ef9974fa05c7a8b0e90502 Mon Sep 17 00:00:00 2001 From: Xu Jingtao Date: Mon, 13 Jun 2016 18:11:04 +0800 Subject: [PATCH 57/57] fix code style --- eclim.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclim.el b/eclim.el index 11e5aa7..4391767 100644 --- a/eclim.el +++ b/eclim.el @@ -373,7 +373,7 @@ FILENAME is given, return that file's project name instead." (goto-char (point-min)) (kill-buffer old-buffer))))) -(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) +(defvar eclim-projects-for-archive-file (make-hash-table :test 'equal)) (defun eclim-java-archive-file (file) (let ((eclim-auto-save nil)) (eclim/with-results tmp-file ("archive_read" ("-f" file))