Skip to content

Commit 8bb0d1e

Browse files
open merge editor from command
1 parent 32da69d commit 8bb0d1e

File tree

4 files changed

+68
-20
lines changed

4 files changed

+68
-20
lines changed

client/src/adt/conections.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { RemoteManager, createClient } from "../config"
22
import { AFsService, AbapStat, Root, isAbapStat } from "abapfs"
3-
import { Uri, FileSystemError } from "vscode"
3+
import { Uri, FileSystemError, workspace } from "vscode"
44
import { ADTClient } from "abap-adt-api"
55
import { LogOutPendingDebuggers } from "./debugger"
66
export const ADTSCHEME = "adt"
@@ -94,3 +94,6 @@ export async function disconnect() {
9494
await Promise.all([...main, ...clones, ...LogOutPendingDebuggers()])
9595
return
9696
}
97+
98+
export const rootIsConnected = (connId: string) =>
99+
!!workspace.workspaceFolders?.find(f => f.uri.scheme === ADTSCHEME && f.uri.authority === connId?.toLowerCase())

client/src/scm/abaprevisions/abaprevisionservice.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ export class AbapRevisionService {
3232
return revisions
3333
}
3434

35-
public uriRevisions(uri: Uri, refresh: boolean) {
35+
public async uriRevisions(uri: Uri, refresh: boolean) {
3636
if (!abapUri(uri)) return
3737
if (!uri.path.match(/\.abap/)) return
38-
const node = getRoot(this.connId).getNode(uri.path)
38+
const node = await getRoot(this.connId).getNodeAsync(uri.path)
3939
if (!isAbapFile(node)) return
4040
return this.objRevisions(node.object, refresh)
4141
}

client/src/scm/abaprevisions/commands.ts

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { command, AbapFsCommands } from "../../commands"
22
import { Uri, QuickPickItem, window, commands, workspace, ProgressLocation } from "vscode"
3-
import { abapUri, uriRoot, getOrCreateRoot, getClient } from "../../adt/conections"
3+
import { abapUri, uriRoot, getOrCreateRoot, getClient, ADTSCHEME, rootIsConnected } from "../../adt/conections"
44
import { AbapRevisionService, revLabel } from "./abaprevisionservice"
55
import { ADTClient, Revision } from "abap-adt-api"
66
import { AbapQuickDiff } from "./quickdiff"
@@ -9,11 +9,31 @@ import { RemoteManager, formatKey } from "../../config"
99
import { isAbapFile } from "abapfs"
1010
import { AGroup, AState } from "./abapscm"
1111
import { caughtToString } from "../../lib"
12+
import * as t from "io-ts"
13+
import { isRight } from "fp-ts/lib/Either"
14+
import { vsCodeUri } from "../../langClient"
1215

1316
interface RevisionItem extends QuickPickItem {
1417
label: string
1518
revision: Revision
1619
}
20+
21+
const revision = t.type({
22+
uri: t.string,
23+
date: t.string,
24+
author: t.string,
25+
version: t.string,
26+
versionTitle: t.string
27+
})
28+
const conflictDetails = t.type({
29+
conflicting: t.string,
30+
transport: t.string,
31+
uri: t.string,
32+
incoming: revision,
33+
conflict: revision
34+
})
35+
36+
type ConflictDetails = t.TypeOf<typeof conflictDetails>
1737
const revItems = (revisions: Revision[]): RevisionItem[] =>
1838
revisions.map((r, i) => ({
1939
label: revLabel(r, `revision ${i}`),
@@ -146,7 +166,20 @@ export class AbapRevisionCommands {
146166
displayRevDiff(rightRev, leftRev, uri)
147167
}
148168

149-
@command(AbapFsCommands.mergeEditor)
169+
private static async showMerge(uri: Uri, incomingUri: Uri, incomings: Revision[], locals: Revision[], incoming: Revision, conflict: Revision) {
170+
const baseVer = await pickCommonAncestor(locals, conflict, incomings, incoming)
171+
if (!baseVer) return
172+
const base = revisionUri(uri, baseVer)
173+
174+
const description = uri.path.replace(/.*\//, "")
175+
176+
const input1 = { uri: revisionUri(incomingUri, incoming), title: `Incoming (${incomingUri.authority})`, description, detail: incoming.version }
177+
const input2 = { uri: revisionUri(uri, conflict), title: `Current (${uri.authority})`, description, detail: conflict.version }
178+
const options = { base, input1, input2, output: uri }
179+
return commands.executeCommand<void>("_open.mergeEditor", options)
180+
181+
}
182+
150183
private static async mergeConflicts(uri: Uri) {
151184
if (!abapUri(uri)) return
152185
try {
@@ -174,23 +207,35 @@ export class AbapRevisionCommands {
174207
const locals = await loadRevisions(uri, true)
175208
const localVer = await pickRevision(locals, "Local version")
176209
if (!localVer) return
177-
const baseVer = await pickCommonAncestor(locals, localVer, remotes, remoteVer)
178-
if (!baseVer) return
179-
const base = revisionUri(uri, baseVer)
180-
181-
const description = uri.path.replace(/.*\//, "")
182-
183-
const options = {
184-
base,
185-
input1: { uri: revisionUri(uri, localVer), title: uri.authority, description, detail: localVer.version },
186-
input2: { uri: revisionUri(remoteUri, remoteVer), title: remoteUri.authority, description, detail: remoteVer.version },
187-
output: uri
188-
}
189-
return commands.executeCommand<void>("_open.mergeEditor", options)
210+
return this.showMerge(uri, remoteUri, remotes, locals, remoteVer, localVer)
190211
} catch (e) {
191212
window.showErrorMessage(caughtToString(e))
192213
}
193214
}
215+
private static async mergeEditorByDetails(details: ConflictDetails) {
216+
const remConnId = details.transport.substring(0, 3).toLowerCase()
217+
const connId = details.conflicting.substring(0, 3).toLowerCase()
218+
if (!rootIsConnected(connId)) {
219+
window.showErrorMessage(`Unable to show merge, connection ${connId} is not part of this workspace`)
220+
return
221+
}
222+
await getOrCreateRoot(remConnId)
223+
await getOrCreateRoot(connId)
224+
const path = await vsCodeUri(connId, details.uri, true, true)
225+
const uri = Uri.parse(path)
226+
const incomingUri = uri.with({ authority: remConnId })
227+
const locals = await loadRevisions(uri, true)
228+
const incoming = await loadRevisions(incomingUri, true)
229+
return this.showMerge(uri, incomingUri, incoming, locals, details.incoming, details.conflict)
230+
}
231+
232+
@command(AbapFsCommands.mergeEditor)
233+
private static async mergeEditor(uri: Uri | ConflictDetails) {
234+
const details = conflictDetails.decode(uri)
235+
if (isRight(details)) this.mergeEditorByDetails(details.right)
236+
if (uri instanceof Uri)
237+
this.mergeConflicts(uri)
238+
}
194239
@command(AbapFsCommands.clearScmGroup)
195240
private static clearGroup(group: AGroup) {
196241
group.resourceStates = []

client/src/scm/abaprevisions/documentprovider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TextDocumentContentProvider, Uri, EventEmitter } from "vscode"
22
import { Revision } from "abap-adt-api"
33
import { atob, btoa } from "../../lib"
4-
import { abapUri, ADTSCHEME, getClient, uriRoot } from "../../adt/conections"
4+
import { abapUri, ADTSCHEME, getClient, getOrCreateClient, uriRoot } from "../../adt/conections"
55
import { isAbapFile } from "abapfs"
66
import { prettyPrint } from "./prettyprint"
77
import { AbapQuickDiff } from "./quickdiff"
@@ -71,7 +71,7 @@ export class AbapRevision implements TextDocumentContentProvider {
7171
async provideTextDocumentContent(uri: Uri) {
7272
const { adtUri, selector } = decodeRevisionUri(uri)
7373
if (!adtUri || !selector) return
74-
const client = getClient(uri.authority)
74+
const client = await getOrCreateClient(uri.authority)
7575
let source = ""
7676
if (isQuickDiff(selector)) {
7777
const revision = AbapQuickDiff.get().getCurrentRev(adtUri)

0 commit comments

Comments
 (0)