Skip to content
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

Inconsistent auto completion #50

Closed
dhaigit opened this issue Jan 11, 2022 · 14 comments
Closed

Inconsistent auto completion #50

dhaigit opened this issue Jan 11, 2022 · 14 comments
Labels
improvement Something needs to be improved

Comments

@dhaigit
Copy link

dhaigit commented Jan 11, 2022

The auto completion is kind of iffy. Sometimes it shows sometimes it doesn't. Looking at the ide messages, I see that it isn't always able to process the classpath and ends up just being able to recognize only keywords and local variables.

A lot of the times, it even shows nothing. With each letter we enter, the idelogs view spits out:

JavaAutoComplete: Completion error java.io.IOException: Stream closed
    at java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433)
    at java.io.OutputStream.write(OutputStream.java:116)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:126)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer.consume(StreamMessageConsumer.java:69)
 Caused by: org.eclipse.lsp4j.jsonrpc.JsonRpcException: java.io.IOException: Stream closed
    at org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer.consume(StreamMessageConsumer.java:72)
    at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.request(RemoteEndpoint.java:161)
    at org.eclipse.lsp4j.jsonrpc.services.EndpointProxy.invoke(EndpointProxy.java:91)
    at java.lang.reflect.Proxy.invoke(Proxy.java:913)
    at $Proxy5.completion(Unknown Source)
    at com.itsaky.androidide.language.java.JavaAutoComplete.getAutoCompleteItems(JavaAutoComplete.java:52)
 Caused by: java.util.concurrent.ExecutionException: org.eclipse.lsp4j.jsonrpc.JsonRpcException: java.io.IOException: Stream closed
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:359)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1921)
    at com.itsaky.androidide.language.java.JavaAutoComplete.getAutoCompleteItems(JavaAutoComplete.java:60)
    at io.github.rosemoe.editor.widget.EditorAutoCompleteWindow$MatchThread.run(EditorAutoCompleteWindow.java:350)
@itsaky
Copy link
Member

itsaky commented Jan 11, 2022

The java language server is started in the JVM and not ART. We use a process builder to start the language server process. This does not work so good.

I'm planning of using something else for completion, or fall back to using JDK 8's compiler.

@dhaigit dhaigit changed the title inconsistent auto complete Inconsistent auto completion Jan 12, 2022
@itsaky
Copy link
Member

itsaky commented Jan 17, 2022

@dhaigit The language server is no longer dependent on the JVM. The java compiler is now included in the IDE and the language server too. I made some improvements in the java completion. Could you please check it?

@dhaigit
Copy link
Author

dhaigit commented Jan 18, 2022

Finally you have updated after many days, lol.

The new auto completion system seems to work better and more consistently. Still, there is a problem that I can't pinpoint at exactly when or why it happened but I think it did sometimes (not every time) while the IDE was doing a build and I was typing some letters to test out the auto completion.

These messages were from the IDE logs screen:

JavaCompletionProvider: Complete at MainActivity.java(29,10)... 
CompletionMatchThread: Error computing completion java.lang.RuntimeException: Compiler us already in use.
    at com.itsaky.lsp.java.compiler.ReusableCompiler.getTask(ReusableCompiler.java:110)
    at com.itsaky.lsp.java.compiler.CompileBatch.batchTask(CompileBatch.java:137)
    at com.itsaky.lsp.java.compiler.CompileBatch.<init>(CompileBatch.java:59)
    at com.itsaky.lsp.java.compiler.JavaCompilerService.doCompile(JavaCompilerService.java:113)
    at com.itsaky.lsp.java.compiler.JavaCompilerService.loadCompile(JavaCompilerService.java:101)
    at com.itsaky.lsp.java.compiler.JavaCompilerService.compileBatch(JavaCompilerService.java:135)
    at com.itsaky.lsp.java.compiler.JavaCompilerService.compile(JavaCompilerService.java:354)
    at com.itsaky.lsp.java.providers.CompletionProvider.compileAndComplete(CompletionProvider.java:149)
    at com.itsaky.lsp.java.providers.CompletionProvider.complete(CompletionProvider.java:129)
    at com.itsaky.lsp.java.providers.CompletionProvider.complete(CompletionProvider.java:111)
    at com.itsaky.androidide.language.java.JavaAutoComplete.lambda$getAutoCompleteItems$0(JavaAutoComplete.java:59)
    at com.itsaky.androidide.language.java.JavaAutoComplete$$ExternalSyntheticLambda1.get(Unknown Source:6)
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1625)
    at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1617)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:285)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1152)
    at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1990)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1938)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
 Caused by: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Compiler us already in use.
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:359)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1921)
    at com.itsaky.androidide.language.java.JavaAutoComplete.getAutoCompleteItems(JavaAutoComplete.java:62)
    at io.github.rosemoe.editor.widget.EditorAutoCompleteWindow$MatchThread.run(EditorAutoCompleteWindow.java:348)

At that moment, auto completion did not show anything while I was typing. (not even when the building process was done)

