addons/vscode/extension/openFile.tsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {Repository} from 'isl-server/src/Repository';
b69ab319import type {AbsolutePath, RepoRelativePath} from 'isl/src/types';
b69ab3110
b69ab3111import * as pathModule from 'node:path';
b69ab3112import * as vscode from 'vscode';
b69ab3113import {shouldOpenBeside} from './config';
b69ab3114
b69ab3115const IMAGE_EXTENSIONS = new Set(['.bmp', '.gif', '.ico', '.jpeg', '.jpg', '.png', '.webp']);
b69ab3116function looksLikeImageUri(uri: vscode.Uri): boolean {
b69ab3117 const ext = pathModule.extname(uri.path).toLowerCase();
b69ab3118 return IMAGE_EXTENSIONS.has(ext);
b69ab3119}
b69ab3120
b69ab3121/**
b69ab3122 * Opens a file in the editor within a provided repository, optionally at a specific line number.
b69ab3123 * The file path should be relative to the repository root.
b69ab3124 */
b69ab3125export function openFileInRepo(
b69ab3126 repo: Repository,
b69ab3127 filePath: RepoRelativePath,
b69ab3128 line?: number,
b69ab3129 preview?: boolean,
b69ab3130 onError?: (err: Error) => void,
b69ab3131 onOpened?: (editor: vscode.TextEditor) => void,
b69ab3132 disableScroll: boolean = false,
b69ab3133) {
b69ab3134 const path: AbsolutePath = pathModule.join(repo.info.repoRoot, filePath);
b69ab3135 openFileImpl(path, line, preview, onError, onOpened, disableScroll);
b69ab3136}
b69ab3137
b69ab3138/**
b69ab3139 * Opens a file in the editor, optionally at a specific line number.
b69ab3140 * The file path should be absolute.
b69ab3141 */
b69ab3142export function openFile(
b69ab3143 filePath: AbsolutePath,
b69ab3144 line?: number,
b69ab3145 preview?: boolean,
b69ab3146 onError?: (err: Error) => void,
b69ab3147 onOpened?: (editor: vscode.TextEditor) => void,
b69ab3148 disableScroll: boolean = false,
b69ab3149): void {
b69ab3150 openFileImpl(filePath, line, preview, onError, onOpened, disableScroll);
b69ab3151}
b69ab3152
b69ab3153function openFileImpl(
b69ab3154 filePath: AbsolutePath,
b69ab3155 line?: number,
b69ab3156 preview?: boolean,
b69ab3157 onError?: (err: Error) => void,
b69ab3158 onOpened?: (editor: vscode.TextEditor) => void,
b69ab3159 disableScroll: boolean = false,
b69ab3160): void {
b69ab3161 const uri = vscode.Uri.file(filePath);
b69ab3162 if (looksLikeImageUri(uri)) {
b69ab3163 vscode.commands.executeCommand('vscode.open', uri).then(undefined, err => {
b69ab3164 vscode.window.showErrorMessage('cannot open file' + (err.message ?? String(err)));
b69ab3165 });
b69ab3166 return;
b69ab3167 }
b69ab3168 vscode.window
b69ab3169 .showTextDocument(uri, {
b69ab3170 preview,
b69ab3171 viewColumn: shouldOpenBeside() ? vscode.ViewColumn.Beside : undefined,
b69ab3172 })
b69ab3173 .then(
b69ab3174 editor => {
b69ab3175 if (!disableScroll && line != null) {
b69ab3176 const lineZeroIndexed = line - 1; // vscode uses 0-indexed line numbers
b69ab3177 editor.selections = [new vscode.Selection(lineZeroIndexed, 0, lineZeroIndexed, 0)]; // move cursor to line
b69ab3178 editor.revealRange(
b69ab3179 new vscode.Range(lineZeroIndexed, 0, lineZeroIndexed, 0),
b69ab3180 vscode.TextEditorRevealType.InCenterIfOutsideViewport,
b69ab3181 ); // scroll to line
b69ab3182 }
b69ab3183 onOpened?.(editor);
b69ab3184 },
b69ab3185 err => {
b69ab3186 if (onError) {
b69ab3187 onError(err);
b69ab3188 } else {
b69ab3189 vscode.window.showErrorMessage(err.message ?? String(err));
b69ab3190 }
b69ab3191 },
b69ab3192 );
b69ab3193}