This commit is contained in:
Liam Galvin 2018-08-09 13:30:16 +01:00
parent 5889d744f9
commit 5e2c2ca690
12 changed files with 358 additions and 190 deletions

View File

@ -52,33 +52,27 @@ Ensure you have your latest graphics card drivers installed before use.
| Mouse interaction | | | Mouse interaction | |
| Sweet render effects | | | Sweet render effects | |
## Configuration
Raft looks for a config file in the following places: `~/.raft.yml`, `~/.config/raft.yml` (earlier in the list prioritised).
Example config:
```
debug: False
```
The following options are available:
| Name | Type | Default |Description |
|---------------|---------|---------|-----------------------|
| debug | bool | False | Enables debug logging
## Flags
| Name | Type | Default |Description |
|------------------|---------|---------|-----------------------|
| --debug | bool | False | Enables debug logging |
| --ignore-config | bool | False | Ignores user config files and uses defaults
| --always-repaint | bool | False | Redraw the terminal constantly, even when no changes have been made
## Keyboard Shortcuts ## Keyboard Shortcuts
| Operation | Key(s) | | Operation | Key(s) |
|-----------|---------------------| |--------------------|---------------------|
| Paste | ctrl + shift + v | Paste | ctrl + shift + v
| Interrupt (SIGINT) | ctrl + c
| Suspend | ctrl + s
| Resume | ctrl + q
## Configuration
Raft looks for a config file in `~/.raft.toml`, and will write one there the first time it runs, if it doesn't already exist.
You can ignore the config and use defauls by specifying `--ignore-config` as a CLI flag.
### Config Options/CLI Flags
| CLI Flag | Config Section | Config Name | Type | Default | Description |
|--------------------|---------------------|------------------------|---------|--------------|-------------|
| --debug | _root_ | debug | boolean | false | Enable debug mode, with debug logging and debug info terminal overlay.
| --slomo | _root_ | slomo | boolean | false | Enable slomo mode, delay the handling of each incoming byte (or escape sequence) from the pty by 100ms. Useful for debugging.
| --always-repaint | rendering | always_repaint | boolean | false | Redraw the terminal GUI constantly, even when no changes have occurred.

View File

