diff --git a/CHANGELOG.md b/CHANGELOG.md index d5c510d..84a60a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Fixed - Fixes [#314](https://github.com/eamodio/vscode-gitlens/issues/314) - Toggle line annotation doesn't work properly - Fixes [#310](https://github.com/eamodio/vscode-gitlens/issues/310) - "via Terminal" commands need quoting around work directory +- Fixes issues with *Open File*, *Open Revision*, *Show File History* commands and images and other binary files ## [8.1.1] - 2018-03-12 ### Fixed diff --git a/src/commands/common.ts b/src/commands/common.ts index c873dfe..23e2d07 100644 --- a/src/commands/common.ts +++ b/src/commands/common.ts @@ -1,9 +1,12 @@ 'use strict'; import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, ViewColumn, window, workspace } from 'vscode'; +import { BuiltInCommands, DocumentSchemes, ImageExtensions } from '../constants'; +import { Container } from '../container'; import { ExplorerNode, ExplorerRefNode } from '../views/explorerNodes'; import { GitBranch, GitCommit, GitRemote, GitUri } from '../gitService'; import { Logger } from '../logger'; // import { Telemetry } from '../telemetry'; +import * as path from 'path'; export enum Commands { ClearFileAnnotations = 'gitlens.clearFileAnnotations', @@ -303,6 +306,21 @@ export async function openEditor(uri: Uri, options: TextDocumentShowOptions & { uri = uri.fileUri({ noSha: true }); } + // TODO: revist this + // This is a bit of an ugly hack, but I added it because there a bunch of call sites and toRevisionUri isn't async (and can't be easily made async because of use in ctors) + if (uri.scheme === DocumentSchemes.GitLensGit) { + const gitUri = GitUri.fromRevisionUri(uri); + if (ImageExtensions.includes(path.extname(gitUri.fsPath))) { + const fileName = await Container.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha); + if (fileName !== undefined) { + uri = Uri.file(fileName); + await commands.executeCommand(BuiltInCommands.Open, uri); + + return undefined; + } + } + } + const document = await workspace.openTextDocument(uri); return window.showTextDocument(document, { preserveFocus: false, @@ -312,6 +330,13 @@ export async function openEditor(uri: Uri, options: TextDocumentShowOptions & { }); } catch (ex) { + const msg = ex.toString(); + if (msg.includes('File seems to be binary and cannot be opened as text')) { + await commands.executeCommand(BuiltInCommands.Open, uri); + + return undefined; + } + if (rethrow) throw ex; Logger.error(ex, 'openEditor'); diff --git a/src/constants.ts b/src/constants.ts index 43cbf20..b4b5811 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -103,6 +103,17 @@ export enum GlobalState { GitLensVersion = 'gitlensVersion' } +export const ImageExtensions = [ + '.png', + '.gif', + '.jpg', + '.jpeg', + '.webp', + '.tif', + '.tiff', + '.bmp' +]; + export enum WorkspaceState { GitExplorerAutoRefresh = 'gitlens:gitExplorer:autoRefresh', GitExplorerView = 'gitlens:gitExplorer:view', diff --git a/src/trackers/documentTracker.ts b/src/trackers/documentTracker.ts index abe15b6..15e3154 100644 --- a/src/trackers/documentTracker.ts +++ b/src/trackers/documentTracker.ts @@ -220,15 +220,22 @@ export class DocumentTracker extends Disposable { documentOrId = await workspace.openTextDocument(documentOrId.fileUri({ useVersionedPath: true })); } catch (ex) { - if (!ex.toString().includes('File not found')) throw ex; - - // If we can't find the file, assume it is because the file has been renamed or deleted at some point - documentOrId = new MissingRevisionTextDocument(documentOrId); + const msg = ex.toString(); + if (msg.includes('File seems to be binary and cannot be opened as text')) { + documentOrId = new BinaryTextDocument(documentOrId); + } + else if (msg.includes('File not found')) { + // If we can't find the file, assume it is because the file has been renamed or deleted at some point + documentOrId = new MissingRevisionTextDocument(documentOrId); - // const [fileName, repoPath] = await Container.git.findWorkingFileName(documentOrId, undefined, ref); - // if (fileName === undefined) throw new Error(`Failed to add tracking for document: ${documentOrId}`); + // const [fileName, repoPath] = await Container.git.findWorkingFileName(documentOrId, undefined, ref); + // if (fileName === undefined) throw new Error(`Failed to add tracking for document: ${documentOrId}`); - // documentOrId = await workspace.openTextDocument(path.resolve(repoPath!, fileName)); + // documentOrId = await workspace.openTextDocument(path.resolve(repoPath!, fileName)); + } + else { + throw ex; + } } } else if (documentOrId instanceof Uri) { @@ -315,7 +322,7 @@ export class DocumentTracker extends Disposable { } } -class MissingRevisionTextDocument implements TextDocument { +class EmptyTextDocument implements TextDocument { readonly eol: EndOfLine; readonly fileName: string; @@ -376,3 +383,6 @@ class MissingRevisionTextDocument implements TextDocument { throw new Error('Method not supported.'); } } + +class BinaryTextDocument extends EmptyTextDocument { } +class MissingRevisionTextDocument extends EmptyTextDocument { } \ No newline at end of file