@@ -171,51 +171,55 @@ public void dispose() {
171
171
public SQLQueryCompletionContext obtainCompletionContext (int offset ) {
172
172
SQLScriptItemAtOffset scriptItem = null ;
173
173
Position requestPosition = new Position (offset );
174
- do {
175
- final long requestStamp = System .currentTimeMillis ();
176
- CompletableFuture <Long > expectedParsingSessionFinishStamp ;
177
- synchronized (this .syncRoot ) {
178
- if (scriptItem == null || this .queuedForReparse .size () == 0 ) {
179
- scriptItem = this .context .findScriptItem (offset - 1 );
180
- if (scriptItem != null ) { // TODO consider statements separation which is ignored for now
181
- if (scriptItem .item .isDirty ()) {
182
- // awaiting reparse, so proceed to release lock and wait for the job to finish, then retry
183
- } else {
184
- return this .prepareCompletionContext (scriptItem , requestPosition .getOffset ());
185
- }
186
- } else {
187
- // no script items here, so fallback to offquery context
188
- break ;
189
- }
190
- }
191
-
174
+ try {
175
+ UIUtils .syncExec (() -> {
192
176
try {
193
177
assert this .document != null ;
194
178
this .document .addPosition (requestPosition );
195
179
} catch (BadLocationException e ) {
196
180
log .error (e );
197
181
throw new RuntimeException (e );
198
182
}
199
- expectedParsingSessionFinishStamp = this .lastParsingFinishStamp ;
200
- }
201
-
202
- try {
203
- // job.join() cannot be used here because completion request is being submitted at before-change event,
204
- // when the job is not scheduled yet (so join returns immediately)
205
- // job.schedule() performed only after the series of keypresses at after-change event
206
- if (expectedParsingSessionFinishStamp .get () < requestStamp ) {
183
+ });
184
+ do {
185
+ final long requestStamp = System .currentTimeMillis ();
186
+ CompletableFuture <Long > expectedParsingSessionFinishStamp ;
187
+ synchronized (this .syncRoot ) {
188
+ if (scriptItem == null || this .queuedForReparse .size () == 0 ) {
189
+ scriptItem = this .context .findScriptItem (offset - 1 );
190
+ if (scriptItem != null ) { // TODO consider statements separation which is ignored for now
191
+ if (scriptItem .item .isDirty ()) {
192
+ // awaiting reparse, so proceed to release lock and wait for the job to finish, then retry
193
+ } else {
194
+ return this .prepareCompletionContext (scriptItem , requestPosition .getOffset ());
195
+ }
196
+ } else {
197
+ // no script items here, so fallback to offquery context
198
+ break ;
199
+ }
200
+ }
201
+ expectedParsingSessionFinishStamp = this .lastParsingFinishStamp ;
202
+ }
203
+
204
+ try {
205
+ // job.join() cannot be used here because completion request is being submitted at before-change event,
206
+ // when the job is not scheduled yet (so join returns immediately)
207
+ // job.schedule() performed only after the series of keypresses at after-change event
208
+ if (expectedParsingSessionFinishStamp .get () < requestStamp ) {
209
+ return SQLQueryCompletionContext .EMPTY ;
210
+ }
211
+ } catch (InterruptedException | ExecutionException e ) {
212
+ break ;
213
+ }
214
+ if (requestPosition .isDeleted ()) {
207
215
return SQLQueryCompletionContext .EMPTY ;
208
216
}
209
- } catch (InterruptedException | ExecutionException e ) {
210
- break ;
211
- }
212
- if (requestPosition .isDeleted ()) {
213
- return SQLQueryCompletionContext .EMPTY ;
214
- } else {
215
- this .document .removePosition (requestPosition );
216
- }
217
- } while (scriptItem != null );
218
- return SQLQueryCompletionContext .prepareOffquery (0 );
217
+ } while (scriptItem != null );
218
+ return SQLQueryCompletionContext .prepareOffquery (0 );
219
+ }
220
+ finally {
221
+ UIUtils .syncExec (() -> this .document .removePosition (requestPosition ));
222
+ }
219
223
}
220
224
221
225
@ NotNull
0 commit comments