Skip to content

Commit

Permalink
- [FEATURE] Find all references in workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
GehDoc committed Jul 1, 2023
1 parent 423cacb commit b357533
Show file tree
Hide file tree
Showing 11 changed files with 1,090 additions and 18 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0


## [UNRELEASED]

### Fixed
- [DEPENDENCIES] Update for security fixes

### Changed
- [INTERNAL] Update to vscode 1.67, without activating new features
- [INTERNAL] Update to vscode 1.67

### Added
- [FEATURE] Find all references in workspace


## [1.3.21] - 20220918
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ This extension is entirely based on the Markdown preview provided by Visual Stud
* view Textile source and its HTML preview side by side, with synchronised scrolling;
* include images, from local or network, with manageable security of the preview's content;
* click on links, in the source view and in the HTML preview;
* Can be run as a [remote/web extension](https://code.visualstudio.com/api/advanced-topics/remote-extensions).
* Can be run as a [remote/web extension](https://code.visualstudio.com/api/advanced-topics/remote-extensions);
* see the document headlines structure in the outline view;
* fold paragraphs from their headline, multi-line list-items, code blocks, and special HTML comments `<!-- #region [Optional text] -->` and `<!-- #endregion [Optional text] -->`.
* blockquote syntax coloring, with `bc[language].` or `<pre><code class="language">`, or `<pre><code lang="language">`.
Look at the official highlight.js documentation for the [list of supported languages](https://highlightjs.org/static/demo/),
Look at the official highlight.js documentation for the [list of supported languages](https://highlightjs.org/static/demo/);
* Internal and external links to a paragraph headline of a local textile file are supported (slugify);
* Path completion for local links.
* Path completion for local links;
* Find all references in workspace.

And also :
* the HTML preview supports VSCode light and dark themes;
Expand All @@ -53,6 +54,9 @@ Maybe implemented, if requested :
* Smart select;
* [Notebook rendering](https://code.visualstudio.com/api/extension-guides/notebook).

Waiting for a release of some VS Code internal APIs :
- Support for file droping;

## Installation

### From Marketplace within VS Code
Expand Down
14 changes: 7 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import * as commands from './commands/index';
import { TextileLinkProvider } from './languageFeatures/documentLinkProvider';
import { TextileDocumentSymbolProvider } from './languageFeatures/documentSymbolProvider';
// FIXME: import { registerDropIntoEditor } from './features/dropIntoEditor';
// FIXME: import { registerFindFileReferences } from './languageFeatures/fileReferences';
import { registerFindFileReferences } from './languageFeatures/fileReferences';
import { TextileFoldingProvider } from './languageFeatures/foldingProvider';
import { TextilePathCompletionProvider } from './languageFeatures/pathCompletions';
// FIXME: import { TextileReferencesProvider } from './languageFeatures/references';
import { TextileReferencesProvider } from './languageFeatures/references';
// FIXME: import { TextileRenameProvider } from './languageFeatures/rename';
// FIXME: import TextileSmartSelect from './features/smartSelect';
import { TextileWorkspaceSymbolProvider } from './languageFeatures/workspaceSymbolProvider';
Expand Down Expand Up @@ -50,7 +50,7 @@ export function activate(context: vscode.ExtensionContext) {
const previewManager = new TextilePreviewManager(contentProvider, logger, contributions, engine);
context.subscriptions.push(previewManager);

context.subscriptions.push(registerTextileLanguageFeatures(/* FIXME: commandManager, */ symbolProvider, engine));
context.subscriptions.push(registerTextileLanguageFeatures(commandManager, symbolProvider, engine));
context.subscriptions.push(registerTextileCommands(commandManager, previewManager, /* Disabled for textile : telemetryReporter, */ cspArbiter, engine));

context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
Expand All @@ -60,7 +60,7 @@ export function activate(context: vscode.ExtensionContext) {
}

function registerTextileLanguageFeatures(
// FIXME: commandManager: CommandManager,
commandManager: CommandManager,
symbolProvider: TextileDocumentSymbolProvider,
engine: TextileEngine
): vscode.Disposable {
Expand All @@ -69,18 +69,18 @@ function registerTextileLanguageFeatures(
const linkProvider = new TextileLinkProvider(engine);
const workspaceContents = new VsCodeTextileWorkspaceContents();

// FIXME: const referencesProvider = new TextileReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier);
const referencesProvider = new TextileReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier);
return vscode.Disposable.from(
vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider),
vscode.languages.registerDocumentLinkProvider(selector, linkProvider),
vscode.languages.registerFoldingRangeProvider(selector, new TextileFoldingProvider(engine)),
// FIXME: vscode.languages.registerSelectionRangeProvider(selector, new TextileSmartSelect(engine)),
vscode.languages.registerWorkspaceSymbolProvider(new TextileWorkspaceSymbolProvider(symbolProvider, workspaceContents)),
// FIXME: vscode.languages.registerReferenceProvider(selector, referencesProvider),
vscode.languages.registerReferenceProvider(selector, referencesProvider),
// FIXME: vscode.languages.registerRenameProvider(selector, new TextileRenameProvider(referencesProvider, workspaceContents, githubSlugifier)),
TextilePathCompletionProvider.register(selector, engine, linkProvider),
// FIXME : registerDropIntoEditor(selector),
// FIXME : registerFindFileReferences(commandManager, referencesProvider),
registerFindFileReferences(commandManager, referencesProvider),
);
}

Expand Down
39 changes: 33 additions & 6 deletions src/languageFeatures/documentLinkProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,14 @@ export function stripAngleBrackets(link: string) {

// -- Begin: Modified for textile

/**
* Matches `"text":link`
*/
const linkPattern = /("(?!\s)((?:[^"]|"(?![\s:])[^\n"]+"(?!:))+)":)((?:[^\s()]|\([^\s()]+\)|[()])+?)(?=[!-\.:-@\[\\\]-`{-~]+(?:$|\s)|$|\s)|(\["([^\n]+?)":)((?:\[[a-z0-9]*\]|[^\]])+)\]/g

/**
* Matches `!url(alt)!`
*/
const imagePattern = /(!(?!\s)((?:\([^\)]+\)|\{[^\}]+\}|\\[[^\[\]]+\]|(?:<>|<|>|=)|[\(\)]+)*(?:\.[^\n\S]|\.(?:[^\.\/]))?)([^!\s]+?) ?(?:\(((?:[^\(\)]|\([^\(\)]+\))+)\))?!)(?::([^\s]+?(?=[!-\.:-@\[\\\]-`{-~](?:$|\s)|\s|$)))?/g

/* Disabled : not relevant for textile
Expand All @@ -182,10 +188,13 @@ const autoLinkPattern = /\<(\w+:[^\>\s]+)\>/g;
*/

/**
* Matches `[alias]http://exemple.com`
* Matches `[text]http://exemple.com`
*/
const definitionPattern = /^\[([^\]]+)\]((?:https?:\/\/|[.]{1,2}\/|#)\S+)(?:\s*(?=\n)|$)/gm;

/**
* Matches `@text@`
*/
const inlineCodePattern = /(?:^|[^@])(@+)(?:.+?|.*?(?:(?:\r?\n).+?)*?)(?:\r?\n)?\1(?:$|[^@])/gm;
// -- End: Modified for textile

Expand Down Expand Up @@ -254,6 +263,24 @@ export class TextileLinkProvider implements vscode.DocumentLinkProvider {
.map(data => this.toValidDocumentLink(data, definitionSet)));
}

// -- Begin: Modified for textile
private toReferenceLink(link: TextileLink, definitionSet: LinkDefinitionSet): TextileLink {
if (link.href.kind === 'internal') {
const def = definitionSet.lookup(link.source.text);
if (def) {
return {
kind: 'link',
href: {
kind: 'reference',
ref: link.source.text,
},
source: link.source,
};
}
}
return link;
}

private toValidDocumentLink(link: TextileLink, definitionSet: LinkDefinitionSet): vscode.DocumentLink | undefined {
switch (link.href.kind) {
case 'external': {
Expand All @@ -280,18 +307,18 @@ export class TextileLinkProvider implements vscode.DocumentLinkProvider {

public async getAllLinks(document: SkinnyTextDocument): Promise<TextileLink[]> {
const codeInDocument = await findCode(document, this.engine);
return Array.from([
const allLinks = Array.from([
...this.getInlineLinks(document, codeInDocument),
// Disabled for Textile : ...this.getReferenceLinks(document, codeInDocument),
...this.getLinkDefinitions2(document, codeInDocument),
// FIXME for Textile : ...this.getAutoLinks(document, codeInDocument),
]);
const definitionSet = new LinkDefinitionSet(allLinks);
return allLinks.map((link) => this.toReferenceLink(link, definitionSet));
}

private *getInlineLinks(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable<TextileLink> {
const text = document.getText();
// -- Begin: Modified for textile

for (const match of text.matchAll(linkPattern)) {
const matchLink = match[1] && extractDocumentLink(document, match[1].length, match[3], match.index);
if (matchLink && !isLinkInsideCode(codeInDocument, matchLink.source.hrefRange)) {
Expand All @@ -312,8 +339,8 @@ export class TextileLinkProvider implements vscode.DocumentLinkProvider {
yield matchLink;
}
}
// -- End: Modified for textile
}
// -- End: Modified for textile

/* Disabled : not relevant for textile
private *getAutoLinks(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable<TextileLink> {
Expand Down Expand Up @@ -418,7 +445,7 @@ export class TextileLinkProvider implements vscode.DocumentLinkProvider {
text: link,
resource: document.uri,
hrefRange,
fragmentRange: getFragmentRange(link, linkStart, linkEnd)
fragmentRange: getFragmentRange(link, linkStart, linkEnd),
},
ref: { text: reference, range: refRange },
href: target,
Expand Down
54 changes: 54 additions & 0 deletions src/languageFeatures/fileReferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Command, CommandManager } from '../commandManager';
import { TextileReferencesProvider } from './references';

const localize = nls.loadMessageBundle();


export class FindFileReferencesCommand implements Command {

public readonly id = 'textile.findAllFileReferences';

constructor(
private readonly referencesProvider: TextileReferencesProvider,
) { }

public async execute(resource?: vscode.Uri) {
if (!resource) {
resource = vscode.window.activeTextEditor?.document.uri;
}

if (!resource) {
vscode.window.showErrorMessage(localize('error.noResource', "Find file references failed. No resource provided."));
return;
}

await vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
title: localize('progress.title', "Finding file references")
}, async (_progress, token) => {
const references = await this.referencesProvider.getAllReferencesToFile(resource!, token);
const locations = references.map(ref => ref.location);

const config = vscode.workspace.getConfiguration('references');
const existingSetting = config.inspect<string>('preferredLocation');

await config.update('preferredLocation', 'view');
try {
await vscode.commands.executeCommand('editor.action.showReferences', resource, new vscode.Position(0, 0), locations);
} finally {
await config.update('preferredLocation', existingSetting?.workspaceFolderValue ?? existingSetting?.workspaceValue);
}
});
}
}

export function registerFindFileReferences(commandManager: CommandManager, referencesProvider: TextileReferencesProvider): vscode.Disposable {
return commandManager.register(new FindFileReferencesCommand(referencesProvider));
}
Loading

0 comments on commit b357533

Please sign in to comment.