From b3c0e35c07b270a77a4f93aced2c878f599857bf Mon Sep 17 00:00:00 2001
From: Akshay Chhajed <akshaychhajed@users.noreply.github.com>
Date: Sat, 27 Oct 2018 19:51:33 +0530
Subject: [PATCH] Added left arrow navigation for moving to parent directory or
 top of root (#43)

---
 ui/filetreeview.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/ui/filetreeview.go b/ui/filetreeview.go
index 0f2796a..f39c933 100644
--- a/ui/filetreeview.go
+++ b/ui/filetreeview.go
@@ -69,6 +69,9 @@ func (view *FileTreeView) Setup(v *gocui.View, header *gocui.View) error {
 	if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowUp, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorUp() }); err != nil {
 		return err
 	}
+	if err := view.gui.SetKeybinding(view.Name, gocui.KeyArrowLeft, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.CursorLeft() }); err != nil {
+		return err
+	}
 	if err := view.gui.SetKeybinding(view.Name, gocui.KeySpace, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return view.toggleCollapse() }); err != nil {
 		return err
 	}
@@ -192,6 +195,62 @@ func (view *FileTreeView) CursorUp() error {
 	return nil
 }
 
+//CursorLeft moves the cursor up until we reach the Parent Node or top of the tree
+func (view *FileTreeView) CursorLeft() error {
+	var visitor func(*filetree.FileNode) error
+	var evaluator func(*filetree.FileNode) bool
+	var dfsCounter, newIndex uint
+	oldIndex := view.TreeIndex
+	parentPath := view.getAbsPositionNode().Parent.Path()
+
+	visitor = func(curNode *filetree.FileNode) error {
+		if strings.Compare(parentPath, curNode.Path()) == 0 {
+			newIndex = dfsCounter
+		}
+		dfsCounter++
+		return nil
+	}
+	var filterBytes []byte
+	var filterRegex *regexp.Regexp
+	read, err := Views.Filter.view.Read(filterBytes)
+	if read > 0 && err == nil {
+		regex, err := regexp.Compile(string(filterBytes))
+		if err == nil {
+			filterRegex = regex
+		}
+	}
+
+	evaluator = func(curNode *filetree.FileNode) bool {
+		regexMatch := true
+		if filterRegex != nil {
+			match := filterRegex.Find([]byte(curNode.Path()))
+			regexMatch = match != nil
+		}
+		return !curNode.Parent.Data.ViewInfo.Collapsed && !curNode.Data.ViewInfo.Hidden && regexMatch
+	}
+
+	err = view.ModelTree.VisitDepthParentFirst(visitor, evaluator)
+	if err != nil {
+		panic(err)
+	}
+
+	view.TreeIndex = newIndex
+	moveIndex := oldIndex - newIndex
+	if newIndex < view.bufferIndexLowerBound {
+		view.bufferIndexUpperBound = view.TreeIndex + view.height()
+		view.bufferIndexLowerBound = view.TreeIndex
+	}
+
+	if view.bufferIndex > moveIndex {
+		view.bufferIndex = view.bufferIndex - moveIndex
+	} else {
+		view.bufferIndex = 0
+	}
+
+	view.Update()
+	return view.Render()
+}
+
 // getAbsPositionNode determines the selected screen cursor's location in the file tree, returning the selected FileNode.
 func (view *FileTreeView) getAbsPositionNode() (node *filetree.FileNode) {
 	var visitor func(*filetree.FileNode) error