mirror of
https://github.com/zyedidia/micro
synced 2024-11-05 17:41:24 +00:00
Use actual lua functions for callbacks instead of strings
This commit is contained in:
parent
c4bfa825a1
commit
8a907956d1
11 changed files with 87 additions and 169 deletions
|
@ -60,7 +60,7 @@ func luaImportMicro() *lua.LTable {
|
|||
func luaImportMicroConfig() *lua.LTable {
|
||||
pkg := ulua.L.NewTable()
|
||||
|
||||
ulua.L.SetField(pkg, "MakeCommand", luar.New(ulua.L, action.LuaMakeCommand))
|
||||
ulua.L.SetField(pkg, "MakeCommand", luar.New(ulua.L, action.MakeCommand))
|
||||
ulua.L.SetField(pkg, "FileComplete", luar.New(ulua.L, buffer.FileComplete))
|
||||
ulua.L.SetField(pkg, "HelpComplete", luar.New(ulua.L, action.HelpComplete))
|
||||
ulua.L.SetField(pkg, "OptionComplete", luar.New(ulua.L, action.OptionComplete))
|
||||
|
|
|
@ -312,7 +312,7 @@ func main() {
|
|||
select {
|
||||
case f := <-shell.Jobs:
|
||||
// If a new job has finished while running in the background we should execute the callback
|
||||
f.Function(f.Output, f.Args...)
|
||||
f.Function(f.Output, f.Args)
|
||||
case <-config.Autosave:
|
||||
for _, b := range buffer.OpenBuffers {
|
||||
b.Save()
|
||||
|
|
|
@ -12,13 +12,9 @@ import (
|
|||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/micro/internal/shell"
|
||||
"github.com/zyedidia/micro/internal/util"
|
||||
|
@ -71,29 +67,9 @@ func InitCommands() {
|
|||
|
||||
// MakeCommand is a function to easily create new commands
|
||||
// This can be called by plugins in Lua so that plugins can define their own commands
|
||||
func LuaMakeCommand(name, function string, completer buffer.Completer) {
|
||||
action := LuaFunctionCommand(function)
|
||||
commands[name] = Command{action, completer}
|
||||
}
|
||||
|
||||
// LuaFunctionCommand returns a normal function
|
||||
// so that a command can be bound to a lua function
|
||||
func LuaFunctionCommand(fn string) func(*BufPane, []string) {
|
||||
luaFn := strings.Split(fn, ".")
|
||||
if len(luaFn) <= 1 {
|
||||
return nil
|
||||
}
|
||||
plName, plFn := luaFn[0], luaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl == nil {
|
||||
return nil
|
||||
}
|
||||
return func(bp *BufPane, args []string) {
|
||||
luaArgs := []lua.LValue{luar.New(ulua.L, bp), luar.New(ulua.L, args)}
|
||||
_, err := pl.Call(plFn, luaArgs...)
|
||||
if err != nil {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
func MakeCommand(name string, action func(bp *BufPane, args []string), completer buffer.Completer) {
|
||||
if action != nil {
|
||||
commands[name] = Command{action, completer}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -843,7 +819,7 @@ func (h *BufPane) TermCmd(args []string) {
|
|||
|
||||
term := func(i int, newtab bool) {
|
||||
t := new(shell.Terminal)
|
||||
t.Start(args, false, true, "", nil)
|
||||
t.Start(args, false, true, nil, nil)
|
||||
|
||||
id := h.ID()
|
||||
if newtab {
|
||||
|
|
|
@ -7,9 +7,14 @@ import (
|
|||
"github.com/zyedidia/micro/internal/shell"
|
||||
)
|
||||
|
||||
// TermEmuSupported is a constant that marks if the terminal emulator is supported
|
||||
const TermEmuSupported = true
|
||||
|
||||
func RunTermEmulator(h *BufPane, input string, wait bool, getOutput bool, callback string, userargs []interface{}) error {
|
||||
// RunTermEmulator starts a terminal emulator from a bufpane with the given input (command)
|
||||
// if wait is true it will wait for the user to exit by pressing enter once the executable has terminated
|
||||
// if getOutput is true it will redirect the stdout of the process to a pipe which will be passed to the
|
||||
// callback which is a function that takes a string and a list of optional user arguments
|
||||
func RunTermEmulator(h *BufPane, input string, wait bool, getOutput bool, callback func(out string, userargs []interface{}), userargs []interface{}) error {
|
||||
args, err := shellquote.Split(input)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -4,8 +4,10 @@ package action
|
|||
|
||||
import "errors"
|
||||
|
||||
// TermEmuSupported is a constant that marks if the terminal emulator is supported
|
||||
const TermEmuSupported = false
|
||||
|
||||
func RunTermEmulator(input string, wait bool, getOutput bool, callback string, userargs []interface{}) error {
|
||||
// RunTermEmulator returns an error for unsupported systems (non-unix systems
|
||||
func RunTermEmulator(input string, wait bool, getOutput bool, callback func(out string, userargs []interface{}), userargs []interface{}) error {
|
||||
return errors.New("Unsupported operating system")
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2,14 +2,8 @@ package info
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
)
|
||||
|
||||
// The InfoBuf displays messages and other info at the bottom of the screen.
|
||||
|
@ -134,63 +128,6 @@ func (i *InfoBuf) YNPrompt(prompt string, donecb func(bool, bool)) {
|
|||
i.YNCallback = donecb
|
||||
}
|
||||
|
||||
// PlugPrompt provides a plugin interface for calling "Prompt" with the appropriate Lua callbacks
|
||||
func (i *InfoBuf) PlugPrompt(prompt string, msg string, ptype string, eventcb string, donecb string) {
|
||||
eventLuaFn := strings.Split(eventcb, ".")
|
||||
doneLuaFn := strings.Split(donecb, ".")
|
||||
var luaEventcb func(string)
|
||||
var luaDonecb func(string, bool)
|
||||
|
||||
if len(eventLuaFn) == 2 {
|
||||
plName, plFn := doneLuaFn[0], doneLuaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl != nil {
|
||||
luaEventcb = func(resp string) {
|
||||
_, err := pl.Call(plFn, luar.New(ulua.L, resp))
|
||||
if err != nil && err != config.ErrNoSuchFunction {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(doneLuaFn) == 2 {
|
||||
plName, plFn := doneLuaFn[0], doneLuaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl != nil {
|
||||
luaDonecb = func(resp string, canceled bool) {
|
||||
_, err := pl.Call(plFn, luar.New(ulua.L, resp), luar.New(ulua.L, canceled))
|
||||
if err != nil && err != config.ErrNoSuchFunction {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i.Prompt(prompt, msg, ptype, luaEventcb, luaDonecb)
|
||||
}
|
||||
|
||||
// PlugYNPrompt provides a plugin interface for calling "YNPrompt" with the appropriate Lua callbacks
|
||||
func (i *InfoBuf) PlugYNPrompt(prompt string, donecb string) {
|
||||
doneLuaFn := strings.Split(donecb, ".")
|
||||
var luaDonecb func(bool, bool)
|
||||
|
||||
if len(doneLuaFn) == 2 {
|
||||
plName, plFn := doneLuaFn[0], doneLuaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl != nil {
|
||||
luaDonecb = func(resp bool, canceled bool) {
|
||||
_, err := pl.Call(plFn, luar.New(ulua.L, resp), luar.New(ulua.L, canceled))
|
||||
if err != nil && err != config.ErrNoSuchFunction {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i.YNPrompt(prompt, luaDonecb)
|
||||
}
|
||||
|
||||
// DonePrompt finishes the current prompt and indicates whether or not it was canceled
|
||||
func (i *InfoBuf) DonePrompt(canceled bool) {
|
||||
hadYN := i.HasYN
|
||||
|
|
|
@ -4,14 +4,6 @@ import (
|
|||
"bytes"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
luar "layeh.com/gopher-luar"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
)
|
||||
|
||||
var Jobs chan JobFunction
|
||||
|
@ -32,7 +24,7 @@ func init() {
|
|||
// JobFunction is a representation of a job (this data structure is what is loaded
|
||||
// into the jobs channel)
|
||||
type JobFunction struct {
|
||||
Function func(string, ...interface{})
|
||||
Function func(string, []interface{})
|
||||
Output string
|
||||
Args []interface{}
|
||||
}
|
||||
|
@ -41,7 +33,7 @@ type JobFunction struct {
|
|||
type CallbackFile struct {
|
||||
io.Writer
|
||||
|
||||
callback func(string, ...interface{})
|
||||
callback func(string, []interface{})
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
|
@ -55,23 +47,23 @@ func (f *CallbackFile) Write(data []byte) (int, error) {
|
|||
|
||||
// JobStart starts a shell command in the background with the given callbacks
|
||||
// It returns an *exec.Cmd as the job id
|
||||
func JobStart(cmd string, onStdout, onStderr, onExit string, userargs ...interface{}) *exec.Cmd {
|
||||
func JobStart(cmd string, onStdout, onStderr, onExit func(string, []interface{}), userargs ...interface{}) *exec.Cmd {
|
||||
return JobSpawn("sh", []string{"-c", cmd}, onStdout, onStderr, onExit, userargs...)
|
||||
}
|
||||
|
||||
// JobSpawn starts a process with args in the background with the given callbacks
|
||||
// It returns an *exec.Cmd as the job id
|
||||
func JobSpawn(cmdName string, cmdArgs []string, onStdout, onStderr, onExit string, userargs ...interface{}) *exec.Cmd {
|
||||
func JobSpawn(cmdName string, cmdArgs []string, onStdout, onStderr, onExit func(string, []interface{}), userargs ...interface{}) *exec.Cmd {
|
||||
// Set up everything correctly if the functions have been provided
|
||||
proc := exec.Command(cmdName, cmdArgs...)
|
||||
var outbuf bytes.Buffer
|
||||
if onStdout != "" {
|
||||
proc.Stdout = &CallbackFile{&outbuf, luaFunctionJob(onStdout), userargs}
|
||||
if onStdout != nil {
|
||||
proc.Stdout = &CallbackFile{&outbuf, onStdout, userargs}
|
||||
} else {
|
||||
proc.Stdout = &outbuf
|
||||
}
|
||||
if onStderr != "" {
|
||||
proc.Stderr = &CallbackFile{&outbuf, luaFunctionJob(onStderr), userargs}
|
||||
if onStderr != nil {
|
||||
proc.Stderr = &CallbackFile{&outbuf, onStderr, userargs}
|
||||
} else {
|
||||
proc.Stderr = &outbuf
|
||||
}
|
||||
|
@ -79,7 +71,7 @@ func JobSpawn(cmdName string, cmdArgs []string, onStdout, onStderr, onExit strin
|
|||
go func() {
|
||||
// Run the process in the background and create the onExit callback
|
||||
proc.Run()
|
||||
jobFunc := JobFunction{luaFunctionJob(onExit), string(outbuf.Bytes()), userargs}
|
||||
jobFunc := JobFunction{onExit, string(outbuf.Bytes()), userargs}
|
||||
Jobs <- jobFunc
|
||||
}()
|
||||
|
||||
|
@ -100,25 +92,3 @@ func JobSend(cmd *exec.Cmd, data string) {
|
|||
|
||||
stdin.Write([]byte(data))
|
||||
}
|
||||
|
||||
// luaFunctionJob returns a function that will call the given lua function
|
||||
// structured as a job call i.e. the job output and arguments are provided
|
||||
// to the lua function
|
||||
func luaFunctionJob(fn string) func(string, ...interface{}) {
|
||||
luaFn := strings.Split(fn, ".")
|
||||
if len(luaFn) <= 1 {
|
||||
return nil
|
||||
}
|
||||
plName, plFn := luaFn[0], luaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl == nil {
|
||||
return nil
|
||||
}
|
||||
return func(output string, args ...interface{}) {
|
||||
luaArgs := []lua.LValue{luar.New(ulua.L, output), luar.New(ulua.L, args)}
|
||||
_, err := pl.Call(plFn, luaArgs...)
|
||||
if err != nil && err != config.ErrNoSuchFunction {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,10 @@ import (
|
|||
"bytes"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/internal/buffer"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
ulua "github.com/zyedidia/micro/internal/lua"
|
||||
"github.com/zyedidia/micro/internal/screen"
|
||||
"github.com/zyedidia/terminal"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
type TermType int
|
||||
|
@ -74,7 +69,7 @@ func (t *Terminal) GetSelection(width int) string {
|
|||
}
|
||||
|
||||
// Start begins a new command in this terminal with a given view
|
||||
func (t *Terminal) Start(execCmd []string, getOutput bool, wait bool, callback string, userargs []interface{}) error {
|
||||
func (t *Terminal) Start(execCmd []string, getOutput bool, wait bool, callback func(out string, userargs []interface{}), userargs []interface{}) error {
|
||||
if len(execCmd) <= 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -93,20 +88,8 @@ func (t *Terminal) Start(execCmd []string, getOutput bool, wait bool, callback s
|
|||
t.Status = TTRunning
|
||||
t.title = execCmd[0] + ":" + strconv.Itoa(cmd.Process.Pid)
|
||||
t.wait = wait
|
||||
|
||||
luaFn := strings.Split(callback, ".")
|
||||
if len(luaFn) >= 2 {
|
||||
plName, plFn := luaFn[0], luaFn[1]
|
||||
pl := config.FindPlugin(plName)
|
||||
if pl != nil {
|
||||
t.callback = func(out string) {
|
||||
luaArgs := []lua.LValue{luar.New(ulua.L, out), luar.New(ulua.L, userargs)}
|
||||
_, err := pl.Call(plFn, luaArgs...)
|
||||
if err != nil {
|
||||
screen.TermMessage(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
t.callback = func(out string) {
|
||||
callback(out, userargs)
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
|
|
@ -105,7 +105,7 @@ function string.starts(String,Start)
|
|||
end
|
||||
|
||||
function init()
|
||||
config.MakeCommand("comment", "comment.comment", config.NoComplete)
|
||||
config.MakeCommand("comment", comment, config.NoComplete)
|
||||
config.TryBindKey("Alt-/", "lua:comment.comment", false)
|
||||
config.AddRuntimeFile("comment", config.RTHelp, "help/comment.md")
|
||||
end
|
||||
|
|
|
@ -82,13 +82,12 @@ function init()
|
|||
makeLinter("swiftc", "swiftc", {"%f"}, "%f:%l:%c:.+: %m", {"linux"}, true)
|
||||
makeLinter("yaml", "yaml", "yamllint", {"--format", "parsable", "%f"}, "%f:%l:%c:.+ %m")
|
||||
|
||||
config.MakeCommand("lint", "linter.lintCmd", config.NoComplete)
|
||||
config.AddRuntimeFile("linter", config.RTHelp, "help/linter.md")
|
||||
end
|
||||
config.MakeCommand("lint", function(bp, args)
|
||||
bp:Save()
|
||||
runLinter(bp.Buf)
|
||||
end, config.NoComplete)
|
||||
|
||||
function lintCmd(bp, args)
|
||||
bp:Save()
|
||||
runLinter(bp.Buf)
|
||||
config.AddRuntimeFile("linter", config.RTHelp, "help/linter.md")
|
||||
end
|
||||
|
||||
function contains(list, element)
|
||||
|
@ -144,7 +143,7 @@ function lint(buf, linter, cmd, args, errorformat, loff, coff, callback)
|
|||
end
|
||||
end
|
||||
|
||||
shell.JobSpawn(cmd, args, "", "", "linter.onExit", buf, linter, errorformat, loff, coff)
|
||||
shell.JobSpawn(cmd, args, nil, nil, onExit, buf, linter, errorformat, loff, coff)
|
||||
end
|
||||
|
||||
function onExit(output, args)
|
||||
|
|
Loading…
Reference in a new issue