-
-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
General stability fixes and arglist support in completion hover #375
General stability fixes and arglist support in completion hover #375
Conversation
See PR description for details.
The link to About-Calva-Jack-in should be (I believe!) to Connect-Calva-to-Your-Project
Fix broken link to Wiki
@PEZ This is ready for testing/merging. |
This is a generally good idea. There are many first time experiences with Calva that get a bit strange because the namespaces are not loaded. However, I think this needs to be a setting. Much as I try to avoid settings, there are quite a few users who have opposed to make namespace loading the default behaviour. They have workflows where their namespaces contain code that can take very long to run, and will be hit badly if Calva runs the code just because a file is opened. I think this setting should default to loading the namespaces. |
Can I haz Maybe |
@PEZ Another option is to make the info call in the user namespace if the namespace of the open file does not exist in the repl. |
Tested the autoload namespace thing now, and love it. However, in a |
I agree that we might do better than just skip loading anything. I still suggest that for now we add a setting that defaults to true and if it is false then the user has to load the file, just as today. We can add an issue for refining it. But it is your call, since your PR. 😄 |
Take a good look at all the changes so I can take care of the PR on Monday. |
Tested:
|
I've skimmed the code changes now. Looks good to me. What do you say, @kstehn ? |
src/nrepl/jack-in.ts
Outdated
// REPL window open commands if needed. | ||
commands["Disconnect from the REPL server"] = "calva.disconnect"; | ||
commands["Disonnect from the REPL server"] = "calva.disconnect"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be Disconnect
or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kstehn Corrected that.
src/providers/hover.ts
Outdated
if(client) { | ||
await util.loadFileIfNamespaceNotExist(document); | ||
let res = await client.info(ns, text); | ||
// I really don't not why result.arglists-str does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for that is the -
Otherwise it would not be possible to do something like this
res.a - res.b
i think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kstehn Okay. gg
// Format the actual docstring | ||
if (doc) { | ||
result += doc.replace(/\s\s+/g, ' '); | ||
if (documentation && documentation != "") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jumping in here, so please disregard.
This is basically the same as https://github.com/BetterThanTomorrow/calva/pull/375/files#diff-9205a2ccff45e74e74a392042d83efe8R25 Could/should it be extracted into a docUtils
(or some such, naming is hard)?
if (this.state.deref().get('connected')) { | ||
let client = util.getSession(util.getFileType(document)); | ||
|
||
if (util.getConnectedState()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My knowledge of typescript is limited, but I'd suggest something like:
// in-ns util
function with-connection(f, ...) {
function (args) {
if (util.getConnectedState() {
return f(args);
} else {
return "Please connect to a REPL to retrieve information."
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I'd recommend decoupling this from the hover
functionality itself.
It seems as provideHover
"bottoms out" in
return new vscode.Hover(someString)
So I'd suggest:
calculateHoverString(document, position) {
const text = util.getWordAtPosition(document, position);
const ns = util.getNamespace(document);
const client = util.getSession(util.getFileType(document));
if(client) {
await util.loadFileIfNamespaceNotExist(document);
let res = await client.info(ns, text);
// I really don't not why result.arglists-str does
// not work, but it leads to an compiler error.
if (res.ns && res.doc) {
return this.formatDocString(res.ns + "/" + res.name, res["arglists-str"] || [], res.doc)
}
if (res.ns) {
return this.formatDocString(res.ns + "/" + res.name, res["arglists-str"] || [], "No documentation available");
} else {
return this.formatDocString(text, "", "No information available");
}
}
return this.formatDocString(text, "", "No information available");
}
async provideHover(document, position, _) {
const message = util.withConnection(calculateHoverString(document, position);
return new score.Hover(message);
}
If you go in this direction, you could potentially unit-test calculateHoverString
@@ -190,6 +190,29 @@ function getWordAtPosition(document, position) { | |||
return text; | |||
} | |||
|
|||
async function loadFileIfNamespaceNotExist(doc) { | |||
|
|||
if (getConnectedState()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest writing this in a guard-clause fashion, and also to possibly throw, since I would assume that it's an error to try loading a ns that we cannot load. Also, by throwing exceptions, we can inform the caller of why we didn't succeed:
async function loadFileIfNamespaceDoesNotExist(doc) {
if (!getConnectedState()) {
throw new Error("Not connected");
}
const document = getDocument(doc);
if (!document) {
throw new Error("Couldn't find " + doc)
}
const client = getSession(getFileType(document));
if (!client) {
throw new Error("No client available for " + document);
}
const ns = getNamespace(document);
const nsList = await client.listNamespaces([]);
if (nsList['ns-list'] && nsList['ns-list'].includes(ns)) {
return;
}
const name = getFileName(document);
const dir = document.hasOwnProperty('fileName') ? path.dirname(document.fileName) : '';
await client.loadFile(document.getText(), name, dir);
}
src/utilities.ts
Outdated
return state.deref().get('launching'); | ||
} | ||
|
||
function setLaunchingState(value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is
function setLaunchingState(value) {
vscode.commands.executeCommand("setContext", "calva:launching", Boolean(value));
state.cursor.set('launching', value);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@slipset Good point!
Many thanks for chipping in, @slipset ! |
…' of github.com:cfehse/calva into fix/general-stability-fixes-arglist-in-completion-hover
I change the mechanism to enable the info data to be retrieved (autoload namespace thing): if the namespace does not exists in the REPL it is now simply created by evaluating a form like
I choose the corresponding REPL for the document using
Yes you can. gg
I would not do this because I find it more robust to surely have any supported project file in the workspace to activate the extension. I incorporated some of your suggestions - thanks for that. Refactor out some code into a new helper unit and decouple some of the hover and completion code I would like to be done in another PR. This is large enough. |
src/utilities.ts
Outdated
@@ -190,24 +190,19 @@ function getWordAtPosition(document, position) { | |||
return text; | |||
} | |||
|
|||
async function loadFileIfNamespaceNotExist(doc) { | |||
async function CreateNamespaceFromDocumentIfNotExists(doc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We name functions using camelCase
, in our undocumented code convention. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! Changed...
Fixes #238, #366, #367, #368
Introduces the following change(s):
HoverProvider
andCalvaCompletionItemProvider
.workspaceContains:**/project.clj
,workspaceContains:**/shadow-cljs.edn
andworkspaceContains:**/deps.edn
to allow the extension to be activated faster.state.initProjectDir()
function to usevscode.workspace.workspaceFolders![0]
as a second starting point in case no file is open in the workspace is not multi-root. This conforms to our wiki entry about the supported workspace layout. Made the function robust if no document is defined.fs.watch()
inexecuteJackInTask()
. These exception is according to thefs
team by design if a given directory to watch does not exists or the underlying filesystem (network filesystems for example) does not support the operation. During the jack-in process this may occur if the user selects the wrong type of project - e.g.Leiningen + shadow-cljs
if there is no shadow support in the project. In case the exception is detected, the jack-in task is canceled.file
anduntitled
schemes to all document selectors. These are the vscode supported schemes. The addition prevents the vscode warning messageExtension '<extension>' uses a document selector without scheme. Learn more about...
.Tested on
I have:
dev
branch. (Or have specific reasons to target some other branch.)master
. (Sorry for the nagging.)[Unreleased]
entry inCHANGELOG.md
, linking the issue(s) that the PR is addressing.Ping: @PEZ, @kstehn