cursive-ide / cursive

Cursive: The IDE for beautiful Clojure code
588 stars 7 forks source link

Suggestion - add namespace :require from anywhere in a file #1430

Open mtruyens opened 8 years ago

mtruyens commented 8 years ago

Probably fifty times per day, I find myself leaving my edit location, scrolling to the top of the file, adding a specific namespace to the :require list, and then finally going back to the initial edit location.

It would be great if a dialog box was added which you could call with a shortcut, which would have three boxes (name of the namespace to require, :as field, and :refer field), and which would then add what is required to the top of the file. Ideally the first box would help with searching/selecting the right namespace, e.g. using autosuggest.

Similar for the :import section at the top of the file.

cursive-ide commented 8 years ago

Your suggestion is a good one. There's actually already some of this support in Cursive, although not in the form you suggest. They're mostly linked to autocomplete. I thought I had documented these, but looking at the documentation I see that I have not.

Cursive indexes the namespaces used in your project and the libraries it uses, and records aliases that are used for them. It then uses those to auto-require when you complete. So if you type (str/tr|) (where | is the caret), if you have referred clojure.string with the alias str anywhere in your project you'll see a completion item like this:

screen shot 2016-06-06 at 10 08 59 pm

Note that the completion item says from clojure.string :as str. If you select that autocompletion, Cursive will complete the name and automatically add a [clojure.string :as str] item to your ns form. Of the 50 times a day I also add requires, I do it like this and I never even see the ns form. There are some cases when it doesn't work - the first time you require an ns anywhere in your project, and if you want to do something more esoteric like :refer something (although I'm planning to fix that too).

This works similarly for classes and imports. In fact, I'm surprised this is a problem for you because it should be almost impossible to ignore Cursive's nagging to import things. If you autocomplete, say, ArrayLi| Cursive will insert the (:import [java.util ArrayList]) item for you. If you have a reference to an unresolved class in your file, Cursive will also show a popup prompting to import it.

mtruyens commented 8 years ago

Thanks for the fast reply!

The :import is indeed much less important (it was a hasty afterthought of mine), so you are right that it's not a real necessity.

As for the :require, I indeed "discovered" the automatic-addition-through-aliases-feature, even without documentation. However, the problem with that feature is that I tend to use :refer very frequently. The reasons are twofold: (1) creative lazyness (coming up with a good, short and unique abbreviation for every single namespace you :require is hard in a large codebase...); (2) clean looks and conciseness: if you use a :require'd function or var twenty times in a given namespace, then I find it much cleaner -- and shorter! -- to not have a namespace prefix every single time.

So it could be me, but I suspect there are many other users out there who :refer without assigning an alias, and do not consider the :refer esoteric...

cursive-ide commented 8 years ago

Sure, perhaps esoteric is the wrong word, but it's certainly less common. I'm planning to do something similar to what's there already for aliases, i.e. record which symbols you like to refer and then offer those in the completion too. However there will always be cases when that doesn't work, and a popup as you suggest would be a good idea too.

mtruyens commented 8 years ago

Super! (And, in general, thanks again for the tool that has made my daily development life so much more smooth...)

SOberhoff commented 8 years ago

There are some cases when it doesn't work - the first time you require an ns anywhere in your project

This use case is quite painful actually. I often want to add a call to clojure.tools.trace. And I tend to remove those when I'm done. I have actually caught myself thinking about a bug for prolonged lengths of time before deciding to add a trace, simply because I was too lazy to edit the :require field at first.