func (t *tbfe) FormatLine(v *backend.View, line int) string { buf := bytes.NewBuffer(nil) vr := v.Buffer().Line(v.Buffer().TextPoint(line, 0)) log4go.Debug("FormatLine: %d, %s", line, vr) if vr.Size() == 0 { return "" } recipie := v.Transform(scheme, vr).Transcribe() highlight_line := false if b, ok := v.Settings().Get("highlight_line", highlight_line).(bool); ok { highlight_line = b } lastEnd := vr.Begin() for _, reg := range recipie { if lastEnd != reg.Region.Begin() { fmt.Fprintf(buf, "<span>%s</span>", v.Buffer().Substr(Region{lastEnd, reg.Region.Begin()})) } fmt.Fprintf(buf, "<span style=\"white-space:pre; color:#%s; background:#%s\">%s</span>", htmlcol(reg.Flavour.Foreground), htmlcol(reg.Flavour.Background), v.Buffer().Substr(reg.Region)) lastEnd = reg.Region.End() } if lastEnd != vr.End() { io.WriteString(buf, v.Buffer().Substr(Region{lastEnd, vr.End()})) } return buf.String() }
func (c *GlueMarkedUndoGroupsCommand) Run(v *backend.View, e *backend.Edit) error { pos := v.UndoStack().Position() if mark, ok := v.Settings().Get(lime_cmd_mark).(int); ok { if l, p := pos-mark, mark; p != -1 && (l-p) > 1 { v.UndoStack().GlueFrom(mark) } } else { return fmt.Errorf("No mark in the current view") } return nil }
func new_view(v *backend.View) { log4go.Debug("new_view entered") defer log4go.Debug("new_view exited") qw := wnds[v.Window()] w := newQLimeView(v) v.Settings().Set("syntax", "../../3rdparty/bundles/GoSublime/GoSublime.tmLanguage") w.SetSizev(600, 400) // w := qt5.NewWidget() sa := qt5.NewScrollArea() sa.SetWidget(w) qw.tw.AddTab(sa, v.Buffer().Name(), nil) }
func (t *tbfe) renderView(wr io.Writer, v *backend.View, lay layout) { p := util.Prof.Enter("render") defer p.Exit() vr := lay.visible runes := v.Buffer().Substr(vr) recipie := v.Transform(scheme, vr).Transcribe() highlight_line := false if b, ok := v.Settings().Get("highlight_line", highlight_line).(bool); ok { highlight_line = b } lastEnd := 0 for _, reg := range recipie { if lastEnd != reg.Region.Begin() { io.WriteString(wr, runes[lastEnd:reg.Region.Begin()]) } fmt.Fprintf(wr, "<span style=\"color:#%s; background-color:#%s\">%s</span>", htmlcol(reg.Flavour.Foreground), htmlcol(reg.Flavour.Background), runes[reg.Region.Begin():reg.Region.End()]) lastEnd = reg.Region.End() } if lastEnd != vr.End() { io.WriteString(wr, v.Buffer().Substr(Region{lastEnd, vr.End()})) } }
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 (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 getSettings(v *backend.View) *FrontendSettings { style, _ := v.Settings().Get("caret_style", "underline").(string) inverse, _ := v.Settings().Get("inverse_caret_state", false).(bool) return &FrontendSettings{ v.Settings().Get("tab_size", 4).(int), v.Settings().Get("caret_blink", true).(bool), v.Settings().Get("highlight_line", false).(bool), getCaretStyle(style, inverse), v.Settings().Get("line_numbers", true).(bool), } }
func (c *MaybeMarkUndoGroupsForGluingCommand) Run(v *backend.View, e *backend.Edit) error { if !v.Settings().Has(lime_cmd_mark) { v.Settings().Set(lime_cmd_mark, v.UndoStack().Position()) } return nil }
func (c *UnmarkUndoGroupsForGluingCommand) Run(v *backend.View, e *backend.Edit) error { v.Settings().Erase(lime_cmd_mark) return nil }
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 tab_size, ok := v.Settings().Get("tab_size", 4).(int) if !ok { tab_size = 4 } recipie := v.Transform(scheme, vr).Transcribe() highlight_line := false if b, ok := v.Settings().Get("highlight_line", highlight_line).(bool); ok { highlight_line = b } if first && len(recipie) > 4 { first = false for i, v := range recipie { log4go.Debug("%d: %+v", i, v) } log4go.Debug("vr: %+v", vr) } // TODO: much of this belongs in backend as it's not specific to any particular frontend curr := 0 fg, bg := defaultFg, defaultBg _ = render.DRAW_TEXT for i, r := range runes { o := vr.Begin() + i curr = 0 fg, bg = defaultFg, defaultBg for curr < len(recipie) && (o >= recipie[curr].Region.Begin()) { // if curr > 0 { // curr-- // } if o < recipie[curr].Region.End() { fg = palLut(textmate.Color(recipie[curr].Flavour.Foreground)) bg = palLut(textmate.Color(recipie[curr].Flavour.Background)) } curr++ } if r == '\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 r == '\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, r, fg, bg) } x++ } }
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 tab_size, ok := v.Settings().Get("tab_size", 4).(int) if !ok { tab_size = 4 } recipie := v.Transform(scheme, vr).Transcribe() curr := 0 fg, bg := defaultFg, defaultBg _ = render.DRAW_TEXT sel := v.Sel() 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 } 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 } } if caret_blink && blink { caret_style = 0 } for i, r := range runes { o := vr.Begin() + i curr = 0 fg, bg = defaultFg, defaultBg for curr < len(recipie) && (o >= recipie[curr].Region.Begin()) { // if curr > 0 { // curr-- // } 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 | caret_style } if r == '\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 r == '\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, r, fg, bg) } x++ } }
func (c *MarkUndoGroupsForGluingCommand) Run(v *backend.View, e *backend.Edit, args backend.Args) error { v.Settings().Set(lime_cmd_mark, v.UndoStack().Position()) return nil }
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 }