I appreciate your thoughtful response -- I wish some of the other tooling could do this level of analysis but I can only imagine the time it took Colin to implement :-). Like I mentioned in my response to him -- I'm going to have to seriously consider leaving the cult of emacs not only for Java but maybe Clojure too :-).
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Wednesday, October 17, 2018 3:56 AM, Aaron Cohen <aa...@assonance.org> wrote: > This seems like it could be done using threading. > > (-> "my-string" > (.ch <-- completion should give you good results here, for only String > methods > > (-> (new MyType) > (. <-- completion should give you only methods of MyType > > ; One interesting case is the following: > (def foo "hello") > > ; foo's type isn't known, so would need to be hinted > (-> ^String foo > (.to <-- good completions again, because of the type hint > > I think you won't be able to get all the way to your jvm macro, but likely > pretty close, and it's much more idiomatic... > > The doto macro is also useful in a similar way, and often what you want when > using some of the more byzantine java libraries. > > (All of the above works in Cursive, I'm not sure about how it works in CIDER, > but I assume it's equivalent). > > --Aaron > > On Tue, Oct 16, 2018 at 8:30 PM 'somewhat-functional-programmer' via Clojure > <clojure@googlegroups.com> wrote: > >> Comments inline... I really appreciate you taking the time to look at this. >> I think I am still imprecise in my language -- I hope the comments below >> doesn't come across as too tedious :-)... >> >> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >> On Tuesday, October 16, 2018 7:46 PM, Timothy Baldridge >> <tbaldri...@gmail.com> wrote: >> >>> As you say, this is a limitation in the code completer. In Cursive this >>> problem doesn't exist to this extent, when I type `(.get` the completer >>> responds with a list of methods and classes that could be completed to that >>> method, starting with classes in the namespace I'm currently editing. >> >> I think we are saying the same thing here. I believe compliment (the >> library CIDER/other clojure tooling uses for code completion) does what we >> are describing (showing Java methods and fields from multiple Java types >> that are imported into the namespace currently being edited (or type hinted >> in locals/function definitions). My point is I want more -- I want the >> completion list to only include methods and fields from the type I as a >> developer know that I have. >> >> Like a Java IDE: >> MyType a = new MyType(); >> Now typing "a." yields just completions valid for MyType, and not 5 other >> types I've used nearby. >> >>> Yes, this takes static analysis, or perhaps some indexing and >>> introspection. But changing the syntax is never really going to gain >>> traction here, as manually typing the name of every method just so my >>> editor can produce a list seems like me conforming to my tool rather than >>> my tool learning to work with me. >> >> Just to make sure I'm completely clear -- I'm *not* advocating a change to >> clojure lang -- only proposing a macro/library. The prototype macro I wrote >> simply transforms the (Type:method ...) syntax into the (. instance-expr >> member-symbol) that (.method ...) macroexpands into anyhow. This is not >> intended to replace (.method obj args) notation. >> >> I'm not sure what you mean by "manually typing the name of every method just >> so my editor can produce a list". >> >> The way this works is, you type "(MyType:" and get presented with a list of >> completions that are *only* applicable to MyType -- there's no manually >> typing lists of methods and fields anywhere. And, the way this works for me >> in CIDER, I type "(My<TAB>" and I get "(MyType", then I add a ":", and now I >> get completions just for MyType -- it also shows me the Java signature of >> the methods as I highlight a potential completion. There's no manually >> seeding the list anywhere... >> >>> The imported classes in the current namespace are stored in the mappings >>> attribute. It seems like an editor should be able to install hooks into >>> that and index the methods on the classes to provide this feedback. >>> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java#L123 >> >> Yes I agree -- and I believe that's exactly what the existing tooling >> already does -- I just want more precision. >> >> Some of my motivation has been working with monstrously large class >> libraries in Java. GIS libraries in Java are notoriously class/method heavy >> and after importing many of these classes into a namespace, completion that >> cannot narrow down to the exact type I'm using for the reasons we agree on >> -- simply is painful to work with. >> >>> On Tue, Oct 16, 2018 at 1:26 PM 'somewhat-functional-programmer' via >>> Clojure <clojure@googlegroups.com> wrote: >>> >>>> I apologize for diving into a solution in my first email -- let me give a >>>> little more of the background as to what I am trying to accomplish. >>>> >>>> I'm proposing an additional syntax for Java interop for the purpose of >>>> allowing support for more precise code-completion of Java fields and >>>> methods in Clojure tooling. The new syntax proposal is why I'm emailing >>>> this list rather than directly going to the project owners of the projects >>>> I've modified to support this. If there is high resistance to any >>>> additional syntax for Java interop, there's not much reason to try to >>>> convince the project owners of cider-nrepl and compliment to support >>>> something just for my personal use :-). >>>> >>>> Note also that when I say "propose additional syntax" I do not mean >>>> "please add this to clojure lang" -- I've implemented this as a couple of >>>> macros which should be the way the language normally gets extended. I >>>> just want feedback and am trying to gauge interest, because if no one >>>> wants this then it's not worth any of the additional effort to "publish" >>>> it -- I'll just manage it as a utility library for myself. >>>> >>>> So when I say more precise code completion for Java fields and methods, I >>>> mean this: >>>> - I want my development environment or REPL to know the type of the Java >>>> object I'm operating on so it can limit the completion list to fields or >>>> methods that are valid for that particular type. >>>> - For example, when typing: >>>> (.get >>>> I'd somehow like my environment to know that I want code completion >>>> for a Java object of type "this.is.AType" >>>> and as such, I would only see methods or fields starting with ".get" >>>> for that type >>>> What happens for me now, is I see some Java methods and fields >>>> starting with ".get" but on a number of Java objects (and not a complete >>>> list at that). >>>> (I believe the tooling looks through symbols in your namespace, >>>> finds Java symbols, and starts pulling methods and fields from any of >>>> them). Using only the text "(.get" the environment cannot know what I'm >>>> trying to do. >>>> >>>> Now the tooling could do static code analysis, it could look at the >>>> surrounding top-level form, and say, what are the locals, are they >>>> type-hinted, and only show me Java methods and fields from locals that >>>> have type hints. Even this approach though, which is complex and error >>>> prone to implement, still doesn't limit my list to just methods and fields >>>> of "this.is.AType" unless I only have one type-hinted local symbol. >>>> >>>> So... if we had a syntax that looked like: >>>> (Type:method obj? args) >>>> My tooling becomes drastically simpler. Now my tooling is fed: >>>> "Type:method" >>>> And code completion simply becomes: >>>> - Look up Type in my active namespace symbols (to find out if it's a >>>> Java type I've imported) (or it could simply be fully qualified, both are >>>> supported) >>>> - Use reflection to find a list of candidate fields and methods >>>> No static analysis required, simple to implement. >>>> >>>> It's so simple to implement that I hastily pasted in my >>>> proof-of-concept/prototype code in the first message -- which hopefully is >>>> easy for folks to just try. I hope that people will try it and think: >>>> this would be great if I were writing a lot of Java interop code -- or >>>> better yet, give suggestions on how to improve it. >>>> >>>> So try this by: >>>> 1) Install boot (or update it via "boot -u") >>>> 2) Make a new temp directory and navigate to it >>>> 3) Run the first command from my prior email in bash >>>> 4) Paste in the code snippet to the resulting rebel-readline repl >>>> 5) Try the limited completion right in rebel-readline >>>> 6) Connect using your cider-nrepl based tooling (CIDER, inf-clojure, >>>> vim-fireplace, others?), and try it from one of those tools. I've only >>>> tested with CIDER -- in my CIDER I get eldoc, help at symbol at point (I >>>> wish this displayed javadoc inline), and better code completion. >>>> 7) Feedback! :-) >>>> >>>> I also realize that this stuff is complex enough that there might be some >>>> set of CIDER settings that solve this problem that I just simply don't >>>> know about or didn't find. Love to hear about how others get better Java >>>> interop code completion. Some of my clojure projects involve lots of Java >>>> interop and this would have been sooooo nice to have while writing those >>>> projects (in my opinion). >>>> >>>> I think there are other advantages to this style syntax (besides >>>> supporting code completion): >>>> - Right now I have the jvm macro throw an error if it can't find the >>>> java symbol -- so you would get a compile time error rather than just a >>>> reflection warning about a non-existent java method. >>>> - In addition to making easier to *write* Java interop, I think it makes >>>> it easier to *read* Java interop >>>> I immediately know the Java type while reading the code, no need to >>>> hunt down the type annotations elsewhere. I've been writing Java since >>>> Java 1.1 and I still like the reminder of what class a method is from. >>>> >>>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >>>> On Tuesday, October 16, 2018 4:23 PM, Timothy Baldridge >>>> <tbaldri...@gmail.com> wrote: >>>> >>>>> I don't understand why this is needed. Why can't cider code complete on >>>>> the normal method format? What's the problem this code is trying to solve? >>>>> >>>>> Timothy >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clojure@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient with >>>>> your first post. >>>>> To unsubscribe from this group, send email to >>>>> [clojure+unsubscr...@googlegroups.com](mailto:clojure%2bunsubscr...@googlegroups.com) >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to the Google Groups >>>>> "Clojure" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send an >>>>> email to clojure+unsubscr...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clojure@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> [clojure+unsubscr...@googlegroups.com](mailto:clojure%2bunsubscr...@googlegroups.com) >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google Groups >>>> "Clojure" group. >>>> To unsubscribe from this group and stop receiving emails from it, send an >>>> email to clojure+unsubscr...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>> >>> -- >>> “One of the main causes of the fall of the Roman Empire was that–lacking >>> zero–they had no way to indicate successful termination of their C >>> programs.” >>> (Robert Firth) >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> [clojure+unsubscr...@googlegroups.com](mailto:clojure%2bunsubscr...@googlegroups.com) >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google Groups >>> "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> [clojure+unsubscr...@googlegroups.com](mailto:clojure%2bunsubscr...@googlegroups.com) >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.