From 6609cfa9d09bb8dedb2cf01f5cf951646bd620cf Mon Sep 17 00:00:00 2001 From: netcon Date: Fri, 2 Apr 2021 15:55:05 +0800 Subject: [PATCH] feat: add open changes button to editor title (#270) --- extensions/github1s/package.json | 19 ++++- extensions/github1s/src/commands/editor.ts | 33 +++++++- extensions/github1s/src/commands/index.ts | 3 + extensions/github1s/src/listeners/vscode.ts | 75 ++++++++++++------- .../github1s/src/source-control/changes.ts | 2 +- 5 files changed, 102 insertions(+), 30 deletions(-) diff --git a/extensions/github1s/package.json b/extensions/github1s/package.json index e41a6b692..f4ee8fb86 100644 --- a/extensions/github1s/package.json +++ b/extensions/github1s/package.json @@ -128,6 +128,12 @@ "category": "GitHub1s", "icon": "$(globe)" }, + { + "command": "github1s.editor-view-open-changes", + "title": "Open Changes", + "category": "GitHub1s", + "icon": "$(compare-changes)" + }, { "command": "github1s.diff-view-open-left-file", "title": "Open Left File", @@ -236,6 +242,10 @@ "command": "github1s.commit-view-item-open-on-github", "when": "false" }, + { + "command": "github1s.editor-view-open-changes", + "when": "false" + }, { "command": "github1s.diff-view-open-left-file", "when": "false" @@ -298,15 +308,20 @@ } ], "editor/title": [ + { + "command": "github1s.editor-view-open-changes", + "when": "!isInDiffEditor && github1s.context.showOpenChangesInEditorTitle", + "group": "navigation@1" + }, { "command": "github1s.diff-view-open-left-file", "when": "isInDiffEditor", - "group": "navigation@1" + "group": "navigation@2" }, { "command": "github1s.diff-view-open-right-file", "when": "isInDiffEditor", - "group": "navigation@2" + "group": "navigation@3" }, { "command": "github1s.editor-view-open-prev-revision", diff --git a/extensions/github1s/src/commands/editor.ts b/extensions/github1s/src/commands/editor.ts index d54a40b22..d4ac2dc50 100644 --- a/extensions/github1s/src/commands/editor.ts +++ b/extensions/github1s/src/commands/editor.ts @@ -9,9 +9,40 @@ import router from '@/router'; import repository from '@/repository'; import { emptyFileUri } from '@/providers'; import { basename } from '@/helpers/util'; -import { getChangedFileDiffTitle } from '@/source-control/changes'; +import { + ChangedFile, + getChangedFiles, + getChangedFileCommand, + getChangedFileDiffTitle, +} from '@/source-control/changes'; import { FileChangeType } from '@/repository/types'; +export const getChangedFileFromSourceControl = async ( + fileUri: vscode.Uri +): Promise => { + // the file should belong to current workspace + if (fileUri.authority) { + return; + } + + return (await getChangedFiles()).find((changedFile) => { + return changedFile.headFileUri.path === fileUri.path; + }); +}; + +// open the diff editor of a file, such as click it in source-control-panel, +// only work when we can found the corresponding file in source-control-panel +export const commandEditorViewOpenChanges = async (fileUri: vscode.Uri) => { + const changedFile = await getChangedFileFromSourceControl(fileUri); + + if (!changedFile) { + return; + } + + const command = await getChangedFileCommand(changedFile); + vscode.commands.executeCommand(command.command, ...command.arguments); +}; + const openFileToEditor = async (fileUri) => { const isCurrentAuthority = fileUri.authority === (await router.getAuthority()); diff --git a/extensions/github1s/src/commands/index.ts b/extensions/github1s/src/commands/index.ts index ed45d97ec..a52c66e59 100644 --- a/extensions/github1s/src/commands/index.ts +++ b/extensions/github1s/src/commands/index.ts @@ -24,6 +24,7 @@ import { } from './commit'; import { commandOpenGitpod } from './gitpod'; import { + commandEditorViewOpenChanges, commandDiffViewOpenLeftFile, commandDiffViewOpenRightFile, commandEditorViewOpenNextRevision, @@ -64,6 +65,8 @@ const commands: { id: string; callback: (...args: any[]) => any }[] = [ // open current repository on gitpod { id: 'github1s.open-gitpod', callback: commandOpenGitpod }, + // open the changes of a file + { id: 'github1s.editor-view-open-changes', callback: commandEditorViewOpenChanges }, // prettier-ignore // open the left file in diff editor { id: 'github1s.diff-view-open-left-file', callback: commandDiffViewOpenLeftFile }, // prettier-ignore // open the right file in diff editor diff --git a/extensions/github1s/src/listeners/vscode.ts b/extensions/github1s/src/listeners/vscode.ts index 5bfe3f255..64acaafbe 100644 --- a/extensions/github1s/src/listeners/vscode.ts +++ b/extensions/github1s/src/listeners/vscode.ts @@ -6,35 +6,58 @@ import * as vscode from 'vscode'; import router from '@/router'; import { PageType } from '@/router/types'; +import { getChangedFileFromSourceControl } from '@/commands/editor'; import { GitHub1sFileSystemProvider } from '@/providers/fileSystemProvider'; -export const registerVSCodeEventListeners = () => { +const handleRouterOnActiveEditorChange = async ( + editor: vscode.TextEditor | undefined +) => { // replace current url when user change active editor - vscode.window.onDidChangeActiveTextEditor(async (editor) => { - const { owner, repo, ref, pageType } = await router.getState(); - const activeFileUri = editor?.document.uri; - - // only `tree/blob` page will replace url with the active editor change - if (![PageType.TREE, PageType.BLOB].includes(pageType)) { - return; - } - - // if the file which not belong to current workspace is opened, or no file - // is opened, only retain `owner` and `repo` (and `ref` if need) in browser url - if ( - !activeFileUri || - activeFileUri?.authority || - activeFileUri?.scheme !== GitHub1sFileSystemProvider.scheme - ) { - const browserPath = - ref.toUpperCase() === 'HEAD' - ? `/${owner}/${repo}` - : `/${owner}/${repo}/tree/${ref}`; - router.history.replace(browserPath); - return; - } - - const browserPath = `/${owner}/${repo}/blob/${ref}${activeFileUri.path}`; + const { owner, repo, ref, pageType } = await router.getState(); + const activeFileUri = editor?.document.uri; + + // only `tree/blob` page will replace url with the active editor change + if (![PageType.TREE, PageType.BLOB].includes(pageType)) { + return; + } + + // if the file which not belong to current workspace is opened, or no file + // is opened, only retain `owner` and `repo` (and `ref` if need) in browser url + if ( + !activeFileUri || + activeFileUri?.authority || + activeFileUri?.scheme !== GitHub1sFileSystemProvider.scheme + ) { + const browserPath = + ref.toUpperCase() === 'HEAD' + ? `/${owner}/${repo}` + : `/${owner}/${repo}/tree/${ref}`; router.history.replace(browserPath); + return; + } + + const browserPath = `/${owner}/${repo}/blob/${ref}${activeFileUri.path}`; + router.history.replace(browserPath); +}; + +// if the `Open Changes` Button should show in editor title +const handleOpenChangesContextOnActiveEditorChange = async ( + editor: vscode.TextEditor | undefined +) => { + const changedFile = editor?.document.uri + ? await getChangedFileFromSourceControl(editor.document.uri) + : undefined; + + return vscode.commands.executeCommand( + 'setContext', + 'github1s.context.showOpenChangesInEditorTitle', + !!changedFile + ); +}; + +export const registerVSCodeEventListeners = () => { + vscode.window.onDidChangeActiveTextEditor(async (editor) => { + handleRouterOnActiveEditorChange(editor); + handleOpenChangesContextOnActiveEditorChange(editor); }); }; diff --git a/extensions/github1s/src/source-control/changes.ts b/extensions/github1s/src/source-control/changes.ts index f51c04184..557118734 100644 --- a/extensions/github1s/src/source-control/changes.ts +++ b/extensions/github1s/src/source-control/changes.ts @@ -79,7 +79,7 @@ export const getCommitChangedFiles = async (commit: RepositoryCommit) => { }); }; -const getChangedFiles = async (): Promise => { +export const getChangedFiles = async (): Promise => { const routerState = await router.getState(); // github pull page