Skip to content

Commit

Permalink
More move commands: Section/Change/Hunk, Unstaged/Staged Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jdanbrown committed Oct 3, 2023
1 parent 3e0cdf8 commit 8f45612
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 13 deletions.
91 changes: 79 additions & 12 deletions src/commands/macros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { MagitRepository } from '../models/magitRepository';
import { ChangeSectionView } from '../views/changes/changesSectionView';
import { DocumentView } from '../views/general/documentView';
import { View } from '../views/general/view';
import { ChangeView } from '../views/changes/changeView';
import { HunkView } from '../views/changes/hunkView';

export async function saveClose() {
await commands.executeCommand('workbench.action.files.save');
Expand Down Expand Up @@ -46,24 +48,88 @@ 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) {
window.activeTextEditor!.selection = new Selection(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();
Expand All @@ -82,15 +148,16 @@ 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);
}
}
}
}
Expand Down
26 changes: 25 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@ 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,
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';
Expand Down Expand Up @@ -178,6 +193,15 @@ 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.save-and-close-editor', saveClose));
Expand Down

0 comments on commit 8f45612

Please sign in to comment.