Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve file navigation #56

Merged
merged 8 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/git-istage.tests/Infrastructure/RepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ internal static void AssertFiles(string expectedChangesText, FileDocument docume
.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

var actualChangeLines = new List<string>();
for (var i = 0; i < document.Height - 1; i++)
for (var i = 0; i < document.Height; i++)
{
var line = document.GetLine(i);
var colon = line.IndexOf(':');
Expand Down
9 changes: 8 additions & 1 deletion src/git-istage/Patches/PatchDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,25 @@ public PatchDocument(IReadOnlyList<PatchEntry> entries, IReadOnlyList<PatchLine>

public override int Width { get; }

public override int EntryCount => Entries.Count;

public override string GetLine(int index)
{
return Lines[index].Text;
}

public override int GetLineIndex(int index)
{
return Entries[index].Offset;
}

public PatchEntry? FindEntry(int lineIndex)
{
var index = FindEntryIndex(lineIndex);
return index < 0 ? null : Entries[index];
}

public int FindEntryIndex(int lineIndex)
public override int FindEntryIndex(int lineIndex)
{
// TODO: binary search would be more appropriate

Expand Down
28 changes: 8 additions & 20 deletions src/git-istage/Patches/PatchExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,20 @@ public static bool IsAdditionOrRemoval(this PatchLineKind kind)
PatchLineKind.Removal;
}

public static int FindPreviousEntryIndex(this PatchDocument document, int lineIndex)
{
var entryIndex = document.FindEntryIndex(lineIndex);
return Math.Max(entryIndex - 1, 0);
}

public static int FindNextEntryIndex(this PatchDocument document, int lineIndex)
{
var entryIndex = document.FindEntryIndex(lineIndex);
return Math.Min(entryIndex + 1, document.Entries.Count - 1);
}

public static int FindPreviousChangeBlock(this PatchDocument document, int lineIndex)
{
var start = lineIndex;

// Skip current block
while (start > 0 && document.Lines[start].Kind.IsAdditionOrRemoval())
while (start >= 0 && document.Lines[start].Kind.IsAdditionOrRemoval())
start--;

// Find next block
while (start > 0 && !document.Lines[start].Kind.IsAdditionOrRemoval())
while (start >= 0 && !document.Lines[start].Kind.IsAdditionOrRemoval())
start--;

if (start < 0 || !document.Lines[start].Kind.IsAdditionOrRemoval())
return lineIndex;
if (start < 0)
return FindStartOfChangeBlock(document, lineIndex);

return start;
}
Expand All @@ -43,15 +31,15 @@ public static int FindNextChangeBlock(this PatchDocument document, int lineIndex
var end = lineIndex;

// Skip current block
while (end < document.Lines.Count - 1 && document.Lines[end].Kind.IsAdditionOrRemoval())
while (end < document.Lines.Count && document.Lines[end].Kind.IsAdditionOrRemoval())
end++;

// Find next block
while (end < document.Lines.Count - 1 && !document.Lines[end].Kind.IsAdditionOrRemoval())
while (end < document.Lines.Count && !document.Lines[end].Kind.IsAdditionOrRemoval())
end++;

if (end >= document.Lines.Count || !document.Lines[end].Kind.IsAdditionOrRemoval())
return lineIndex;
if (end >= document.Lines.Count)
return FindEndOfChangeBlock(document, lineIndex);

return end;
}
Expand Down
29 changes: 18 additions & 11 deletions src/git-istage/Services/CommandService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using GitIStage.Commands;
using GitIStage.Patches;
using GitIStage.UI;
using LibGit2Sharp;
using Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -273,18 +274,19 @@ private void ScrollDown()
[CommandHandler("Selects the line one screen above.", "PageUp")]
private void ScrollPageUp()
{
_uiService.View.TopLine = Math.Max(0, _uiService.View.TopLine - _uiService.View.Height);
_uiService.View.SelectedLine = _uiService.View.TopLine;
var delta = Math.Min(_uiService.View.Height, _uiService.View.SelectedLine);
_uiService.View.TopLine = Math.Max(0, _uiService.View.TopLine - delta);
_uiService.View.SelectedLine = _uiService.View.SelectedLine - delta;
}

[CommandHandler("Selects the line one screen below.", "PageDown", "SpaceBar")]
private void ScrollPageDown()
{
var delta = Math.Min(_uiService.View.Height, _uiService.View.DocumentHeight - _uiService.View.SelectedLine - 1);
_uiService.View.TopLine = Math.Min(
Math.Max(0, _uiService.View.DocumentHeight - _uiService.View.Height),
_uiService.View.TopLine + _uiService.View.Height);

_uiService.View.SelectedLine = _uiService.View.TopLine;
_uiService.View.TopLine + delta);
_uiService.View.SelectedLine = _uiService.View.SelectedLine + delta;
}

[CommandHandler("Scrolls left by one character.", "Control+LeftArrow")]
Expand Down Expand Up @@ -313,9 +315,9 @@ private void GoPreviousFile()
if (i < 0)
return;

var document = (PatchDocument)_documentService.Document;
var document = _documentService.Document;
var nextIndex = document.FindPreviousEntryIndex(i);
_uiService.View.SelectedLine = document.Entries[nextIndex].Offset;
_uiService.View.SelectedLine = document.GetLineIndex(nextIndex);
_uiService.View.BringIntoView(_uiService.View.SelectedLine);
}

Expand All @@ -327,16 +329,21 @@ private void GoNextFile()
if (i < 0)
return;

var document = (PatchDocument)_documentService.Document;
var document = _documentService.Document;
var nextIndex = document.FindNextEntryIndex(i);
_uiService.View.SelectedLine = document.Entries[nextIndex].Offset;

if (nextIndex < document.EntryCount)
_uiService.View.SelectedLine = document.GetLineIndex(nextIndex);
else
_uiService.View.SelectedLine = _uiService.View.DocumentHeight - 1;

_uiService.View.BringIntoView(_uiService.View.SelectedLine);
}

