emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/geiser-kawa 05e1eaa 029/119: Add initial support for compl


From: Philip Kaludercic
Subject: [nongnu] elpa/geiser-kawa 05e1eaa 029/119: Add initial support for completing java packages
Date: Sun, 1 Aug 2021 18:30:32 -0400 (EDT)

branch: elpa/geiser-kawa
commit 05e1eaa69ab06d916dfeb23dac87aca2bac11db0
Author: spellcard199 <spellcard199@protonmail.com>
Commit: spellcard199 <spellcard199@protonmail.com>

    Add initial support for completing java packages
---
 README.org                                  |  12 ++-
 elisp/geiser-kawa-complete-java.el          | 110 ++++++++++++++++++----------
 pom.xml                                     |   2 +-
 src/main/java/kawageiser/java/Complete.java |  77 +++++++++++--------
 4 files changed, 122 insertions(+), 79 deletions(-)

diff --git a/README.org b/README.org
index f919cf3..dc3cb66 100644
--- a/README.org
+++ b/README.org
@@ -31,7 +31,8 @@ Only versions of Kawa > 3.1 are supported, mostly due to the 
fact that before th
             - info: using emacs' Info-mode
             - epub: using emacs' eww browser
 - kawa- and java-specific:
-    - completion for java classes' fields and methods accessed through 
colon-notation: don't expect java-grade reliability
+    - completion for java's field and method names accessed through 
colon-notation (don't expect java-grade reliability)
+    - completion for java's package and class names
 
 ** Unsupported features
 
@@ -46,9 +47,6 @@ geiser-related:
 - callees
 - generic-methods
 
-kawa- and java-specific:
-- completion for java package names and class names
-
 ** Try geiser-kawa without modifying your emacs configuration
 
 1. Get Emacs and [[https://github.com/cask/cask][Cask]] and make them 
available through your $PATH
@@ -66,11 +64,11 @@ To try geiser-kawa you need neither Maven nor Kawa:
 - =mvnw= ([[https://github.com/takari/maven-wrapper][maven-wrapper]]) takes 
care of downloading a project-specific Maven version
 - kawa-geiser has [[https://gitlab.com/groups/kashell/][Kawa's master branch]] 
as one of its dependencies. When =quickstart.el= calls =./mvnw package= 
(wrapped by =geiser-kawa-compile-java-dependencies=), it produces a jar that 
includes kawa-geiser and all its dependencies, including Kawa itself.
 
-** About completion for java classes' fields and methods
+** About completion for java's fields, methods and packages (that's what =fmp= 
stands for in the function names)
 
-The whole project is in a persistent "experimental" state, but this part even 
more so.
+The whole project is in a persistent "experimental" state, but this part even 
more so because it's based on assumptions I'm not sure about.
 
-The main interactive elisp function is 
=geiser-kawa-complete-java-fom-at-point=. It's not bound to a key by default.
+The main interactive elisp function is 
=geiser-kawa-complete-java-fmp-at-point=. It's not bound to a key by default.
 
 For this to work you have to:
 - use Kawa's type annotations: rememver that the Kawa compiler mostly trusts 
you and can't actually check
diff --git a/elisp/geiser-kawa-complete-java.el 
b/elisp/geiser-kawa-complete-java.el
index 55eac45..2e4b2b8 100644
--- a/elisp/geiser-kawa-complete-java.el
+++ b/elisp/geiser-kawa-complete-java.el
@@ -43,51 +43,81 @@
                 (list (string-trim
                        (car (split-string (geiser-eval--retort-output
                                            geiser-answer)
-                             "\t")))))
+                                          "\t")))))
       (geiser-eval--retort-result geiser-answer))))
 
