1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-11-26 09:00:57 +02:00

add file watching for modified files

log createErrorPanel error

swallow error when adding file to watcher
This commit is contained in:
Jesse Duffield 2019-11-12 22:19:20 +11:00
parent 7995d56a85
commit f15e47bb67
3 changed files with 101 additions and 17 deletions

64
pkg/gui/file_watching.go Normal file
View File

@ -0,0 +1,64 @@
package gui
import (
"os"
"path/filepath"
"github.com/fsnotify/fsnotify"
"github.com/jesseduffield/lazygit/pkg/commands"
)
// NOTE: given that we often edit files ourselves, this may make us end up refreshing files too often
// TODO: consider watching the whole directory recursively (could be more expensive)
func (gui *Gui) watchFilesForChanges() {
var err error
gui.fileWatcher, err = fsnotify.NewWatcher()
if err != nil {
gui.Log.Error(err)
return
}
go func() {
for {
select {
// watch for events
case event := <-gui.fileWatcher.Events:
if event.Op == fsnotify.Chmod {
// for some reason we pick up chmod events when they don't actually happen
continue
}
// only refresh if we're not already
if !gui.State.IsRefreshingFiles {
if err := gui.refreshFiles(); err != nil {
err = gui.createErrorPanel(gui.g, err.Error())
if err != nil {
gui.Log.Error(err)
}
}
}
// watch for errors
case err := <-gui.fileWatcher.Errors:
if err != nil {
gui.Log.Warn(err)
}
}
}
}()
}
func (gui *Gui) addFilesToFileWatcher(files []*commands.File) error {
// watch the files for changes
dirName, err := os.Getwd()
if err != nil {
return err
}
for _, file := range files {
if err := gui.fileWatcher.Add(filepath.Join(dirName, file.Name)); err != nil {
// swallowing errors here because it doesn't really matter if we can't watch a file
gui.Log.Warn(err)
}
}
return nil
}

View File

@ -105,6 +105,13 @@ func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View, alreadySelected bo
}
func (gui *Gui) refreshFiles() error {
gui.State.RefreshingFilesMutex.Lock()
gui.State.IsRefreshingFiles = true
defer func() {
gui.State.IsRefreshingFiles = false
gui.State.RefreshingFilesMutex.Unlock()
}()
selectedFile, _ := gui.getSelectedFile(gui.g)
filesView := gui.getFilesView()
@ -126,7 +133,7 @@ func (gui *Gui) refreshFiles() error {
}
fmt.Fprint(filesView, list)
if filesView == g.CurrentView() {
if g.CurrentView() == filesView || (g.CurrentView() == gui.getMainView() && gui.State.Context == "merging") {
newSelectedFile, _ := gui.getSelectedFile(gui.g)
alreadySelected := newSelectedFile.Name == selectedFile.Name
return gui.handleFileSelect(g, filesView, alreadySelected)
@ -387,6 +394,11 @@ func (gui *Gui) refreshStateFiles() error {
// get files to stage
files := gui.GitCommand.GetStatusFiles()
gui.State.Files = gui.GitCommand.MergeStatusFiles(gui.State.Files, files)
if err := gui.addFilesToFileWatcher(files); err != nil {
return err
}
gui.refreshSelectedLine(&gui.State.Panels.Files.SelectedLine, len(gui.State.Files))
return gui.updateWorkTreeState()
}

View File

@ -14,6 +14,7 @@ import (
"strings"
"time"
"github.com/fsnotify/fsnotify"
"github.com/go-errors/errors"
// "strings"
@ -79,6 +80,7 @@ type Gui struct {
statusManager *statusManager
credentials credentials
waitForIntro sync.WaitGroup
fileWatcher *fsnotify.Watcher
}
// for now the staging panel state, unlike the other panel states, is going to be
@ -145,22 +147,24 @@ type panelStates struct {
}
type guiState struct {
Files []*commands.File
Branches []*commands.Branch
Commits []*commands.Commit
StashEntries []*commands.StashEntry
CommitFiles []*commands.CommitFile
DiffEntries []*commands.Commit
MenuItemCount int // can't store the actual list because it's of interface{} type
PreviousView string
Platform commands.Platform
Updating bool
Panels *panelStates
WorkingTreeState string // one of "merging", "rebasing", "normal"
Context string // important not to set this value directly but to use gui.changeContext("new context")
CherryPickedCommits []*commands.Commit
SplitMainPanel bool
RetainOriginalDir bool
Files []*commands.File
Branches []*commands.Branch
Commits []*commands.Commit
StashEntries []*commands.StashEntry
CommitFiles []*commands.CommitFile
DiffEntries []*commands.Commit
MenuItemCount int // can't store the actual list because it's of interface{} type
PreviousView string
Platform commands.Platform
Updating bool
Panels *panelStates
WorkingTreeState string // one of "merging", "rebasing", "normal"
Context string // important not to set this value directly but to use gui.changeContext("new context")
CherryPickedCommits []*commands.Commit
SplitMainPanel bool
RetainOriginalDir bool
IsRefreshingFiles bool
RefreshingFilesMutex sync.Mutex
}
// for now the split view will always be on
@ -204,6 +208,8 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
statusManager: &statusManager{},
}
gui.watchFilesForChanges()
gui.GenerateSentinelErrors()
return gui, nil
@ -786,6 +792,8 @@ func (gui *Gui) RunWithSubprocesses() error {
}
}
gui.fileWatcher.Close()
break
} else if err == gui.Errors.ErrSwitchRepo {
continue