@ -21,19 +21,16 @@ func newCell() Cell {
return Cell{} return Cell{}
} }
func (cell *Cell) Attr() CellAttributes {
return cell.attr
}
func (cell *Cell) Rune() rune { func (cell *Cell) Rune() rune {
if cell.r == 0 {
return '~'
}
return cell.r return cell.r
} }
func (cell *Cell) Fg() [3]float32 { func (cell *Cell) Fg() [3]float32 {
if cell.r == 0 { return cell.attr.FgColour
return [3]float32{0.5, 0.5, 0.5}
}
return [3]float32{0.9, 0.9, 0.9} // @todo fix this
//return cell.attr.FgColour
} }
func (cell *Cell) Bg() [3]float32 { func (cell *Cell) Bg() [3]float32 {

81
config/colours.go Normal file
View File

@ -0,0 +1,81 @@
package config
import (
"encoding/hex"
"fmt"
"math"
"strings"
)
type Colour [3]float32
func (c *Colour) UnmarshalText(data []byte) error {
hexStr := string(data)
if strings.HasPrefix(hexStr, "#") {
hexStr = hexStr[1:]
}
if len(hexStr) != 6 {
return fmt.Errorf("Invalid colour format. Should be like #ffffff")
}
bytes, err := hex.DecodeString(hexStr)
if err != nil {
return err
}
c[0] = float32(bytes[0]) / 255
c[1] = float32(bytes[1]) / 255
c[2] = float32(bytes[2]) / 255
return nil
}
func (c Colour) MarshalText() (text []byte, err error) {
return []byte(fmt.Sprintf(
"#%02x%02x%02x",
uint8(math.Floor(float64(255*c[0]))),
uint8(math.Floor(float64(255*c[1]))),
uint8(math.Floor(float64(255*c[2]))),
)), nil
}
type ColourScheme struct {
Cursor Colour `toml:"cursor"`
DefaultFg Colour `toml:"default_fg"`
BlackFg Colour `toml:"black_fg"`
RedFg Colour `toml:"red_fg"`
GreenFg Colour `toml:"green_fg"`
YellowFg Colour `toml:"yellow_fg"`
BlueFg Colour `toml:"blue_fg"`
MagentaFg Colour `toml:"magenta_fg"`
CyanFg Colour `toml:"cyan_fg"`
LightGreyFg Colour `toml:"light_grey_fg"`
DarkGreyFg Colour `toml:"dark_grey_fg"`
LightRedFg Colour `toml:"light_red_fg"`
LightGreenFg Colour `toml:"light_green_fg"`
LightYellowFg Colour `toml:"light_yellow_fg"`
LightBlueFg Colour `toml:"light_blue_fg"`
LightMagentaFg Colour `toml:"light_magenta_fg"`
LightCyanFg Colour `toml:"light_cyan_fg"`
WhiteFg Colour `toml:"white_fg"`
DefaultBg Colour `toml:"default_bg"`
BlackBg Colour `toml:"black_bg"`
RedBg Colour `toml:"red_bg"`
GreenBg Colour `toml:"green_bg"`
YellowBg Colour `toml:"yellow_bg"`
BlueBg Colour `toml:"blue_bg"`
MagentaBg Colour `toml:"magenta_bg"`
CyanBg Colour `toml:"cyan_bg"`
LightGreyBg Colour `toml:"light_grey_bg"`
DarkGreyBg Colour `toml:"dark_grey_bg"`
LightRedBg Colour `toml:"light_red_bg"`
LightGreenBg Colour `toml:"light_green_bg"`
LightYellowBg Colour `toml:"light_yellow_bg"`
LightBlueBg Colour `toml:"light_blue_bg"`
LightMagentaBg Colour `toml:"light_magenta_bg"`
LightCyanBg Colour `toml:"light_cyan_bg"`
WhiteBg Colour `toml:"white_bg"`
}

35
config/colours_test.go Normal file
View File

@ -0,0 +1,35 @@
package config
import (
"bytes"
"testing"
"github.com/BurntSushi/toml"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestColourTomlEncoding(t *testing.T) {
target := struct {
Orange Colour `toml:"colour"`
}{
Orange: Colour([3]float32{1, 0.5, 0}),
}
var buf bytes.Buffer
e := toml.NewEncoder(&buf)
err := e.Encode(target)
require.Nil(t, err)
assert.Equal(t, `colour = "#ff7f00"
`, buf.String())
}
func TestColourTomlUnmarshalling(t *testing.T) {
target := struct {
Purple Colour `toml:"colour"`
}{}
err := toml.Unmarshal([]byte(`colour = "#7f00ff"`), &target)
require.Nil(t, err)
assert.InDelta(t, 0.5, target.Purple[0], 0.01)
assert.InDelta(t, 0.0, target.Purple[1], 0.01)
assert.InDelta(t, 1.0, target.Purple[2], 0.01)
}

View File

@ -1,105 +1,34 @@
package config package config
import ( import (
yaml "gopkg.in/yaml.v2" "bytes"
"github.com/BurntSushi/toml"
) )
type Config struct { type Config struct {
DebugMode bool `yaml:"debug"` DebugMode bool `toml:"debug"`
ColourScheme ColourScheme Rendering RenderingConfig `toml:"rendering"`
Rendering RenderingConfig `yaml:"rendering"` Slomo bool `toml:"slomo"`
Slomo bool `yaml:"slomo"` ColourScheme ColourScheme `toml:"colours"`
} }
type RenderingConfig struct { type RenderingConfig struct {
AlwaysRepaint bool `yaml:"always_repaint"` AlwaysRepaint bool `toml:"always_repaint"`
}
var DefaultConfig = Config{
DebugMode: false,
ColourScheme: DefaultColourScheme,
} }
func Parse(data []byte) (*Config, error) { func Parse(data []byte) (*Config, error) {
c := DefaultConfig c := DefaultConfig
err := yaml.Unmarshal(data, &c) err := toml.Unmarshal(data, &c)
return &c, err return &c, err
} }
type ColourScheme struct { func (c *Config) Encode() ([]byte, error) {
Cursor [3]float32 var buf bytes.Buffer
DefaultFg [3]float32 e := toml.NewEncoder(&buf)
BlackFg [3]float32 err := e.Encode(c)
RedFg [3]float32 if err != nil {
GreenFg [3]float32 return nil, err
YellowFg [3]float32 }
BlueFg [3]float32 return buf.Bytes(), nil
MagentaFg [3]float32
CyanFg [3]float32
LightGreyFg [3]float32
DarkGreyFg [3]float32
LightRedFg [3]float32
LightGreenFg [3]float32
LightYellowFg [3]float32
LightBlueFg [3]float32
LightMagentaFg [3]float32
LightCyanFg [3]float32
WhiteFg [3]float32
DefaultBg [3]float32
BlackBg [3]float32
RedBg [3]float32
GreenBg [3]float32
YellowBg [3]float32
BlueBg [3]float32
MagentaBg [3]float32
CyanBg [3]float32
LightGreyBg [3]float32
DarkGreyBg [3]float32
LightRedBg [3]float32
LightGreenBg [3]float32
LightYellowBg [3]float32
LightBlueBg [3]float32
LightMagentaBg [3]float32
LightCyanBg [3]float32
WhiteBg [3]float32
}
var DefaultColourScheme = ColourScheme{
Cursor: [3]float32{0.8, 0.8, 0.8},
//fg
DefaultFg: [3]float32{1, 1, 1},
BlackFg: [3]float32{0, 0, 0},
RedFg: [3]float32{1, 0, 0},
GreenFg: [3]float32{0, 1, 0},
YellowFg: [3]float32{1, 1, 0},
BlueFg: [3]float32{0, 0, 1},
MagentaFg: [3]float32{1, 0, 1},
CyanFg: [3]float32{0, 1, 1},
LightGreyFg: [3]float32{0.7, 0.7, 0.7},
DarkGreyFg: [3]float32{0.3, 0.3, 0.3},
LightRedFg: [3]float32{1, 0.5, 0.5},
LightGreenFg: [3]float32{0.5, 1, 0.5},
LightYellowFg: [3]float32{1, 1, 0.5},
LightBlueFg: [3]float32{0.5, 0.5, 1},
LightMagentaFg: [3]float32{1, 0.5, 1},
LightCyanFg: [3]float32{0.5, 1, 1},
WhiteFg: [3]float32{1, 1, 1},
// bg
DefaultBg: [3]float32{0.1, 0.1, 0.1},
BlackBg: [3]float32{0, 0, 0},
RedBg: [3]float32{1, 0, 0},
GreenBg: [3]float32{0, 1, 0},
YellowBg: [3]float32{1, 1, 0},
BlueBg: [3]float32{0, 0, 1},
MagentaBg: [3]float32{1, 0, 1},
CyanBg: [3]float32{0, 1, 1},
LightGreyBg: [3]float32{0.7, 0.7, 0.7},
DarkGreyBg: [3]float32{0.3, 0.3, 0.3},
LightRedBg: [3]float32{1, 0.5, 0.5},
LightGreenBg: [3]float32{0.5, 1, 0.5},
LightYellowBg: [3]float32{1, 1, 0.5},
LightBlueBg: [3]float32{0.5, 0.5, 1},
LightMagentaBg: [3]float32{1, 0.5, 1},
LightCyanBg: [3]float32{0.5, 1, 1},
WhiteBg: [3]float32{1, 1, 1},
} }

44
config/defaults.go Normal file
View File

@ -0,0 +1,44 @@
package config
var DefaultConfig = Config{
DebugMode: false,
ColourScheme: ColourScheme{
Cursor: [3]float32{0.8, 0.8, 0.8},
//fg
DefaultFg: [3]float32{1, 1, 1},
BlackFg: [3]float32{0, 0, 0},
RedFg: [3]float32{1, 0, 0},
GreenFg: [3]float32{0, 1, 0},
YellowFg: [3]float32{1, 1, 0},
BlueFg: [3]float32{0, 0, 1},
MagentaFg: [3]float32{1, 0, 1},
CyanFg: [3]float32{0, 1, 1},
LightGreyFg: [3]float32{0.7, 0.7, 0.7},
DarkGreyFg: [3]float32{0.3, 0.3, 0.3},
LightRedFg: [3]float32{1, 0.5, 0.5},
LightGreenFg: [3]float32{0.5, 1, 0.5},
LightYellowFg: [3]float32{1, 1, 0.5},
LightBlueFg: [3]float32{0.5, 0.5, 1},
LightMagentaFg: [3]float32{1, 0.5, 1},
LightCyanFg: [3]float32{0.5, 1, 1},
WhiteFg: [3]float32{1, 1, 1},
// bg
DefaultBg: [3]float32{0.1, 0.1, 0.1},
BlackBg: [3]float32{0, 0, 0},
RedBg: [3]float32{1, 0, 0},
GreenBg: [3]float32{0, 1, 0},
YellowBg: [3]float32{1, 1, 0},
BlueBg: [3]float32{0, 0, 1},
MagentaBg: [3]float32{1, 0, 1},
CyanBg: [3]float32{0, 1, 1},
LightGreyBg: [3]float32{0.7, 0.7, 0.7},
DarkGreyBg: [3]float32{0.3, 0.3, 0.3},
LightRedBg: [3]float32{1, 0.5, 0.5},
LightGreenBg: [3]float32{0.5, 1, 0.5},
LightYellowBg: [3]float32{1, 1, 0.5},
LightBlueBg: [3]float32{0.5, 0.5, 1},
LightMagentaBg: [3]float32{1, 0.5, 1},
LightCyanBg: [3]float32{0.5, 1, 1},
WhiteBg: [3]float32{1, 1, 1},
},
}

View File

@ -106,7 +106,7 @@ func (gui *GUI) Render() error {
return fmt.Errorf("Failed to load font: %s", err) return fmt.Errorf("Failed to load font: %s", err)
} }
gui.renderer = NewOpenGLRenderer(gui.font, gui.fontScale, 0, 0, gui.width, gui.height) gui.renderer = NewOpenGLRenderer(gui.config, gui.font, gui.fontScale, 0, 0, gui.width, gui.height)
gui.window.SetFramebufferSizeCallback(gui.resize) gui.window.SetFramebufferSizeCallback(gui.resize)
gui.window.SetKeyCallback(gui.key) gui.window.SetKeyCallback(gui.key)
@ -137,7 +137,7 @@ func (gui *GUI) Render() error {
//glfw.SwapInterval(1) //glfw.SwapInterval(1)
gl.ClearColor( gl.ClearColor(
gui.config.ColourScheme.DefaultBg[0], 1.0, //gui.config.ColourScheme.DefaultBg[0],
gui.config.ColourScheme.DefaultBg[1], gui.config.ColourScheme.DefaultBg[1],
gui.config.ColourScheme.DefaultBg[2], gui.config.ColourScheme.DefaultBg[2],
1.0, 1.0,

View File

@ -4,8 +4,10 @@ import (
"fmt" "fmt"
"math" "math"
"github.com/go-gl/gl/all-core/gl"
"github.com/liamg/glfont" "github.com/liamg/glfont"
"gitlab.com/liamg/raft/buffer" "gitlab.com/liamg/raft/buffer"
"gitlab.com/liamg/raft/config"
) )
type Renderer interface { type Renderer interface {
@ -27,9 +29,90 @@ type OpenGLRenderer struct {
termCols int termCols int
termRows int termRows int
cellPositions map[[2]int][2]float32 cellPositions map[[2]int][2]float32
rectangles map[[2]int]*rectangle
config config.Config
} }
func NewOpenGLRenderer(font *glfont.Font, fontScale int32, areaX int, areaY int, areaWidth int, areaHeight int) *OpenGLRenderer { type rectangle struct {
vao uint32
vbo uint32
cv uint32
colourAttr uint32
colour [3]float32
points []float32
}
func (r *OpenGLRenderer) newRectangle(x float32, y float32) *rectangle {
x = (x - float32(r.areaWidth/2)) / float32(r.areaWidth/2)
y = -(y - float32(r.areaHeight/2)) / float32(r.areaHeight/2)
w := r.cellWidth / float32(r.areaWidth/2)
h := r.cellHeight / float32(r.areaHeight/2)
rect := &rectangle{
colour: [3]float32{0, 0, 1},
points: []float32{
x, y + h, 0,
x, y, 0,
x + w, y, 0,
x, y + h, 0,
x + w, y + h, 0,
x + w, y, 0,
},
}
rect.gen()
return rect
}
func (rect *rectangle) gen() {
colour := []float32{
rect.colour[0], rect.colour[1], rect.colour[2],
rect.colour[0], rect.colour[1], rect.colour[2],
rect.colour[0], rect.colour[1], rect.colour[2],
rect.colour[0], rect.colour[1], rect.colour[2],
rect.colour[0], rect.colour[1], rect.colour[2],
rect.colour[0], rect.colour[1], rect.colour[2],
}
// SHAPE
gl.GenBuffers(1, &rect.vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, rect.vbo)
gl.BufferData(gl.ARRAY_BUFFER, 4*len(rect.points), gl.Ptr(rect.points), gl.STATIC_DRAW)
gl.GenVertexArrays(1, &rect.vao)
gl.BindVertexArray(rect.vao)
gl.EnableVertexAttribArray(0)
gl.BindBuffer(gl.ARRAY_BUFFER, rect.vbo)
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil)
// colour
gl.GenBuffers(1, &rect.cv)
gl.BindBuffer(gl.ARRAY_BUFFER, rect.cv)
gl.BufferData(gl.ARRAY_BUFFER, len(colour)*4, gl.Ptr(colour), gl.STATIC_DRAW)
gl.EnableVertexAttribArray(rect.colourAttr)
gl.VertexAttribPointer(rect.colourAttr, 3, gl.FLOAT, false, 0, gl.PtrOffset(0))
}
func (rect *rectangle) setColour(colour [3]float32) {
if rect.colour == colour || true {
return
}
rect.Free()
rect.colour = colour
rect.gen()
}
func (rect *rectangle) Free() {
gl.DeleteVertexArrays(1, &rect.vao)
gl.DeleteBuffers(1, &rect.vbo)
gl.DeleteBuffers(1, &rect.cv)
}
func NewOpenGLRenderer(config config.Config, font *glfont.Font, fontScale int32, areaX int, areaY int, areaWidth int, areaHeight int) *OpenGLRenderer {
r := &OpenGLRenderer{ r := &OpenGLRenderer{
areaWidth: areaWidth, areaWidth: areaWidth,
areaHeight: areaHeight, areaHeight: areaHeight,
@ -37,6 +120,8 @@ func NewOpenGLRenderer(font *glfont.Font, fontScale int32, areaX int, areaY int,
areaY: areaY, areaY: areaY,
fontScale: fontScale, fontScale: fontScale,
cellPositions: map[[2]int][2]float32{}, cellPositions: map[[2]int][2]float32{},
rectangles: map[[2]int]*rectangle{},
config: config,
} }
r.SetFont(font) r.SetFont(font)
return r return r
@ -59,7 +144,7 @@ func (r *OpenGLRenderer) SetFontScale(fontScale int32) {
r.SetFont(r.font) r.SetFont(r.font)
} }
func (r *OpenGLRenderer) SetFont(font *glfont.Font) { func (r *OpenGLRenderer) SetFont(font *glfont.Font) { // @todo check for monospace and return error if not?
r.font = font r.font = font
r.verticalCellPadding = (0.3 * float32(r.fontScale)) r.verticalCellPadding = (0.3 * float32(r.fontScale))
r.cellWidth = font.Width(1, "X") r.cellWidth = font.Width(1, "X")
@ -67,14 +152,15 @@ func (r *OpenGLRenderer) SetFont(font *glfont.Font) {
r.termCols = int(math.Floor(float64(float32(r.areaWidth) / r.cellWidth))) r.termCols = int(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
r.termRows = int(math.Floor(float64(float32(r.areaHeight) / r.cellHeight))) r.termRows = int(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
r.calculatePositions() r.calculatePositions()
r.generateRectangles()
} }
func (r *OpenGLRenderer) calculatePositions() { func (r *OpenGLRenderer) calculatePositions() {
for line := 0; line < r.termRows; line++ { for line := 0; line < r.termRows; line++ {
for col := 0; col < r.termCols; col++ { for col := 0; col < r.termCols; col++ {
// rounding to whole pixels makes everything nice // rounding to whole pixels makes everything nice
x := float32(math.Floor(float64((float32(col) * r.cellWidth) + (r.cellWidth / 2)))) x := float32(math.Round(float64((float32(col) * r.cellWidth))))
y := float32(math.Floor(float64( y := float32(math.Round(float64(
(float32(line) * r.cellHeight) + (r.cellHeight / 2) + r.verticalCellPadding, (float32(line) * r.cellHeight) + (r.cellHeight / 2) + r.verticalCellPadding,
))) )))
r.cellPositions[[2]int{col, line}] = [2]float32{x, y} r.cellPositions[[2]int{col, line}] = [2]float32{x, y}
@ -82,19 +168,66 @@ func (r *OpenGLRenderer) calculatePositions() {
} }
} }
func (r *OpenGLRenderer) generateRectangles() {
for line := 0; line < r.termRows; line++ {
for col := 0; col < r.termCols; col++ {
rect, ok := r.rectangles[[2]int{col, line}]
if ok {
rect.Free()
}
// rounding to whole pixels makes everything nice
x := float32(float64((float32(col) * r.cellWidth)))
y := float32(float64((float32(line) * r.cellHeight) + (r.cellHeight)))
r.rectangles[[2]int{col, line}] = r.newRectangle(x, y)
}
}
}
func (r *OpenGLRenderer) DrawCell(cell *buffer.Cell, col int, row int) { func (r *OpenGLRenderer) DrawCell(cell *buffer.Cell, col int, row int) {
if cell == nil { if cell == nil || cell.Attr().Hidden || cell.Rune() == 0x00 {
return return
} }
fg := cell.Fg() var fg [3]float32
r.font.SetColor(fg[0], fg[1], fg[2], 1) var bg [3]float32
if cell.Attr().Reverse {
fg = cell.Bg()
bg = cell.Fg()
} else {
fg = cell.Fg()
bg = cell.Bg()
}
var alpha float32 = 1
if cell.Attr().Dim {
alpha = 0.5
}
r.font.SetColor(fg[0], fg[1], fg[2], alpha)
pos, ok := r.cellPositions[[2]int{col, row}] pos, ok := r.cellPositions[[2]int{col, row}]
if !ok { if !ok {
panic(fmt.Sprintf("Missing position data for cell at %d,%d", col, row)) panic(fmt.Sprintf("Missing position data for cell at %d,%d", col, row))
} }
rect, ok := r.rectangles[[2]int{col, row}]
if !ok {
panic(fmt.Sprintf("Missing rectangle data for cell at %d,%d", col, row))
}
//rect.setColour(bg)
_ = bg
rect.setColour([3]float32{0, 0, 1})
gl.BindVertexArray(rect.vao)
gl.DrawArrays(gl.TRIANGLES, 0, 6)
if cell.Attr().Bold { // bold means draw text again one pixel to right, so it's fatter
r.font.Print(pos[0]+1, pos[1], 1, string(cell.Rune()))
}
r.font.Print(pos[0], pos[1], 1, string(cell.Rune())) r.font.Print(pos[0], pos[1], 1, string(cell.Rune()))
/* /*

16
main.go
View File

@ -21,6 +21,7 @@ func getConfig() config.Config {
} }
conf := loadConfigFile() conf := loadConfigFile()
flag.BoolVar(&conf.DebugMode, "debug", conf.DebugMode, "Enable debug logging") flag.BoolVar(&conf.DebugMode, "debug", conf.DebugMode, "Enable debug logging")
flag.BoolVar(&conf.Slomo, "slomo", conf.Slomo, "Render in slow motion (useful for debugging)") flag.BoolVar(&conf.Slomo, "slomo", conf.Slomo, "Render in slow motion (useful for debugging)")
flag.BoolVar(&conf.Rendering.AlwaysRepaint, "always-repaint", conf.Rendering.AlwaysRepaint, "Always repaint the window, even when no changes have occurred") flag.BoolVar(&conf.Rendering.AlwaysRepaint, "always-repaint", conf.Rendering.AlwaysRepaint, "Always repaint the window, even when no changes have occurred")
@ -37,8 +38,8 @@ func loadConfigFile() config.Config {
} }
places := []string{ places := []string{
fmt.Sprintf("%s/.raft.yml", home), //fmt.Sprintf("%s/.config/raft.yml", home),
fmt.Sprintf("%s/.config/raft.yml", home), fmt.Sprintf("%s/.raft.toml", home),
} }
for _, place := range places { for _, place := range places {
@ -51,6 +52,13 @@ func loadConfigFile() config.Config {
} }
} }
if b, err := config.DefaultConfig.Encode(); err != nil {
fmt.Printf("Failed to encode config file: %s\n", err)
} else {
if err := ioutil.WriteFile(fmt.Sprintf("%s/.raft.toml", home), b, 0644); err != nil {
fmt.Printf("Failed to encode config file: %s\n", err)
}
}
return config.DefaultConfig return config.DefaultConfig
} }
@ -61,7 +69,9 @@ func getLogger(conf config.Config) (*zap.SugaredLogger, error) {
if conf.DebugMode { if conf.DebugMode {
logger, err = zap.NewDevelopment() logger, err = zap.NewDevelopment()
} else { } else {
logger, err = zap.NewProduction() loggerConfig := zap.NewProductionConfig()
loggerConfig.Encoding = "console"
logger, err = loggerConfig.Build()
} }
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to create logger: %s", err) return nil, fmt.Errorf("Failed to create logger: %s", err)

View File

@ -1,50 +0,0 @@
package terminal
type Cell struct {
r rune
attr CellAttributes
}
type CellAttributes struct {
FgColour [3]float32
BgColour [3]float32
Bold bool
Dim bool
Underline bool
Blink bool
Reverse bool
Hidden bool
}
func (terminal *Terminal) NewCell() Cell {
return Cell{
attr: CellAttributes{
FgColour: terminal.config.ColourScheme.DefaultFg,
BgColour: terminal.config.ColourScheme.DefaultBg,
},
}
}
func (cell *Cell) GetRune() rune {
return cell.r
}
func (cell *Cell) IsHidden() bool {
return cell.attr.Hidden
}
func (cell *Cell) GetFgColour() (r float32, g float32, b float32) {
if cell.attr.Reverse {
return cell.attr.BgColour[0], cell.attr.BgColour[1], cell.attr.BgColour[2]
}
return cell.attr.FgColour[0], cell.attr.FgColour[1], cell.attr.FgColour[2]
}
func (cell *Cell) GetBgColour() (r float32, g float32, b float32) {
if cell.attr.Reverse {
return cell.attr.FgColour[0], cell.attr.FgColour[1], cell.attr.FgColour[2]
}
return cell.attr.BgColour[0], cell.attr.BgColour[1], cell.attr.BgColour[2]
}

View File

@ -28,11 +28,6 @@ type Terminal struct {
resumeChan chan bool resumeChan chan bool
} }
type Line struct {
Cells []Cell
wrapped bool
}
type Winsize struct { type Winsize struct {
Height uint16 Height uint16
Width uint16 Width uint16