2.9 KB94 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {Repository} from 'isl-server/src/Repository';
9import type {AbsolutePath, RepoRelativePath} from 'isl/src/types';
10
11import * as pathModule from 'node:path';
12import * as vscode from 'vscode';
13import {shouldOpenBeside} from './config';
14
15const IMAGE_EXTENSIONS = new Set(['.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.png', '.webp']);
16function looksLikeImageUri(uri: vscode.Uri): boolean {
17 const ext = pathModule.extname(uri.path).toLowerCase();
18 return IMAGE_EXTENSIONS.has(ext);
19}
20
21/**
22 * Opens a file in the editor within a provided repository, optionally at a specific line number.
23 * The file path should be relative to the repository root.
24 */
25export function openFileInRepo(
26 repo: Repository,
27 filePath: RepoRelativePath,
28 line?: number,
29 preview?: boolean,
30 onError?: (err: Error) => void,
31 onOpened?: (editor: vscode.TextEditor) => void,
32 disableScroll: boolean = false,
33) {
34 const path: AbsolutePath = pathModule.join(repo.info.repoRoot, filePath);
35 openFileImpl(path, line, preview, onError, onOpened, disableScroll);
36}
37
38/**
39 * Opens a file in the editor, optionally at a specific line number.
40 * The file path should be absolute.
41 */
42export function openFile(
43 filePath: AbsolutePath,
44 line?: number,
45 preview?: boolean,
46 onError?: (err: Error) => void,
47 onOpened?: (editor: vscode.TextEditor) => void,
48 disableScroll: boolean = false,
49): void {
50 openFileImpl(filePath, line, preview, onError, onOpened, disableScroll);
51}
52
53function openFileImpl(
54 filePath: AbsolutePath,
55 line?: number,
56 preview?: boolean,
57 onError?: (err: Error) => void,
58 onOpened?: (editor: vscode.TextEditor) => void,
59 disableScroll: boolean = false,
60): void {
61 const uri = vscode.Uri.file(filePath);
62 if (looksLikeImageUri(uri)) {
63 vscode.commands.executeCommand('vscode.open', uri).then(undefined, err => {
64 vscode.window.showErrorMessage('cannot open file' + (err.message ?? String(err)));
65 });
66 return;
67 }
68 vscode.window
69 .showTextDocument(uri, {
70 preview,
71 viewColumn: shouldOpenBeside() ? vscode.ViewColumn.Beside : undefined,
72 })
73 .then(
74 editor => {
75 if (!disableScroll && line != null) {
76 const lineZeroIndexed = line - 1; // vscode uses 0-indexed line numbers
77 editor.selections = [new vscode.Selection(lineZeroIndexed, 0, lineZeroIndexed, 0)]; // move cursor to line
78 editor.revealRange(
79 new vscode.Range(lineZeroIndexed, 0, lineZeroIndexed, 0),
80 vscode.TextEditorRevealType.InCenterIfOutsideViewport,
81 ); // scroll to line
82 }
83 onOpened?.(editor);
84 },
85 err => {
86 if (onError) {
87 onError(err);
88 } else {
89 vscode.window.showErrorMessage(err.message ?? String(err));
90 }
91 },
92 );
93}
94