How to process grid_line and flush events properly #576
-
Hi I hope it's ok to ask this here. Here's some of the code: //neovim.go
func StartListening(servername string, ctx context.Context) {
cols := 100
rows := 40
screen = NewScreen(ctx, cols, rows)
var err error
NvimInstance, err = nvim.NewChildProcess(
nvim.ChildProcessCommand("nvim"),
nvim.ChildProcessArgs("--embed", "/tmp/foo.lua"),
nvim.ChildProcessContext(context.Background()),
)
if err != nil {
log.Println(err)
return
}
defer NvimInstance.Close()
var result string
opts := make(map[string]interface{})
opts["ext_cmdline"] = true
opts["ext_linegrid"] = true
opts["ext_messages"] = true
err = NvimInstance.AttachUI(cols, rows, opts)
if err != nil {
utils.Log(err.Error())
}
NvimInstance.RegisterHandler("redraw", func(updates ...[]interface{}) {
screen.handleRedraw(updates)
})
...
//screen.go
type Screen struct {
Content [][]*Cell `json:"content"`
rows int
cols int
grids map[int][][]*Cell
ctx context.Context
}
func NewScreen(ctx context.Context, cols int, rows int) *Screen {
content := make([][]*Cell, rows)
for i := range content {
content[i] = make([]*Cell, cols)
for j := range content[i] {
content[i][j] = &Cell{
Char: " ",
Highlight: 0,
}
}
}
return &Screen{
Content: content,
rows: rows,
cols: cols,
grids: map[int][][]*Cell{1: content}, // Grid 1 is the main content grid
ctx: ctx,
}
}
func (s *Screen) handleRedraw(updates [][]interface{}) {
for _, update := range updates {
if len(update) == 0 {
continue
}
event := update[0].(string)
args := update[1:]
switch event {
case "grid_clear":
s.gridClear(args)
case "grid_line":
s.gridLine(args)
case "flush":
s.flush()
case "cmdline_show":
Runtime.EventsEmit(s.ctx, "cmdline_show")
case "cmdline_hide":
Runtime.EventsEmit(s.ctx, "cmdline_hide")
}
}
}
func (s *Screen) gridLine(args []interface{}) {
if len(args) < 1 {
return
}
gridArgs, ok := args[0].([]interface{})
if !ok || len(gridArgs) < 4 {
return
}
gridId := utils.ReflectToInt(gridArgs[0])
row := utils.ReflectToInt(gridArgs[1])
col := utils.ReflectToInt(gridArgs[2])
if row >= 7 && row <= 10 {
utils.Log(fmt.Sprintf("grid_line: grid=%d, row=%d, col=%d", gridId, row, col))
}
if gridId != 1 {
return
}
cells := gridArgs[3].([]interface{})
if row >= s.rows || col >= s.cols {
return
}
currentCol := col
for _, cell := range cells {
cellData, ok := cell.([]interface{})
if !ok || len(cellData) == 0 {
continue
}
char := cellData[0].(string)
repeat := 1
if len(cellData) > 2 {
repeat = utils.ReflectToInt(cellData[2])
}
hl := 0
if len(cellData) > 1 {
hl = utils.ReflectToInt(cellData[1])
}
for i := 0; i < repeat && currentCol < s.cols; i++ {
if row < len(s.Content) && currentCol < len(s.Content[row]) {
s.Content[row][currentCol] = &Cell{
Char: char,
Highlight: hl,
}
currentCol++
}
}
}
}
func (s *Screen) flush() {
Runtime.EventsEmit(s.ctx, "flush", s.Content)
} As far as I understand it should be sufficient to parse and render only gridId 1 for now, but I also tried with I checked if it's a viewport issue. as far as I can tell from the win_viewport event the concerning rows are indeed inside the viewport as expected. The statusline isn't, but is rendered on the main grid anyways. I also checked if it's some sort of an issue with my config by using I don't expect anyone to "do the work for me", but any help is greatly appreciated 🧡 |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
Answering my own question:
and then also the call site:
|
Beta Was this translation helpful? Give feedback.
-
@stefanwatt
If you have any other questions, feel free to discuss with me. |
Beta Was this translation helpful? Give feedback.
-
Communication in this discussions is better for me :) |
Beta Was this translation helpful? Give feedback.
Answering my own question:
I changed the signature of gridLine: