Completion contributor freezes UI if at least one element isn't added immediately

已回答

Let's say we have a CompletionContributor, ordered as 

first, before commitCompletion

with the following code:

resultSet
.withPrefixMatcher(typeStr)
.withRelevanceSorter(sorter(CommitTypeElementWeigher))
.also { rs ->
extensionPoint.getExtensions(project)
.flatMap { runWithCheckCanceled { it.getCommitTypes(typeStr) } }
.map { CommitTypePsiElement(it, psiManager) }
.mapIndexed { i, psi -> CommitTypeLookupElement(i, psi) }
.forEach { rs.addElement(it) }
}

 

Where

it.getCommitTypes(typeStr)

will return elements after a long running operation.

 

When an element is inserted immediately in the Lookup

CompletionProgressIndicator#addItemToLookup

is called and the myFreezeSemaphore Semaphore is released. Thus flow will resume from

CodeCompletionHandlerBase#trySynchronousCompletion {
...

if (indicator.blockingWaitForFinish(timeout))

 

However, if no elements are added immediately

blockingWaitForFinish

will block for a couple seconds, freezing the UI.

What can we do to avoid this?

0

Currently, nothing. This is an intended behavior to allow for auto-inserting single item without confusing the user by showing it.

0

Looking at the sources I've seen there exist also "non-real" LookupElement(s), which theoretically should not be shown in the Lookup.

Does it work that way? And can I produce one?

Thanks!

0

Which non-real lookup elements do you mean?

0

The

LookupElementPresentation

class exposes the

isReal

method, and its documentation says "whether the presentation is requested to actually render lookup element on screen, or just to estimate its width". I could use an invisible LookupElement as initial element.

But maybe I misunderstood.

0

This only applies to the presentation, not lookup elements themselves. Their `render` method can be called several times, for purposes that you cite here.

0

Oh ok, nevermind then.

Thank you.

0

请先登录再写评论。