mirror of
https://github.com/kahole/edamagit.git
synced 2024-09-11 07:15:31 +03:00
Compare commits
17 Commits
3e0cdf82d1
...
53d8f64ae1
Author | SHA1 | Date | |
---|---|---|---|
|
53d8f64ae1 | ||
|
e82f11094c | ||
|
8829229881 | ||
|
fe1a861861 | ||
|
9a12bc3b15 | ||
|
7308619938 | ||
|
9578299b88 | ||
|
284dd61a33 | ||
|
5c7676b472 | ||
|
8f45612161 | ||
|
2230d0d45e | ||
|
d0d9da8219 | ||
|
06d81d5cf9 | ||
|
6ea7fb5b74 | ||
|
086066aa7d | ||
|
8c231e46a1 | ||
|
2ad5c22c74 |
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## [0.6.46]
|
||||
- Show running git command in git status message: @Rutherther, Rutherther
|
||||
- More move commands: @jdanbrown, Dan Brown
|
||||
- Add command toggle-all-folds-for-change-views: @jdanbrown, Dan Brown
|
||||
- Concise log decorate: @evannjohnson
|
||||
- Support fold/unfold diff hunks in commit detail view: @Rutherther, Rutherther
|
||||
|
||||
|
||||
## [0.6.45]
|
||||
- Fix resolution of user keybindings for help-view (`?` view)
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
<h3 align="center">
|
||||
<a href="#usage">Usage</a> •
|
||||
<a href="https://hole.dev/articles/edamagit-introduction/">Tutorial</a> •
|
||||
<a href="https://kahole.github.io/hole.dev/articles/edamagit-introduction/">Tutorial</a> •
|
||||
<a href="#settings">Settings</a> •
|
||||
<a href="#vim-support-vscodevim">Vim Bindings</a> •
|
||||
<a href="#roadmap">Roadmap</a>
|
||||
@ -77,7 +77,7 @@ Essential commands
|
||||
ctrl+k Move cursor to previous entity
|
||||
```
|
||||
|
||||
## [[ See also the edamagit tutorial ]](https://hole.dev/articles/edamagit-introduction/)
|
||||
## [[ See also the edamagit tutorial ]](https://kahole.github.io/hole.dev/articles/edamagit-introduction/)
|
||||
---
|
||||
|
||||
|
||||
|
26
TUTORIAL.md
26
TUTORIAL.md
@ -20,11 +20,11 @@ Once in the status view, press `Tab` to fold and unfold sections, files, and cha
|
||||
|
||||
Place the cursor on a section
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/tab_closed.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/tab_closed.jpg)
|
||||
|
||||
press `Tab` to unfold/fold:
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/tab_open.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/tab_open.jpg)
|
||||
|
||||
#### Staging
|
||||
|
||||
@ -32,11 +32,11 @@ Pressing `s` and `u` allows you to stage and unstage changes under the cursor. E
|
||||
|
||||
From
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/unstaged_file.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/unstaged_file.jpg)
|
||||
|
||||
pressing `s` will stage the file:
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/staged_file.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/staged_file.jpg)
|
||||
|
||||
#### Other status view actions
|
||||
|
||||
@ -51,7 +51,7 @@ From the status view press `?` to bring up the help view.
|
||||
This shows you the available edamagit menus and which key to press to invoke them.
|
||||
For example, pressing `b` brings up the `Branching`-menu.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/help_view.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/help_view.jpg)
|
||||
|
||||
This menu-system is based on a modified version of VSCode's QuickPick selection menu.
|
||||
|
||||
@ -59,15 +59,15 @@ Similarly to the help view, the entries in this menu show a key and which action
|
||||
|
||||
From here, a single press of `c` invokes the action `Checkout new branch`.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/branching_menu_1.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/branching_menu_1.jpg)
|
||||
|
||||
Choose a branch to base the new branch on. Search and/or select with arrow keys. Confirm choice with `Enter`.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/branching_menu_2.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/branching_menu_2.jpg)
|
||||
|
||||
Give the new branch a name and press `Enter`
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/branching_menu_3.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/branching_menu_3.jpg)
|
||||
|
||||
### Committing
|
||||
|
||||
@ -76,7 +76,7 @@ Press `c` to bring up committing menu, and `c` once again to start a normal comm
|
||||
|
||||
This brings up the commit view where you will write a commit message. Next to an editor showing which changes you are committing is shown.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/committing.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/committing.jpg)
|
||||
|
||||
Once you have written a commit-message press `ctrl+c ctrl+c` to finish the commit.
|
||||
Or manually save and close the commit-message editor, this has the same effect.
|
||||
@ -90,19 +90,19 @@ E.g. `push --force`
|
||||
|
||||
Many of the edamagit command menus have a switches menu which can be activated by pressing `-`.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/switches_1.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/switches_1.jpg)
|
||||
|
||||
Toggle a switch by pressing its letter. E.g. `F` (uppercase) for `--force`.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/switches_2.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/switches_2.jpg)
|
||||
|
||||
Press `Enter` to confirm the switch selection.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/switches_3.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/switches_3.jpg)
|
||||
|
||||
Now you'll see the active switches listed in the 'Switches' menu entry.
|
||||
|
||||
![](https://hole.dev/images/edamagit_introduction/switches_4.jpg)
|
||||
![](https://kahole.github.io/hole.dev/images/edamagit_introduction/switches_4.jpg)
|
||||
|
||||
### Tips & Tricks
|
||||
- Using the vscode command palette and typing `Magit ` will show you all available magit actions from where you currently are.
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "magit",
|
||||
"version": "0.6.45",
|
||||
"version": "0.6.46",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "magit",
|
||||
"version": "0.6.45",
|
||||
"version": "0.6.46",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vscode/iconv-lite-umd": "^0.7.0",
|
||||
|
34
package.json
34
package.json
@ -7,7 +7,7 @@
|
||||
"author": {
|
||||
"name": "Kristian Andersen Hole"
|
||||
},
|
||||
"version": "0.6.45",
|
||||
"version": "0.6.46",
|
||||
"engines": {
|
||||
"vscode": "^1.50.0"
|
||||
},
|
||||
@ -206,6 +206,14 @@
|
||||
{
|
||||
"command": "magit.toggle-fold",
|
||||
"title": "Magit Toggle Fold"
|
||||
},
|
||||
{
|
||||
"command": "magit.toggle-all-folds-in-change-section-at-point",
|
||||
"title": "Magit Toggle All Folds in Change Section at Point"
|
||||
},
|
||||
{
|
||||
"command": "magit.toggle-all-folds-for-change-views",
|
||||
"title": "Magit Toggle All Folds for Change Views"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@ -367,6 +375,14 @@
|
||||
{
|
||||
"command": "magit.toggle-fold",
|
||||
"when": "editorLangId == magit"
|
||||
},
|
||||
{
|
||||
"command": "magit.toggle-all-folds-in-change-section-at-point",
|
||||
"when": "editorLangId == magit"
|
||||
},
|
||||
{
|
||||
"command": "magit.toggle-all-folds-for-change-views",
|
||||
"when": "editorLangId == magit"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -453,6 +469,16 @@
|
||||
"superType": "label",
|
||||
"description": "Name of a git ref from a remote."
|
||||
},
|
||||
{
|
||||
"id": "magit-head-name",
|
||||
"superType": "label",
|
||||
"description": "Name of the (local) HEAD git ref."
|
||||
},
|
||||
{
|
||||
"id": "magit-remote-head-name",
|
||||
"superType": "label",
|
||||
"description": "Name of a HEAD git ref on a remote repo."
|
||||
},
|
||||
{
|
||||
"id": "magit-tag-name",
|
||||
"superType": "label",
|
||||
@ -468,6 +494,12 @@
|
||||
"magit-remote-ref-name": [
|
||||
"variable.other.constant"
|
||||
],
|
||||
"magit-head-name": [
|
||||
"entity.name.tag"
|
||||
],
|
||||
"magit-remote-head-name": [
|
||||
"variable.object.property"
|
||||
],
|
||||
"magit-tag-name": [
|
||||
"string.highlight"
|
||||
]
|
||||
|
@ -104,7 +104,7 @@ async function showStash({ repository }: MenuState) {
|
||||
}
|
||||
}
|
||||
|
||||
function stashToMagitChanges(nameStatusText: string, diff: string): MagitChange[] {
|
||||
export function stashToMagitChanges(nameStatusText: string, diff: string): MagitChange[] {
|
||||
const DIFF_PREFIX = 'diff --git';
|
||||
const filesWithStatus = nameStatusText.split(Constants.LineSplitterRegex).filter(t => t !== '').map(s => s.split('\t'));
|
||||
const diffs = diff.split(DIFF_PREFIX).filter(r => r !== '');
|
||||
@ -134,7 +134,7 @@ function getStatusFromString(status: String): number {
|
||||
case 'A':
|
||||
return Status.INDEX_ADDED;
|
||||
case 'C':
|
||||
return Status.INDEX_COPIED ;
|
||||
return Status.INDEX_COPIED;
|
||||
case 'D':
|
||||
return Status.DELETED;
|
||||
case 'R' :
|
||||
|
@ -99,7 +99,16 @@ async function log(repository: MagitRepository, args: string[], revs: string[],
|
||||
const logEntries = parseLog(output.stdout);
|
||||
const revName = revs.join(' ');
|
||||
const uri = LogView.encodeLocation(repository);
|
||||
return ViewUtils.showView(uri, new LogView(uri, { entries: logEntries, revName }));
|
||||
|
||||
let defaultBranches: { [remoteName: string]: string } = {};
|
||||
for await (const remote of repository.remotes) {
|
||||
try {
|
||||
let defaultBranch = await gitRun(repository.gitRepository, ['symbolic-ref', `refs/remotes/${remote.name}/HEAD`], undefined, LogLevel.Error);
|
||||
defaultBranches[remote.name] = defaultBranch.stdout.replace(`refs/remotes/${remote.name}/`, '').trimEnd();
|
||||
} catch { } // gitRun will throw an error if remote/HEAD doesn't exist - we do not need to do anything in this case
|
||||
}
|
||||
|
||||
return ViewUtils.showView(uri, new LogView(uri, { entries: logEntries, revName }, repository, defaultBranches));
|
||||
}
|
||||
|
||||
async function getRevs(repository: MagitRepository) {
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { commands, TextEditor, Range, window, Selection, TextEditorRevealType, Position } from 'vscode';
|
||||
import { MagitRepository } from '../models/magitRepository';
|
||||
import { ChangeSectionView } from '../views/changes/changesSectionView';
|
||||
import { ChangeView } from '../views/changes/changeView';
|
||||
import { DocumentView } from '../views/general/documentView';
|
||||
import { View } from '../views/general/view';
|
||||
import { HunkView } from '../views/changes/hunkView';
|
||||
|
||||
export async function saveClose() {
|
||||
await commands.executeCommand('workbench.action.files.save');
|
||||
@ -37,6 +39,17 @@ export async function toggleAllFoldsInChangeSection(repo: MagitRepository, view:
|
||||
}
|
||||
}
|
||||
|
||||
export async function toggleAllFoldsForChangeViews(repo: MagitRepository, view: DocumentView) {
|
||||
let changeViews = Array.from(view.walkAllSubViews()).filter(x => x instanceof ChangeView);
|
||||
if (changeViews.length === 0) {
|
||||
return;
|
||||
}
|
||||
const newFoldState = !changeViews[0].folded;
|
||||
for (let changeView of changeViews) {
|
||||
changeView.folded = newFoldState;
|
||||
}
|
||||
}
|
||||
|
||||
const subViewDepthSearchFlatten = (view: View, depth: number = 0): View[] => {
|
||||
if (view.folded || depth >= 3) {
|
||||
return [];
|
||||
@ -46,11 +59,43 @@ const subViewDepthSearchFlatten = (view: View, depth: number = 0): View[] => {
|
||||
};
|
||||
|
||||
export async function moveToNextEntity(repo: MagitRepository, view: DocumentView) {
|
||||
moveToEntity(view, 'next');
|
||||
moveToNextPreviousEntity(view, 'next', 'entity');
|
||||
}
|
||||
|
||||
export async function moveToPreviousEntity(repo: MagitRepository, view: DocumentView) {
|
||||
moveToEntity(view, 'previous');
|
||||
moveToNextPreviousEntity(view, 'previous', 'entity');
|
||||
}
|
||||
|
||||
export async function moveToNextSection(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'next', 'section');
|
||||
}
|
||||
|
||||
export async function moveToPreviousSection(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'previous', 'section');
|
||||
}
|
||||
|
||||
export async function moveToNextChange(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'next', 'change');
|
||||
}
|
||||
|
||||
export async function moveToPreviousChange(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'previous', 'change');
|
||||
}
|
||||
|
||||
export async function moveToNextHunk(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'next', 'hunk');
|
||||
}
|
||||
|
||||
export async function moveToPreviousHunk(repo: MagitRepository, view: DocumentView) {
|
||||
moveToNextPreviousEntity(view, 'previous', 'hunk');
|
||||
}
|
||||
|
||||
export async function moveToUnstagedChanges(repo: MagitRepository, view: DocumentView) {
|
||||
moveToTargetEntity(view, 'unstaged-changes');
|
||||
}
|
||||
|
||||
export async function moveToStagedChanges(repo: MagitRepository, view: DocumentView) {
|
||||
moveToTargetEntity(view, 'staged-changes');
|
||||
}
|
||||
|
||||
function moveCursorAndReveal(position: Position) {
|
||||
@ -58,12 +103,44 @@ function moveCursorAndReveal(position: Position) {
|
||||
window.activeTextEditor!.revealRange(new Selection(position, position), TextEditorRevealType.Default);
|
||||
}
|
||||
|
||||
function moveToEntity(view: View, direction: 'next' | 'previous') {
|
||||
function moveToTargetEntity(view: View, target: 'unstaged-changes' | 'staged-changes') {
|
||||
let views = (
|
||||
[view, ...subViewDepthSearchFlatten(view)]
|
||||
.filter(v =>
|
||||
target === 'unstaged-changes' ? v instanceof ChangeSectionView && v.section === 'Unstaged changes' :
|
||||
target === 'staged-changes' ? v instanceof ChangeSectionView && v.section === 'Staged changes' :
|
||||
false // Unreachable
|
||||
)
|
||||
);
|
||||
|
||||
let targetView = views[0];
|
||||
if (targetView) {
|
||||
let nextLocation = targetView.range.start;
|
||||
moveCursorAndReveal(nextLocation);
|
||||
}
|
||||
}
|
||||
|
||||
function moveToNextPreviousEntity(
|
||||
view: View,
|
||||
direction: 'next' | 'previous',
|
||||
filter: 'entity' | 'section' | 'change' | 'hunk',
|
||||
) {
|
||||
const selectedView = view.click(window.activeTextEditor!.selection.active);
|
||||
|
||||
if (selectedView) {
|
||||
|
||||
let foldableViews = [view, ...subViewDepthSearchFlatten(view)];
|
||||
let foldableViews = (
|
||||
[view, ...subViewDepthSearchFlatten(view)]
|
||||
.filter(v =>
|
||||
v === selectedView || (
|
||||
filter === 'entity' ? true :
|
||||
filter === 'section' ? v.constructor.name.endsWith('SectionView') :
|
||||
filter === 'change' ? v instanceof ChangeView :
|
||||
filter === 'hunk' ? v instanceof HunkView :
|
||||
false // Unreachable
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (direction === 'previous') {
|
||||
foldableViews = foldableViews.reverse();
|
||||
@ -82,16 +159,17 @@ function moveToEntity(view: View, direction: 'next' | 'previous') {
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid standing still and getting stuck
|
||||
if (direction === 'next') {
|
||||
let newPos = selectedView.range.end.with({ line: selectedView.range.end.line });
|
||||
moveCursorAndReveal(newPos);
|
||||
} else if (direction === 'previous') {
|
||||
if (selectedView.range.start.line > 0) {
|
||||
let newPos = selectedView.range.start.with({ line: selectedView.range.start.line - 1 });
|
||||
if (filter === 'entity') {
|
||||
// Avoid standing still and getting stuck
|
||||
if (direction === 'next') {
|
||||
let newPos = selectedView.range.end.with({ line: selectedView.range.end.line });
|
||||
moveCursorAndReveal(newPos);
|
||||
|
||||
} else if (direction === 'previous') {
|
||||
if (selectedView.range.start.line > 0) {
|
||||
let newPos = selectedView.range.start.with({ line: selectedView.range.start.line - 1 });
|
||||
moveCursorAndReveal(newPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import { PullRequestView } from '../views/forge/pullRequestView';
|
||||
import { sep } from 'path';
|
||||
import { ErrorMessageView } from '../views/errorMessageView';
|
||||
import { processView } from './processCommands';
|
||||
import { stashToMagitChanges } from './diffingCommands';
|
||||
|
||||
export async function magitVisitAtPoint(repository: MagitRepository, currentView: DocumentView) {
|
||||
|
||||
@ -141,9 +142,11 @@ async function visitHunk(selectedView: HunkView, activePosition?: Position) {
|
||||
}
|
||||
|
||||
export async function visitCommit(repository: MagitRepository, commitHash: string) {
|
||||
const result = await gitRun(repository.gitRepository, ['show', commitHash]);
|
||||
const nameStatus = await gitRun(repository.gitRepository, ['show', '--name-status', '--pretty=format:', commitHash]);
|
||||
const header = await gitRun(repository.gitRepository, ['show', '-s', '--shortstat', commitHash]);
|
||||
const diffs = await gitRun(repository.gitRepository, ['show', '--pretty=format:', commitHash]);
|
||||
const commit: MagitCommit = { hash: commitHash, message: '', parents: [] };
|
||||
|
||||
const uri = CommitDetailView.encodeLocation(repository, commit.hash);
|
||||
return ViewUtils.showView(uri, new CommitDetailView(uri, commit, result.stdout));
|
||||
return ViewUtils.showView(uri, new CommitDetailView(uri, commit, header.stdout, stashToMagitChanges(nameStatus.stdout, diffs.stdout)));
|
||||
}
|
@ -14,5 +14,7 @@ export const MagitDocumentSelector: DocumentSelector = { scheme: MagitUriScheme,
|
||||
export enum SemanticTokenTypes {
|
||||
RefName = 'magit-ref-name',
|
||||
RemoteRefName = 'magit-remote-ref-name',
|
||||
HeadName = 'magit-head-name',
|
||||
RemoteHeadName = 'magit-remote-head-name',
|
||||
TagName = 'magit-tag-name',
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,23 @@ import { magitVisitAtPoint } from './commands/visitAtPointCommands';
|
||||
import { MagitRepository } from './models/magitRepository';
|
||||
import { magitCommit, setCodePath } from './commands/commitCommands';
|
||||
import { magitStage, magitStageAll, magitUnstageAll, magitUnstage, stageFile, unstageFile } from './commands/stagingCommands';
|
||||
import { saveClose, clearSaveClose, quitMagitView, toggleAllFoldsInChangeSection, moveToPreviousEntity, moveToNextEntity } from './commands/macros';
|
||||
import {
|
||||
saveClose,
|
||||
clearSaveClose,
|
||||
quitMagitView,
|
||||
toggleAllFoldsForChangeViews,
|
||||
toggleAllFoldsInChangeSection,
|
||||
moveToPreviousEntity,
|
||||
moveToNextEntity,
|
||||
moveToNextSection,
|
||||
moveToPreviousSection,
|
||||
moveToNextChange,
|
||||
moveToPreviousChange,
|
||||
moveToNextHunk,
|
||||
moveToPreviousHunk,
|
||||
moveToUnstagedChanges,
|
||||
moveToStagedChanges,
|
||||
} from './commands/macros';
|
||||
import HighlightProvider from './providers/highlightProvider';
|
||||
import SemanticTokensProvider from './providers/semanticTokensProvider';
|
||||
import { CommandPrimer } from './commands/commandPrimer';
|
||||
@ -178,7 +194,17 @@ export function activate(context: ExtensionContext) {
|
||||
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-next-entity', CommandPrimer.primeRepoAndView(moveToNextEntity, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-previous-entity', CommandPrimer.primeRepoAndView(moveToPreviousEntity, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-next-section', CommandPrimer.primeRepoAndView(moveToNextSection, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-previous-section', CommandPrimer.primeRepoAndView(moveToPreviousSection, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-next-change', CommandPrimer.primeRepoAndView(moveToNextChange, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-previous-change', CommandPrimer.primeRepoAndView(moveToPreviousChange, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-next-hunk', CommandPrimer.primeRepoAndView(moveToNextHunk, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-previous-hunk', CommandPrimer.primeRepoAndView(moveToPreviousHunk, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-to-unstaged-changes', CommandPrimer.primeRepoAndView(moveToUnstagedChanges, false)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.move-to-staged-changes', CommandPrimer.primeRepoAndView(moveToStagedChanges, false)));
|
||||
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.toggle-all-folds-in-change-section-at-point', CommandPrimer.primeRepoAndView(toggleAllFoldsInChangeSection, true)));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.toggle-all-folds-for-change-views', CommandPrimer.primeRepoAndView(toggleAllFoldsForChangeViews, true)));
|
||||
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.save-and-close-editor', saveClose));
|
||||
context.subscriptions.push(commands.registerTextEditorCommand('magit.clear-and-abort-editor', clearSaveClose));
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { Repository } from '../typings/git';
|
||||
import { run, SpawnOptions } from './commandRunner/command';
|
||||
import { window } from 'vscode';
|
||||
import GitProcessLogger from './gitProcessLogger';
|
||||
import * as Constants from '../common/constants';
|
||||
|
||||
export enum LogLevel {
|
||||
None,
|
||||
@ -8,7 +10,10 @@ export enum LogLevel {
|
||||
Detailed
|
||||
}
|
||||
|
||||
export async function gitRun(repository: Repository, args: string[], spawnOptions?: SpawnOptions, logLevel = LogLevel.Detailed) {
|
||||
export async function gitRun(repository: Repository, args: string[], spawnOptions?: SpawnOptions, logLevel = LogLevel.Detailed, showStatus: boolean = true) {
|
||||
if (showStatus) {
|
||||
window.setStatusBarMessage(`Running git ${args.join(' ')}...`);
|
||||
}
|
||||
|
||||
let logEntry;
|
||||
if (logLevel > LogLevel.None) {
|
||||
@ -26,11 +31,18 @@ export async function gitRun(repository: Repository, args: string[], spawnOption
|
||||
GitProcessLogger.logGitResult(result, logEntry);
|
||||
}
|
||||
|
||||
if (showStatus) {
|
||||
window.setStatusBarMessage(`Git finished successfully`, Constants.StatusMessageDisplayTimeout);
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (logLevel > LogLevel.None && logEntry) {
|
||||
GitProcessLogger.logGitError(error, logEntry);
|
||||
}
|
||||
|
||||
if (showStatus) {
|
||||
window.setStatusBarMessage(error.message);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ export default class ViewUtils {
|
||||
return selectedViews;
|
||||
}
|
||||
|
||||
public static generateRefTokensLine(commitHash: string, refs?: Ref[]): (string | Token)[] {
|
||||
public static generateRefTokensLine(commitHash: string, refs?: Ref[], headName?: string, defaultBranches?: { [remoteName: string]: string }): (string | Token)[] {
|
||||
|
||||
const matchingRefs = (refs ?? [])
|
||||
.filter(ref => ref.commit === commitHash)
|
||||
@ -103,7 +103,19 @@ export default class ViewUtils {
|
||||
let m = matchingRefs.find(other => other.name === namePart && other.type === RefType.Head);
|
||||
if (m && m.name) {
|
||||
hasMatchingRemoteBranch[m.name!] = true;
|
||||
refsContent.push(new Token(remotePart + '/', SemanticTokenTypes.RemoteRefName), new Token(m.name ?? '', SemanticTokenTypes.RefName));
|
||||
|
||||
// Determine if local or remote branches are HEADs
|
||||
let remoteRefTokenType = SemanticTokenTypes.RemoteRefName;
|
||||
if (defaultBranches && ref.remote && defaultBranches[ref.remote] === namePart) {
|
||||
remoteRefTokenType = SemanticTokenTypes.RemoteHeadName;
|
||||
}
|
||||
|
||||
let refTokenType = SemanticTokenTypes.RefName;
|
||||
if (m.name === headName) {
|
||||
refTokenType = SemanticTokenTypes.HeadName;
|
||||
}
|
||||
|
||||
refsContent.push(new Token(remotePart + '/', remoteRefTokenType), new Token(m.name ?? '', refTokenType));
|
||||
refsContent.push(' ');
|
||||
return;
|
||||
}
|
||||
@ -114,8 +126,13 @@ export default class ViewUtils {
|
||||
|
||||
let refTokenType = SemanticTokenTypes.RefName;
|
||||
|
||||
if (ref.remote) {
|
||||
if (ref.name === headName) {
|
||||
refTokenType = SemanticTokenTypes.HeadName;
|
||||
} else if (ref.remote) {
|
||||
refTokenType = SemanticTokenTypes.RemoteRefName;
|
||||
if (defaultBranches && ref.remote && ref.remote + '/' + defaultBranches[ref.remote] === ref.name) {
|
||||
refTokenType = SemanticTokenTypes.RemoteHeadName;
|
||||
}
|
||||
} else if (ref.type === RefType.Tag) {
|
||||
refTokenType = SemanticTokenTypes.TagName;
|
||||
}
|
||||
@ -126,4 +143,4 @@ export default class ViewUtils {
|
||||
|
||||
return refsContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { DocumentView } from './general/documentView';
|
||||
import { Uri } from 'vscode';
|
||||
import { Section } from './general/sectionHeader';
|
||||
import * as Constants from '../common/constants';
|
||||
import { TextView } from './general/textView';
|
||||
import { MagitCommit } from '../models/magitCommit';
|
||||
import { MagitRepository } from '../models/magitRepository';
|
||||
import { MagitChange } from '../models/magitChange';
|
||||
import { ChangeSectionView } from './changes/changesSectionView';
|
||||
|
||||
export class CommitDetailView extends DocumentView {
|
||||
|
||||
@ -11,11 +14,14 @@ export class CommitDetailView extends DocumentView {
|
||||
isHighlightable = false;
|
||||
needsUpdate = false;
|
||||
|
||||
constructor(uri: Uri, public commit: MagitCommit, diff: string) {
|
||||
constructor(uri: Uri, public commit: MagitCommit, header: string, diffChanges: MagitChange[]) {
|
||||
super(uri);
|
||||
|
||||
const commitTextView = new TextView(diff);
|
||||
commitTextView.isHighlightable = false;
|
||||
const commitTextView = new ChangeSectionView(Section.Changes, diffChanges);
|
||||
const headerView = new TextView(header);
|
||||
headerView.isHighlightable = false;
|
||||
|
||||
this.addSubview(headerView);
|
||||
this.addSubview(commitTextView);
|
||||
}
|
||||
|
||||
|
@ -85,4 +85,11 @@ export abstract class View {
|
||||
addSubview(...views: View[]) {
|
||||
this.subViews.push(...views);
|
||||
}
|
||||
}
|
||||
|
||||
*walkAllSubViews(): Generator<View> {
|
||||
for (let subView of this.subViews) {
|
||||
yield subView;
|
||||
yield* subView.walkAllSubViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,17 +10,21 @@ import { DocumentView } from './general/documentView';
|
||||
import { TextView } from './general/textView';
|
||||
import { Token } from './general/semanticTextView';
|
||||
import { SemanticTokenTypes } from '../common/constants';
|
||||
import { Ref, RefType } from '../typings/git';
|
||||
import ViewUtils from '../utils/viewUtils';
|
||||
import { MagitRemote } from '../models/magitRemote';
|
||||
|
||||
export default class LogView extends DocumentView {
|
||||
|
||||
static UriPath: string = 'log.magit';
|
||||
|
||||
constructor(uri: Uri, log: MagitLog) {
|
||||
constructor(uri: Uri, log: MagitLog, magitState: MagitRepository, defaultBranches?: { [remoteName: string]: string }) {
|
||||
super(uri);
|
||||
const refs = magitState.remotes.reduce((prev, remote) => remote.branches.concat(prev), magitState.branches.concat(magitState.tags));
|
||||
|
||||
this.subViews = [
|
||||
new TextView(`Commits in ${log.revName}`),
|
||||
...log.entries.map(entry => new CommitLongFormItemView(entry)),
|
||||
...log.entries.map(entry => new CommitLongFormItemView(entry, refs, magitState.HEAD?.name, defaultBranches)),
|
||||
];
|
||||
}
|
||||
|
||||
@ -34,8 +38,8 @@ export default class LogView extends DocumentView {
|
||||
|
||||
export class CommitLongFormItemView extends CommitItemView {
|
||||
|
||||
constructor(public logEntry: MagitLogEntry) {
|
||||
super(logEntry.commit);
|
||||
constructor(public logEntry: MagitLogEntry, refs?: Ref[], headName?: string, defaultBranches?: { [remoteName: string]: string }) {
|
||||
super(logEntry.commit, undefined, refs);
|
||||
|
||||
const timeDistance = formatDistanceToNowStrict(logEntry.time);
|
||||
const hash = `${GitTextUtils.shortHash(logEntry.commit.hash)} `;
|
||||
@ -46,16 +50,8 @@ export class CommitLongFormItemView extends CommitItemView {
|
||||
const msg = GitTextUtils.shortCommitMessage(logEntry.commit.message);
|
||||
this.content.push(`${hash}${graph}`);
|
||||
|
||||
const refTokens: Token[] = logEntry.refs.map(ref => new Token(ref, SemanticTokenTypes.RefName));
|
||||
if (refTokens.length) {
|
||||
|
||||
this.content.push(' (');
|
||||
refTokens.forEach(refToken => {
|
||||
this.content.push(refToken, ' ');
|
||||
});
|
||||
this.content.pop();
|
||||
|
||||
this.content.push(') ');
|
||||
if (logEntry.refs.length) {
|
||||
this.content.push(...ViewUtils.generateRefTokensLine(logEntry.commit.hash, refs, headName, defaultBranches));
|
||||
}
|
||||
|
||||
const availableMsgWidth = 70 - this.content.reduce((prev, v) => prev + v.length, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user