diff --git a/package.json b/package.json index 1e8c2fe5..5ccbf446 100644 --- a/package.json +++ b/package.json @@ -408,6 +408,12 @@ }, "category": "Atlassian" }, + { + "command": "atlascode.bb.togglediffNormalize", + "title": "Normalize files", + "icon": "$(law)", + "category": "Atlassian" + }, { "command": "atlascode.debug.bitbucketSites", "title": "Show Bitbucket sites info", @@ -480,6 +486,11 @@ "command": "atlascode.bb.editThisFile", "when": "resourceScheme == atlascode.bbpr && config.atlascode.bitbucket.enabled", "group": "navigation" + }, + { + "command": "atlascode.bb.togglediffNormalize", + "group": "navigation", + "when": "isInDiffEditor && resourceScheme == atlascode.bbpr && atlascode:IsNormalizerEnabled" } ], "editor/context": [ @@ -811,6 +822,10 @@ "command": "atlascode.bb.toggleCommentsVisibility", "when": "false" }, + { + "command": "atlascode.bb.togglediffNormalize", + "when": "false" + }, { "command": "atlascode.jira.showIssueForKey", "when": "atlascode:isJiraAuthenticated && config.atlascode.jira.enabled" @@ -1575,4 +1590,4 @@ "webpack-node-externals": "^3.0.0" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} +} \ No newline at end of file diff --git a/src/commands.ts b/src/commands.ts index db8bd167..9a48a3be 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -24,6 +24,7 @@ import { ConfigSection, ConfigSubSection } from './lib/ipc/models/config'; import { AbstractBaseNode } from './views/nodes/abstractBaseNode'; import { IssueNode } from './views/nodes/issueNode'; import { PipelineNode } from './views/pipelines/PipelinesTree'; +import { toggleDiffNormalize } from './normalize'; export enum Commands { BitbucketSelectContainer = 'atlascode.bb.selectContainer', @@ -51,6 +52,7 @@ export enum Commands { BitbucketMarkTaskComplete = 'atlascode.bb.markTaskComplete', BitbucketMarkTaskIncomplete = 'atlascode.bb.markTaskIncomplete', BitbucketToggleCommentsVisibility = 'atlascode.bb.toggleCommentsVisibility', + BitbucketToggleDiffNormalize = 'atlascode.bb.togglediffNormalize', EditThisFile = 'atlascode.bb.editThisFile', CreateIssue = 'atlascode.jira.createIssue', RefreshJiraExplorer = 'atlascode.jira.refreshExplorer', @@ -199,6 +201,7 @@ export function registerCommands(vscodeContext: ExtensionContext) { diffArgs[0](); commands.executeCommand('vscode.diff', ...diffArgs.slice(1)); }), + commands.registerCommand(Commands.BitbucketToggleDiffNormalize, toggleDiffNormalize), commands.registerCommand(Commands.RerunPipeline, (node: PipelineNode) => { rerunPipeline(node.pipeline); }), diff --git a/src/constants.ts b/src/constants.ts index 339bdce0..cf8cfb62 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -26,3 +26,15 @@ export const AuthInfoVersionKey = 'authInfoVersion'; export const ATLASCODE_TEST_USER_EMAIL = 'axontest2025@gmail.com'; export const ATLASCODE_TEST_HOST = 'axontest2025.atlassian.net'; +export enum CommandContext { + JiraExplorer = 'atlascode:jiraExplorerEnabled', + BitbucketExplorer = 'atlascode:bitbucketExplorerEnabled', + PipelineExplorer = 'atlascode:pipelineExplorerEnabled', + BitbucketIssuesExplorer = 'atlascode:bitbucketIssuesExplorerEnabled', + OpenIssuesTree = 'atlascode:openIssuesTreeEnabled', + AssignedIssuesTree = 'atlascode:assignedIssuesTreeEnabled', + JiraLoginTree = 'atlascode:jiraLoginTreeEnabled', + IsJiraAuthenticated = 'atlascode:isJiraAuthenticated', + IsBBAuthenticated = 'atlascode:isBBAuthenticated', + IsNormalizerEnabled = 'atlascode:IsNormalizerEnabled', +} diff --git a/src/extension.ts b/src/extension.ts index f29eb7a0..52ddf3be 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -23,6 +23,7 @@ import { registerResources } from './resources'; import { GitExtension } from './typings/git'; import { pid } from 'process'; import { startListening } from './atlclients/negotiate'; +import { api } from './normalize'; const AnalyticDelay = 5000; @@ -86,6 +87,7 @@ export async function activate(context: ExtensionContext) { duration[0] * 1000 + Math.floor(duration[1] / 1000000) } ms`, ); + return api; } async function activateBitbucketFeatures() { diff --git a/src/normalize.ts b/src/normalize.ts new file mode 100644 index 00000000..25e8d1d5 --- /dev/null +++ b/src/normalize.ts @@ -0,0 +1,72 @@ +import { commands, TabInputTextDiff, TextEditor, Uri, window } from 'vscode'; +import { CommandContext } from './constants'; +import { Container } from './container'; + +interface CodeNormalizer { + isRelevant: (u: Uri) => boolean; + normalize: (code: string, uri: Uri) => string | Promise; +} + +const normalizers: CodeNormalizer[] = []; + +function setCommandContext(key: CommandContext | string, value: any) { + return commands.executeCommand('setContext', key, value); +} + +const registerCodeNormalizer = (normalizer: CodeNormalizer) => { + if (normalizers.indexOf(normalizer) < 0) { + normalizers.push(normalizer); + } + return { + dispose: () => { + const idx = normalizers.indexOf(normalizer); + if (idx >= 0) { + normalizers.splice(idx, 1); + } + }, + }; +}; + +const enableDiffNormalize = (e?: TextEditor) => { + const relevant = e?.document.uri.scheme === 'atlascode.bbpr'; + const active = relevant && normalizers.some((n) => n.isRelevant(e.document.uri)); + setCommandContext(CommandContext.IsNormalizerEnabled, active); +}; + +const toggleNorm = (u: Uri) => { + const q = JSON.parse(u.query); + if (q.normalized) { + delete q.normalized; + } else { + q.normalized = true; + } + return u.with({ query: JSON.stringify(q) }); +}; + +export const toggleDiffNormalize = () => { + try { + const tab = window.tabGroups.activeTabGroup.activeTab; + if (tab?.input instanceof TabInputTextDiff) { + const { original, modified } = tab.input; + const controller = Container.bitbucketContext.prCommentController; + const origN = toggleNorm(original); + const modifN = toggleNorm(modified); + controller.provideComments(origN); + controller.provideComments(modifN); + return commands.executeCommand('vscode.diff', origN, modifN, tab.label); + } + } catch (error) {} + return; +}; + +export const normalize = (original: string, uri: Uri) => { + for (const n of normalizers) { + if (n.isRelevant(uri)) { + return n.normalize(original, uri); + } + } + return original; +}; + +export const api = { registerCodeNormalizer }; +window.onDidChangeActiveTextEditor(enableDiffNormalize); diff --git a/src/views/gitContentProvider.ts b/src/views/gitContentProvider.ts index b18267b4..da1e9ee9 100644 --- a/src/views/gitContentProvider.ts +++ b/src/views/gitContentProvider.ts @@ -5,6 +5,7 @@ import { BitbucketContext } from '../bitbucket/bbContext'; import { clientForSite } from '../bitbucket/bbUtils'; import { Container } from '../container'; import { PRFileDiffQueryParams } from './pullrequest/diffViewHelper'; +import { normalize } from 'src/normalize'; //This class is responsible for fetching the text of a specific version of a file which may not be on your machine //Everytime the vscode.diff is invoked in this extension, it's using this file to fetch the data for both files. @@ -58,6 +59,6 @@ export class GitContentProvider implements vscode.TextDocumentContentProvider { ); } - return content || ''; + return normalize(content || '', uri); } }