Add options

This commit is contained in:
Zachary Yedidia 2016-03-26 10:54:18 -04:00
parent 70590d5e28
commit b32f0eb94f
8 changed files with 88 additions and 33 deletions

View file

@ -41,12 +41,17 @@ func NewBuffer(txt, path string) *Buffer {
b.savedText = txt
b.Update()
b.rules, b.filetype = GetRules(b)
b.UpdateRules()
return b
}
// UpdateRules updates the syntax rules and filetype for this buffer
// This is called when the colorscheme changes
func (b *Buffer) UpdateRules() {
b.rules, b.filetype = GetRules(b)
}
// Update fetches the string from the rope and updates the `text` and `lines` in the buffer
func (b *Buffer) Update() {
b.text = b.r.String()

View file

@ -10,8 +10,6 @@ import (
"strings"
)
const defaultColorscheme = "default"
// Colorscheme is a map from string to style -- it represents a colorscheme
type Colorscheme map[string]tcell.Style
@ -30,7 +28,7 @@ func LoadDefaultColorscheme() {
TermMessage("Error finding your home directory\nCan't load runtime files")
return
}
LoadColorscheme(defaultColorscheme, dir+"/.micro/colorschemes")
LoadColorscheme(options["colorscheme"].(string), dir+"/.micro/colorschemes")
}
// LoadColorscheme loads the given colorscheme from a directory

View file

