Created
February 25, 2015 04:16
-
-
Save bwiggs/b86d577b31519ba13c4a to your computer and use it in GitHub Desktop.
limetext refactor snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// newQmlEngine creates a new qml engine. Destroys the old one if set. | |
// | |
// This is needed to re-load qml files to get the new file contents from disc as | |
// otherwise the old file would still be what is referenced. | |
func (t *qmlfrontend) newQmlEngine() (err error) { | |
if t.engine != nil { | |
// TODO(.): calling this appears to make the editor *very* crash-prone, just let it leak for now | |
// engine.Destroy() | |
t.engine = nil | |
} | |
t.engine = qml.NewEngine() | |
t.engine.Context().SetVar("frontend", t) | |
t.engine.Context().SetVar("editor", backend.GetEditor()) | |
return | |
} | |
// loop is the main application loop started by qml.Run | |
func (t *qmlfrontend) loop() (err error) { | |
backend.OnNew.Add(t.onNew) | |
backend.OnClose.Add(t.onClose) | |
backend.OnLoad.Add(t.onLoad) | |
ed := backend.GetEditor() | |
ed.Init() | |
go sublime.Init() | |
ed.SetFrontend(t) | |
ed.LogInput(false) | |
ed.LogCommands(false) | |
c := ed.Console() | |
t.Console = &frontendView{bv: c} | |
c.Buffer().AddObserver(t.Console) | |
c.Buffer().AddObserver(t) | |
var ( | |
windowComponent qml.Object // main QML windowComponent | |
wg sync.WaitGroup // keeps track of open windows | |
) | |
if err := t.newQmlEngine(); err != nil { | |
log.Error(err) | |
} | |
windowComponent, err = t.engine.LoadFile(qmlMainFile) | |
if err != nil { | |
return err | |
} | |
limeViewComponent, err = t.engine.LoadFile(qmlViewFile) | |
if err != nil { | |
return err | |
} | |
backend.OnNewWindow.Add(func(w *backend.Window) { | |
fw := &frontendWindow{bw: w} | |
t.windows[w] = fw | |
if windowComponent != nil { | |
fw.launch(&wg, windowComponent) | |
} | |
}) | |
// TODO: should be done backend side | |
if sc, err := textmate.LoadTheme("../../packages/themes/TextMate-Themes/Monokai.tmTheme"); err != nil { | |
log.Error(err) | |
} else { | |
scheme = sc | |
} | |
defer func() { | |
fmt.Println(util.Prof) | |
}() | |
w := ed.NewWindow() | |
v := w.OpenFile("main.go", 0) | |
// TODO: should be done backend side | |
v.Settings().Set("syntax", "../../packages/go.tmbundle/Syntaxes/Go.tmLanguage") | |
v = w.OpenFile("../../backend/editor.go", 0) | |
// TODO: should be done backend side | |
v.Settings().Set("syntax", "../../packages/go.tmbundle/Syntaxes/Go.tmLanguage") | |
watch, err := fsnotify.NewWatcher() | |
if err != nil { | |
log.Errorf("Unable to create file watcher: %s", err) | |
return | |
} | |
defer watch.Close() | |
watch.Watch(".") | |
defer watch.RemoveWatch(".") | |
reloadRequested := false | |
go func() { | |
for { | |
select { | |
case ev := <-watch.Event: | |
if ev != nil && strings.HasSuffix(ev.Name, ".qml") && ev.IsModify() && !ev.IsAttrib() { | |
reloadRequested = true | |
// Close all open windows to de-reference all | |
// qml objects | |
for _, v := range t.windows { | |
if v.window != nil { | |
v.window.Hide() | |
v.window.Destroy() | |
v.window = nil | |
} | |
} | |
} | |
} | |
} | |
}() | |
for { | |
// Reset reload status | |
reloadRequested = false | |
log.Debug("Waiting for all windows to close") | |
// wg would be the WaitGroup all windows belong to, so first we wait for | |
// all windows to close. | |
wg.Wait() | |
log.Debug("All windows closed. reloadRequest: %v", reloadRequested) | |
// then we check if there's a reload request in the pipe | |
if !reloadRequested || len(t.windows) == 0 { | |
// This would be a genuine exit; all windows closed by the user | |
break | |
} | |
// *We* closed all windows because we want to reload freshly changed qml | |
// files. | |
for { | |
log.Debug("Calling newEngine") | |
if err := t.newQmlEngine(); err != nil { | |
// Reset reload status | |
reloadRequested = false | |
log.Error(err) | |
for !reloadRequested { | |
// This loop allows us to re-try reloading | |
// if there was an error in the file this time, | |
// we just loop around again when we receive the next | |
// reload request (ie on the next save of the file). | |
time.Sleep(time.Second) | |
} | |
continue | |
} | |
log.Debug("break") | |
break | |
} | |
log.Debug("re-launching all windows") | |
// Succeeded loading the file, re-launch all windows | |
for _, v := range t.windows { | |
v.launch(&wg, windowComponent) | |
} | |
} | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment