Compare commits

..

5 Commits

Author SHA1 Message Date
Zachary Yedidia
8c403655a7 First attempt at resizable panes 2017-09-13 10:49:12 -04:00
Zachary Yedidia
612658d9c4 Add documentation for new lua functions 2017-09-11 12:23:19 -04:00
Zachary Yedidia
c31613b2c7 Add --config-dir option 2017-09-10 23:20:21 -04:00
Zachary Yedidia
d7419d213a Merge branch 'better-lua' 2017-09-10 22:22:31 -04:00
Zachary Yedidia
67a3f86cc9 Update tcell 2017-09-10 17:21:37 -04:00
7 changed files with 156 additions and 70 deletions

View File

@@ -62,54 +62,71 @@ func (v *View) MousePress(usePlugin bool, e *tcell.EventMouse) bool {
return false
}
x, y := e.Position()
x -= v.lineNumOffset - v.leftCol + v.x
y += v.Topline - v.y
rawX, rawY := e.Position()
x := rawX - v.lineNumOffset - v.leftCol + v.x
y := rawY + v.Topline - v.y
// This is usually bound to left click
v.MoveToMouseClick(x, y)
if !(rawX == v.x+v.Width || rawY == v.y+v.Height || v.resizeX || v.resizeY) {
v.MoveToMouseClick(x, y)
}
if v.mouseReleased {
if len(v.Buf.cursors) > 1 {
for i := 1; i < len(v.Buf.cursors); i++ {
v.Buf.cursors[i] = nil
}
v.Buf.cursors = v.Buf.cursors[:1]
v.Buf.UpdateCursors()
v.Cursor.ResetSelection()
v.Relocate()
}
if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold {
if v.doubleClick {
// Triple click
v.lastClickTime = time.Now()
v.tripleClick = true
v.doubleClick = false
v.Cursor.SelectLine()
v.Cursor.CopySelection("primary")
} else {
// Double click
v.lastClickTime = time.Now()
v.doubleClick = true
v.tripleClick = false
v.Cursor.SelectWord()
v.Cursor.CopySelection("primary")
}
if rawX == v.x+v.Width {
v.resizeX = true
} else if rawY == v.y+v.Height {
v.resizeY = true
} else {
v.doubleClick = false
v.tripleClick = false
v.lastClickTime = time.Now()
if len(v.Buf.cursors) > 1 {
for i := 1; i < len(v.Buf.cursors); i++ {
v.Buf.cursors[i] = nil
}
v.Buf.cursors = v.Buf.cursors[:1]
v.Buf.UpdateCursors()
v.Cursor.ResetSelection()
v.Relocate()
}
if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold {
if v.doubleClick {
// Triple click
v.lastClickTime = time.Now()
v.Cursor.OrigSelection[0] = v.Cursor.Loc
v.Cursor.CurSelection[0] = v.Cursor.Loc
v.Cursor.CurSelection[1] = v.Cursor.Loc
v.tripleClick = true
v.doubleClick = false
v.Cursor.SelectLine()
v.Cursor.CopySelection("primary")
} else {
// Double click
v.lastClickTime = time.Now()
v.doubleClick = true
v.tripleClick = false
v.Cursor.SelectWord()
v.Cursor.CopySelection("primary")
}
} else {
v.doubleClick = false
v.tripleClick = false
v.lastClickTime = time.Now()
v.Cursor.OrigSelection[0] = v.Cursor.Loc
v.Cursor.CurSelection[0] = v.Cursor.Loc
v.Cursor.CurSelection[1] = v.Cursor.Loc
}
}
v.mouseReleased = false
} else if !v.mouseReleased {
if v.tripleClick {
if v.resizeX {
v.Width = rawX - v.x
v.LockWidth = true
v.splitNode.parent.ResizeSplits()
} else if v.resizeY {
v.Height = rawY - v.y
v.LockHeight = true
v.splitNode.parent.ResizeSplits()
} else if v.tripleClick {
v.Cursor.AddLineToSelection()
} else if v.doubleClick {
v.Cursor.AddWordToSelection()

View File

@@ -112,6 +112,9 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
// We'll either draw the length of the line, or the width of the screen
// whichever is smaller
lineLength := min(StringWidth(lineStr, tabsize), width)
if lineLength < 0 {
return
}
c.lines = append(c.lines, make([]*Char, lineLength))
wrap := false
@@ -133,38 +136,50 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) {
char := line[colN]
if viewCol >= 0 {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1}
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1}
}
}
if char == '\t' {
charWidth := tabsize - (viewCol+left)%tabsize
if viewCol >= 0 {
c.lines[viewLine][viewCol].drawChar = indentchar
c.lines[viewLine][viewCol].width = charWidth
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol].drawChar = indentchar
c.lines[viewLine][viewCol].width = charWidth
}
indentStyle := curStyle
if group, ok := colorscheme["indent-char"]; ok {
indentStyle = group
}
c.lines[viewLine][viewCol].style = indentStyle
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol].style = indentStyle
}
}
for i := 1; i < charWidth; i++ {
viewCol++
if viewCol >= 0 && viewCol < lineLength {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
}
}
}
viewCol++
} else if runewidth.RuneWidth(char) > 1 {
charWidth := runewidth.RuneWidth(char)
if viewCol >= 0 {
c.lines[viewLine][viewCol].width = charWidth
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol].width = charWidth
}
}
for i := 1; i < charWidth; i++ {
viewCol++
if viewCol >= 0 && viewCol < lineLength {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
if viewCol < len(c.lines[viewLine]) {
c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1}
}
}
}
viewCol++

View File