@ -149,6 +149,7 @@ func (c *Cursor) Start() {
// GetCharPosInLine gets the char position of a visual x y coordinate (this is necessary because tabs are 1 char but 4 visual spaces)
func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
tabSize := options["tabsize"].(int)
visualLine := strings.Replace(c.v.buf.lines[lineNum], "\t", "\t"+Spaces(tabSize-1), -1)
if visualPos > Count(visualLine) {
visualPos = Count(visualLine)
@ -163,6 +164,7 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
// GetVisualX returns the x value of the cursor in visual spaces
func (c *Cursor) GetVisualX() int {
runes := []rune(c.v.buf.lines[c.y])
tabSize := options["tabsize"].(int)
return c.x + NumOccurences(string(runes[:c.x]), '\t')*(tabSize-1)
}

View file

@ -256,9 +256,9 @@ func Match(v *View) SyntaxMatches {
lineNum -= viewStart
if lineNum >= 0 && lineNum < v.height {
if lineNum >= len(matches) {
v.m.Error("Line " + strconv.Itoa(lineNum))
messenger.Error("Line " + strconv.Itoa(lineNum))
} else if colNum >= len(matches[lineNum]) {
v.m.Error("Line " + strconv.Itoa(lineNum) + " Col " + strconv.Itoa(colNum) + " " + strconv.Itoa(len(matches[lineNum])))
messenger.Error("Line " + strconv.Itoa(lineNum) + " Col " + strconv.Itoa(colNum) + " " + strconv.Itoa(len(matches[lineNum])))
}
matches[lineNum][colNum] = rule.style
}

View file

@ -10,7 +10,6 @@ import (
)
const (
tabSize = 4 // This should be configurable
synLinesUp = 75 // How many lines up to look to do syntax highlighting
synLinesDown = 75 // How many lines down to look to do syntax highlighting
)
@ -18,6 +17,9 @@ const (
// The main screen
var screen tcell.Screen
// Object to send messages and prompts to the user
var messenger *Messenger
// LoadInput loads the file input for the editor
func LoadInput() (string, []byte, error) {
// There are a number of ways micro should start given its input
@ -61,6 +63,8 @@ func main() {
os.Exit(1)
}
InitOptions()
// Should we enable true color?
truecolor := os.Getenv("MICRO_TRUECOLOR") == "1"
@ -115,8 +119,8 @@ func main() {
screen.SetStyle(defStyle)
screen.EnableMouse()
messenger := new(Messenger)
view := NewView(NewBuffer(string(input), filename), messenger)
messenger = new(Messenger)
view := NewView(NewBuffer(string(input), filename))
for {
// Display everything
@ -133,12 +137,15 @@ func main() {
// Check if we should quit
switch e := event.(type) {
case *tcell.EventKey:
if e.Key() == tcell.KeyCtrlQ {
switch e.Key() {
case tcell.KeyCtrlQ:
// Make sure not to quit if there are unsaved changes
if view.CanClose("Quit anyway? ") {
screen.Fini()
os.Exit(0)
}
case tcell.KeyCtrlE:
SetOption(view)
}
}

45
src/option.go Normal file
View file

@ -0,0 +1,45 @@
package main
import (
"strconv"
"strings"
)
// The options that the user can set
var options map[string]interface{}
func InitOptions() {
options = make(map[string]interface{})
options["tabsize"] = 4
options["colorscheme"] = "default"
}
func SetOption(view *View) {
choice, canceled := messenger.Prompt("Option: ")
if !canceled {
split := strings.Split(choice, "=")
if len(split) == 2 {
option := strings.TrimSpace(split[0])
value := strings.TrimSpace(split[1])
if _, exists := options[option]; exists {
if option == "tabsize" {
tsize, err := strconv.Atoi(value)
if err != nil {
messenger.Error("Invalid value for " + option)
return
}
options[option] = tsize
}
if option == "colorscheme" {
options[option] = value
LoadSyntaxFiles()
view.buf.UpdateRules()
}
} else {
messenger.Error("Option " + option + " does not exist")
}
} else {
messenger.Error("Invalid option, please use option = value")
}
}
}

View file

@ -51,24 +51,19 @@ type View struct {
// This is the range of lines that should have their syntax highlighting updated
updateLines [2]int
// The messenger so we can send messages to the user and get input from them
m *Messenger
}
// NewView returns a new fullscreen view
func NewView(buf *Buffer, m *Messenger) *View {
return NewViewWidthHeight(buf, m, 100, 100)
func NewView(buf *Buffer) *View {
return NewViewWidthHeight(buf, 100, 100)
}
// NewViewWidthHeight returns a new view with the specified width and height percentages
// Note that w and h are percentages not actual values
func NewViewWidthHeight(buf *Buffer, m *Messenger, w, h int) *View {
func NewViewWidthHeight(buf *Buffer, w, h int) *View {
v := new(View)
v.buf = buf
// Messenger
v.m = m
v.widthPercent = w
v.heightPercent = h
@ -180,7 +175,7 @@ func (v *View) HalfPageDown() {
// The message is what to print after saying "You have unsaved changes. "
func (v *View) CanClose(msg string) bool {
if v.buf.IsDirty() {
quit, canceled := v.m.Prompt("You have unsaved changes. " + msg)
quit, canceled := messenger.Prompt("You have unsaved changes. " + msg)
if !canceled {
if strings.ToLower(quit) == "yes" || strings.ToLower(quit) == "y" {
return true
@ -196,7 +191,7 @@ func (v *View) CanClose(msg string) bool {
func (v *View) Save() {
// If this is an empty buffer, ask for a filename
if v.buf.path == "" {
filename, canceled := v.m.Prompt("Filename: ")
filename, canceled := messenger.Prompt("Filename: ")
if !canceled {
v.buf.path = filename
v.buf.name = filename
@ -206,7 +201,7 @@ func (v *View) Save() {
}
err := v.buf.Save()
if err != nil {
v.m.Error(err.Error())
messenger.Error(err.Error())
}
}
@ -216,7 +211,7 @@ func (v *View) Copy() {
if !clipboard.Unsupported {
clipboard.WriteAll(v.cursor.GetSelection())
} else {
v.m.Error("Clipboard is not supported on your system")
messenger.Error("Clipboard is not supported on your system")
}
}
}
@ -229,7 +224,7 @@ func (v *View) Cut() {
v.cursor.DeleteSelection()
v.cursor.ResetSelection()
} else {
v.m.Error("Clipboard is not supported on your system")
messenger.Error("Clipboard is not supported on your system")
}
}
}
@ -249,7 +244,7 @@ func (v *View) Paste() {
v.cursor.Right()
}
} else {
v.m.Error("Clipboard is not supported on your system")
messenger.Error("Clipboard is not supported on your system")
}
}
@ -267,14 +262,14 @@ func (v *View) SelectAll() {
// It makes sure that the current buffer can be closed first (unsaved changes)
func (v *View) OpenFile() {
if v.CanClose("Continue? ") {
filename, canceled := v.m.Prompt("File to open: ")
filename, canceled := messenger.Prompt("File to open: ")
if canceled {
return
}
file, err := ioutil.ReadFile(filename)
if err != nil {
v.m.Error(err.Error())
messenger.Error(err.Error())
return
}
v.buf = NewBuffer(string(file), filename)
@ -552,6 +547,7 @@ func (v *View) DisplayView() {
if ch == '\t' {
screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
tabSize := options["tabsize"].(int)
for i := 0; i < tabSize-1; i++ {
tabchars++
screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)

View file

@ -4,6 +4,8 @@
- [ ] Optimization
- [ ] Documentation
- [ ] Search and replace
- [ ] Better selection
@ -26,21 +28,21 @@
- [ ] Allow executing simple commands at the bottom of the editor
(like vim or emacs)
- [ ] Options
- [ ] Add options such as tab size, use tabs or use spaces, etc...
### Done
- [x] Readme
- [x] Line numbers
- [x] Tests
- [x] Simple tests
- [x] Proper error handling
- [x] Cleanup
- [x] Options
- [x] Colorscheme
- [x] tab size
- [ ] tabs or spaces
- [x] Syntax highlighting
- [x] Use nano-like syntax files (https://github.com/scopatz/nanorc)