I managed to make it work again by selecting quick run or one of the two assemble options (after waiting for the ongoing one to finish first of course)

Also, maybe you could tweak to make completion suggestions appear a little more snappy.

Lastly, the Diagnostics view never showed anything.

@dhaigit
Copy link
Author

dhaigit commented Jan 19, 2022

Also, maybe you could tweak to make completion suggestions appear a little more snappy.

I just noticed something while playing around with the auto completion.

Open a simple project and make sure auto completion is working, then try this:

  1. Type "Toas"
  2. You should see "android.widget.Toast" appear in the list below the cursor.
  3. Now, tap backspace to delete "s"
  4. Type "s" again
  5. Keep deleting "s" and typing "s" quickly

You will notice that the big red icon "C" (for class) at the start of the list item jitters (but the rest of the line does not)

Auto completion should appear smoother if that is fixed.

Maybe we could find some more ways to improve it. I think quick and instant auto completion would make a very positive user experience.

@itsaky
Copy link
Member

itsaky commented Jan 19, 2022

That is because the height of the icon widget is set dynamically to match the height of the completion item view. See this.

But I'll fix it.

@dhaigit
Copy link
Author

dhaigit commented Jan 19, 2022

Yes! It appears snappier now without the jittery completion results list.

Some more related thoughts:

When I open a project, I would like to be able to start typing and see the completion results as soon as possible. Currently, the IDE is always trying to run assembleDebug the moment we open a project, and it usually takes a while (also depends on the size of the project of course) before I could use auto completion.

Do we really need to assembleDebug every time we open a project? We do need to quickly analyze the project for possible compile errors so we could fix them, but probably not doing a build yet.

So maybe we could shorten the time from opening a project to the time the auto completion starting to work.

@itsaky
Copy link
Member

itsaky commented Jan 21, 2022

The initializeIDEProject task is executed after the java compilation task. This initialize task allows us to get the list of dependencies (including other project details). Then the paths of those dependency jars are passed to the java language server. So, yes, that build is needed.

There is another way of getting the details we need. We could use the Gradle Tooling API. But we'll be able to use it only on the JVM. That's because the tooling API uses class loaders.

@dhaigit
Copy link
Author

dhaigit commented Jan 24, 2022

Yes! It appears snappier now without the jittery completion results list.

I just noticed the icon "F" still needs to be fixed.

@itsaky
Copy link
Member

itsaky commented Jan 27, 2022

I didn't get any issues with the 'F' letter in completion window. Any specific way to reprodice it?

(Accidentally closed the issue).

@itsaky itsaky closed this as completed Jan 27, 2022
@itsaky itsaky reopened this Jan 27, 2022
@dhaigit
Copy link
Author

dhaigit commented Jan 27, 2022

Any specific way to reprodice it?

It's "F" for "Field" so any results list with fields in it would do. I think starting with "Me..." has plenty of those.

  1. Open a simple project and make sure autocompletion is working.
  2. Type "Med" (without quotes)
  3. Tap backspace to delete "d"
  4. Type "d"
  5. Keep deleting and typing "d"

Any list item that contains a field will jitter.

@dhaigit
Copy link
Author

dhaigit commented Jan 27, 2022

Even with the latest build, autocompletion still isn't 100% consistent. It will still sometimes fail with "...already in use" message. Here are my workarounds (that seem to work for me) that I have shared in another post, in order to continue using the IDE when it happens.

  1. Keep checking it out until it's working. (e.g., keep typing and deleting "t" repeatedly) Be patient because it could take a while. This works most of the time, but there will be times when no matter how many times we repeat doing, it still won't work. That's when we should try number 2.
  2. Run a build again. Use number 1 to test to see when it's starting to work. With the latest build, I've always managed to get it working again after this method.

I wish we could just open a project and start coding right away with perfect autocompletion, but according to Itsaky, we can't avoid that (long) initial build (that sometimes causes autocompletion failure) for now.

@dhaigit
Copy link
Author

dhaigit commented Jan 29, 2022

Any list item that contains a field will jitter.

With more testing, I have found that the jittering is caused not only specifically by having a field but anything that has the added "deprecated since..." info below it.

@itsaky
Copy link
Member

itsaky commented Jan 29, 2022

Okay. I think that happens because we check the API details in the completion adapter itself (getView method). Takes a few milliseconds to compute. Maybe we could animate it?

Computing it in completion provider itself will make the completions a bit slower.

@dhaigit
Copy link
Author

dhaigit commented Jan 30, 2022

It flickers because of the switching back and forth between GONE and VISIBLE.
I have two suggestions for choice:

  1. Don't set the API info view to GONE. Instead, let it say something like "API info not available" in grayed out text.

  2. Move API info somewhere else. For example:

   C   Toast                         Since
class android.widget.Toast API 1

(or maybe API info on the right and kind info on the left)

@itsaky itsaky added the improvement Something needs to be improved label Feb 1, 2022
@itsaky itsaky closed this as completed Mar 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement Something needs to be improved
Projects
None yet
Development

No branches or pull requests

2 participants