-(defun geiser-kawa-complete-java--user-choice
-    (compl-for-class modifiers
-     field-or-method completions
-     before-cursor)
-  "`for-class' is the class that owns the field or methods in
-`completions'.
-`field-or-method' should be either 'field or 'method, but it's not
-checked.
-`completions' is a list of names (strings) that the user can pick
-from."
-  (completing-read
-   (concat "(" (string-join modifiers " ") " " field-or-method ") "
-           compl-for-class "."
-           ;; "- Exp  : " compl-for-expr "\n"
-           ;; ": "
-           )
-   completions
-   nil
-   nil
-   before-cursor))
-
-(defun geiser-kawa-complete-java--user-choice-data
-    (compl-data)
+(defun geiser-kawa-complete-java--user-choice--field-or-method
+    (fm-compl-data)
+  ;; fm stands for field or method.
   (let ((compl-for-class
-         (cadr (assoc "compl-for-class" compl-data)))
+         (cadr (assoc "compl-for-class" fm-compl-data)))
         (modifiers
-         (cadr (assoc "modifiers" compl-data)))
+         (cadr (assoc "modifiers" fm-compl-data)))
         (field-or-method
-         (cadr (assoc "field-or-method" compl-data)))
-        (completions
-         (cadr (assoc "completions" compl-data)))
-        ;; unused
+         (cadr (assoc "field-or-method-or-package" fm-compl-data)))
+        (names
+         (cadr (assoc "names" fm-compl-data)))
         (before-cursor
-         (cadr (assoc "before-cursor" compl-data)))
+         (cadr (assoc "before-cursor" fm-compl-data)))
         ;; unused
         (after-cursor
-         (cadr (assoc "after-cursor" compl-data))))
-    (geiser-kawa-complete-java--user-choice
-     compl-for-class modifiers
-     field-or-method completions
+         (cadr (assoc "after-cursor" fm-compl-data))))
+
+    (completing-read
+     (concat "(" (string-join modifiers " ") " " field-or-method ") "
+             compl-for-class "."
+             ;; "- Exp  : " compl-for-expr "\n"
+             ;; ": "
+             )
+     names
+     nil
+     nil
      before-cursor)))
 
+(defun geiser-kawa-complete-java--user-choice--package
+    (package-compl-data)
+  (let ((field-or-method-or-package
+         (cadr (assoc "field-or-method-or-package" package-compl-data)))
+        (package-name
+         (cadr (assoc "package-name" package-compl-data)))
+        (names
+         (cadr (assoc "names" package-compl-data)))
+        (before-cursor
+         (cadr (assoc "before-cursor" package-compl-data)))
+        ;; unused
+        (after-cursor
+         (cadr (assoc "after-cursor" package-compl-data))))
+    (completing-read
+     (concat "(" field-or-method-or-package ") "
+             (if (string-equal "" package-name)
+                 "(root.)"
+               (concat package-name ".")))
+     (mapcar (lambda (name)
+               (string-remove-prefix
+                "." (string-remove-prefix package-name name)))
+             names)
+     nil
+     nil
+     (string-remove-prefix
+      "." (string-remove-prefix package-name before-cursor))
+     )))
+
+(defun geiser-kawa-complete-java--user-choice-dispatch
+    (compl-data)
+  (let ((compl-for (cadr (assoc "field-or-method-or-package"
+                                compl-data))))
+    (cond ((equal compl-for "FIELD")
+           (geiser-kawa-complete-java--user-choice--field-or-method
+            compl-data))
+          ((equal compl-for "METHOD")
+           (geiser-kawa-complete-java--user-choice--field-or-method
+            compl-data))
+          ((equal compl-for "PACKAGE")
+           (geiser-kawa-complete-java--user-choice--package
+            compl-data))
+          (t (error (format "[Unexpected condition] compl-for: %s"
+                            (prin1-to-string compl-for)))))))
+
 (defun geiser-kawa-complete-java--code-point-from-toplevel ()
   (let* (reg-beg
          reg-end
@@ -119,24 +149,24 @@ from."
      `("code-str"     . ,code-str)
      `("cursor-index" . ,cursor-index))))
 
-(defun geiser-kawa-complete-java-fom-at-point ()
+(defun geiser-kawa-complete-java-fmp-at-point ()
   (interactive)
-  "Complete java field or method at point"
+  "Complete java field or method or package (fmp) at point"
 
   (let* ((code-and-point-data
-         (geiser-kawa-complete-java--code-point-from-toplevel))
+          (geiser-kawa-complete-java--code-point-from-toplevel))
          (code-str     (cdr (assoc "code-str"
                                    code-and-point-data)))
          (cursor-index (cdr (assoc "cursor-index"
                                    code-and-point-data)))
          (compl-data (geiser-kawa-complete-java--get-data
                       code-str cursor-index))
-         (user-choice (geiser-kawa-complete-java--user-choice-data
+         (user-choice (geiser-kawa-complete-java--user-choice-dispatch
                        compl-data)))
     (when (word-at-point)
       (if (looking-back ":" (- (point) 2))
           (kill-word 1)
-          (kill-word -1)))
+        (kill-word -1)))
     (insert user-choice)
     ;; (when (not (equal (word-at-point) user-choice))
     ;;   (kill-word 1)
diff --git a/pom.xml b/pom.xml
index 3d11883..c571396 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,7 +63,7 @@
         <dependency>
             <groupId>com.gitlab.spellcard199</groupId>
             <artifactId>kawa-devutil</artifactId>
-            <version>0c12c104505e4965308b9214486f2051af152360</version>
+            <version>593d76dcb9a6b21e120f754b0b5f53dcfd4e17e0</version>
         </dependency>
 
         <!-- https://mvnrepository.com/artifact/org.testng/testng -->
diff --git a/src/main/java/kawageiser/java/Complete.java 
b/src/main/java/kawageiser/java/Complete.java
index 6be9291..deaec3b 100644
--- a/src/main/java/kawageiser/java/Complete.java
+++ b/src/main/java/kawageiser/java/Complete.java
@@ -8,22 +8,16 @@ package kawageiser.java;
 import gnu.expr.Language;
 import gnu.lists.IString;
 import gnu.lists.LList;
-import gnu.lists.Pair;
 import gnu.mapping.Environment;
-import gnu.mapping.Procedure1or2;
-import gnu.mapping.Procedure3;
 import gnu.mapping.Procedure4;
 import gnu.math.IntNum;
 import kawadevutil.complete.*;
 
-import java.io.File;
-import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 public class Complete extends Procedure4 {
 
@@ -64,36 +58,57 @@ public class Complete extends Procedure4 {
             return LList.Empty;
         } else {
             CompletionDataForJava complData = complDataMaybe.get();
-            if (complData.getClass().equals(CompletionDataForJavaField.class)) 
{
-                CompletionDataForJavaField complDataForField = 
(CompletionDataForJavaField) complData;
-            } else if 
(complData.getClass().equals(CompletionDataForJavaMethod.class)) {
-                CompletionDataForJavaMethod complDataForMethod = 
(CompletionDataForJavaMethod) complData;
+            LList res = null;
+            if (complData.getClass().equals(CompletionDataForJavaField.class)
+                    || 
complData.getClass().equals(CompletionDataForJavaMethod.class)) {
+                res = toLList((CompletionDataForJavaFOM) complData);
+            } else if 
(complData.getClass().equals(CompletionDataForJavaPackage.class)) {
+                res = toLList((CompletionDataForJavaPackage) complData);
             } else {
                 throw new Error("Bug spotted.");
             }
+            return gnu.kawa.functions.Format.format("~S", res);
+        }
+    }
 
-            String completionsForClass = complData.getForClass().getName();
-            CompletionDataForJava.FieldOrMethod fieldOrMethod = 
complData.getFieldOrMethod();
-            List<String> names = (List<String>) 
complData.getNames().stream().distinct().collect(Collectors.toList());
-            String beforeCursor = 
complData.getCursorMatcher().getCursorMatch().getBeforeCursor();
-            String afterCursor = 
complData.getCursorMatcher().getCursorMatch().getAfterCursor();
-            // I don't know why it says "unchecked call" when using 
complData.getRequiredModifiers().stream()
-            ArrayList<String> modifiers = new ArrayList<>();
-            for (Object modifier : complData.getRequiredModifiers()) {
-                modifiers.add(modifier.toString());
-            }
-
-            java.util.List<LList> res = Arrays.asList(
-                    LList.list2("compl-for-class", completionsForClass),
-                    LList.list2("modifiers", LList.makeList(modifiers)),
-                    LList.list2("field-or-method", fieldOrMethod.toString()),
-                    LList.list2("completions", LList.makeList(names)),
-                    LList.list2("before-cursor", beforeCursor),
-                    LList.list2("after-cursor", afterCursor)
-            );
-            LList resLList = LList.makeList(res);
-            return gnu.kawa.functions.Format.format("~S", resLList);
+    private static LList toLList(CompletionDataForJavaFOM complData) {
+        String completionsForClass = complData.getForClass().getName();
+        // I don't know why it says "unchecked call" when using 
complData.getRequiredModifiers().stream()
+        ArrayList<String> modifiers = new ArrayList<>();
+        for (Object modifier : complData.getRequiredModifiers()) {
+            modifiers.add(modifier.toString());
         }
+
+        ArrayList<LList> res = new ArrayList<>(getCommonData(complData));
+        res.addAll(Arrays.asList(
+                LList.list2("compl-for-class", completionsForClass),
+                LList.list2("modifiers", LList.makeList(modifiers))
+        ));
+        return LList.makeList(res);
+
+    }
+
+    private static LList toLList(CompletionDataForJavaPackage complData) {
+        ArrayList<LList> res = new ArrayList<>(getCommonData(complData));
+        res.addAll(Arrays.asList(
+                LList.list2("package-name", complData.getPinfo().getName())
+        ));
+        return LList.makeList(res);
+    }
+
+    private static List<LList> getCommonData(CompletionDataForJava complData) {
+        CompletionDataForJava.FieldOrMethodOrPackage fieldOrMethod = 
complData.getFieldOrMethodOrPackage();
+        List<String> names = (List<String>) 
complData.getNames().stream().distinct().collect(Collectors.toList());
+        String beforeCursor = 
complData.getCursorMatcher().getCursorMatch().getBeforeCursor();
+        String afterCursor = 
complData.getCursorMatcher().getCursorMatch().getAfterCursor();
+
+        java.util.List<LList> res = Arrays.asList(
+                LList.list2("field-or-method-or-package", 
fieldOrMethod.toString()),
+                LList.list2("names", LList.makeList(names)),
+                LList.list2("before-cursor", beforeCursor),
+                LList.list2("after-cursor", afterCursor)
+        );
+        return res;
     }
 
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]