func (t *tbfe) renderLStatus(v *backend.View, y int, fg, bg termbox.Attribute) { st := v.Status() sel := v.Sel() j := 0 for k, v := range st { s := fmt.Sprintf("%s: %s, ", k, v) addString(j, y, s, fg, bg) } if sel.Len() == 0 { return } else if l := sel.Len(); l > 1 { s := fmt.Sprintf("%d selection regions", l) j = addString(j, y, s, fg, bg) } else if r := sel.Get(0); r.Size() == 0 { row, col := v.Buffer().RowCol(r.A) s := fmt.Sprintf("Line %d, Column %d", row, col) j = addString(j, y, s, fg, bg) } else { ls := v.Buffer().Lines(r) s := v.Buffer().Substr(r) if len(ls) < 2 { s := fmt.Sprintf("%d characters selected", len(s)) j = addString(j, y, s, fg, bg) } else { s := fmt.Sprintf("%d lines %d characters selected", len(ls), len(s)) j = addString(j, y, s, fg, bg) } } if t.status_message != "" { s := fmt.Sprintf("; %s", t.status_message) addString(j, y, s, fg, bg) } }
func (t *tbfe) renderView(v *backend.View, lay layout) { p := util.Prof.Enter("render") defer p.Exit() sx, sy, w, h := lay.x, lay.y, lay.width, lay.height vr := lay.visible runes := v.Buffer().Substr(vr) x, y := sx, sy ex, ey := sx+w, sy+h style, _ := v.Settings().Get("caret_style", "underline").(string) inverse, _ := v.Settings().Get("inverse_caret_state", false).(bool) caretStyle := getCaretStyle(style, inverse) caretBlink, _ := v.Settings().Get("caret_blink", true).(bool) if caretBlink && blink { caretStyle = 0 } tabSize := 4 ts := v.Settings().Get("tab_size", tabSize) // TODO(.): crikey... if i, ok := ts.(int); ok { tabSize = i } else if f, ok := ts.(float64); ok { tabSize = int(f) } lineNumbers, _ := v.Settings().Get("line_numbers", true).(bool) recipie := v.Transform(scheme, vr).Transcribe() fg, bg := defaultFg, defaultBg sel := v.Sel() line, _ := v.Buffer().RowCol(vr.Begin()) eofline, _ := v.Buffer().RowCol(v.Buffer().Size()) lineNumberRenderSize := len(intToRunes(eofline)) for i, r := range runes { o := vr.Begin() + i curr := 0 fg, bg = defaultFg, defaultBg if lineNumbers { renderLineNumber(&line, &x, y, lineNumberRenderSize, fg, bg) } for curr < len(recipie) && (o >= recipie[curr].Region.Begin()) { if o < recipie[curr].Region.End() { fg = palLut(textmate.Color(recipie[curr].Flavour.Foreground)) bg = palLut(textmate.Color(recipie[curr].Flavour.Background)) } curr++ } iscursor := sel.Contains(Region{o, o}) if iscursor { fg = fg | caretStyle termbox.SetCell(x, y, ' ', fg, bg) } if r == '\t' { add := (x + 1 + (tabSize - 1)) &^ (tabSize - 1) for x < add { if x < ex { termbox.SetCell(x, y, ' ', fg, bg) } // A long cursor looks weird fg = fg & ^(termbox.AttrUnderline | termbox.AttrReverse) x++ } continue } else if r == '\n' { x = sx if y++; y > ey { break } else if lineNumbers { renderLineNumber(&line, &x, y, lineNumberRenderSize, fg, bg) } continue } if x < ex { termbox.SetCell(x, y, r, fg, bg) } x++ } fg, bg = defaultFg, defaultBg // Need this if the cursor is at the end of the buffer o := vr.Begin() + len(runes) iscursor := sel.Contains(Region{o, o}) if iscursor { fg = fg | caretStyle termbox.SetCell(x, y, ' ', fg, bg) } // restore original caretStyle before blink modification caretStyle = caretStyle }
func (t *tbfe) renderView(v *backend.View, lay layout) { p := util.Prof.Enter("render") defer p.Exit() sx, sy, w, h := lay.x, lay.y, lay.width, lay.height vr := lay.visible runes := v.Buffer().Substr(vr) x, y := sx, sy ex, ey := sx+w, sy+h style, _ := v.Settings().Get("caret_style", "underline").(string) inverse, _ := v.Settings().Get("inverse_caret_state", false).(bool) caretStyle := getCaretStyle(style, inverse) oldCaretStyle := caretStyle caretBlink, _ := v.Settings().Get("caret_blink", true).(bool) if caretBlink && blink { caretStyle = 0 } tabSize := 4 if i, ok := v.Settings().Get("tab_size", tabSize).(int); ok { tabSize = i } lineNumbers, _ := v.Settings().Get("line_numbers", true).(bool) recipie := v.Transform(scheme, vr).Transcribe() fg, bg := defaultFg, defaultBg sel := v.Sel() line, _ := v.Buffer().RowCol(vr.Begin()) eofline, _ := v.Buffer().RowCol(v.Buffer().Size()) lineNumberRenderSize := len(intToRunes(eofline)) for i, r := range runes { o := vr.Begin() + i curr := 0 fg, bg = defaultFg, defaultBg if lineNumbers { renderLineNumber(&line, &x, y, lineNumberRenderSize, fg, bg) } // TODO: doc for curr < len(recipie) && (o >= recipie[curr].Region.Begin()) { if o < recipie[curr].Region.End() { fg = palLut(textmate.Color(recipie[curr].Flavour.Foreground)) bg = palLut(textmate.Color(recipie[curr].Flavour.Background)) } curr++ } iscursor := sel.Contains(Region{o, o}) if iscursor { fg = fg | caretStyle termbox.SetCell(x, y, ' ', fg, bg) } if r == '\t' { add := (x + 1 + (tabSize - 1)) &^ (tabSize - 1) for ; x < add; x++ { if x < ex { termbox.SetCell(x, y, ' ', fg, bg) } // A long cursor looks weird fg = fg & ^(termbox.AttrUnderline | termbox.AttrReverse) } continue } else if r == '\n' { x = sx if y++; y > ey { break } else if lineNumbers { // This results in additional calls to renderLineNumber. // Maybe just accumulate positions needing line numbers, rendering them // after the loop? renderLineNumber(&line, &x, y, lineNumberRenderSize, defaultFg, defaultBg) } continue } if x < ex { termbox.SetCell(x, y, r, fg, bg) } x++ } fg, bg = defaultFg, defaultBg // Need this if the cursor is at the end of the buffer o := vr.Begin() + len(runes) iscursor := sel.Contains(Region{o, o}) if iscursor { fg = fg | caretStyle termbox.SetCell(x, y, ' ', fg, bg) } // restore original caretStyle before blink modification caretStyle = oldCaretStyle if rs := sel.Regions(); len(rs) > 0 { if r := rs[len(rs)-1]; !vr.Covers(r) { t.Show(v, r) } } fg, bg = defaultFg, palLut(textmate.Color{28, 29, 26, 1}) y = t.window_layout.height - statusbarHeight // Draw status bar bottom of window for i := 0; i < t.window_layout.width; i++ { termbox.SetCell(i, y, ' ', fg, bg) } t.renderLStatus(v, y, fg, bg) // The right status rns := []rune(fmt.Sprintf("Tab Size:%d %s", tabSize, "Go")) x = t.window_layout.width - 1 - len(rns) addRunes(x, y, rns, fg, bg) }
func (t *tbfe) renderView(v *backend.View, lay layout) { p := util.Prof.Enter("render") defer p.Exit() sx, sy, w, h := lay.x, lay.y, lay.width, lay.height vr := lay.visible runes := v.Buffer().Substr(vr) x, y := sx, sy ex, ey := sx+w, sy+h caretStyle := t.settings.caretStyle if t.settings.caretBlink && blink { t.settings.caretStyle = 0 } recipie := v.Transform(scheme, vr).Transcribe() fg, bg := defaultFg, defaultBg sel := v.Sel() line, _ := v.Buffer().RowCol(vr.Begin()) eofline, _ := v.Buffer().RowCol(v.Buffer().Size()) lineNumberRenderSize := len(intToRunes(eofline)) for i, r := range runes { o := vr.Begin() + i curr := 0 fg, bg = defaultFg, defaultBg if t.settings.lineNumbers { renderLineNumber(&line, &x, y, lineNumberRenderSize, fg, bg) } for curr < len(recipie) && (o >= recipie[curr].Region.Begin()) { if o < recipie[curr].Region.End() { fg = palLut(textmate.Color(recipie[curr].Flavour.Foreground)) bg = palLut(textmate.Color(recipie[curr].Flavour.Background)) } curr++ } if sel.Contains(Region{o, o}) { fg = fg | t.settings.caretStyle } if r == '\t' { add := (x + 1 + (t.settings.tabSize - 1)) &^ (t.settings.tabSize - 1) for x < add { if x < ex { termbox.SetCell(x, y, ' ', fg, bg) } fg = fg &^ termbox.AttrUnderline // Just looks weird with a long underline x++ } continue } else if r == '\n' { x = sx y++ if y > ey { break } continue } if x < ex { termbox.SetCell(x, y, r, fg, bg) } x++ } // restore original caretStyle before blink modification t.settings.caretStyle = caretStyle }
func (t *tbfe) GetSelectionMessage(v *backend.View) map[string]interface{} { return map[string]interface{}{ "type": "selection", "sel": v.Sel().Regions(), } }
func (t *tbfe) loop() { var ( ed = t.setupEditor() c = ed.Console() w = ed.NewWindow() v *backend.View ) if len(os.Args) > 1 { v = createNewView(os.Args[1], w) } else { v = w.NewFile() } 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() } }