mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-09 08:15:05 +01:00
@@ -23,6 +23,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { QueryBuilder } from 'vs/workbench/services/search/common/queryBuilder';
|
||||
import { ISearchService } from 'vs/workbench/services/search/common/search';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
|
||||
export class TerminalLocalFileLinkOpener implements ITerminalLinkOpener {
|
||||
constructor(
|
||||
@@ -35,7 +36,7 @@ export class TerminalLocalFileLinkOpener implements ITerminalLinkOpener {
|
||||
if (!link.uri) {
|
||||
throw new Error('Tried to open file link without a resolved URI');
|
||||
}
|
||||
const lineColumnInfo: ILineColumnInfo = this.extractLineColumnInfo(link.text);
|
||||
const lineColumnInfo: ILineColumnInfo = this.extractLineColumnInfo(link.text, link.uri);
|
||||
const selection: ITextEditorSelection = {
|
||||
startLineNumber: lineColumnInfo.lineNumber,
|
||||
startColumn: lineColumnInfo.columnNumber
|
||||
@@ -51,12 +52,22 @@ export class TerminalLocalFileLinkOpener implements ITerminalLinkOpener {
|
||||
*
|
||||
* @param link Url link which may contain line and column number.
|
||||
*/
|
||||
extractLineColumnInfo(link: string): ILineColumnInfo {
|
||||
extractLineColumnInfo(link: string, uri?: URI): ILineColumnInfo {
|
||||
const lineColumnInfo: ILineColumnInfo = {
|
||||
lineNumber: 1,
|
||||
columnNumber: 1
|
||||
};
|
||||
|
||||
// If a URI was passed in the exact file is known, sanitize the link text such that the
|
||||
// folders and file name do not contain whitespace. The actual path isn't important in
|
||||
// extracting the line and column from the regex so this is safe
|
||||
if (uri) {
|
||||
const fileName = basename(uri.path);
|
||||
const index = link.indexOf(fileName);
|
||||
const endIndex = index + fileName.length;
|
||||
link = link.slice(0, endIndex).replace(/\s/g, '_') + link.slice(endIndex);
|
||||
}
|
||||
|
||||
// The local link regex only works for non file:// links, check these for a simple
|
||||
// `:line:col` suffix
|
||||
if (link.startsWith('file://')) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { deepStrictEqual } from 'assert';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { OperatingSystem } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { ITextEditorSelection, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IFileService, IFileStatWithPartialMetadata } from 'vs/platform/files/common/files';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
@@ -27,6 +27,7 @@ import { Terminal } from 'xterm';
|
||||
export interface ITerminalLinkActivationResult {
|
||||
source: 'editor' | 'search';
|
||||
link: string;
|
||||
selection?: ITextEditorSelection;
|
||||
}
|
||||
|
||||
class TestCommandDetectionCapability extends CommandDetectionCapability {
|
||||
@@ -79,6 +80,10 @@ suite('Workbench - TerminalLinkOpeners', () => {
|
||||
source: 'editor',
|
||||
link: editor.resource?.toString()
|
||||
};
|
||||
// Only assert on selection if it's not the default value
|
||||
if (editor.options?.selection && (editor.options.selection.startColumn !== 1 || editor.options.selection.startLineNumber !== 1)) {
|
||||
activationResult.selection = editor.options.selection;
|
||||
}
|
||||
}
|
||||
} as Partial<IEditorService>);
|
||||
// /*editorServiceSpy = */instantiationService.spy(IEditorService, 'openEditor');
|
||||
@@ -165,6 +170,28 @@ suite('Workbench - TerminalLinkOpeners', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('should extract line and column from links in a workspace containing spaces', async () => {
|
||||
localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux);
|
||||
const localFolderOpener = instantiationService.createInstance(TerminalLocalFolderInWorkspaceLinkOpener);
|
||||
opener = instantiationService.createInstance(TerminalSearchLinkOpener, capabilities, Promise.resolve('/space folder'), localFileOpener, localFolderOpener, OperatingSystem.Linux);
|
||||
fileService.setFiles([
|
||||
URI.from({ scheme: Schemas.file, path: '/space folder/foo/bar.txt' })
|
||||
]);
|
||||
await opener.open({
|
||||
text: './foo/bar.txt:10:5',
|
||||
bufferRange: { start: { x: 1, y: 1 }, end: { x: 8, y: 1 } },
|
||||
type: TerminalBuiltinLinkType.Search
|
||||
});
|
||||
deepStrictEqual(activationResult, {
|
||||
link: 'file:///space%20folder/foo/bar.txt',
|
||||
source: 'editor',
|
||||
selection: {
|
||||
startColumn: 5,
|
||||
startLineNumber: 10
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
suite('macOS/Linux', () => {
|
||||
setup(() => {
|
||||
localFileOpener = instantiationService.createInstance(TerminalLocalFileLinkOpener, OperatingSystem.Linux);
|
||||
|
||||
Reference in New Issue
Block a user