From 115c4baccaaf0e905fa8eefee8cb5f35abfff88f Mon Sep 17 00:00:00 2001 From: Vinzent Date: Fri, 12 Jul 2024 01:29:03 +0200 Subject: [PATCH] feat: add context menu to git views close #615 --- src/main.ts | 131 ++++++++++-------- .../components/logFileComponent.svelte | 13 +- .../components/fileComponent.svelte | 12 +- .../components/pulledFileComponent.svelte | 11 +- .../components/stagedFileComponent.svelte | 11 +- .../components/treeComponent.svelte | 9 ++ src/utils.ts | 21 ++- 7 files changed, 139 insertions(+), 69 deletions(-) diff --git a/src/main.ts b/src/main.ts index abdecc1..1827dd4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -298,18 +298,7 @@ export default class ObsidianGit extends Plugin { if (checking) { return file !== null; } else { - this.app.vault.adapter - .append( - this.gitManager.getRelativeVaultPath(".gitignore"), - "\n" + - this.gitManager.getRelativeRepoPath( - file!.path, - true - ) - ) - .then(() => { - this.refresh(); - }); + this.addFileToGitignore(file!); } }, }); @@ -625,55 +614,83 @@ export default class ObsidianGit extends Plugin { } } + async addFileToGitignore(file: TAbstractFile): Promise { + await this.app.vault.adapter.append( + this.gitManager.getRelativeVaultPath(".gitignore"), + "\n" + this.gitManager.getRelativeRepoPath(file!.path, true) + ); + this.refresh(); + } + handleFileMenu(menu: Menu, file: TAbstractFile, source: string): void { - if (!this.settings.showFileMenu) return; - if (source !== "file-explorer-context-menu") { - return; - } - if (!file) { - return; - } if (!this.gitReady) return; - menu.addItem((item) => { - item.setTitle(`Git: Stage`) - .setIcon("plus-circle") - .setSection("action") - .onClick((_) => { - this.promiseQueue.addTask(async () => { - if (file instanceof TFile) { - await this.gitManager.stage(file.path, true); - } else { - await this.gitManager.stageAll({ - dir: this.gitManager.getRelativeRepoPath( - file.path, - true - ), - }); - } - this.displayMessage(`Staged ${file.path}`); + if (!this.settings.showFileMenu) return; + if (!file) return; + + if ( + this.settings.showFileMenu && + source == "file-explorer-context-menu" + ) { + menu.addItem((item) => { + item.setTitle(`Git: Stage`) + .setIcon("plus-circle") + .setSection("action") + .onClick((_) => { + this.promiseQueue.addTask(async () => { + if (file instanceof TFile) { + await this.gitManager.stage(file.path, true); + } else { + await this.gitManager.stageAll({ + dir: this.gitManager.getRelativeRepoPath( + file.path, + true + ), + }); + } + this.displayMessage(`Staged ${file.path}`); + }); }); - }); - }); - menu.addItem((item) => { - item.setTitle(`Git: Unstage`) - .setIcon("minus-circle") - .setSection("action") - .onClick((_) => { - this.promiseQueue.addTask(async () => { - if (file instanceof TFile) { - await this.gitManager.unstage(file.path, true); - } else { - await this.gitManager.unstageAll({ - dir: this.gitManager.getRelativeRepoPath( - file.path, - true - ), - }); - } - this.displayMessage(`Unstaged ${file.path}`); + }); + menu.addItem((item) => { + item.setTitle(`Git: Unstage`) + .setIcon("minus-circle") + .setSection("action") + .onClick((_) => { + this.promiseQueue.addTask(async () => { + if (file instanceof TFile) { + await this.gitManager.unstage(file.path, true); + } else { + await this.gitManager.unstageAll({ + dir: this.gitManager.getRelativeRepoPath( + file.path, + true + ), + }); + } + this.displayMessage(`Unstaged ${file.path}`); + }); }); - }); - }); + }); + menu.addItem((item) => { + item.setTitle(`Git: Add to .gitignore`) + .setIcon("file-x") + .setSection("action") + .onClick((_) => { + this.addFileToGitignore(file); + }); + }); + } + + if (source == "git-source-control") { + menu.addItem((item) => { + item.setTitle(`Git: Add to .gitignore`) + .setIcon("file-x") + .setSection("action") + .onClick((_) => { + this.addFileToGitignore(file); + }); + }); + } } async migrateSettings(): Promise { diff --git a/src/ui/history/components/logFileComponent.svelte b/src/ui/history/components/logFileComponent.svelte index 80d4fda..81674bc 100644 --- a/src/ui/history/components/logFileComponent.svelte +++ b/src/ui/history/components/logFileComponent.svelte @@ -2,7 +2,7 @@ import { setIcon, TFile } from "obsidian"; import { DIFF_VIEW_CONFIG } from "src/constants"; import type { DiffFile } from "src/types"; - import { getDisplayPath, getNewLeaf } from "src/utils"; + import { getDisplayPath, getNewLeaf, mayTriggerFileMenu } from "src/utils"; import type HistoryView from "../historyView"; export let diff: DiffFile; @@ -42,7 +42,14 @@
+ mayTriggerFileMenu( + view.app, + event, + diff.vault_path, + view.leaf, + "git-history" + )} on:focus class="tree-item nav-file" > @@ -59,7 +66,7 @@
- {#if view.app.vault.getAbstractFileByPath(diff.vault_path)} + {#if view.app.vault.getAbstractFileByPath(diff.vault_path) instanceof TFile}
+ mayTriggerFileMenu( + view.app, + event, + change.vault_path, + view.leaf, + "git-source-control" + )} on:focus class="tree-item nav-file" > diff --git a/src/ui/sourceControl/components/pulledFileComponent.svelte b/src/ui/sourceControl/components/pulledFileComponent.svelte index 4658e1d..ec648d3 100644 --- a/src/ui/sourceControl/components/pulledFileComponent.svelte +++ b/src/ui/sourceControl/components/pulledFileComponent.svelte @@ -2,7 +2,7 @@ import { TFile } from "obsidian"; import { hoverPreview } from "obsidian-community-lib"; import type { FileStatusResult } from "src/types"; - import { getDisplayPath, getNewLeaf } from "src/utils"; + import { getDisplayPath, getNewLeaf, mayTriggerFileMenu } from "src/utils"; import type GitView from "../sourceControl"; export let change: FileStatusResult; @@ -29,7 +29,14 @@
+ mayTriggerFileMenu( + view.app, + event, + change.vault_path, + view.leaf, + "git-source-control" + )} on:focus class="tree-item nav-file" > diff --git a/src/ui/sourceControl/components/stagedFileComponent.svelte b/src/ui/sourceControl/components/stagedFileComponent.svelte index cf23360..cee1d53 100644 --- a/src/ui/sourceControl/components/stagedFileComponent.svelte +++ b/src/ui/sourceControl/components/stagedFileComponent.svelte @@ -4,7 +4,7 @@ import { DIFF_VIEW_CONFIG } from "src/constants"; import type { GitManager } from "src/gitManager/gitManager"; import type { FileStatusResult } from "src/types"; - import { getDisplayPath, getNewLeaf } from "src/utils"; + import { getDisplayPath, getNewLeaf, mayTriggerFileMenu } from "src/utils"; import type GitView from "../sourceControl"; export let change: FileStatusResult; @@ -57,7 +57,14 @@ on:mouseover={hover} on:focus on:click|stopPropagation={showDiff} - on:auxclick|stopPropagation={showDiff} + on:auxclick|stopPropagation={(event) => + mayTriggerFileMenu( + view.app, + event, + change.vault_path, + view.leaf, + "git-source-control" + )} class="tree-item nav-file" >
fold(entity)} + on:auxclick|stopPropagation={(event) => + mayTriggerFileMenu( + view.app, + event, + entity.vaultPath, + view.leaf, + "git-source-control" + )} class="tree-item nav-folder" class:is-collapsed={closed[entity.title]} > diff --git a/src/utils.ts b/src/utils.ts index eaa5edc..52d419f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ import * as cssColorConverter from "css-color-converter"; import deepEqual from "deep-equal"; -import type { RGB, WorkspaceLeaf } from "obsidian"; -import { Keymap, moment } from "obsidian"; +import type { App, RGB, WorkspaceLeaf } from "obsidian"; +import { Keymap, Menu, moment } from "obsidian"; export const worthWalking = (filepath: string, root?: string) => { if (filepath === "." || root == null || root.length === 0 || root === ".") { @@ -27,6 +27,23 @@ export function getNewLeaf(event?: MouseEvent): WorkspaceLeaf | undefined { return leaf; } +export function mayTriggerFileMenu( + app: App, + event: MouseEvent, + filePath: string, + view: WorkspaceLeaf, + source: string +) { + if (event.button == 2) { + const file = app.vault.getAbstractFileByPath(filePath); + if (file != null) { + const fileMenu = new Menu(); + app.workspace.trigger("file-menu", fileMenu, file, source, view); + fileMenu.showAtPosition({ x: event.pageX, y: event.pageY }); + } + } +} + /** * Creates a type-error, if this function is in a possible branch. *