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

WIP: Retain the view position on update of FileViewer and GoToLine #5474

Closed

Conversation

mstv
Copy link
Member

@mstv mstv commented Sep 23, 2018

Fixes #5327
base functionality for #5328

Changes proposed in this pull request:

  • retain the view position in FileViewerInternal.cs, not spread in every using ContainerControl/Form
    • FormCommit works
    • FormFileHistory works
    • RevisionDiffControl works
    • RevisionFileTreeControl works
  • retain the view position when updating the diff with caret visible
  • retain the view position when updating the diff with caret invisible
  • retain the view position when changing diff settings grafik with caret visible
  • retain the view position when changing diff settings grafik with caret invisible
  • retain the view position of a plain file (problem: how to distinguish between update and different file, simple heuristic: same TotalNumberOfLines)
  • retain the caret column
  • GoToLine works for a file diff
  • GoToLine works for a plain file if commit dialog does not refresh on form focus
  • GoToLine works for a plain file if commit dialog does refresh on form focus
  • GotoNext/PreviousChange works if commit dialog does not refresh on form focus
  • GotoNext/PreviousChange works if commit dialog does refresh on form focus

The following will be done in a dedicated PR for #5328:

  • show all assigned hotkeys in the context menus of the FileViewer
  • (optional?) show all assigned hotkeys in tooltips of toolbar buttons (Thoughts?)
  • check GoToLine after a .png was displayed
  • The context menu text shall be "Go to line... Ctrl+G", i.e. with dots "..." because it will open a subdialog.
  • The menu item shall be disabled if an image file or a binary diff is displayed.

Maybe a new issue:

  • in general? refresh FormCommit only if the GE application gets the focus again, not after own dialog window (Thoughts?)

Screenshots before and after (if PR changes UI):

  • none yet

What did I do to test the code and ensure quality:

  • manual testing see checklist above

