Skip to content

Commit

Permalink
fix: Clean up non-visible diagnostics (#3867)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored Dec 2, 2024
1 parent 018cd45 commit f056daf
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 60 deletions.
2 changes: 2 additions & 0 deletions fixtures/workspaces/single/py/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
print(foo.islower())
print(foo.isupper())
print(foo.isprintable())

# Stop the execution of the script
2 changes: 1 addition & 1 deletion packages/client/src/applyCorrections.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as di from './di.mjs';
import { toRegExp } from './extensionRegEx/evaluateRegExp.js';
import * as Settings from './settings/index.mjs';
import { logErrors, showErrors } from './util/errors.js';
import { findEditor, findTextDocument } from './util/findEditor.js';
import { findEditor, findTextDocument } from './vscode/findEditor.js';
import { pvShowErrorMessage, pvShowInformationMessage } from './util/vscodeHelpers.js';

const propertyFixSpellingWithRenameProvider = Settings.ConfigFields.fixSpellingWithRenameProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { extractMatchingDiagRanges, getCSpellDiags } from '../diags.mjs';
import { toRange } from '../languageServer/clientHelpers.js';
import type { RangeLike } from '../languageServer/models.js';
import { ConfigFields, getSettingFromVSConfig } from '../settings/index.mjs';
import { findEditor } from '../util/findEditor.js';
import { findEditor } from '../vscode/findEditor.js';
import { pVoid } from '../util/pVoid.js';

interface SuggestionQuickPickItem extends QuickPickItem {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/decorators/decorateIssues.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { IssueTracker, SpellingCheckerIssue } from '../issueTracker.mjs';
import type { CSpellSettings } from '../settings/index.mjs';
import { ConfigFields } from '../settings/index.mjs';
import { setContext } from '../storage/context.mjs';
import { findEditor } from '../util/findEditor.js';
import { findEditor } from '../vscode/findEditor.js';

const defaultHideIssuesWhileTyping: Required<PartialCSpellUserSettings<'hideIssuesWhileTyping'>>['hideIssuesWhileTyping'] = 'Word';
const defaultRevealIssuesAfterDelayMS: Required<PartialCSpellUserSettings<'revealIssuesAfterDelayMS'>>['revealIssuesAfterDelayMS'] = 1000;
Expand Down
24 changes: 21 additions & 3 deletions packages/client/src/diags.mts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IssueType } from '@cspell/cspell-types';
import { createDisposableList } from 'utils-disposables';
import type { Diagnostic, Disposable, Event, Range, Selection, TextDocument, Uri } from 'vscode';
import type { Diagnostic, Disposable, Event, Range, Selection, TabChangeEvent, TextDocument, TextEditor, Uri } from 'vscode';
import vscode from 'vscode';

import { diagnosticSource } from './constants.js';
Expand All @@ -10,6 +10,7 @@ import type { CSpellSettings } from './settings/CSpellSettings.mjs';
import { isWordLike } from './settings/CSpellSettings.mjs';
import { ConfigFields } from './settings/index.mjs';
import { isDefined, uniqueFilter } from './util/index.mjs';
import { createIsUriVisibleFilter } from './vscode/createIsUriVisibleFilter.mjs';

/**
* Return cspell diags for a given uri.
Expand Down Expand Up @@ -121,14 +122,29 @@ export function registerDiagWatcher(show: boolean, onShowChange: Event<boolean>)
}
});

const isUriInUse = createIsUriVisibleFilter(true);

for (const uri of uris) {
if (!useDiagnosticsCollectionForScheme(uri)) continue;
const diags = issueTracker.getSpellingIssues(uri);
if (!useDiagnosticsCollectionForScheme(uri)) {
collection.set(uri, undefined);
continue;
}
const diags = (isUriInUse(uri) && issueTracker.getSpellingIssues(uri)) || undefined;
collection.set(
uri,
diags?.map((issue) => issue.diag),
);
}

for (const [uri] of collection) {
if (useDiagnosticsCollectionForScheme(uri) || isUriInUse(uri)) continue;
collection.set(uri, undefined);
}
}

function onDidChange(_event: TabChangeEvent | readonly TextEditor[]) {
// console.log('OnDidChange: %o', _event);
updateDiags();
}

dList.push(
Expand All @@ -138,6 +154,8 @@ export function registerDiagWatcher(show: boolean, onShowChange: Event<boolean>)
updateDiags();
}),
vscode.workspace.onDidChangeConfiguration(updateConfig),
vscode.window.onDidChangeVisibleTextEditors(onDidChange),
vscode.window.tabGroups.onDidChangeTabs(onDidChange),
issueTracker.onDidChangeDiagnostics(({ uris }) => updateDiags(uris)),
);

Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/issueTracker.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { workspace } from 'vscode';

import type { CSpellClient, DiagnosticsFromServer, SpellCheckerDiagnosticData } from './client/index.mjs';
import { createEmitter } from './Subscribables/index.js';
import { findTextDocument } from './util/findEditor.js';
import { findTextDocument } from './vscode/findEditor.js';

type UriString = string;

Expand Down
43 changes: 2 additions & 41 deletions packages/client/src/issueViewer/issueFilter.mts
Original file line number Diff line number Diff line change
@@ -1,47 +1,8 @@
import type { Uri } from 'vscode';
import { window } from 'vscode';

import { createIsUriVisibleFilter } from '../vscode/createIsUriVisibleFilter.mjs';

export function createIsItemVisibleFilter<T extends { uri: Uri }>(onlyVisible: boolean): (item: T) => boolean {
const filter = createIsUriVisibleFilter(onlyVisible);
return (item: T) => filter(item.uri);
}

export function createIsUriVisibleFilter(onlyVisible: boolean): (uri: Uri) => boolean {
if (!onlyVisible) return () => true;
// Use the path to avoid scheme issues.
const tabs = extractUrisFromTabs();

const visibleUris = new Set([
...tabs.map((tab) => tab.uri.toString()),
...window.visibleTextEditors.map((e) => e.document.uri.toString()),
]);
return (uri: Uri) => {
const h = visibleUris.has(uri.toString());
// console.log('isUriVisible', uri.toString(), h);
return h;
};
}

interface TabUri {
label: string;
uri: Uri;
}

function extractUrisFromTabs(): TabUri[] {
const tabs: TabUri[] = [];

for (const tg of window.tabGroups.all) {
for (const tab of tg.tabs) {
const { label, input } = tab;
if (hasUri(input)) {
tabs.push({ label, uri: input.uri });
}
}
}
return tabs;
}

function hasUri<T extends { uri: Uri }>(v: T | unknown): v is T {
if (!v || typeof v !== 'object') return false;
return 'uri' in v;
}
3 changes: 2 additions & 1 deletion packages/client/src/issueViewer/issuesViewerByFile.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type { IssueTracker, SpellingCheckerIssue } from '../issueTracker.mjs';
import { consoleDebug } from '../repl/consoleDebug.mjs';
import { findConicalDocument, findNotebookCellForDocument } from '../util/documentUri.js';
import { handleErrors, logErrors } from '../util/errors.js';
import { findTextDocument } from '../util/findEditor.js';
import { isDefined } from '../util/index.mjs';
import { findTextDocument } from '../vscode/findEditor.js';
import { getIconForSpellingIssue, icons } from './icons.mjs';
import { createIsItemVisibleFilter } from './issueFilter.mjs';
import { IssueTreeItemBase } from './IssueTreeItemBase.js';
Expand Down Expand Up @@ -217,6 +217,7 @@ class IssuesTreeDataProvider implements TreeDataProvider<IssueTreeItemBase> {
this.disposeList.push(
this.emitOnDidChange,
vscode.window.onDidChangeVisibleTextEditors(() => this.updateChild()),
vscode.window.tabGroups.onDidChangeTabs(() => this.updateChild()),
);
options.issueTracker.then((tracker) => {
this.issueTracker = tracker;
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/issueViewer/unknownWordsViewer.mts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class UnknownWordsTreeDataProvider implements TreeDataProvider<IssueTreeItemBase
this.disposeList.push(
this.emitOnDidChange,
vscode.window.onDidChangeVisibleTextEditors(() => this.refresh()),
vscode.window.tabGroups.onDidChangeTabs(() => this.refresh()),
);
if (this.options.issueTracker) {
this.setIssuesTracker(this.options.issueTracker);
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/promptUser.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Uri, window } from 'vscode';

import { extractMatchingDiagTexts, getCSpellDiags } from './diags.mjs';
import { normalizeWords } from './settings/CSpellSettings.mjs';
import { findEditor } from './util/findEditor.js';
import { findEditor } from './vscode/findEditor.js';
import { toUri } from './util/uriHelper.mjs';

const compareStrings = new Intl.Collator().compare;
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/util/documentUri.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ConfigurationScope, NotebookCell, NotebookDocument, TextDocument } from 'vscode';
import { Uri, workspace } from 'vscode';

import { findTextDocument } from './findEditor';
import { findTextDocument } from '../vscode/findEditor';

const _schemeBlocked = {
git: true,
Expand Down
19 changes: 19 additions & 0 deletions packages/client/src/vscode/createIsUriVisibleFilter.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type Uri, window } from 'vscode';

import { findTabsWithUriInput } from './tabs.mjs';

export function createIsUriVisibleFilter(onlyVisible: boolean): (uri: Uri) => boolean {
if (!onlyVisible) return () => true;
// Use the path to avoid scheme issues.
const tabs = findTabsWithUriInput();

const visibleUris = new Set([
...tabs.map((tab) => tab.uri.toString()),
...window.visibleTextEditors.map((e) => e.document.uri.toString()),
]);
return (uri: Uri) => {
const h = visibleUris.has(uri.toString());
// console.log('isUriVisible', uri.toString(), h);
return h;
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { TextDocument, TextEditor, Uri } from 'vscode';
import { window, workspace } from 'vscode';
import type { TextDocument, TextEditor } from 'vscode';
import { Uri, window, workspace } from 'vscode';

export function findEditor(uri?: Uri | string): TextEditor | undefined {
if (!uri) return window.activeTextEditor;
Expand Down
8 changes: 8 additions & 0 deletions packages/client/src/vscode/isUriResource.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Uri } from 'vscode';

interface UriResource {
readonly uri: Uri;
}
export function isUriResource<T extends UriResource>(r: unknown | undefined): r is T {
return r instanceof Object && 'uri' in r && r.uri instanceof Uri;
}
39 changes: 39 additions & 0 deletions packages/client/src/vscode/tabs.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Tab, Uri } from 'vscode';
import { window } from 'vscode';

import { isUriResource } from './isUriResource.mjs';

interface TabUri {
label: string;
uri: Uri;
tab: Tab;
}
export function findTabsWithUriInput(): TabUri[] {
const tabs: TabUri[] = [];

for (const tg of window.tabGroups.all) {
for (const tab of tg.tabs) {
const { label, input } = tab;
if (hasUri(input)) {
tabs.push({ tab, label, uri: input.uri });
}
}
}
return tabs;
}
function hasUri<T extends { uri: Uri }>(v: T | unknown): v is T {
if (!v || typeof v !== 'object') return false;
return 'uri' in v;
}

export function extractUrisFromTabs(): Uri[] {
return window.tabGroups.all
.flatMap((tabGroup) => tabGroup.tabs)
.map((tab) => tab.input)
.filter(isUriResource)
.map((r) => r.uri);
}

export function findAllOpenUrisInTabs(): Uri[] {
return extractUrisFromTabs();
}
10 changes: 3 additions & 7 deletions packages/client/src/webview/AppState/store.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DisposableClassic, DisposableHybrid, DisposableLike } from 'utils-
import { createDisposable, createDisposableFromList, disposeOf, injectDisposable } from 'utils-disposables';
import { LogLevelMasks } from 'utils-logger';
import type { TextDocument, TextEditor, Uri } from 'vscode';
import { window } from 'vscode';
import { window, workspace } from 'vscode';
import type { WatchFieldList, WatchFields } from 'webview-api';

import { getDependencies } from '../../di.mjs';
Expand Down Expand Up @@ -130,12 +130,8 @@ export function watchFieldList(fieldsToWatch: Set<WatchFields>, onChange: (chang
}

function findMatchTextDocument(url: UrlLike): TextDocument | undefined {
return findMatchingEditor(url)?.document;
}

function findMatchingEditor(url: UrlLike): TextEditor | undefined {
for (const editor of window.visibleTextEditors) {
if (!compareUrl(editor.document.uri, url)) return editor;
for (const doc of workspace.textDocuments) {
if (!compareUrl(doc.uri, url)) return doc;
}
return undefined;
}
Expand Down

0 comments on commit f056daf

Please sign in to comment.