mirror of
https://github.com/kahole/edamagit.git
synced 2024-09-11 07:15:31 +03:00
refactor, create menu system
This commit is contained in:
parent
e82e8a8737
commit
0a6b90bf58
@ -1,7 +1,7 @@
|
||||
{
|
||||
"folding": {
|
||||
"markers": {
|
||||
"start": "^(Untracked files)|((Unstaged|Staged) changes)|(Recent commits)",
|
||||
"start": "^(Untracked files)|((Unstaged|Staged) changes)|(Stashes)|(Recent commits)",
|
||||
"end": "^\\.$"
|
||||
}
|
||||
}
|
||||
|
30
package.json
30
package.json
@ -26,19 +26,33 @@
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-key-b",
|
||||
"title": "Magit Branch",
|
||||
"title": "Magit Branching",
|
||||
"when": "editorLangId == magit-status"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-pushing",
|
||||
"title": "Magit Pushing",
|
||||
"when": "editorLangId == magit-status"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-help",
|
||||
"title": "Magit Help",
|
||||
"when": "editorLangId == magit-status"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "extension.magit-key-b",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-choose",
|
||||
"when": "editorLangId == magit-status"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-key-b",
|
||||
"when": "false && editorLangId == magit-status"
|
||||
"command": "extension.magit-pushing",
|
||||
"when": "editorLangId == magit-status"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -72,6 +86,16 @@
|
||||
"command": "extension.magit-key-b",
|
||||
"key": "b",
|
||||
"when": "editorTextFocus && editorLangId == magit-status"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-pushing",
|
||||
"key": "shift+p",
|
||||
"when": "editorTextFocus && editorLangId == magit-status"
|
||||
},
|
||||
{
|
||||
"command": "extension.magit-help",
|
||||
"key": "?",
|
||||
"when": "editorTextFocus && editorLangId == magit-status"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
6
src/commands/branchingCommands.ts
Normal file
6
src/commands/branchingCommands.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { BranchingMenu } from "../menus/branching/branchingMenu";
|
||||
import { MagitPicker } from "../menus/magitPicker";
|
||||
|
||||
export function branching() {
|
||||
MagitPicker.showMagitPicker(new BranchingMenu());
|
||||
}
|
23
src/commands/helpCommands.ts
Normal file
23
src/commands/helpCommands.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { window } from "vscode";
|
||||
|
||||
export function magitHelp() {
|
||||
window.showInformationMessage(`Popup and dwim commands
|
||||
A Cherry-picking b Branching B Bisecting c Committing
|
||||
d Diffing D Change diffs e Ediff dwimming E Ediffing
|
||||
f Fetching F Pulling l Logging L Change logs
|
||||
m Merging M Remoting o Submodules O Subtrees
|
||||
P Pushing r Rebasing t Tagging T Notes
|
||||
V Reverting w Apply patches W Format patches X Resetting
|
||||
y Show Refs z Stashing ! Running % Worktree
|
||||
|
||||
Applying changes
|
||||
a Apply s Stage u Unstage
|
||||
v Reverse S Stage all U Unstage all
|
||||
k Discard
|
||||
|
||||
Essential commands
|
||||
g refresh current buffer
|
||||
TAB toggle section at point
|
||||
RET visit thing at point
|
||||
C-h m show all key bindings `);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { MagitState } from "../model/magitStatus";
|
||||
|
||||
// export async function magitStatus() : Promise<MagitStatus> {
|
||||
// return {
|
||||
// head: "",
|
||||
// untrackedFiles: [],
|
||||
// unstagedChanges: [],
|
||||
// stashes: [],
|
||||
// recentCommits: []
|
||||
// };
|
||||
// }
|
7
src/commands/pushingCommands.ts
Normal file
7
src/commands/pushingCommands.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { MagitPicker } from "../menus/magitPicker";
|
||||
import { PushingMenu } from "../menus/pushing/pushingMenu";
|
||||
|
||||
|
||||
export function pushing() {
|
||||
MagitPicker.showMagitPicker(new PushingMenu());
|
||||
}
|
94
src/commands/statusCommands.ts
Normal file
94
src/commands/statusCommands.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import { MagitState } from "../model/magitStatus";
|
||||
import { MagitChange } from "../model/magitChange";
|
||||
import { encodeLocation } from "../contentProvider";
|
||||
import { workspace, window, ViewColumn } from "vscode";
|
||||
import { gitApi, magitStates } from "../extension";
|
||||
import { isDescendant, keepOnlyChunksFromDiff } from "../util";
|
||||
import { Repository, Status } from "../typings/git";
|
||||
|
||||
export function magitStatus() {
|
||||
|
||||
if (workspace.workspaceFolders && workspace.workspaceFolders[0]) {
|
||||
|
||||
const rootPath = workspace.workspaceFolders[0].uri.fsPath;
|
||||
const repository = gitApi.repositories.filter(r => isDescendant(r.rootUri.fsPath, rootPath))[0];
|
||||
|
||||
const uri = encodeLocation(rootPath);
|
||||
|
||||
MagitStatus(repository)
|
||||
.then(m => {
|
||||
magitStates[uri.query] = m;
|
||||
workspace.openTextDocument(uri).then(doc => window.showTextDocument(doc, ViewColumn.Beside));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function MagitStatus(repository: Repository): Promise<MagitState> {
|
||||
|
||||
await repository.status();
|
||||
|
||||
let stashTask = repository._repository.getStashes();
|
||||
|
||||
let logTask = repository.log({ maxEntries: 10 });
|
||||
|
||||
let commitTasks = Promise.all(
|
||||
[repository.state.HEAD!.commit!]
|
||||
.map(c => repository.getCommit(c)));
|
||||
// .map(repository.getCommit));
|
||||
|
||||
let untrackedFiles: MagitChange[] = [];
|
||||
|
||||
let workingTreeChanges_NoUntracked = repository.state.workingTreeChanges
|
||||
.filter( c => {
|
||||
if (c.status === Status.UNTRACKED) {
|
||||
untrackedFiles.push(c);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
let workingTreeChangesTasks = Promise.all(workingTreeChanges_NoUntracked
|
||||
.map(change =>
|
||||
repository.diffWithHEAD(change.uri.path)
|
||||
.then(keepOnlyChunksFromDiff)
|
||||
.then<MagitChange>(diff => {
|
||||
let magitChange: MagitChange = change;
|
||||
magitChange.diff = diff;
|
||||
return magitChange;
|
||||
})
|
||||
));
|
||||
|
||||
let indexChangesTasks = Promise.all(repository.state.indexChanges
|
||||
.map(change =>
|
||||
repository.diffIndexWithHEAD(change.uri.path)
|
||||
.then(keepOnlyChunksFromDiff)
|
||||
.then<MagitChange>(diff => {
|
||||
let magitChange: MagitChange = change;
|
||||
magitChange.diff = diff;
|
||||
return magitChange;
|
||||
})
|
||||
));
|
||||
|
||||
let [commits, workingTreeChanges, indexChanges, stashes, log] =
|
||||
await Promise.all([
|
||||
commitTasks,
|
||||
workingTreeChangesTasks,
|
||||
indexChangesTasks,
|
||||
stashTask,
|
||||
logTask
|
||||
]);
|
||||
|
||||
let commitCache = commits.reduce((prev, commit) => ({ ...prev, [commit.hash]: commit }), {});
|
||||
|
||||
return {
|
||||
_state: repository.state,
|
||||
stashes,
|
||||
log,
|
||||
commitCache,
|
||||
workingTreeChanges,
|
||||
indexChanges,
|
||||
mergeChanges: undefined,
|
||||
untrackedFiles
|
||||
};
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { MagitState, Change } from '../model/magitStatus';
|
||||
import { MagitState } from '../model/magitStatus';
|
||||
import { MagitChange } from "../model/magitChange";
|
||||
import { Status } from '../typings/git';
|
||||
|
||||
export default class StatusDocument {
|
||||
@ -45,10 +46,19 @@ export default class StatusDocument {
|
||||
this._lines.push(this.SECTION_FOLD_REGION_END);
|
||||
}
|
||||
|
||||
if (magitStatus.stashes) {
|
||||
this._lines.push(`Stashes (${magitStatus.stashes.length})`);
|
||||
magitStatus.stashes
|
||||
.forEach(stash => {
|
||||
this._lines.push(`stash@{${stash.index}} ${stash.description}`);
|
||||
});
|
||||
this._lines.push(this.SECTION_FOLD_REGION_END);
|
||||
}
|
||||
|
||||
if (magitStatus.log) {
|
||||
this._lines.push(`Recent commits`);
|
||||
magitStatus.log
|
||||
.forEach(commit => {
|
||||
this._lines.push(`Recent commits`);
|
||||
this._lines.push(`${commit.hash.slice(0, 7)} ${commit.message}`);
|
||||
});
|
||||
this._lines.push(this.SECTION_FOLD_REGION_END);
|
||||
@ -57,7 +67,7 @@ export default class StatusDocument {
|
||||
this._lines.push('');
|
||||
}
|
||||
|
||||
private renderChanges(changes: Change[]) : string[] {
|
||||
private renderChanges(changes: MagitChange[]) : string[] {
|
||||
return changes
|
||||
.map(change => `${mapFileStatusToLabel(change.status)} ${change.uri.path}${change.diff ? '\n' + change.diff : ''}`);
|
||||
}
|
||||
|
@ -1,46 +1,48 @@
|
||||
import { workspace, languages, window, extensions, commands, ExtensionContext, Disposable, ViewColumn, FileChangeType } from 'vscode';
|
||||
import ContentProvider, { encodeLocation } from './contentProvider';
|
||||
import { GitExtension } from './typings/git';
|
||||
import { MagitStatus, MagitState } from './model/magitStatus';
|
||||
import { isDescendant } from './util';
|
||||
import { workspace, extensions, commands, ExtensionContext, Disposable } from 'vscode';
|
||||
import ContentProvider from './contentProvider';
|
||||
import { GitExtension, API } from './typings/git';
|
||||
import { pushing } from './commands/pushingCommands';
|
||||
import { branching } from './commands/branchingCommands';
|
||||
import { magitHelp } from './commands/helpCommands';
|
||||
import { magitStatus } from './commands/statusCommands';
|
||||
import { MagitState } from './model/magitStatus';
|
||||
|
||||
export let magitStates: {[id: string]: MagitState} = {};
|
||||
export let magitStates: { [id: string]: MagitState } = {};
|
||||
export let gitApi: API;
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
|
||||
if (workspace.workspaceFolders && workspace.workspaceFolders[0]) {
|
||||
|
||||
let gitExtension = extensions.getExtension<GitExtension>('vscode.git')!.exports;
|
||||
if (!gitExtension.enabled) {
|
||||
throw new Error("vscode.git Git extension not enabled");
|
||||
}
|
||||
const gitApi = gitExtension.getAPI(1);
|
||||
|
||||
const rootPath = workspace.workspaceFolders[0].uri.fsPath;
|
||||
const repository = gitApi.repositories.filter(r => isDescendant(r.rootUri.fsPath, rootPath))[0];
|
||||
|
||||
const provider = new ContentProvider();
|
||||
|
||||
const providerRegistrations = Disposable.from(
|
||||
workspace.registerTextDocumentContentProvider(ContentProvider.scheme, provider)
|
||||
);
|
||||
|
||||
let disposable = commands.registerCommand('extension.magit', async () => {
|
||||
const uri = encodeLocation(rootPath);
|
||||
|
||||
MagitStatus(repository)
|
||||
.then(m => {
|
||||
magitStates[uri.query] = m;
|
||||
workspace.openTextDocument(uri).then(doc => window.showTextDocument(doc, ViewColumn.Beside));
|
||||
});
|
||||
});
|
||||
|
||||
context.subscriptions.push(
|
||||
provider,
|
||||
providerRegistrations,
|
||||
disposable
|
||||
);
|
||||
let gitExtension = extensions.getExtension<GitExtension>('vscode.git')!.exports;
|
||||
if (!gitExtension.enabled) {
|
||||
throw new Error("vscode.git Git extension not enabled");
|
||||
}
|
||||
// TODO: Ikke sikkert dette er et problem. Kan være magit virker fortsatt!
|
||||
// gitExtension.onDidChangeEnablement(enabled => {
|
||||
// if (!enabled) {
|
||||
// throw new Error("vscode.git Git extension was disabled");
|
||||
// }
|
||||
// });
|
||||
gitApi = gitExtension.getAPI(1);
|
||||
// gitExecutablePath = gitApi.git.path;
|
||||
|
||||
const provider = new ContentProvider();
|
||||
|
||||
const providerRegistrations = Disposable.from(
|
||||
workspace.registerTextDocumentContentProvider(ContentProvider.scheme, provider)
|
||||
);
|
||||
context.subscriptions.push(
|
||||
provider,
|
||||
providerRegistrations,
|
||||
);
|
||||
|
||||
context.subscriptions.push(commands.registerCommand('extension.magit', magitStatus));
|
||||
context.subscriptions.push(commands.registerCommand('extension.magit-help', magitHelp));
|
||||
context.subscriptions.push(commands.registerCommand('extension.magit-key-F', async () => {
|
||||
// TODO: Options should be dynamically decided based on whether or not they can be done
|
||||
// e.g Pull in magit with no remotes results in: e elsewhere
|
||||
}));
|
||||
context.subscriptions.push(commands.registerCommand('extension.magit-pushing', pushing));
|
||||
context.subscriptions.push(commands.registerCommand('extension.magit-key-b', branching));
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
|
37
src/gitApiExtensions.ts
Normal file
37
src/gitApiExtensions.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { Repository } from "./typings/git";
|
||||
|
||||
export interface BaseRepository extends Repository {
|
||||
getStashes(): Promise<Stash[]>;
|
||||
pushTo(remote?: string, name?: string, setUpstream?: boolean, forcePushMode?: ForcePushMode): Promise<void>;
|
||||
}
|
||||
|
||||
// Repository.prototype.getStashes = function(this: any) {
|
||||
// return this._repository.getStashes();
|
||||
// };
|
||||
|
||||
declare module "./typings/git" {
|
||||
export interface Repository {
|
||||
readonly _repository: BaseRepository;
|
||||
}
|
||||
}
|
||||
|
||||
// Repository.prototype.getStashes = function(this: any) {
|
||||
// return this._repository.getStashes();
|
||||
// };
|
||||
|
||||
// (Repository.fn as any).getStashes = function () {
|
||||
// const _self = this as moment.Moment;
|
||||
// return _self.year() - 1911;
|
||||
// }
|
||||
|
||||
// types from /extensions/git/src/git.ts
|
||||
|
||||
export interface Stash {
|
||||
index: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export enum ForcePushMode {
|
||||
Force,
|
||||
ForceWithLease
|
||||
}
|
8
src/menus/abstract/menu.ts
Normal file
8
src/menus/abstract/menu.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { MenuItem } from "./menuItem";
|
||||
|
||||
export interface Menu {
|
||||
title?: string;
|
||||
items: MenuItem[];
|
||||
onDidAcceptItems(acceptedItems: readonly MenuItem[]): Menu | undefined;
|
||||
isSwitchesMenu?: boolean;
|
||||
}
|
5
src/menus/abstract/menuItem.ts
Normal file
5
src/menus/abstract/menuItem.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { QuickPick, QuickPickItem, window } from "vscode";
|
||||
|
||||
export interface MenuItem extends QuickPickItem {
|
||||
id: number;
|
||||
}
|
57
src/menus/branching/branchingMenu.ts
Normal file
57
src/menus/branching/branchingMenu.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { Menu } from "../abstract/menu";
|
||||
import { MenuItem } from "../abstract/menuItem";
|
||||
import { MagitState } from "../../model/magitStatus";
|
||||
|
||||
enum Items {
|
||||
Checkout,
|
||||
Configure,
|
||||
CreateNewSpinoff,
|
||||
CheckoutNewBranch,
|
||||
Reset,
|
||||
CreateNewWorktree,
|
||||
CheckoutPullRequest,
|
||||
CheckoutLocalBranch,
|
||||
Rename,
|
||||
CreateNewBranch,
|
||||
CheckoutNewWorktree,
|
||||
Delete,
|
||||
CreateFromPullRequest
|
||||
}
|
||||
|
||||
export class BranchingMenu implements Menu {
|
||||
|
||||
title: string = "Branching";
|
||||
items: MenuItem[];
|
||||
|
||||
constructor() {
|
||||
this.items = [
|
||||
{id: Items.Checkout , label: "b", description: "Checkout"},
|
||||
{id: Items.Configure , label: "C", description: "Configure"},
|
||||
{id: Items.CreateNewSpinoff , label: "s", description: "Create new spin-off"},
|
||||
{id: Items.CheckoutNewBranch , label: "c", description: "Checkout new branch"},
|
||||
{id: Items.Reset , label: "x", description: "Reset"},
|
||||
{id: Items.CreateNewWorktree , label: "W", description: "Create new worktree"},
|
||||
{id: Items.CheckoutPullRequest , label: "y", description: "Checkout pull-request"},
|
||||
{id: Items.CheckoutLocalBranch , label: "l", description: "Checkout local branch"},
|
||||
{id: Items.Rename , label: "m", description: "Rename"},
|
||||
{id: Items.CreateNewBranch , label: "n", description: "Create new branch"},
|
||||
{id: Items.CheckoutNewWorktree , label: "w", description: "Checkout new worktree"},
|
||||
{id: Items.Delete , label: "k", description: "Delete"},
|
||||
{id: Items.CreateFromPullRequest , label: "Y", description: "Create from pull-request"}
|
||||
];
|
||||
}
|
||||
|
||||
onDidAcceptItems(acceptedItems: readonly MenuItem[]): Menu | undefined {
|
||||
|
||||
// Weak abstraction in this function
|
||||
let firstItem = acceptedItems[0];
|
||||
|
||||
switch (firstItem.id) {
|
||||
case Items.Checkout:
|
||||
// branchQuickPick.hide();
|
||||
// window.showQuickPick(["master", "exp", "origin/master"]);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
41
src/menus/magitPicker.ts
Normal file
41
src/menus/magitPicker.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { QuickPick, window } from "vscode";
|
||||
import { MenuItem } from "./abstract/menuItem";
|
||||
import { Menu } from "./abstract/menu";
|
||||
|
||||
export class MagitPicker {
|
||||
|
||||
private _quickPick: QuickPick<MenuItem>;
|
||||
|
||||
static showMagitPicker(menu: Menu) {
|
||||
new MagitPicker(menu).show();
|
||||
}
|
||||
|
||||
constructor(private _menu: Menu) {
|
||||
this._quickPick = window.createQuickPick();
|
||||
|
||||
this.loadMenu(this._menu);
|
||||
|
||||
this._quickPick.onDidAccept(() => {
|
||||
let nextMenu = this._menu.onDidAcceptItems(this._quickPick.activeItems);
|
||||
if (nextMenu) {
|
||||
this._menu = nextMenu;
|
||||
this.loadMenu(this._menu);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadMenu(menu: Menu) {
|
||||
this._quickPick.title = menu.title;
|
||||
|
||||
if (menu.isSwitchesMenu) {
|
||||
this._quickPick.canSelectMany = true;
|
||||
this._quickPick.title = "Switches (select with <space>)";
|
||||
}
|
||||
|
||||
this._quickPick.items = menu.items;
|
||||
}
|
||||
|
||||
show() {
|
||||
this._quickPick.show();
|
||||
}
|
||||
}
|
32
src/menus/pushing/pushingMenu.ts
Normal file
32
src/menus/pushing/pushingMenu.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { Menu } from "../abstract/menu";
|
||||
import { MenuItem } from "../abstract/menuItem";
|
||||
import { MagitState } from "../../model/magitStatus";
|
||||
import { PushingSwitches } from "./switches";
|
||||
|
||||
enum Items {
|
||||
Switches
|
||||
}
|
||||
|
||||
export class PushingMenu implements Menu {
|
||||
|
||||
title: string = "Pushing";
|
||||
items: MenuItem[];
|
||||
|
||||
constructor() {
|
||||
// TODO: take in some state to customize and narrow selection!
|
||||
this.items = [{id: Items.Switches, label: "-", description: "Switches"}];
|
||||
}
|
||||
|
||||
onDidAcceptItems(acceptedItems: readonly MenuItem[]): Menu | undefined {
|
||||
|
||||
// Weak abstraction in this function
|
||||
let firstItem = acceptedItems[0];
|
||||
|
||||
switch (firstItem.id) {
|
||||
case Items.Switches:
|
||||
return new PushingSwitches();
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
44
src/menus/pushing/switches.ts
Normal file
44
src/menus/pushing/switches.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Menu } from "../abstract/menu";
|
||||
import { MenuItem } from "../abstract/menuItem";
|
||||
import { MagitState } from "../../model/magitStatus";
|
||||
|
||||
enum Items {
|
||||
ForceWithLease,
|
||||
Force,
|
||||
DisableHooks,
|
||||
DryRun
|
||||
}
|
||||
|
||||
export class PushingSwitches implements Menu {
|
||||
|
||||
items: MenuItem[];
|
||||
isSwitchesMenu = true;
|
||||
|
||||
constructor() {
|
||||
this.items = [
|
||||
{ id: Items.ForceWithLease, label: "-f", description: "force with lease (--force-with-lease)" },
|
||||
{ id: Items.Force, label: "-F", description: "force (--force)" },
|
||||
{ id: Items.DisableHooks, label: "-h", description: "disable hooks (--no-verify)" },
|
||||
{ id: Items.DryRun, label: "-d", description: "Dry run (--dry-run)" },
|
||||
];
|
||||
}
|
||||
|
||||
onDidAcceptItems(acceptedItems: readonly MenuItem[]): Menu | undefined {
|
||||
|
||||
// Weak abstraction in this function
|
||||
let firstItem = acceptedItems[0];
|
||||
|
||||
switch (firstItem.id) {
|
||||
case Items.ForceWithLease:
|
||||
return undefined;
|
||||
case Items.Force:
|
||||
return undefined;
|
||||
case Items.DisableHooks:
|
||||
return undefined;
|
||||
case Items.DryRun:
|
||||
return undefined;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
5
src/model/magitChange.ts
Normal file
5
src/model/magitChange.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { Change } from "../typings/git";
|
||||
|
||||
export interface MagitChange extends Change {
|
||||
diff?: string;
|
||||
}
|
@ -1,100 +1,14 @@
|
||||
import { RepositoryState, Commit, Repository, Change as GitChange, Status } from "../typings/git";
|
||||
|
||||
export interface Change extends GitChange {
|
||||
diff?: string;
|
||||
}
|
||||
import { RepositoryState, Commit } from "../typings/git";
|
||||
import { Stash } from "../gitApiExtensions";
|
||||
import { MagitChange } from "./magitChange";
|
||||
|
||||
export interface MagitState {
|
||||
_state: RepositoryState; // TODO: shouldnt need this?
|
||||
readonly stashes?: Commit[];
|
||||
readonly log?: Commit[];
|
||||
readonly commitCache: { [id: string]: Commit; }; // TODO: rigid model with everything needed better?
|
||||
readonly workingTreeChanges?: Change[];
|
||||
readonly indexChanges?: Change[];
|
||||
readonly mergeChanges?: Change[];
|
||||
readonly untrackedFiles?: Change[];
|
||||
}
|
||||
|
||||
export async function MagitStatus(repository: Repository): Promise<MagitState> {
|
||||
|
||||
await repository.status();
|
||||
|
||||
let logTask = repository.log({ maxEntries: 10 });
|
||||
|
||||
let commitTasks = Promise.all(
|
||||
[repository.state.HEAD!.commit!]
|
||||
.map(c => repository.getCommit(c)));
|
||||
// .map(repository.getCommit));
|
||||
|
||||
let untrackedFiles: Change[] = [];
|
||||
|
||||
let workingTreeChanges_NoUntracked = repository.state.workingTreeChanges
|
||||
.filter( c => {
|
||||
if (c.status === Status.UNTRACKED) {
|
||||
untrackedFiles.push(c);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
let workingTreeChangesTasks = Promise.all(workingTreeChanges_NoUntracked
|
||||
.map(change =>
|
||||
repository.diffWithHEAD(change.uri.path)
|
||||
.then(getOnlyChunksFromDiff)
|
||||
.then<Change>(diff => {
|
||||
let magitChange: Change = change;
|
||||
magitChange.diff = diff;
|
||||
return magitChange;
|
||||
})
|
||||
));
|
||||
|
||||
let indexChangesTasks = Promise.all(repository.state.indexChanges
|
||||
.map(change =>
|
||||
repository.diffIndexWithHEAD(change.uri.path)
|
||||
.then(getOnlyChunksFromDiff)
|
||||
.then<Change>(diff => {
|
||||
let magitChange: Change = change;
|
||||
magitChange.diff = diff;
|
||||
return magitChange;
|
||||
})
|
||||
));
|
||||
|
||||
let [log, commits, workingTreeChanges, indexChanges] =
|
||||
await Promise.all([
|
||||
logTask,
|
||||
commitTasks,
|
||||
workingTreeChangesTasks,
|
||||
indexChangesTasks
|
||||
]);
|
||||
|
||||
let commitCache = commits.reduce((prev, commit) => ({ ...prev, [commit.hash]: commit }), {});
|
||||
|
||||
return {
|
||||
_state: repository.state,
|
||||
stashes: undefined,
|
||||
log,
|
||||
commitCache,
|
||||
workingTreeChanges,
|
||||
indexChanges,
|
||||
mergeChanges: undefined,
|
||||
untrackedFiles
|
||||
};
|
||||
}
|
||||
|
||||
function getOnlyChunksFromDiff(diff: string): string {
|
||||
return diff.substring(diff.indexOf("@@"));
|
||||
}
|
||||
|
||||
// function inflateChanges(changes: GitChange[]) : Promise<Change[]> {
|
||||
// return Promise.all(changes
|
||||
// .map(change =>
|
||||
// repository.diffIndexWithHEAD(change.uri.path)
|
||||
// .then(getOnlyChunksFromDiff)
|
||||
// .then<Change>(diff => {
|
||||
// let magitChange: Change = change;
|
||||
// magitChange.diff = diff;
|
||||
// return magitChange;
|
||||
// })
|
||||
// ));
|
||||
// }
|
||||
readonly workingTreeChanges?: MagitChange[];
|
||||
readonly indexChanges?: MagitChange[];
|
||||
readonly mergeChanges?: MagitChange[];
|
||||
readonly untrackedFiles?: MagitChange[];
|
||||
readonly stashes?: Stash[];
|
||||
readonly log?: Commit[];
|
||||
}
|
@ -21,4 +21,8 @@ export function isDescendant(parent: string, descendant: string): boolean {
|
||||
}
|
||||
|
||||
return descendant.startsWith(parent);
|
||||
}
|
||||
|
||||
export function keepOnlyChunksFromDiff(diff: string): string {
|
||||
return diff.substring(diff.indexOf("@@"));
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
"patterns": [{ "include": "#sectionHeader" }, { "include": "#branchName" }]
|
||||
},
|
||||
"sectionHeader": {
|
||||
"match": "Untracked files|((Unstaged|Staged) changes)|Recent commits",
|
||||
"match": "Untracked files|((Unstaged|Staged) changes)|Stashes|Recent commits",
|
||||
"name": "keyword.sectionHeader",
|
||||
"comment": ";; kan bruke markup.bold.sectionHeader"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user