[CommandHandler("Go to previous change block.", "Oem4")]
private void GoPreviousHunk()
{
if (_uiService.HelpShowing) return;
if (_uiService.HelpShowing || _documentService.ViewFiles) return;
var i = _uiService.View.SelectedLine;
if (i < 0)
return;
Expand All @@ -349,7 +356,7 @@ private void GoPreviousHunk()
[CommandHandler("Go to next change block.", "Oem6")]
private void GoNextHunk()
{
if (_uiService.HelpShowing) return;
if (_uiService.HelpShowing || _documentService.ViewFiles) return;
var i = _uiService.View.SelectedLine;
if (i < 0)
return;
Expand Down
4 changes: 2 additions & 2 deletions src/git-istage/Services/UIService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ public void Search()
Vt100.SetForegroundColor(ConsoleColor.Blue);
Vt100.SetBackgroundColor(ConsoleColor.Gray);
Console.Write("/");
Vt100.EraseRestOfCurrentLine();
Console.Write(sb);
Vt100.EraseRestOfCurrentLine();
Vt100.ShowCursor();

var k = Console.ReadKey(intercept: true);
Expand Down Expand Up @@ -205,8 +205,8 @@ public void Search()
Vt100.SetCursorPosition(0, Console.WindowHeight - 1);
Vt100.SetForegroundColor(ConsoleColor.Blue);
Vt100.SetBackgroundColor(ConsoleColor.Gray);
Vt100.EraseRestOfCurrentLine();
Console.Write("<< NO RESULTS FOUND >>");
Vt100.EraseRestOfCurrentLine();
Console.ReadKey();
UpdateFooter();
return;
Expand Down
14 changes: 14 additions & 0 deletions src/git-istage/UI/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@ internal abstract class Document

public abstract int Height { get; }
public abstract int Width { get; }
public abstract int EntryCount { get; }

public abstract string GetLine(int index);
public abstract int GetLineIndex(int index);
public abstract int FindEntryIndex(int lineIndex);

private sealed class EmptyDocument : Document
{
public override int Height => 0;
public override int Width => 0;
public override int EntryCount => 0;

public override string GetLine(int index)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

public override int GetLineIndex(int index)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

public override int FindEntryIndex(int lineIndex)
{
throw new ArgumentOutOfRangeException(nameof(lineIndex));
}
}
}
20 changes: 20 additions & 0 deletions src/git-istage/UI/DocumentExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace GitIStage.UI;

internal static class DocumentExtensions
{
public static int FindPreviousEntryIndex(this Document document, int lineIndex)
{
var entryIndex = document.FindEntryIndex(lineIndex);
var index = document.GetLineIndex(entryIndex);
if (index < lineIndex)
return entryIndex;
else
return Math.Max(entryIndex - 1, 0);
}

public static int FindNextEntryIndex(this Document document, int lineIndex)
{
var entryIndex = document.FindEntryIndex(lineIndex);
return Math.Min(entryIndex + 1, document.EntryCount);
}
}
16 changes: 14 additions & 2 deletions src/git-istage/UI/FileDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,26 @@ private FileDocument(int indexOfFirstFile, string[] lines, IReadOnlyList<TreeEnt

public override int Width { get; }

public override int EntryCount => _changes.Count;

public IReadOnlyList<TreeEntryChanges> Changes => _changes;

public override string GetLine(int index)
{
return _lines[index];
}

public override int GetLineIndex(int index)
{
return _indexOfFirstFile + index;
}

public override int FindEntryIndex(int lineIndex)
{
var changeIndex = lineIndex - _indexOfFirstFile;
return Math.Min(Math.Max(changeIndex, -1), _changes.Count - 1);
}

public TreeEntryChanges? GetChange(int index)
{
var changeIndex = index - _indexOfFirstFile;
Expand All @@ -44,7 +57,6 @@ public static FileDocument Create(IReadOnlyList<TreeEntryChanges> changes, bool
{
builder.AppendLine();
builder.AppendLine(viewStage ? "Changes to be committed:" : "Changes not staged for commit:");
builder.AppendLine();

var indent = new string(' ', 8);

Expand All @@ -53,10 +65,10 @@ public static FileDocument Create(IReadOnlyList<TreeEntryChanges> changes, bool
var path = c.Path;
var change = (c.Status.ToString().ToLower() + ":").PadRight(12);

builder.AppendLine();
builder.Append(indent);
builder.Append(change);
builder.Append(path);
builder.AppendLine();
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/git-istage/UI/HelpDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,20 @@ public HelpDocument(IReadOnlyCollection<ConsoleCommand> commands)

public override int Width { get; }

public override int EntryCount => _lines.Length;

public override string GetLine(int index)
{
return _lines[index];
}

public override int GetLineIndex(int index)
{
return index;
}

public override int FindEntryIndex(int lineIndex)
{
return lineIndex;
}
}
2 changes: 1 addition & 1 deletion src/git-istage/UI/Label.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private void Render()
Vt100.SetCursorPosition(_left, _top);
Vt100.SetForegroundColor(_foreground);
Vt100.SetBackgroundColor(_background);
Vt100.EraseRestOfCurrentLine();
Console.Write(text);
Vt100.EraseRestOfCurrentLine();
}
}
2 changes: 1 addition & 1 deletion src/git-istage/UI/ViewLineRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ protected static void RenderLine(View view, int lineIndex, string line, ConsoleC
Vt100.SetCursorPosition(view.Left, visualLine);
Vt100.SetForegroundColor(foregroundColor);
Vt100.SetBackgroundColor(backgroundColor);
Vt100.EraseRestOfCurrentLine();
Console.Write(text);
Vt100.EraseRestOfCurrentLine();

if (view.SearchResults is not null)
{
Expand Down
Loading