@@ -143,6 +143,15 @@ func InitConfigDir() {
}
configDir = xdgHome + "/micro"
if len(*flagConfigDir) > 0 {
if _, err := os.Stat(*flagConfigDir); os.IsNotExist(err) {
TermMessage("Error: " + *flagConfigDir + " does not exist. Defaulting to " + configDir + ".")
} else {
configDir = *flagConfigDir
return
}
}
if _, err := os.Stat(xdgHome); os.IsNotExist(err) {
// If the xdgHome doesn't exist we should create it
err = os.Mkdir(xdgHome, os.ModePerm)
@@ -240,19 +249,24 @@ func LoadAll() {
// Passing -version as a flag will have micro print out the version number
var flagVersion = flag.Bool("version", false, "Show the version number and information")
var flagStartPos = flag.String("startpos", "", "LINE,COL to start the cursor at when opening a buffer.")
var flagConfigDir = flag.String("config-dir", "", "Specify a custom location for the configuration directory")
var optionFlagSet = flag.NewFlagSet("option", flag.ExitOnError)
func main() {
flag.Usage = func() {
fmt.Println("Usage: micro [OPTIONS] [FILE]...")
fmt.Print("Micro's options can be set via command line arguments for quick adjustments. For real configuration, please use the bindings.json file (see 'help options').\n\n")
flag.CommandLine.SetOutput(os.Stdout)
flag.PrintDefaults()
optionFlagSet.SetOutput(os.Stdout)
fmt.Print("\n------------------------------------------------------------------\n")
fmt.Print("Micro's options can also be set via command line arguments for quick\nadjustments. For real configuration, please use the bindings.json\nfile (see 'help options').\n\n")
optionFlagSet.PrintDefaults()
}
optionFlags := make(map[string]*string)
for k, v := range DefaultGlobalSettings() {
optionFlags[k] = flag.String(k, "", fmt.Sprintf("The %s option. Default value: '%v'", k, v))
optionFlags[k] = optionFlagSet.String(k, "", fmt.Sprintf("The %s option. Default value: '%v'", k, v))
}
flag.Parse()
@@ -462,7 +476,7 @@ func main() {
// We loop through each view in the current tab and make sure the current view
// is the one being clicked in
for _, v := range tabs[curTab].views {
if x >= v.x && x < v.x+v.Width && y >= v.y && y < v.y+v.Height {
if x > v.x && x <= v.x+v.Width && y > v.y && y <= v.y+v.Height {
tabs[curTab].CurView = v.Num
}
}

File diff suppressed because one or more lines are too long

View File

@@ -91,6 +91,9 @@ type View struct {
cellview *CellView
splitNode *LeafNode
resizeX bool
resizeY bool
}
// NewView returns a new fullscreen view
@@ -599,21 +602,26 @@ func (v *View) HandleEvent(event tcell.Event) {
// Mouse event with no click
if !v.mouseReleased {
// Mouse was just released
if v.resizeX || v.resizeY {
v.resizeX = false
v.resizeY = false
} else {
x, y := e.Position()
x -= v.lineNumOffset - v.leftCol + v.x
y += v.Topline - v.y
x, y := e.Position()
x -= v.lineNumOffset - v.leftCol + v.x
y += v.Topline - v.y
// Relocating here isn't really necessary because the cursor will
// be in the right place from the last mouse event
// However, if we are running in a terminal that doesn't support mouse motion
// events, this still allows the user to make selections, except only after they
// release the mouse
// Relocating here isn't really necessary because the cursor will
// be in the right place from the last mouse event
// However, if we are running in a terminal that doesn't support mouse motion
// events, this still allows the user to make selections, except only after they
// release the mouse
if !v.doubleClick && !v.tripleClick {
v.MoveToMouseClick(x, y)
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
v.Cursor.CopySelection("primary")
if !v.doubleClick && !v.tripleClick {
v.MoveToMouseClick(x, y)
v.Cursor.SetSelectionEnd(v.Cursor.Loc)
v.Cursor.CopySelection("primary")
}
}
v.mouseReleased = true
}

View File

@@ -147,14 +147,17 @@ The possible methods which you can call using the `messenger` variable are:
* `messenger.AddLog(msg ...interface{})`
## Note
`golang` function signatures use `.` and lua uses `:` so
Go function signatures use `.` and lua uses `:` so
```go
messenger.Message()
```
turns to
```lua
messenger:Message()
```
turns to
```lua
messenger:Message()
```
If you want a standard prompt, just use
```lua
@@ -165,9 +168,38 @@ Debug or logging your plugin can be done with below lua example code.
```lua
messenger:AddLog("Message goes here ",pluginVariableToPrintHere)
```
In Micro Editor to see your plugin logging output press `ctrl E` then type `log`
In Micro to see your plugin logging output press `CtrlE` then type `log`
A logging window will open and any logging sent from your plugin will be displayed here.
# Accessing the Go standard library
It is possible for your lua code to access many of the functions in the Go standard library.
Simply import the package you'd like and then you can use it. For example:
```lua
local ioutil = import("ioutil")
local fmt = import("fmt")
local data, err = ioutil.ReadFile("SomeFile.txt")
if err ~= nil then
messenger:Error("Error reading file: SomeFile.txt")
else
-- Data is returned as an array of bytes
-- Using Sprintf will convert it to a string
local str = fmt.Sprintf("%s", data)
-- Do something with the file you just read!
-- ...
end
```
For a full list of which packages and functions from the standard library
you can access, look at `lua.go` in the source code (it shouldn't be
too hard to look through).
# Adding help files, syntax files, or colorschemes in your plugin
You can use the `AddRuntimeFile(name, type, path string)` function to add various kinds of