1
1
mirror of https://github.com/kahole/edamagit.git synced 2024-10-26 09:00:54 +03:00

refactors

This commit is contained in:
kahole 2019-12-18 19:36:06 +01:00
parent f686d5fad4
commit 0bd845e2d8
26 changed files with 227 additions and 437 deletions

View File

@ -1,13 +1,13 @@
## General
- Use existing tooling as much as possible
make magit, but the fancy stuff should be vscode like
- Go for MVP consisting of 90% of common use
- plus all convenient features that come along with it
## Auto refresh
- FileChangeEvent
## Workspaces
- Needs to support multiple workspaces (Already does this somewhat)
- Needs to support multiple workspaces (Already do this somewhat)
- Find out how to deal with status views and other views
- Dispose of stuff when quit workspace etc..
@ -27,6 +27,7 @@
## UI
- icons
https://code.visualstudio.com/api/references/icons-in-labels
e.g $(git-branch)
- Transient interface:
CONFIGURE should be just one action in the list.

View File

@ -1,47 +1,47 @@
import { window, commands } from "vscode";
import { Menu, MenuState } from "../menu/menu";
import { window } from "vscode";
import { Menu, MenuState, MenuUtil } from "../menu/menu";
import { MagitRepository } from "../models/magitRepository";
import MagitUtils from "../utils/magitUtils";
import MagitStatusView from "../views/magitStatusView";
import { Ref } from "../typings/git";
export async function branching(repository: MagitRepository, currentView: MagitStatusView, switches: any = {}) {
const branchingMenu = {
title: "Branching",
commands: [
{ label: "b", description: "Checkout", action: checkout },
{ label: "l", description: "Checkout local branch", action: checkoutLocal },
{ label: "c", description: "Checkout new branch", action: checkoutNewBranch },
// { label: "w", description: "Checkout new worktree", action: checkout },
// { label: "y", description: "Checkout pull-request", action: checkout },
{ label: "s", description: "Create new spin-off", action: createNewSpinoff },
{ label: "n", description: "Create new branch", action: createNewBranch },
// { label: "W", description: "Create new worktree", action: checkout },
// { label: "Y", description: "Create from pull-request", action: checkout },
{ label: "C", description: "Configure", action: checkout },
{ label: "m", description: "Rename", action: renameBranch },
{ label: "x", description: "Reset", action: resetBranch },
{ label: "k", description: "Delete", action: deleteBranch },
]
};
export async function branching(repository: MagitRepository, currentView: MagitStatusView) {
// commands.executeCommand('setContext', 'magit.branching', true);
Menu.showMenu(branchingMap, { repository, currentView });
return MenuUtil.showMenu(branchingMenu, { repository, currentView });
}
const branchingMap = [
{ label: "b", description: "$(git-branch) Checkout", action: checkout },
{ label: "l", description: "Checkout local branch", action: checkoutLocal },
{ label: "c", description: "Checkout new branch", action: checkoutNewBranch },
{ label: "w", description: "Checkout new worktree", action: checkout },
{ label: "y", description: "Checkout pull-request", action: checkout },
{ label: "s", description: "Create new spin-off", action: createNewSpinoff },
{ label: "n", description: "Create new branch", action: createNewBranch },
{ label: "W", description: "Create new worktree", action: checkout },
{ label: "Y", description: "Create from pull-request", action: checkout },
{ label: "C", description: "Configure", action: checkout },
{ label: "m", description: "Rename", action: renameBranch },
{ label: "x", description: "Reset", action: checkout },
{ label: "k", description: "Delete", action: deleteBranch },
];
async function checkout(menuState: MenuState) {
_checkout(menuState, menuState.repository.state.refs);
return _checkout(menuState, menuState.repository.state.refs);
}
async function checkoutLocal(menuState: MenuState) {
_checkout(menuState, menuState.repository.state.refs);
return _checkout(menuState, menuState.repository.state.refs);
}
async function checkoutNewBranch(menuState: MenuState) {
_createBranch(menuState, true);
return _createBranch(menuState, true);
}
async function createNewBranch(menuState: MenuState) {
_createBranch(menuState, false);
return _createBranch(menuState, false);
}
async function createNewSpinoff(menuState: MenuState) {
@ -52,85 +52,78 @@ async function createNewSpinoff(menuState: MenuState) {
// C-h F magit-branch-spinoff
}
async function renameBranch(menuState: MenuState) {
async function renameBranch({ repository, currentView }: MenuState) {
let { repository, currentView } = menuState;
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Rename branch" });
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Create and checkout branch starting at:" });
if (ref) {
let newName = await window.showInputBox({ prompt: `Rename branch '${ref}' to:` });
if (newName && newName.length > 0) {
try {
// TODO: denne kan kun rename current branch
await repository._repository.renameBranch(newName);
MagitUtils.magitStatusAndUpdate(repository, currentView);
} catch (error) {
window.showErrorMessage(error.stderr);
}
// TODO: denne kan kun rename current branch
return await repository._repository.renameBranch(newName);
} else {
window.showErrorMessage("No name given");
throw new Error("No name given for branch rename");
}
}
}
async function deleteBranch(menuState: MenuState) {
async function deleteBranch({ repository, currentView }: MenuState) {
let { repository, currentView } = menuState;
// TODO: menu-title
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Delete" });
// TODO
let force = false;
// TODO:
// If unmerged
// How: maybe try deleting and check the error response for "not fully merged"?
let confirmed = await window.showInputBox({ prompt: `Delete unmerged branch ${ref}?` });
if (confirmed !== undefined) {
force = true;
}
if (ref) {
try {
await repository.deleteBranch(ref, force);
MagitUtils.magitStatusAndUpdate(repository, currentView);
} catch (error) {
window.showErrorMessage(error.stderr);
}
return repository.deleteBranch(ref, force);
}
}
async function resetBranch({ repository, currentView }: MenuState) {
// TODO
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Rename branch" });
let resetToRef = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Rename branch" });
if (ref) {
// repository._repository.reset()
}
}
//--------------------------------
async function _checkout(menuState: MenuState, refs: Ref[]) {
async function _checkout({ repository, currentView }: MenuState, refs: Ref[]) {
let { repository, currentView } = menuState;
// TODO: menu-title
let ref = await window.showQuickPick(refs.map(r => r.name!), { placeHolder: "Checkout" });
if (ref) {
try {
await repository.checkout(ref);
MagitUtils.magitStatusAndUpdate(repository, currentView);
} catch (error) {
window.showErrorMessage(error.stderr);
}
return repository.checkout(ref);
}
}
async function _createBranch(menuState: MenuState, checkout: boolean) {
async function _createBranch({ repository, currentView }: MenuState, checkout: boolean) {
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Create and checkout branch starting at" });
let { repository, currentView } = menuState;
let ref = await window.showQuickPick(repository.state.refs.map(r => r.name!), { placeHolder: "Create and checkout branch starting at:" });
if (ref) {
let newBranchName = await window.showInputBox({ prompt: "Name for new branch" });
if (newBranchName && newBranchName.length > 0) {
try {
await repository.createBranch(newBranchName, checkout, ref);
MagitUtils.magitStatusAndUpdate(repository, currentView);
} catch (error) {
window.showErrorMessage(error.stderr);
}
return repository.createBranch(newBranchName, checkout, ref);
} else {
window.showErrorMessage("No name given for new branch");
}

View File

@ -1,27 +1,41 @@
import MagitUtils from "../utils/magitUtils";
import { MagitRepository } from "../models/magitRepository";
import MagitStatusView from "../views/magitStatusView";
import { TextEditor } from "vscode";
import { TextEditor, window } from "vscode";
export class CommandPrimer {
static primeRepo(command: (repository: MagitRepository) => Promise<void>) {
return (editor: TextEditor) => {
let repository = MagitUtils.getCurrentMagitRepo(editor.document);
// static primeRepo(command: (repository: MagitRepository) => Promise<void>) {
// return (editor: TextEditor) => {
// let repository = MagitUtils.getCurrentMagitRepo(editor.document);
if (repository) {
command(repository);
}
};
}
// if (repository) {
// command(repository);
// }
// };
// }
static primeRepoAndView(command: (repository: MagitRepository, view: MagitStatusView) => Promise<void>): (editor: TextEditor) => void {
static primeRepoAndView(command: (repository: MagitRepository, view: MagitStatusView) => Promise<void>): (editor: TextEditor) => Promise<void> {
return (editor: TextEditor) => {
return async (editor: TextEditor) => {
let [repository, currentView] = MagitUtils.getCurrentMagitRepoAndView(editor);
if (repository && currentView) {
command(repository, currentView);
try {
await command(repository, currentView);
MagitUtils.magitStatusAndUpdate(repository, currentView);
} catch (error) {
// TODO: statusView error message:
// e.g top: GitError! Your local changes to the following files would be overwritten by checkout
// This error type, too heavy for most errors?
// statusBar message might be better
// but then custom, shorter messages are needed
window.showErrorMessage(error.stderr ?? error.message);
}
}
};
}

View File

@ -2,7 +2,7 @@ import { gitApi } from "../extension";
import { exec, spawn, ExecException } from "child_process";
import { window } from "vscode";
import MagitUtils from "../utils/magitUtils";
import { LineSplitterRegex } from "../common/constants";
import * as Constants from "../common/constants";
import { execPath } from "process";
import { MagitRepository } from "../models/magitRepository";
import MagitStatusView from "../views/magitStatusView";
@ -18,9 +18,8 @@ export async function magitCommit(repository: MagitRepository, currentView: Magi
let vscodeExecutablePath = execPath; // Different in debug / developing extension mode than normal vscode mode??
console.log(vscodeExecutablePath);
let gitExecutablePath = gitApi.git.path;
let cwd = repository.rootUri.fsPath;
// let gitExecutablePath = gitApi.git.path;
// let cwd = repository.rootUri.fsPath;
let userEditor: string | undefined;
try {
@ -35,17 +34,19 @@ export async function magitCommit(repository: MagitRepository, currentView: Magi
window.setStatusBarMessage(`Type C-c C-c to finish, or C-c C-k to cancel`);
// TODO:
// Is spawn faster? doesnt spawn a shell
// spawn(gitExecutablePath, ["commit"], { cwd: currentRepository.rootUri.fsPath });
// Which one:
let commitSuccessMessage = await execPromise(`${gitExecutablePath} commit`, cwd);
// let commitSuccessMessage = await execPromise(`${gitExecutablePath} commit`, cwd);
window.setStatusBarMessage(`Git finished: ${commitSuccessMessage.replace(LineSplitterRegex, ' ')}`);
// TODO: this needs to be wrapped, and it needs to decide between run and exec!
let args = ["commit"];
let commitSuccessMessage = await repository._repository.repository.run(args);
window.setStatusBarMessage(`Git finished: ${commitSuccessMessage.stdout.replace(Constants.LineSplitterRegex, ' ')}`, Constants.StatusMessageDisplayTimeout);
} catch (e) {
//YES: Aborting due to empty commit message will appear here
window.setStatusBarMessage(`Commit canceled.`);
console.log(e);
window.setStatusBarMessage(`Commit canceled.`, Constants.StatusMessageDisplayTimeout);
} finally {
if (userEditor) {
repository.setConfig("core.editor", userEditor);
@ -54,19 +55,19 @@ export async function magitCommit(repository: MagitRepository, currentView: Magi
}
}
function execPromise(command: string, cwd: string): Promise<string> {
return new Promise( (resolve, reject) => {
// function execPromise(command: string, cwd: string): Promise<string> {
// return new Promise( (resolve, reject) => {
exec(command, { cwd }, (error, stdout, stderr) => {
if (error) {
reject(stderr);
}
else {
resolve(stdout);
}
});
});
}
// exec(command, { cwd }, (error, stdout, stderr) => {
// if (error) {
// reject(stderr);
// }
// else {
// resolve(stdout);
// }
// });
// });
// }
// function spawnPromise(command: string, args: string[], cwd: string): Promise<string> {
// return new Promise( async (resolve, reject) => {

View File

@ -1,8 +1,6 @@
import { commands } from "vscode";
export function saveClose() {
commands.executeCommand("workbench.action.files.save")
.then(() => {
commands.executeCommand("workbench.action.closeActiveEditor");
});
export async function saveClose() {
await commands.executeCommand("workbench.action.files.save");
return commands.executeCommand("workbench.action.closeActiveEditor");
}

View File

@ -1,15 +1,13 @@
import { MagitPicker } from "../menus/magitPicker";
import { PushingMenu } from "../menus/pushing/pushingMenu";
import MagitUtils from "../utils/magitUtils";
import { MagitRepository } from "../models/magitRepository";
import MagitStatusView from "../views/magitStatusView";
export function pushing(repository: MagitRepository, currentView: MagitStatusView) {
export async function pushing(repository: MagitRepository, currentView: MagitStatusView) {
console.log("Working tree changes, but from pushing command");
console.log(repository.magitState!.workingTreeChanges);
MagitPicker.showMagitPicker(new PushingMenu(undefined, undefined));
// Hvordan git push kommandoen bygges opp:
// https://github.com/microsoft/vscode/blob/master/extensions/git/src/git.ts#L1491

View File

@ -10,75 +10,57 @@ import { MagitRepository } from "../models/magitRepository";
import MagitStatusView from "../views/magitStatusView";
import { Status } from "../typings/git";
export async function magitStage(repository: MagitRepository, currentView: MagitStatusView) {
export async function magitStage(repository: MagitRepository, currentView: MagitStatusView): Promise<any> {
// TODO:
// Bytt til ASYNC-AWAIT!!!!!??????
let selectedView = currentView.click(window.activeTextEditor!.selection.active);
const selectedView = currentView.click(window.activeTextEditor!.selection.active);
if (selectedView instanceof HunkView) {
let changeHunkDiff = (selectedView as HunkView).changeHunk.diff;
const changeHunk = (selectedView as HunkView).changeHunk;
// Clean up
var enc = new TextEncoder();
let tmpPatchFilePath = "/tmp/minmagitdiffpatchting";
workspace.fs.writeFile(Uri.parse("file://" + tmpPatchFilePath),
// TODO: this linebreak might be fucked on windows
enc.encode(selectedView.changeHunk.diffHeader + changeHunkDiff + "\n"))
.then(async () => {
// stage hunk
// await currentRepository
// .apply("/tmp/minmagitdiffpatchting");
const patch = changeHunk.diffHeader + changeHunk.diff + "\n";
let args = ["apply", tmpPatchFilePath, "--cached"];
// TODO: this needs to be wrapped, and it needs to decide between run and exec!
const args = ["apply", "--cached"];
return repository._repository.repository.run(args, { input: patch});
let result = await repository._repository.repository.run(args);
console.log(result);
MagitUtils.magitStatusAndUpdate(repository, currentView);
});
} else if (selectedView instanceof ChangeView) {
let magitChange = (selectedView as ChangeView).change;
const magitChange = (selectedView as ChangeView).change;
await repository
return repository
._repository
.add([magitChange.uri], { update: false/*magitChange.status !== Status.UNTRACKED*/ }); // TODO: litt usikker om update eller ikke
MagitUtils.magitStatusAndUpdate(repository, currentView);
} else if (selectedView instanceof ChangeSectionView) {
let section = (selectedView as ChangeSectionView).section;
// TODO: Add confirmation question?
// only for lowercase s command, not for big S
switch (section) {
case Section.Untracked:
magitStageAll(repository, currentView, StageAllKind.AllUntracked);
break;
return magitStageAll(repository, currentView, StageAllKind.AllUntracked);
case Section.Unstaged:
magitStageAll(repository, currentView, StageAllKind.AllTracked);
break;
return magitStageAll(repository, currentView, StageAllKind.AllTracked);
default:
break;
}
} else {
// TODO:
// Switch to a quick pick where i can pass data, and have a title
// Maybe make a simple wrapper
// This should NOT be the same as a menu!
await window.showQuickPick([
const choosenFilePath = await window.showQuickPick([
...repository.magitState?.workingTreeChanges!,
...repository.magitState?.indexChanges!,
...repository.magitState?.untrackedFiles!,
// ...currentRepository.magitState?.mergeChanges
].map(c => FilePathUtils.pathRelativeTo(c.uri, repository.rootUri)),
{ placeHolder: "Stage" }
)
.then(chosenFilePath => {
);
// TODO: stage file
// return repo . add ( filePath )
});
MagitUtils.magitStatusAndUpdate(repository, currentView);
}
}
@ -88,14 +70,9 @@ export enum StageAllKind {
AllUntracked = "stageAllUntracked"
}
export async function magitStageAll(repository: MagitRepository, currentView: MagitStatusView, kind: StageAllKind = StageAllKind.AllTracked) {
export async function magitStageAll(repository: MagitRepository, currentView: MagitStatusView, kind: StageAllKind = StageAllKind.AllTracked): Promise<void> {
// if (currentView instanceof MagitStatusView) {
await commands.executeCommand("git." + kind.valueOf());
MagitUtils.magitStatusAndUpdate(repository, currentView);
// }
return commands.executeCommand("git." + kind.valueOf());
}
export async function magitUnstage(repository: MagitRepository, currentView: MagitStatusView) {
@ -103,19 +80,19 @@ export async function magitUnstage(repository: MagitRepository, currentView: Mag
// TODO
// For files:
// repository._repository.reset()
// repository._repository.reset(, false);
// For hunks:
// git apply --cached --reverse
// return async task
}
export async function magitUnstageAll(repository: MagitRepository, currentView: MagitStatusView) {
export async function magitUnstageAll(repository: MagitRepository, currentView: MagitStatusView): Promise<void> {
let response = await window.showInputBox({ prompt: "Unstage all changes?" });
if (response !== undefined) {
await commands.executeCommand("git.unstageAll");
MagitUtils.magitStatusAndUpdate(repository, currentView);
let confirmed = await window.showInputBox({ prompt: "Unstage all changes?" });
if (confirmed !== undefined) {
return commands.executeCommand("git.unstageAll");
}
}

View File

@ -2,3 +2,5 @@
export const LineSplitterRegex: RegExp = /\r?\n/g;
export const FinalLineBreakRegex: RegExp = /\r?\n$/g;
export const StatusMessageDisplayTimeout: number = 5;

View File

@ -1,6 +1,6 @@
import { Repository } from "../typings/git";
import { Uri } from "vscode";
import { SpawnOptions } from "child_process";
import * as cp from "child_process";
interface BaseBaseRepository {
run(args: string[], options?: SpawnOptions): Promise<IExecutionResult<string>>;
@ -54,4 +54,12 @@ export interface Stash {
export enum ForcePushMode {
Force,
ForceWithLease
}
interface SpawnOptions extends cp.SpawnOptions {
input?: string;
encoding?: string;
log?: boolean;
// cancellationToken?: CancellationToken;
// onSpawn?: (childProcess: cp.ChildProcess) => void;
}

View File

@ -59,7 +59,7 @@ export function activate(context: ExtensionContext) {
context.subscriptions.push(commands.registerCommand('extension.magit-pushing', pushing));
context.subscriptions.push(commands.registerTextEditorCommand('extension.magit-branching', CommandPrimer.primeRepoAndView(branching)));
context.subscriptions.push(commands.registerTextEditorCommand('extension.magit-stage', CommandPrimer.primeRepoAndView(magitStage)));
context.subscriptions.push(commands.registerCommand('extension.magit-stage-all', CommandPrimer.primeRepoAndView(magitStageAll)));
context.subscriptions.push(commands.registerTextEditorCommand('extension.magit-stage-all', CommandPrimer.primeRepoAndView(magitStageAll)));
context.subscriptions.push(commands.registerTextEditorCommand('extension.magit-unstage', CommandPrimer.primeRepoAndView(magitUnstage)));
context.subscriptions.push(commands.registerTextEditorCommand('extension.magit-unstage-all', CommandPrimer.primeRepoAndView(magitUnstageAll)));

View File

@ -1,9 +1,13 @@
import { QuickPick, window, QuickPickItem, Disposable } from "vscode";
import { window } from "vscode";
import { MenuItem } from "./menuItem";
import { MagitRepository } from "../models/magitRepository";
import MagitStatusView from "../views/magitStatusView";
import { DocumentView } from "../views/general/documentView";
export interface Menu {
title: string;
commands: MenuItem[];
isSwitchesMenu?: boolean;
}
export interface MenuState {
repository: MagitRepository;
@ -12,65 +16,58 @@ export interface MenuState {
switches?: any;
}
export class Menu {
export class MenuUtil {
private _quickPick: QuickPick<MenuItem>;
activeSwitches: any[] = [];
static showMenu(menu: Menu, menuState: MenuState): Promise<void> {
return new Promise((resolve, reject) => {
let _quickPick = window.createQuickPick<MenuItem>();
_quickPick.title = menu.title;
_quickPick.ignoreFocusOut = true;
constructor(menu: MenuItem[], menuState: MenuState, isSwitchesMenu?: boolean) {
this._quickPick = window.createQuickPick<MenuItem>();
this._quickPick.title = "Wow wow we we C - Configure";
if (isSwitchesMenu) {
this._quickPick.canSelectMany = true;
this._quickPick.title = "Switches (select with <space>)";
}
this._quickPick.items = menu;
// Experiments
// TODO: THIS ALSO WORKS PRETTY NICELY
// no duplicate definitions of keybindings+menu keys
// menu becomes actual menu, not just a visual element
// and if it cant be enabled=false anyways, might as well just do it like this
// but keep the notes about the other method
this._quickPick.onDidChangeValue( (e) => {
console.log(e);
console.log(this._quickPick.value);
// TODO
// clean up
let selectedItem = this._quickPick.activeItems.filter(i => i.label === this._quickPick.value);
this._quickPick.value = "";
console.log(selectedItem);
selectedItem[0].action(menuState);
this._quickPick.dispose(); //??
});
// end Experiments
this._quickPick.onDidAccept(() => {
if (this._quickPick.activeItems.length > 0) {
let chosenItem = this._quickPick.activeItems[0] as MenuItem;
chosenItem.action(menuState);
if (menu.isSwitchesMenu) {
_quickPick.canSelectMany = true;
_quickPick.title = "Switches (select with <space>)";
}
_quickPick.items = menu.commands;
let eventListenerDisposable = _quickPick.onDidChangeValue( async (e) => {
console.log(e);
console.log(_quickPick.value);
// TODO
// clean up
let chosenItem = _quickPick.activeItems.filter(i => i.label === _quickPick.value);
_quickPick.value = "";
try {
await chosenItem[0].action(menuState);
resolve();
} catch (error) {
reject(error);
}
_quickPick.dispose(); //??
eventListenerDisposable.dispose(); //??
});
// Keep both of these (Select with key or with arrows + enter)
_quickPick.onDidAccept(async () => {
if (_quickPick.activeItems.length > 0) {
let chosenItem = _quickPick.activeItems[0] as MenuItem;
try {
await chosenItem.action(menuState);
resolve();
} catch (error) {
reject(error);
}
}
});
_quickPick.show();
});
}
show() {
this._quickPick.show();
this._quickPick.ignoreFocusOut = true;
// this._quickPick.enabled = false;
// this._quickPick.dispose();
}
static showMenu(menu: MenuItem[], menuState: MenuState, isSwitchesMenu?: boolean) {
new Menu(menu, menuState, isSwitchesMenu).show();
}
}

View File

@ -1,8 +0,0 @@
import { MenuItem } from "./menuItem";
export interface Menu {
title?: string;
items: MenuItem[];
onDidAcceptItems(acceptedItems: readonly MenuItem[]): Menu | undefined;
isSwitchesMenu?: boolean;
}

View File

@ -1,5 +0,0 @@
import { QuickPick, QuickPickItem, window } from "vscode";
export interface MenuItem extends QuickPickItem {
id: number;
}

View File

@ -1,43 +0,0 @@
import { Menu } from "../abstract/menu";
import { MenuItem } from "../abstract/menuItem";
import { MagitState } from "../../models/magitState";
import { BranchingMenuItem } from "./branchingMenuSelection";
export class BranchingMenu implements Menu {
title: string = "Branching";
items: MenuItem[];
constructor() {
this.items = [
{id: BranchingMenuItem.Checkout , label: "b", description: "Checkout"},
{id: BranchingMenuItem.Configure , label: "C", description: "Configure"},
{id: BranchingMenuItem.CreateNewSpinoff , label: "s", description: "Create new spin-off"},
{id: BranchingMenuItem.CheckoutNewBranch , label: "c", description: "Checkout new branch"},
{id: BranchingMenuItem.Reset , label: "x", description: "Reset"},
{id: BranchingMenuItem.CreateNewWorktree , label: "W", description: "Create new worktree"},
{id: BranchingMenuItem.CheckoutPullRequest , label: "y", description: "Checkout pull-request"},
{id: BranchingMenuItem.CheckoutLocalBranch , label: "l", description: "Checkout local branch"},
{id: BranchingMenuItem.Rename , label: "m", description: "Rename"},
{id: BranchingMenuItem.CreateNewBranch , label: "n", description: "Create new branch"},
{id: BranchingMenuItem.CheckoutNewWorktree , label: "w", description: "Checkout new worktree"},
{id: BranchingMenuItem.Delete , label: "k", description: "Delete"},
{id: BranchingMenuItem.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 BranchingMenuItem.Checkout:
// branchQuickPick.hide();
// window.showQuickPick(["master", "exp", "origin/master"]);
default:
return undefined;
}
}
}

View File

@ -1,21 +0,0 @@
import { BranchingMenu } from "./branchingMenu";
export enum BranchingMenuItem {
Checkout,
Configure,
CreateNewSpinoff,
CheckoutNewBranch,
Reset,
CreateNewWorktree,
CheckoutPullRequest,
CheckoutLocalBranch,
Rename,
CreateNewBranch,
CheckoutNewWorktree,
Delete,
CreateFromPullRequest
}
export interface BranchingMenuSelection {
item: BranchingMenuItem;
}

View File

@ -1,41 +0,0 @@
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();
}
}

View File

@ -1,8 +0,0 @@
import { ForcePushMode } from "../../../common/gitApiExtensions";
export interface PushingOutput {
remote?: string;
name?: string;
setUpstream?: boolean;
forcePushMode?: ForcePushMode;
}

View File

@ -1,31 +0,0 @@
import { Menu } from "../abstract/menu";
import { MenuItem } from "../abstract/menuItem";
import { PushingSwitches } from "./switches";
enum Items {
Switches
}
export class PushingMenu implements Menu {
title: string = "Pushing";
items: MenuItem[];
constructor(remote?: string, upstream?: string) {
// 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;
}
}
}

View File

@ -1,44 +0,0 @@
import { Menu } from "../abstract/menu";
import { MenuItem } from "../abstract/menuItem";
import { MagitState } from "../../models/magitState";
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;
}
}
}

View File

@ -1,7 +1,5 @@
import { Uri } from "vscode";
export interface MagitChangeHunk {
diff: string;
diffHeader: string;
uri: Uri; // TODO: blir ikke brukt?
}

View File

@ -2,7 +2,7 @@ import { View } from "../general/view";
import { MagitChange } from "../../models/magitChange";
import { ChangeView } from "./changeView";
import { Section, SectionHeaderView } from "../sectionHeader";
import { LineBreakView } from "../lineBreakView";
import { LineBreakView } from "../general/lineBreakView";
export class ChangeSectionView extends View {
isFoldable = true;

View File

@ -0,0 +1,5 @@
// TODO: husk at alle keybindings virker her også. Akkurat som statusView
// Derfor må documentView sendes rundt

View File

@ -1,9 +1,8 @@
import { View } from "../general/view";
import { Section, SectionHeaderView } from "../sectionHeader";
import { LineBreakView } from "../lineBreakView";
import { Stash } from "../../common/gitApiExtensions";
import { TextView } from "../general/textView";
import { Commit } from "../../typings/git";
import { LineBreakView } from "../general/lineBreakView";
export class CommitSectionView extends View {
isFoldable = true;

View File

@ -1,4 +1,4 @@
import { TextView } from "./general/textView";
import { TextView } from "./textView";
export class LineBreakView extends TextView {

View File

@ -7,7 +7,7 @@ import { StashSectionView } from './stashes/stashSectionView';
import { CommitSectionView } from './commits/commitSectionView';
import { BranchHeaderView } from './branches/branchHeaderView';
import { TextView } from './general/textView';
import { LineBreakView } from './lineBreakView';
import { LineBreakView } from './general/lineBreakView';
export default class MagitStatusView extends DocumentView implements vscode.Disposable {

View File

@ -1,8 +1,8 @@
import { View } from "../general/view";
import { Section, SectionHeaderView } from "../sectionHeader";
import { LineBreakView } from "../lineBreakView";
import { Stash } from "../../common/gitApiExtensions";
import { TextView } from "../general/textView";
import { LineBreakView } from "../general/lineBreakView";
export class StashSectionView extends View {
isFoldable = true;