From 4766ce009edda8a4f20025fe79a03bb4e50fbbfc Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 20 Sep 2026 15:32:33 +0200 Subject: [PATCH] Compare user-facing paths when re-finding the selection after a refresh When the selected rename splits into its two halves, e.g. because it was unstaged, the selection is meant to move to the new half. With the default setting of gui.showRootItemInFileTree, it lands on the file that follows the rename in the list instead. findNewSelectedIdx identifies a rename by the names of its two halves. These are user-facing paths, without the "./" prefix that the root item adds to every internal path, but they were compared against internal paths. The comparison never matched while the root item was shown. Compare user-facing paths throughout findNewSelectedIdx. Node.ID already identifies list items by their user-facing path. Co-Authored-By: Claude Fable 5.1 --- pkg/gui/filetree/file_tree_view_model.go | 6 ++++-- pkg/gui/filetree/file_tree_view_model_test.go | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/gui/filetree/file_tree_view_model.go b/pkg/gui/filetree/file_tree_view_model.go index 68829b444..514fbca01 100644 --- a/pkg/gui/filetree/file_tree_view_model.go +++ b/pkg/gui/filetree/file_tree_view_model.go @@ -132,6 +132,8 @@ func (self *FileTreeViewModel) SetTree() { // to that. // prevNodes starts from our previously selected node because we don't need to consider anything above that func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNodes []*FileNode) int { + // Paths are compared as the user sees them, without the "./" prefix of the + // root item, so that they line up with the names of a rename. getPaths := func(node *FileNode) []string { if node == nil { return nil @@ -139,7 +141,7 @@ func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNod if node.File != nil && node.File.IsRename() { return node.File.Names() } - return []string{node.path} + return []string{node.GetPath()} } for _, prevNode := range prevNodes { @@ -150,7 +152,7 @@ func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNod // If you started off with a rename selected, and now it's broken in two, we want you to jump to the new file, not the old file. // This is because the new should be in the same position as the rename was meaning less cursor jumping - foundOldFileInRename := prevNode.File != nil && prevNode.File.IsRename() && node.path == prevNode.File.PreviousPath + foundOldFileInRename := prevNode.File != nil && prevNode.File.IsRename() && node.GetPath() == prevNode.File.PreviousPath foundNode := utils.StringArraysOverlap(paths, selectedPaths) && !foundOldFileInRename if foundNode { return idx diff --git a/pkg/gui/filetree/file_tree_view_model_test.go b/pkg/gui/filetree/file_tree_view_model_test.go index 9777a2e31..fcc24a1b4 100644 --- a/pkg/gui/filetree/file_tree_view_model_test.go +++ b/pkg/gui/filetree/file_tree_view_model_test.go @@ -41,10 +41,7 @@ func TestSetTreeSelectsNewFileWhenSelectedRenameSplits(t *testing.T) { { name: "with root item", showRootItem: true, - /* EXPECTED: expectedPath: "dir/new.go", - ACTUAL: */ - expectedPath: "other.go", }, { name: "without root item",