mirror of
https://github.com/felixangell/phi.git
synced 2024-09-11 07:45:30 +03:00
editor slightly handles modification sys notification
the editor will now reload a file if it has been modified outside of the editor. still a huge wip.
This commit is contained in:
parent
e4dd07aead
commit
aa723f172f
@ -17,6 +17,7 @@ import (
|
||||
"github.com/felixangell/phi/cfg"
|
||||
"github.com/felixangell/phi/lex"
|
||||
"github.com/felixangell/strife"
|
||||
"github.com/sqweek/dialog"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
@ -184,6 +185,44 @@ func (s *selection) renderAt(ctx *strife.Renderer, xOff int, yOff int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Buffer) reload() {
|
||||
// if the file doesn't exist, try to create it before reading it
|
||||
if _, err := os.Stat(b.filePath); os.IsNotExist(err) {
|
||||
// this shouldn't really happen, for some
|
||||
// reason the file no longer exists?
|
||||
log.Println("File does not exist when reloading?! " + b.filePath)
|
||||
return
|
||||
}
|
||||
|
||||
// if the file has modifications made to it
|
||||
// ask if the user wants to reload the file or not
|
||||
// otherwise re-load it anyway.
|
||||
if b.modified {
|
||||
ok := dialog.Message("This file has been modified, would you like to reload?").YesNo()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadFile(b.filePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b.contents = []*rope.Rope{}
|
||||
|
||||
lines := strings.Split(string(contents), "\n")
|
||||
for _, line := range lines {
|
||||
b.appendLine(line)
|
||||
}
|
||||
|
||||
// TODO perhaps when we reload the current line might not exist or something
|
||||
// try and set the cursor to what it was before but maybe make sure its not out
|
||||
// of bounds, etc.
|
||||
|
||||
b.modified = false
|
||||
}
|
||||
|
||||
func (b *Buffer) OpenFile(filePath string) {
|
||||
b.filePath = filePath
|
||||
|
||||
@ -212,6 +251,9 @@ func (b *Buffer) OpenFile(filePath string) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// add the file to the watcher.
|
||||
b.parent.registerFile(filePath, b)
|
||||
|
||||
lines := strings.Split(string(contents), "\n")
|
||||
for _, line := range lines {
|
||||
b.appendLine(line)
|
||||
|
82
gui/view.go
82
gui/view.go
@ -1,15 +1,35 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"unicode"
|
||||
|
||||
"github.com/felixangell/phi/cfg"
|
||||
"github.com/felixangell/strife"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
type bufferEvent interface {
|
||||
Process(view *View)
|
||||
String() string
|
||||
}
|
||||
|
||||
type ReloadBufferEvent struct {
|
||||
buff *Buffer
|
||||
}
|
||||
|
||||
func (r *ReloadBufferEvent) Process(view *View) {
|
||||
log.Println("reloading buffer", r.buff.filePath)
|
||||
r.buff.reload()
|
||||
}
|
||||
|
||||
func (r *ReloadBufferEvent) String() string {
|
||||
return "reload-buffer-event"
|
||||
}
|
||||
|
||||
// View is an array of buffers basically.
|
||||
type View struct {
|
||||
BaseComponent
|
||||
@ -18,12 +38,18 @@ type View struct {
|
||||
buffers []*BufferPane
|
||||
focusedBuff int
|
||||
commandPalette *CommandPalette
|
||||
|
||||
watcher *fsnotify.Watcher
|
||||
bufferMap map[string]*Buffer
|
||||
bufferEvents chan bufferEvent
|
||||
}
|
||||
|
||||
func NewView(width, height int, conf *cfg.TomlConfig) *View {
|
||||
view := &View{
|
||||
conf: conf,
|
||||
buffers: []*BufferPane{},
|
||||
bufferMap: map[string]*Buffer{},
|
||||
bufferEvents: make(chan bufferEvent),
|
||||
}
|
||||
|
||||
view.Translate(width, height)
|
||||
@ -32,9 +58,65 @@ func NewView(width, height int, conf *cfg.TomlConfig) *View {
|
||||
view.commandPalette = NewCommandPalette(*conf, view)
|
||||
view.UnfocusBuffers()
|
||||
|
||||
var err error
|
||||
view.watcher, err = fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
// ?
|
||||
}
|
||||
|
||||
// goroutine to handle all of the fsnotify events
|
||||
// converts them into events phi can handle cleanly.
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event := <-view.watcher.Events:
|
||||
log.Println("evt: ", event)
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
|
||||
// modified so we specify a reload event
|
||||
buff, ok := view.bufferMap[event.Name]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("no such buffer for file '%s'", event.Name))
|
||||
break
|
||||
}
|
||||
|
||||
view.bufferEvents <- &ReloadBufferEvent{buff}
|
||||
log.Println("modified file:", event.Name)
|
||||
}
|
||||
case err := <-view.watcher.Errors:
|
||||
log.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// handles all of the phi events
|
||||
go func() {
|
||||
for {
|
||||
event := <-view.bufferEvents
|
||||
event.Process(view)
|
||||
}
|
||||
}()
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func (n *View) registerFile(path string, buff *Buffer) {
|
||||
log.Println("Registering file ", path)
|
||||
|
||||
err := n.watcher.Add(path)
|
||||
if err != nil {
|
||||
log.Println(fmt.Sprintf("Failed to register file '%s'", path), "to buffer ", buff.index)
|
||||
return
|
||||
}
|
||||
|
||||
n.bufferMap[path] = buff
|
||||
}
|
||||
|
||||
func (n *View) Close() {
|
||||
n.watcher.Close()
|
||||
}
|
||||
|
||||
func (n *View) hidePalette() {
|
||||
p := n.commandPalette
|
||||
p.clearInput()
|
||||
|
Loading…
Reference in New Issue
Block a user