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 sel := v.Sel() vr := lay.visible runes := v.Buffer().SubstrR(vr) x, y := sx, sy ex, ey := sx+w, sy+h var ( lastScope string lfg, lbg = defaultFg, defaultBg ) tab_size, ok := v.Settings().Get("tab_size", 4).(int) if !ok { tab_size = 4 } caret_style := termbox.AttrUnderline if b, ok := v.Settings().Get("caret_style", "underline").(string); ok { if b == "block" { caret_style = termbox.AttrReverse } } if b, ok := v.Settings().Get("inverse_caret_state", false).(bool); !b && ok { if caret_style == termbox.AttrReverse { caret_style = termbox.AttrUnderline } else { caret_style = termbox.AttrReverse } } caret_blink := true if b, ok := v.Settings().Get("caret_blink", true).(bool); ok { caret_blink = b } highlight_line := false if b, ok := v.Settings().Get("highlight_line", highlight_line).(bool); ok { highlight_line = b } // TODO: much of this belongs in backend as it's not specific to any particular frontend for i := range runes { o := vr.Begin() + i fg, bg := lfg, lbg scope := v.ScopeName(o) var lr Region if highlight_line { lr = v.Buffer().Line(o) } if scope != lastScope { fg, bg = defaultFg, defaultBg lastScope = scope na := scope for len(na) > 0 { sn := na i := strings.LastIndex(sn, " ") if i != -1 { sn = sn[i+1:] } if c, ok := schemelut[sn]; ok { fg, bg = c[0], c[1] break } if i2 := strings.LastIndex(na, "."); i2 == -1 { break } else if i > i2 { na = na[:i] } else { na = strings.TrimSpace(na[:i2]) } } lfg, lbg = fg, bg } else { fg, bg = lfg, lbg } for _, r2 := range sel.Regions() { if highlight_line && (lr.Contains(r2.A) || lr.Contains(r2.B)) { // TODO: highlight color bg |= termbox.AttrReverse continue } if r2.Contains(o) { if r2.Size() == 0 { if !caret_blink || blink { fg |= caret_style } break } else if r2.Contains(o + 1) { // TODO: selection color fg |= termbox.AttrReverse break } } } if runes[i] == '\t' { add := (x + 1 + (tab_size - 1)) &^ (tab_size - 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 runes[i] == '\n' { for ; x < ex; x++ { termbox.SetCell(x, y, ' ', fg, bg) if !highlight_line { break } } x = sx y++ if y > ey { break } continue } if x < ex { termbox.SetCell(x, y, runes[i], fg, bg) } x++ } }
func (t *tbfe) renderView(sx, sy, w, h int, v *backend.View) { sel := v.Sel() substr := v.Buffer().Data() vr := t.VisibleRegion(v) lines := strings.Split(substr, "\n") s, _ := v.Buffer().RowCol(vr.Begin()) e, _ := v.Buffer().RowCol(vr.End()) if e > 1 { e = e - 1 if e > h { s = e - h } } off := len(strings.Join(lines[:s], "\n")) lines = lines[s:e] runes := []rune(strings.Join(lines, "\n")) x, y := sx, sy ex, ey := sx+w, sy+h sub2 := "" var ( lastScope string lfg, lbg = defaultFg, defaultBg ) tab_size, ok := v.Settings().Get("tab_size", 4).(int) if !ok { tab_size = 4 } caret_style := termbox.AttrUnderline if b, ok := v.Settings().Get("caret_style", "underline").(string); ok { if b == "block" { caret_style = termbox.AttrReverse } } if b, ok := v.Settings().Get("inverse_caret_state", false).(bool); !b && ok { if caret_style == termbox.AttrReverse { caret_style = termbox.AttrUnderline } else { caret_style = termbox.AttrReverse } } caret_blink := true if b, ok := v.Settings().Get("caret_blink", true).(bool); ok { caret_blink = b } for i := range runes { sub2 += string(runes[i]) if x < ex { o := off + len(sub2) r := primitives.Region{o, o} fg, bg := lfg, lbg scope := v.ScopeName(o) if scope != lastScope { fg, bg = defaultFg, defaultBg lastScope = scope na := scope for len(na) > 0 { sn := na i := strings.LastIndex(sn, " ") if i != -1 { sn = sn[i+1:] } if c, ok := schemelut[sn]; ok { fg, bg = c[0], c[1] break } if i2 := strings.LastIndex(na, "."); i2 == -1 { break } else if i > i2 { na = na[:i] } else { na = strings.TrimSpace(na[:i2]) } } lfg, lbg = fg, bg } else { fg, bg = lfg, lbg } for _, r2 := range sel.Regions() { if r2.B == r.B { if !caret_blink || blink { if r2.Contains(o) { fg |= termbox.AttrReverse } else { fg |= caret_style } } break } else if r2.Contains(o) { fg |= termbox.AttrReverse break } } if runes[i] == '\t' { add := (x + 1 + (tab_size - 1)) &^ (tab_size - 1) for x < add { termbox.SetCell(x, y, ' ', fg, bg) x++ } continue } else if runes[i] == '\n' { termbox.SetCell(x, y, ' ', fg, bg) x = sx y++ if y > ey { break } continue } termbox.SetCell(x, y, runes[i], fg, bg) } x++ } }
func newQLimeView(v *backend.View) *QLimeView { log4go.Debug("new_QLimeView entered") defer log4go.Debug("new_QLimeView exited") var ret QLimeView ret.Widget = qt5.NewWidget() ret.v = v ret.Widget.OnPaintEvent(func(ev *qt5.PaintEvent) { p := qt5.NewPainter() defer p.Close() p.Begin(ret) b := v.Buffer() ps := p.Font().PointSize() pen := qt5.NewPen() p.SetPen(pen) brush := qt5.NewBrush() brush.SetStyle(qt5.SolidPattern) def := scheme.Settings[0] p.SetBrush(brush) f := p.Font() f.SetFixedPitch(true) p.SetFont(f) brush.SetColor(color.RGBA(def.Settings["background"])) p.DrawRect(ev.Rect()) is_widget, ok := v.Settings().Get("is_widget", false).(bool) is_widget = ok && is_widget pen.SetColor(color.RGBA(def.Settings["background"])) p.SetPen(pen) for y := 0; y < 20; y++ { pos := b.TextPoint(y, 0) line := b.Line(pos) if is_widget { p.DrawText(qt5.Point{0, (y + 1) * (ps + 2)}, b.Substr(line)) } else { for line.Contains(pos) { scope := primitives.Region{pos, pos} sn := v.ScopeName(pos) for line.Contains(pos) { pos++ if v.ScopeName(pos) != sn { scope.B = pos break } } is := line.Intersection(scope) c := color.RGBA(def.Settings["foreground"]) s := scheme.ClosestMatchingSetting(sn) if v, ok := s.Settings["foreground"]; ok { c = color.RGBA(v) } pen.SetColor(c) p.SetPen(pen) _, col := b.RowCol(line.A) p.DrawText(qt5.Point{col * ps / 2, (y + 1) * (ps + 2)}, b.Substr(is)) line.A = is.End() } } } }) ret.Widget.OnResizeEvent(func(ev *qt5.ResizeEvent) { if w, ok := v.Settings().Get("is_widget", false).(bool); ok && !w { ret.Widget.SetMinimumSize(qt5.Size{600, 100}) } }) v.Settings().Set("lime.qt.widget", &ret) return &ret }