package main import ( "fmt" "strings" ) func (m model) View() string { var view strings.Builder for y := 0; y < m.win_h-1; y++ { if y < len(m.lines) { var ( gutter string currentLine bool = false lineNumber int ) if y > m.cursor.y { lineNumber = y - m.cursor.y gutter = fmt.Sprintf("%*d ", m.s_gutter-1, lineNumber) } else if y < m.cursor.y { lineNumber = m.cursor.y - y gutter = fmt.Sprintf("%*d ", m.s_gutter-1, lineNumber) } else { lineNumber = y + 1 currentLine = true if lineNumber < 100 { gutter = fmt.Sprintf("%*d ", m.s_gutter-2, lineNumber) } else { gutter = fmt.Sprintf("%*d ", m.s_gutter-1, lineNumber) } } view.WriteString(m.gutterStyle(currentLine).Render(gutter)) // TODO: Do we need to do offset calculation? runes := []rune(m.lines[y]) for x := 0; x <= len(runes); x++ { if m.cursor.y == y && m.cursor.x == x { if x < len(runes) { view.WriteString(m.cursorStyle().Render(string(runes[x]))) } else { view.WriteString(m.cursorStyle().Render(" ")) } } else if x < len(runes) { view.WriteRune(runes[x]) } } } else { format := fmt.Sprintf("%%-%ds ", m.s_gutter-1) fmt.Fprintf(&view, format, "~") } view.WriteString("\n") } // Draw status bar var modeString string switch m.mode { case NormalMode: modeString = "NORMAL" case InsertMode: modeString = "INSERT" case CommandMode: modeString = "COMMAND" } var bar string if m.mode == CommandMode { bar = fmt.Sprintf(" %6s | %d:%d (%d:%d) %s | %s", modeString, m.cursor.x, m.cursor.y, m.win_w, m.win_h, m.command, m.input.buffer) } else { bar = fmt.Sprintf(" %6s | %d:%d (%d:%d) | %s", modeString, m.cursor.x, m.cursor.y, m.win_w, m.win_h, m.input.buffer) } view.WriteString(bar) return view.String() }