Exemple #1
0
// Creates and initializes the frontend.
func createFrontend() *tbfe {
	var t tbfe
	t.dorender = make(chan bool, render_chan_len)
	t.shutdown = make(chan bool, 2)
	t.layout = make(map[*backend.View]layout)

	t.editor = t.setupEditor()
	t.console = t.editor.Console()
	t.currentWindow = t.editor.NewWindow()

	// Assuming that all extra arguments are files
	if files := flag.Args(); len(files) > 0 {
		for _, file := range files {
			t.currentView = createNewView(file, t.currentWindow)
		}
	} else {
		t.currentView = t.currentWindow.NewFile()
	}

	t.console.Buffer().AddCallback(t.scroll)
	t.setupCallbacks(t.currentView)

	path := path.Join("..", "..", "3rdparty", "bundles", "TextMate-Themes", "Monokai.tmTheme")
	if sc, err := textmate.LoadTheme(path); err != nil {
		log.Error(err)
	} else {
		scheme = sc
	}

	setColorMode()
	setSchemeSettings()

	w, h := termbox.Size()
	t.handleResize(h, w, true)

	// These might take a while
	t.editor.Init()
	go sublime.Init()

	return &t
}
Exemple #2
0
func (t *tbfe) loop() {
	backend.OnNew.Add(func(v *backend.View) {
		v.Settings().AddOnChange("lime.frontend.html.render", func(name string) { t.dirty = true })
	})
	backend.OnModified.Add(func(v *backend.View) {
		t.dirty = true
	})
	backend.OnSelectionModified.Add(func(v *backend.View) {
		t.dirty = true
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()
	if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil {
		log4go.Error(err)
	} else {
		scheme = sc
	}

	defer func() {
		fmt.Println(util.Prof)
	}()

	w := ed.NewWindow()
	v := w.OpenFile("main.go", 0)
	v.Settings().Set("trace", true)
	v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	c.Buffer().AddCallback(t.scroll)

	sel := v.Sel()
	sel.Clear()
	//	end := v.Buffer().Size() - 2
	sel.Add(Region{0, 0})
	// sel.Add(Region{end - 22, end - 22})
	// sel.Add(Region{end - 16, end - 20})
	// sel.Add(Region{end - 13, end - 10})

	{
		w, h := 800, 600
		t.lock.Lock()
		t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0}
		t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})

	go func() {
		ed.Init()
		sublime.Init()
	}()
	log4go.Debug("serving")
	http.HandleFunc("/key", t.key)
	http.HandleFunc("/", t.ServeHTTP)
	http.HandleFunc("/view", t.view)
	if err := http.ListenAndServe("localhost:8080", nil); err != nil {
		log4go.Error("Error serving: %s", err)
	}
	log4go.Debug("Done")
}
Exemple #3
0
func (t *qmlfrontend) loop() (err error) {

	backend.OnNew.Add(func(v *backend.View) {
		fv := &frontendView{bv: v}
		v.Buffer().AddCallback(fv.bufferChanged)
		v.Settings().AddOnChange("blah", func(name string) {
			if name == "lime.syntax.updated" {
				// force redraw, as the syntax regions might have changed...
				for i := range fv.FormattedLine {
					fv.formatLine(i)
				}
			}
		})

		fv.Title.Text = v.Buffer().FileName()
		if len(fv.Title.Text) == 0 {
			fv.Title.Text = "untitled"
		}

		w2 := t.windows[v.Window()]
		w2.views = append(w2.views, fv)
		w2.Len = len(w2.views)
		t.qmlChanged(w2, &w2.Len)
	})

	backend.OnClose.Add(func(v *backend.View) {
		w2 := t.windows[v.Window()]
		for i := range w2.views {
			if w2.views[i].bv == v {
				copy(w2.views[i:], w2.views[i+1:])
				w2.views = w2.views[:len(w2.views)-1]
				w2.Len = len(w2.views)
				t.qmlChanged(w2, &w2.Len)
				return
			}
		}
		log4go.Error("Couldn't find closed view...")
	})

	backend.OnLoad.Add(func(v *backend.View) {
		w2 := t.windows[v.Window()]
		i := 0
		for i, _ = range w2.views {
			if w2.views[i].bv == v {
				break
			}
		}
		v2 := w2.views[i]
		v2.Title.Text = v.Buffer().FileName()
		t.qmlChanged(v2, &v2.Title)
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()
	t.Console = &frontendView{bv: c}
	c.Buffer().AddCallback(t.Console.bufferChanged)
	c.Buffer().AddCallback(t.scroll)

	const qmlMainFile = "main.qml"
	var (
		engine    *qml.Engine
		component qml.Object
		// WaitGroup keeping track of open windows
		wg sync.WaitGroup
	)

	// create and setup a new engine, destroying
	// the old one if one exists.
	//
	// 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.
	newEngine := func() (err error) {
		if engine != nil {
			log4go.Debug("calling destroy")
			// TODO(.): calling this appears to make the editor *very* crash-prone, just let it leak for now
			// engine.Destroy()
			engine = nil
		}
		log4go.Debug("calling newEngine")
		engine = qml.NewEngine()
		log4go.Debug("setvar frontend")
		engine.Context().SetVar("frontend", t)
		log4go.Debug("setvar editor")
		engine.Context().SetVar("editor", backend.GetEditor())

		log4go.Debug("loadfile")
		component, err = engine.LoadFile(qmlMainFile)
		return
	}
	if err := newEngine(); err != nil {
		log4go.Error(err)
	}

	backend.OnNewWindow.Add(func(w *backend.Window) {
		fw := &frontendWindow{bw: w}
		t.windows[w] = fw
		if component != nil {
			fw.launch(&wg, component)
		}
	})

	// TODO: should be done backend side
	if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/Monokai.tmTheme"); err != nil {
		log4go.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", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	v.Sel().Clear()
	v.Sel().Add(Region{0, 0})
	v = w.OpenFile("../../backend/editor.go", 0)
	// TODO: should be done backend side
	v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	v.Sel().Clear()
	v.Sel().Add(Region{0, 0})

	ed.Init()
	sublime.Init()

	watch, err := fsnotify.NewWatcher()
	if err != nil {
		log4go.Error("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

		log4go.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()
		log4go.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 {
			log4go.Debug("Calling newEngine")
			if err := newEngine(); err != nil {
				// Reset reload status
				reloadRequested = false
				log4go.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
			}
			log4go.Debug("break")
			break
		}
		log4go.Debug("re-launching all windows")
		// Succeeded loading the file, re-launch all windows
		for _, v := range t.windows {
			v.launch(&wg, component)
		}
	}
	return
}
Exemple #4
0
func (t *tbfe) loop() {

	var (
		ed = t.setupEditor()
		c  = ed.Console()
		w  = ed.NewWindow()
		v  *backend.View
	)

	// Assuming that all extra arguments are files
	if files := flag.Args(); len(files) > 0 {
		for _, file := range files {
			v = createNewView(file, w)
		}
	} else {
		v = w.NewFile()
	}

	c.Buffer().AddCallback(t.scroll)

	t.setupCallbacks(v)
	path := "../../3rdparty/bundles/TextMate-Themes/Monokai.tmTheme"
	if sc, err := textmate.LoadTheme(path); err != nil {
		log4go.Error(err)
		return
	} else {
		scheme = sc
	}
	setColorMode()
	setSchemeSettings()

	// We start the renderThread here, after we have done our setup of termbox.
	// That way, we do not clash with our output.
	go t.renderthread()

	evchan := make(chan termbox.Event, 32)
	defer func() {
		close(evchan)
	}()

	go func() {
		for {
			evchan <- termbox.PollEvent()
		}
	}()

	{
		w, h := termbox.Size()
		t.lock.Lock()
		if *showConsole {
			t.layout[v] = layout{0, 0, w, h - *consoleHeight - 4, Region{}, 0}
			t.layout[c] = layout{0, h - *consoleHeight - 2, w, *consoleHeight - 1, Region{}, 0}
		} else {
			t.layout[v] = layout{0, 0, w, h - 3, Region{}, 0}
		}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})

	go func() {
		ed.Init()
		sublime.Init()
	}()

	for {
		p := util.Prof.Enter("mainloop")

		blink_phase := time.Second
		if p, ok := ed.Settings().Get("caret_blink_phase", 1.0).(float64); ok {
			blink_phase = time.Duration(float64(time.Second) * p)
		}

		// Divided by two since we're only doing a simple toggle blink
		timer := time.NewTimer(blink_phase / 2)
		select {
		case ev := <-evchan:
			mp := util.Prof.Enter("evchan")
			limit := 3
		loop:
			switch ev.Type {
			case termbox.EventError:
				log4go.Debug("error occured")
				return
			case termbox.EventResize:
				// We have to resize our layouts...
				// There is currently duplicate code for calculating the layout:
				// during initialization (above), and here. Not nice
				if *showConsole {
					view_layout := t.layout[v]
					view_layout.height = ev.Height - *consoleHeight - 4
					view_layout.width = ev.Width

					console_layout := t.layout[c]
					console_layout.y = ev.Height - *consoleHeight - 2
					console_layout.width = ev.Width

					t.layout[v] = view_layout
					t.layout[c] = console_layout
				} else {
					view_layout := t.layout[v]
					view_layout.height = ev.Height - 3
					view_layout.width = ev.Width
					t.layout[v] = view_layout
				}

				// Ensure that the new visible region is recalculated
				t.Show(v, t.VisibleRegion(v))
			case termbox.EventKey:
				var kp backend.KeyPress

				if ev.Ch != 0 {
					kp.Key = backend.Key(ev.Ch)
				} else if v2, ok := lut[ev.Key]; ok {
					kp = v2
				} else {
					break
				}

				if ev.Key == termbox.KeyCtrlQ {
					return
				}
				ed.HandleInput(kp)

				blink = false
			}
			if len(evchan) > 0 {
				limit--
				ev = <-evchan
				goto loop
			}
			mp.Exit()
		case <-timer.C:
			// TODO(q): Shouldn't redraw if blink is disabled...

			blink = !blink
			t.render()
		}
		timer.Stop()
		p.Exit()
	}
}
Exemple #5
0
func (t *tbfe) loop() {
	qml.Init(nil)
	engine := qml.NewEngine()

	engine.Context().SetVar("lines", t)
	engine.Context().SetVar("frontend", t)
	engine.Context().SetVar("editor", backend.GetEditor())

	backend.OnNew.Add(func(v *backend.View) {
		fv := &frontendView{bv: v}
		v.Buffer().AddCallback(fv.bufferChanged)
		v.Settings().AddOnChange("blah", func(name string) {
			if name == "lime.syntax.updated" {
				// force redraw, as the syntax regions might have changed...
				for i := range fv.FormattedLine {
					fv.formatLine(i)
				}
			}
		})

		t.views[v] = fv
		t.Len = len(t.views)
		qml.Changed(t, &t.Len)
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()

	t.Console = &frontendView{bv: c}
	c.Buffer().AddCallback(t.Console.bufferChanged)

	if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil {
		log4go.Error(err)
	} else {
		scheme = sc
	}

	defer func() {
		fmt.Println(util.Prof)
	}()

	w := ed.NewWindow()
	v := w.OpenFile("main.go", 0)
	v.Settings().Set("trace", true)
	v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	c.Buffer().AddCallback(t.scroll)

	sel := v.Sel()
	sel.Clear()
	sel.Add(Region{0, 0})

	{
		w, h := 800, 600
		t.lock.Lock()
		t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0}
		t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})
	//	t.Len, _ = v.Buffer().RowCol(v.Buffer().Size())

	ed.Init()
	sublime.Init()

	component, err := engine.LoadFile("main.qml")
	if err != nil {
		log4go.Exit(err)
	}
	window := component.CreateWindow(nil)
	window.Show()

	log4go.Debug("Done")
	window.Wait()
}
Exemple #6
0
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 (
		engine    *qml.Engine
		component qml.Object
		// WaitGroup keeping track of open windows
		wg sync.WaitGroup
	)

	// create and setup a new engine, destroying
	// the old one if one exists.
	//
	// 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.
	newEngine := func() (err error) {
		if engine != nil {
			log.Debug("calling destroy")
			// TODO(.): calling this appears to make the editor *very* crash-prone, just let it leak for now
			// engine.Destroy()
			engine = nil
		}
		log.Debug("calling newEngine")
		engine = qml.NewEngine()
		log.Debug("setvar frontend")
		engine.Context().SetVar("frontend", t)
		log.Debug("setvar editor")
		engine.Context().SetVar("editor", backend.GetEditor())

		log.Debug("loadfile")
		component, err = engine.LoadFile(qmlMainFile)
		if err != nil {
			return err
		}
		limeViewComponent, err = engine.LoadFile(qmlViewFile)
		return
	}
	if err := newEngine(); err != nil {
		log.Error(err)
	}

	backend.OnNewWindow.Add(func(w *backend.Window) {
		fw := &frontendWindow{bw: w}
		t.windows[w] = fw
		if component != nil {
			fw.launch(&wg, component)
		}
	})

	// 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 := newEngine(); 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, component)
		}
	}
	return
}
Exemple #7
0
func (t *tbfe) loop() {
	var (
		ed  = t.setupEditor()
		c   = ed.Console()
		w   = ed.NewWindow()
		v   = createNewView("main.go", w)
		sel = v.Sel()
	)

	t.settings = getSettings(v)
	c.Buffer().AddCallback(t.scroll)

	t.setupCallbacks(v)
	loadTextMateScheme()
	setColorMode()
	setSchemeSettings()
	sel.Clear()
	sel.Add(Region{0, 0})

	evchan := make(chan termbox.Event, 32)
	defer func() {
		close(evchan)
		fmt.Println(util.Prof)
	}()

	go func() {
		for {
			evchan <- termbox.PollEvent()
		}
	}()

	{
		w, h := termbox.Size()
		t.lock.Lock()
		t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0}
		t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})

	go func() {
		ed.Init()
		sublime.Init()
	}()

	for {
		p := util.Prof.Enter("mainloop")

		blink_phase := time.Second
		if p, ok := ed.Settings().Get("caret_blink_phase", 1.0).(float64); ok {
			blink_phase = time.Duration(float64(time.Second) * p)
		}

		// Divided by two since we're only doing a simple toggle blink
		timer := time.NewTimer(blink_phase / 2)
		select {
		case ev := <-evchan:
			mp := util.Prof.Enter("evchan")
			limit := 3
		loop:
			switch ev.Type {
			case termbox.EventError:
				log4go.Debug("error occured")
				return
			case termbox.EventKey:
				var kp backend.KeyPress

				if ev.Ch != 0 {
					kp.Key = backend.Key(ev.Ch)
				} else if v2, ok := lut[ev.Key]; ok {
					kp = v2
				} else {
					break
				}

				if ev.Key == termbox.KeyCtrlQ {
					return
				}
				ed.HandleInput(kp)

				blink = false
			}
			if len(evchan) > 0 {
				limit--
				ev = <-evchan
				goto loop
			}
			mp.Exit()
		case <-timer.C:
			// TODO(q): Shouldn't redraw if blink is disabled...

			blink = !blink
			t.render()
		}
		timer.Stop()
		p.Exit()
	}
}
Exemple #8
0
func (t *tbfe) loop() {
	backend.OnNew.Add(func(v *backend.View) {
		v.Settings().AddOnChange("lime.frontend.html.render", func(name string) {
			if name != "lime.syntax.updated" {
				return
			}
			t.SetDirty()
		})
	})
	// TODO: maybe not useful?
	/*backend.OnModified.Add(func(v *backend.View) {
		t.SetDirty()
	})*/
	backend.OnSelectionModified.Add(func(v *backend.View) {
		t.BroadcastData(t.GetSelectionMessage(v))
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()
	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)
	//v.Settings().Set("trace", true)
	v.Settings().Set("syntax", "../../packages/go.tmbundle/Syntaxes/Go.tmLanguage")
	c.Buffer().AddObserver(t)

	sel := v.Sel()
	sel.Clear()
	//	end := v.Buffer().Size() - 2
	sel.Add(Region{0, 0})
	// sel.Add(Region{end - 22, end - 22})
	// sel.Add(Region{end - 16, end - 20})
	// sel.Add(Region{end - 13, end - 10})

	{
		w, h := 800, 600
		t.lock.Lock()
		t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0}
		t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})

	go func() {
		ed.Init()
		sublime.Init()
	}()
	log.Debug("Serving on port %d", *port)
	http.HandleFunc("/", t.ServeHTTP)
	http.HandleFunc("/view", t.view)
	http.HandleFunc("/key", t.key)
	http.HandleFunc("/themes/", t.theme)
	http.Handle("/ws", websocket.Handler(t.WebsocketServer))
	if err := http.ListenAndServe(fmt.Sprintf("localhost:%d", *port), nil); err != nil {
		log.Errorf("Error serving: %s", err)
	}
	log.Debug("Done")
}
Exemple #9
0
func (t *tbfe) loop() {
	qml.Init(nil)
	engine := qml.NewEngine()

	engine.Context().SetVar("lines", t)
	engine.Context().SetVar("frontend", t)
	engine.Context().SetVar("editor", backend.GetEditor())

	backend.OnNew.Add(func(v *backend.View) {
		fv := &frontendView{bv: v}
		v.Buffer().AddCallback(fv.bufferChanged)
		v.Settings().AddOnChange("blah", func(name string) {
			if name == "lime.syntax.updated" {
				// force redraw, as the syntax regions might have changed...
				for i := range fv.FormattedLine {
					fv.formatLine(i)
				}
			}
		})

		fv.Title.Text = v.Buffer().FileName()
		if len(fv.Title.Text) == 0 {
			fv.Title.Text = "untitled"
		}

		w2 := t.windows[v.Window()]
		w2.views = append(w2.views, fv)
		w2.Len = len(w2.views)
		t.qmlChanged(w2, &w2.Len)
	})

	backend.OnLoad.Add(func(v *backend.View) {
		w2 := t.windows[v.Window()]
		i := 0
		for i, _ = range w2.views {
			if w2.views[i].bv == v {
				break
			}
		}
		v2 := w2.views[i]
		v2.Title.Text = v.Buffer().FileName()
		t.qmlChanged(v2, &v2.Title)
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()
	t.Console = &frontendView{bv: c}
	c.Buffer().AddCallback(t.Console.bufferChanged)
	c.Buffer().AddCallback(t.scroll)

	component, err := engine.LoadFile("main.qml")
	if err != nil {
		log4go.Exit(err)
	}

	wg := sync.WaitGroup{}
	backend.OnNewWindow.Add(func(w *backend.Window) {
		wg.Add(1)
		fw := &frontendWindow{bw: w, window: component.CreateWindow(nil)}
		t.windows[w] = fw
		fw.window.Show()
		fw.window.Set("myWindow", fw)

		go func() {
			fw.window.Wait()
			wg.Done()
		}()
	})

	// TODO: should be done backend side
	if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil {
		log4go.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", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	v = w.OpenFile("../../backend/editor.go", 0)
	// TODO: should be done backend side
	v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")

	ed.Init()
	sublime.Init()
	wg.Wait()
}
Exemple #10
0
func (t *tbfe) loop() {

	var (
		ed = t.setupEditor()
		c  = ed.Console()
		w  = ed.NewWindow()
		v  *backend.View
	)

	// Assuming that all extra arguments are files
	if files := flag.Args(); len(files) > 0 {
		for _, file := range files {
			v = createNewView(file, w)
		}
	} else {
		v = w.NewFile()
	}

	t.settings = getSettings(v)
	c.Buffer().AddCallback(t.scroll)

	t.setupCallbacks(v)
	path := "../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"
	if sc, err := textmate.LoadTheme(path); err != nil {
		log4go.Error(err)
		return
	} else {
		scheme = sc
	}
	setColorMode()
	setSchemeSettings()

	evchan := make(chan termbox.Event, 32)
	defer func() {
		close(evchan)
		fmt.Println(util.Prof)
	}()

	go func() {
		for {
			evchan <- termbox.PollEvent()
		}
	}()

	{
		w, h := termbox.Size()
		t.lock.Lock()
		if *showConsole {
			t.layout[v] = layout{0, 0, w, h - *consoleHeight - 4, Region{}, 0}
			t.layout[c] = layout{0, h - *consoleHeight - 2, w, *consoleHeight - 1, Region{}, 0}
		} else {
			t.layout[v] = layout{0, 0, w, h - 3, Region{}, 0}
		}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})

	go func() {
		ed.Init()
		sublime.Init()
	}()

	for {
		p := util.Prof.Enter("mainloop")

		blink_phase := time.Second
		if p, ok := ed.Settings().Get("caret_blink_phase", 1.0).(float64); ok {
			blink_phase = time.Duration(float64(time.Second) * p)
		}

		// Divided by two since we're only doing a simple toggle blink
		timer := time.NewTimer(blink_phase / 2)
		select {
		case ev := <-evchan:
			mp := util.Prof.Enter("evchan")
			limit := 3
		loop:
			switch ev.Type {
			case termbox.EventError:
				log4go.Debug("error occured")
				return
			case termbox.EventKey:
				var kp backend.KeyPress

				if ev.Ch != 0 {
					kp.Key = backend.Key(ev.Ch)
				} else if v2, ok := lut[ev.Key]; ok {
					kp = v2
				} else {
					break
				}

				if ev.Key == termbox.KeyCtrlQ {
					return
				}
				ed.HandleInput(kp)

				blink = false
			}
			if len(evchan) > 0 {
				limit--
				ev = <-evchan
				goto loop
			}
			mp.Exit()
		case <-timer.C:
			// TODO(q): Shouldn't redraw if blink is disabled...

			blink = !blink
			t.render()
		}
		timer.Stop()
		p.Exit()
	}
}
Exemple #11
0
Fichier : main.go Projet : rzh/lime
func (t *tbfe) loop() {
	qml.Init(nil)
	engine := qml.NewEngine()

	engine.Context().SetVar("lines", t)
	engine.Context().SetVar("frontend", t)
	engine.Context().SetVar("editor", backend.GetEditor())

	backend.OnNew.Add(func(v *backend.View) {
		v.Settings().AddOnChange("lime.frontend.html.render", func(name string) { t.dirty = true })
	})
	backend.OnModified.Add(func(v *backend.View) {
		t.dirty = true
	})
	backend.OnSelectionModified.Add(func(v *backend.View) {
		t.dirty = true
	})

	ed := backend.GetEditor()
	ed.SetFrontend(t)
	ed.LogInput(false)
	ed.LogCommands(false)
	c := ed.Console()
	if sc, err := textmate.LoadTheme("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil {
		log4go.Error(err)
	} else {
		scheme = sc
	}

	defer func() {
		fmt.Println(util.Prof)
	}()

	w := ed.NewWindow()
	v := w.OpenFile("main.go", 0)
	v.Settings().Set("trace", true)
	v.Settings().Set("syntax", "../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage")
	c.Buffer().AddCallback(t.scroll)

	sel := v.Sel()
	sel.Clear()
	sel.Add(Region{0, 0})

	{
		w, h := 800, 600
		t.lock.Lock()
		t.layout[v] = layout{0, 0, w, h - console_height - 1, Region{}, 0}
		t.layout[c] = layout{0, h - console_height + 1, w, console_height - 5, Region{}, 0}
		t.lock.Unlock()
		t.Show(v, Region{1, 1})
	}
	t.Show(v, Region{100, 100})
	t.Show(v, Region{1, 1})
	t.Len, _ = v.Buffer().RowCol(v.Buffer().Size())

	ed.Init()
	sublime.Init()

	component, err := engine.LoadFile("main.qml")
	if err != nil {
		log4go.Exit(err)
	}
	window := component.CreateWindow(nil)
	window.Show()
	qml.Changed(t, &t.Len)

	log4go.Debug("Done")
	window.Wait()
}