5454import org .eclipse .lsp4e .LanguageServerPlugin ;
5555import org .eclipse .lsp4e .LanguageServers ;
5656import org .eclipse .lsp4e .internal .DocumentOffsetAsyncCache ;
57+ import org .eclipse .lsp4e .internal .DocumentUtil ;
5758import org .eclipse .lsp4j .DocumentHighlight ;
5859import org .eclipse .lsp4j .DocumentHighlightKind ;
5960import org .eclipse .lsp4j .DocumentHighlightParams ;
@@ -130,8 +131,11 @@ private void updateHighlights(ISelection selection) {
130131 if (highlightJob != null ) {
131132 highlightJob .cancel ();
132133 }
134+
135+ long timestamp = DocumentUtil .getDocumentModificationStamp (document );
136+
133137 highlightJob = Job .createSystem ("LSP4E Highlight" , //$NON-NLS-1$
134- (ICoreRunnable )(monitor -> collectHighlights (textSelection .getOffset (), monitor )));
138+ (ICoreRunnable )(monitor -> collectHighlights (textSelection .getOffset (), timestamp , monitor )));
135139 // Debounce scheduling slightly to coalesce rapid selection changes
136140 highlightJob .schedule (HIGHLIGHT_DEBOUNCE_MS );
137141 }
@@ -194,15 +198,17 @@ public void setDocument(@Nullable IDocument document) {
194198 * server 'documentHighligh't.
195199 *
196200 * @param caretOffset
201+ * @param timestamp
197202 * @param monitor
198203 */
199- private void collectHighlights (int caretOffset , @ Nullable IProgressMonitor monitor ) {
204+ private void collectHighlights (int caretOffset , long timestamp , @ Nullable IProgressMonitor monitor ) {
200205 final var sourceViewer = this .sourceViewer ;
201206 final var document = this .document ;
202207 if (sourceViewer == null || document == null || !enabled || monitor != null && monitor .isCanceled ()) {
203208 return ;
204209 }
205210
211+
206212 // Normalize the cache key to the start of the word/symbol.
207213 final int cacheKeyOffset = normalizedOffset (document , caretOffset );
208214
@@ -212,13 +218,20 @@ private void collectHighlights(int caretOffset, @Nullable IProgressMonitor monit
212218 lastCacheKeyOffset = cacheKeyOffset ;
213219 }
214220
221+ if (DocumentUtil .getDocumentModificationStamp (document ) != timestamp ) {
222+ return ;
223+ }
224+
215225 Position position ;
216226 try {
217227 // Send the original caret offset to the LS to preserve behavior
218228 // expected by tests and servers that distinguish positions within a word.
219229 position = LSPEclipseUtils .toPosition (caretOffset , document );
220230 } catch (BadLocationException e ) {
221- LanguageServerPlugin .logError (e );
231+ // skip error if the document changed in the background
232+ if (DocumentUtil .getDocumentModificationStamp (document ) == timestamp ) {
233+ LanguageServerPlugin .logError (e );
234+ }
222235 return ;
223236 }
224237 URI uri = LSPEclipseUtils .toUri (document );
0 commit comments