Has been tested on (remove any that don't apply):

  • GIT 2.18.0.w.x64
  • Windows 7

@mstv mstv force-pushed the 5327_retain_diff_view_position branch from d7e3795 to a99382f Compare September 24, 2018 22:16
@mstv mstv force-pushed the 5327_retain_diff_view_position branch from a99382f to 4ea58a9 Compare September 25, 2018 22:21
@mstv
Copy link
Member Author

mstv commented Sep 25, 2018

It is almost done. Are there concerns against my approach?
What else could be affected by removing FileViewer.SaveCurrentScrollPos, .ResetCurrentScrollPos, and .RestoreCurrentScrollPos?
@RussKie Who else should have a look at it?

@RussKie
Copy link
Member

RussKie commented Sep 25, 2018

Apologies, I haven't had a chance to look, I have a lot of RL commitments atm that are taking precedence.
I will try to review it over the coming weekend.

@RussKie RussKie self-requested a review September 25, 2018 23:09
@mstv
Copy link
Member Author

mstv commented Sep 25, 2018

I didn't want to push you. With the first commit and the WIP PR, I just wanted to indicate that I work on these issues.

Today, I mainly wanted to get some reinsurance. This can wait.

Copy link
Member

@RussKie RussKie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a chance to run it, just reviewed it in GH UI.

In general I very much like the idea of centralising the behaviour and removing it from consumers. I think it is a move in the right direction.

On a flip side I'm finding the new code somewhat difficult to comprehend. The lack of tests and testability (of the new code) is very concerning to me as well.
I totally appreciate the existing code isn't particularly extensible and doesn't lend itself well to testing, but we shouldn't continue with bad practices :)

At the moment I don't have any suggestions on how to restructure the code to be testable or easier to read, but I'll think about in coming days.

private bool _visible = true;

public DiffViewerLineNumberControl(TextArea textArea) : base(textArea)
{
DiffLines = new Dictionary<int, DiffLineNum>();
}

/// <summary>
/// returns the according line numbers or null if the caretLine is not mapped
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please rephrase the summary, it is quite confusing now

@@ -14,21 +14,33 @@ internal class DiffViewerLineNumberControl : AbstractMargin

private Dictionary<int, DiffLineNum> DiffLines { get; set; }

private int _maxValueOfLineNum;
public int MaxValueOfLineNum { get; private set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename to MaxLineNumber to keep it consistent with DiffLineNumAnalyzer.Result.MaxLineNumber
Worth adding a comment explaining the purpose of the property


public Action OpenWithDifftool { get; private set; }

private struct ViewPosition
{
internal string FirstLine; // contains the file names in case of a diff
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change comments to proper xml-doc
Same for the rest of fields in the struct.

private struct ViewPosition
{
internal string FirstLine; // contains the file names in case of a diff
internal int TotalNumberOfLines; // if changed, CaretPosition and FirstVisibleLine must be ignored and the line number must be searched
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is not very clear on its intent

_previousViewPosition.ActiveLineNum = null;
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We made a rule to keep all private functions (if they are necessary) at the end of parent functions, after return statement. If return statement is missing, it gets added.
Please move this function to the end.

void SetActiveLineNum(int line)
{
_previousViewPosition.ActiveLineNum = _lineNumbersControl.GetLineNum(line);
if (_previousViewPosition.ActiveLineNum != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please invert all ifs to reduce nesting.
This applies to other cases as well.

int initialActiveLine = _previousViewPosition.CaretVisible ? _previousViewPosition.CaretPosition.Line : _previousViewPosition.FirstVisibleLine;
if (/*a diff was displayed*/!TextEditor.ShowLineNumbers)
{
void SetActiveLineNum(int line)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make the method "purer", that is determine the value of ActiveLineNum and return it, rather than set it to _previousViewPosition.ActiveLineNum.

{
return lineNumber - 1;
}
else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else is redundant

_previousViewPosition.TotalNumberOfLines = TotalNumberOfLines;
_previousViewPosition.CaretPosition = TextEditor.ActiveTextAreaControl.Caret.Position;
_previousViewPosition.FirstVisibleLine = FirstVisibleLine;
_previousViewPosition.CaretVisible
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like the only place where CaretVisible is set. And for the most part it is based off what the struct already "knows" bar TextEditor.ActiveTextAreaControl.TextArea.TextView.VisibleLineCount.
It kind of feels it would be a good candidate for a method placed in ViewPosition however it also becomes dependent on the order in which other properties are set, which is equally bad...

* Rename DiffLineNumAnalyzer.Result -> DiffLineNumAnalyzer.DiffLinesInfo
* Rename DiffLineNum -> DiffLineInfo
* Rename DiffLineNum.DiffLineStyle -> DiffLineInfo.DiffLineType
* Move DiffLineNumAnalyzer.AddToResult to DiffLinesInfo.Add
* Rearrange order of few class members
@RussKie
Copy link
Member

RussKie commented Sep 29, 2018

I had a little bit of time and tweaked the API slightly, these tweaks mainly deal with the overall hygiene of the code related to the PR (not necessarily originated by you).

* Extract DiffLinesInfo from DiffLineNumAnalyzer
* Extract DiffLineType from DiffLineInfo
Extract functionality get/set of the current view position into own methods.
@RussKie RussKie force-pushed the 5327_retain_diff_view_position branch from 232819f to c292e7c Compare September 29, 2018 23:21
To faciliate testing `GitHighlightingStrategyBase` must depend on
`IGitModule` instead of `GitModule`.

This change requires a little hack because `IConfigFileSettings` does
not expose `GetString(string, stirng)` that is exposed by `ConfigFileSettings`
class. This will need to be reconciled separately later.
@RussKie
Copy link
Member

RussKie commented Sep 30, 2018

Michael, please have a look at the refactor I pushed.
The code has been restructured to make it (more) modular, and that made the code testable.
I've also added a test scaffold that tests view position captures and restorations; it would be great if you could add tests for necessary use cases.

Eager to hear your thoughts.

GitUI/Editor/FileViewerInternal.cs Outdated Show resolved Hide resolved
GitUI/Editor/FileViewerInternal.cs Outdated Show resolved Hide resolved
GitUI/Editor/FileViewerInternal.cs Show resolved Hide resolved

if (isDiff)
{
_lineNumbersControl.DisplayLineNumFor(text);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be too early now: _lineNumbersControl holds a reference to the TextEditor.ActiveTextAreaControl.TextArea but TextEditor.Text has not been updated yet.
I'll check whether this matters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check, I grouped them together but the order may matter

GitUI/Editor/FileViewerInternal.cs Outdated Show resolved Hide resolved
return false;
}
if (index == 1 && char.IsWhiteSpace(c))
{
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, this additional indentation was not intended, was it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it wasn't. Looks like my VS settings are different

@mstv
Copy link
Member Author

mstv commented Sep 30, 2018

Thank you for the refactorings (I like the very descriptive identifier CurrentViewPositionCache) and for providing the test scaffold. It will make it much easier for me to write my first NUnit test cases.

@RussKie RussKie closed this Oct 1, 2018
@RussKie RussKie reopened this Oct 1, 2018
@gitextensions gitextensions deleted a comment from codecov bot Oct 1, 2018
@RussKie RussKie mentioned this pull request Oct 15, 2018
16 tasks
@RussKie
Copy link
Member

RussKie commented Oct 15, 2018

Superseded by #5563

@mstv mstv deleted the 5327_retain_diff_view_position branch November 13, 2018 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants