Add options
This commit is contained in:
parent
70590d5e28
commit
b32f0eb94f
8 changed files with 88 additions and 33 deletions
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
15
src/micro.go
15
src/micro.go
|
@ -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
45
src/option.go
Normal 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")
|
||||
}
|
||||
}
|
||||
}
|
28
src/view.go
28
src/view.go
|
@ -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)
|
||||
|
|
14
todolist.md
14
todolist.md
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue