Full extensible linter support

This commit is contained in:
Zachary Yedidia
2019-08-03 15:19:28 -07:00
parent 4027081e0e
commit be136a4648
6 changed files with 159 additions and 82 deletions

View File

@@ -28,6 +28,8 @@ func LuaImport(pkg string) *lua.LTable {
return luaImportMicroShell() return luaImportMicroShell()
case "micro/buffer": case "micro/buffer":
return luaImportMicroBuffer() return luaImportMicroBuffer()
case "micro/config":
return luaImportMicroConfig()
case "micro/util": case "micro/util":
return luaImportMicroUtil() return luaImportMicroUtil()
default: default:
@@ -43,7 +45,20 @@ func luaImportMicro() *lua.LTable {
ulua.L.SetField(pkg, "InfoBar", luar.New(ulua.L, action.GetInfoBar)) ulua.L.SetField(pkg, "InfoBar", luar.New(ulua.L, action.GetInfoBar))
ulua.L.SetField(pkg, "Log", luar.New(ulua.L, log.Println)) ulua.L.SetField(pkg, "Log", luar.New(ulua.L, log.Println))
ulua.L.SetField(pkg, "SetStatusInfoFn", luar.New(ulua.L, display.SetStatusInfoFnLua)) ulua.L.SetField(pkg, "SetStatusInfoFn", luar.New(ulua.L, display.SetStatusInfoFnLua))
// ulua.L.SetField(pkg, "TryBindKey", luar.New(ulua.L, action.TryBindKey))
return pkg
}
func luaImportMicroConfig() *lua.LTable {
pkg := ulua.L.NewTable()
ulua.L.SetField(pkg, "MakeCommand", luar.New(ulua.L, action.LuaMakeCommand))
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))
ulua.L.SetField(pkg, "OptionValueComplete", luar.New(ulua.L, action.OptionValueComplete))
ulua.L.SetField(pkg, "NoComplete", luar.New(ulua.L, nil))
ulua.L.SetField(pkg, "TryBindKey", luar.New(ulua.L, action.TryBindKey))
return pkg return pkg
} }

View File

@@ -10,8 +10,12 @@ import (
"strings" "strings"
"unicode/utf8" "unicode/utf8"
luar "layeh.com/gopher-luar"
lua "github.com/yuin/gopher-lua"
"github.com/zyedidia/micro/internal/buffer" "github.com/zyedidia/micro/internal/buffer"
"github.com/zyedidia/micro/internal/config" "github.com/zyedidia/micro/internal/config"
ulua "github.com/zyedidia/micro/internal/lua"
"github.com/zyedidia/micro/internal/screen" "github.com/zyedidia/micro/internal/screen"
"github.com/zyedidia/micro/internal/shell" "github.com/zyedidia/micro/internal/shell"
"github.com/zyedidia/micro/internal/util" "github.com/zyedidia/micro/internal/util"
@@ -63,16 +67,29 @@ func InitCommands() {
// MakeCommand is a function to easily create new commands // 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 // This can be called by plugins in Lua so that plugins can define their own commands
// func MakeCommand(name, function string, completions ...Completion) { func LuaMakeCommand(name, function string, completer buffer.Completer) {
// action := commandActions[function] action := LuaFunctionCommand(function)
// // if _, ok := commandActions[function]; !ok { commands[name] = Command{action, completer}
// // If the user seems to be binding a function that doesn't exist }
// // We hope that it's a lua function that exists and bind it to that
// // action = LuaFunctionCommand(function) // LuaFunctionCommand returns a normal function
// // } // so that a command can be bound to a lua function
// func LuaFunctionCommand(fn string) func(*BufPane, []string) {
// commands[name] = Command{action, completions} luaFn := strings.Split(fn, ".")
// } plName, plFn := luaFn[0], luaFn[1]
pl := config.FindPlugin(plName)
return func(bp *BufPane, args []string) {
var luaArgs []lua.LValue
luaArgs = append(luaArgs, luar.New(ulua.L, bp))
for _, v := range args {
luaArgs = append(luaArgs, luar.New(ulua.L, v))
}
_, err := pl.Call(plFn, luaArgs...)
if err != nil {
screen.TermMessage(err)
}
}
}
// CommandEditAction returns a bindable function that opens a prompt with // CommandEditAction returns a bindable function that opens a prompt with
// the given string and executes the command when the user presses // the given string and executes the command when the user presses
@@ -456,7 +473,6 @@ func (h *BufPane) SetLocalCmd(args []string) {
if err != nil { if err != nil {
InfoBar.Error(err) InfoBar.Error(err)
} }
} }
// ShowCmd shows the value of the given option // ShowCmd shows the value of the given option

View File

@@ -95,9 +95,7 @@ func (p *Plugin) Load() error {
return err return err
} }
p.Loaded = true p.Loaded = true
if _, ok := GlobalSettings[p.Name]; !ok { RegisterGlobalOption(p.Name, true)
AddOption(p.Name, true)
}
} }
return nil return nil
} }

File diff suppressed because one or more lines are too long

View File

@@ -114,12 +114,35 @@ func WriteSettings(filename string) error {
return err return err
} }
// AddOption creates a new option. This is meant to be called by plugins to add options. // RegisterCommonOption creates a new option. This is meant to be called by plugins to add options.
func AddOption(name string, value interface{}) error { func RegisterCommonOption(name string, defaultvalue interface{}) error {
GlobalSettings[name] = value if v, ok := GlobalSettings[name]; !ok {
err := WriteSettings(ConfigDir + "/settings.json") defaultCommonSettings[name] = defaultvalue
if err != nil { GlobalSettings[name] = defaultvalue
return errors.New("Error writing settings.json file: " + err.Error()) err := WriteSettings(ConfigDir + "/settings.json")
if err != nil {
return errors.New("Error writing settings.json file: " + err.Error())
}
} else {
defaultCommonSettings[name] = v
}
return nil
}
func RegisterLocalOption(name string, defaultvalue interface{}) {
defaultLocalSettings[name] = defaultvalue
}
func RegisterGlobalOption(name string, defaultvalue interface{}) error {
if v, ok := GlobalSettings[name]; !ok {
defaultGlobalSettings[name] = defaultvalue
GlobalSettings[name] = defaultvalue
err := WriteSettings(ConfigDir + "/settings.json")
if err != nil {
return errors.New("Error writing settings.json file: " + err.Error())
}
} else {
defaultGlobalSettings[name] = v
} }
return nil return nil
} }
@@ -129,42 +152,40 @@ func GetGlobalOption(name string) interface{} {
return GlobalSettings[name] return GlobalSettings[name]
} }
func DefaultCommonSettings() map[string]interface{} { var defaultCommonSettings = map[string]interface{}{
return map[string]interface{}{ "autoindent": true,
"autoindent": true, "autosave": false,
"autosave": false, "basename": false,
"basename": false, "colorcolumn": float64(0),
"colorcolumn": float64(0), "cursorline": true,
"cursorline": true, "encoding": "utf-8",
"encoding": "utf-8", "eofnewline": false,
"eofnewline": false, "fastdirty": true,
"fastdirty": true, "fileformat": "unix",
"fileformat": "unix", "ignorecase": false,
"ignorecase": false, "indentchar": " ",
"indentchar": " ", "keepautoindent": false,
"keepautoindent": false, "matchbrace": false,
"matchbrace": false, "matchbraceleft": false,
"matchbraceleft": false, "rmtrailingws": false,
"rmtrailingws": false, "ruler": true,
"ruler": true, "savecursor": false,
"savecursor": false, "saveundo": false,
"saveundo": false, "scrollbar": false,
"scrollbar": false, "scrollmargin": float64(3),
"scrollmargin": float64(3), "scrollspeed": float64(2),
"scrollspeed": float64(2), "smartpaste": true,
"smartpaste": true, "softwrap": false,
"softwrap": false, "splitbottom": true,
"splitbottom": true, "splitright": true,
"splitright": true, "statusformatl": "$(filename) $(modified)($(line),$(col)) $(opt:filetype) $(opt:fileformat) $(opt:encoding)",
"statusformatl": "$(filename) $(modified)($(line),$(col)) $(opt:filetype) $(opt:fileformat) $(opt:encoding)", "statusformatr": "$(bind:ToggleKeyMenu): show bindings, $(bind:ToggleHelp): toggle help",
"statusformatr": "$(bind:ToggleKeyMenu): show bindings, $(bind:ToggleHelp): toggle help", "statusline": true,
"statusline": true, "syntax": true,
"syntax": true, "tabmovement": false,
"tabmovement": false, "tabsize": float64(4),
"tabsize": float64(4), "tabstospaces": false,
"tabstospaces": false, "useprimary": true,
"useprimary": true,
}
} }
func GetInfoBarOffset() int { func GetInfoBarOffset() int {
@@ -178,41 +199,64 @@ func GetInfoBarOffset() int {
return offset return offset
} }
var defaultGlobalSettings = map[string]interface{}{
"colorscheme": "default",
"infobar": true,
"keymenu": false,
"mouse": true,
"savehistory": true,
"sucmd": "sudo",
"termtitle": false,
}
// DefaultGlobalSettings returns the default global settings for micro // DefaultGlobalSettings returns the default global settings for micro
// Note that colorscheme is a global only option // Note that colorscheme is a global only option
func DefaultGlobalSettings() map[string]interface{} { func DefaultGlobalSettings() map[string]interface{} {
common := DefaultCommonSettings() globalsettings := make(map[string]interface{})
common["colorscheme"] = "default" for k, v := range defaultCommonSettings {
common["infobar"] = true globalsettings[k] = v
common["keymenu"] = false }
common["mouse"] = true for k, v := range defaultGlobalSettings {
common["pluginchannels"] = []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"} globalsettings[k] = v
common["pluginrepos"] = []string{} }
common["savehistory"] = true return globalsettings
common["sucmd"] = "sudo"
common["termtitle"] = false
return common
} }
// LocalSettings is a list of the local only settings // LocalSettings is a list of the local only settings
var LocalSettings = []string{"filetype", "readonly"} var LocalSettings = []string{"filetype", "readonly"}
var defaultLocalSettings = map[string]interface{}{
"filetype": "unknown",
"readonly": false,
}
// DefaultLocalSettings returns the default local settings // DefaultLocalSettings returns the default local settings
// Note that filetype is a local only option // Note that filetype is a local only option
func DefaultLocalSettings() map[string]interface{} { func DefaultLocalSettings() map[string]interface{} {
common := DefaultCommonSettings() localsettings := make(map[string]interface{})
common["filetype"] = "unknown" for k, v := range defaultCommonSettings {
common["readonly"] = false localsettings[k] = v
return common }
for k, v := range defaultLocalSettings {
localsettings[k] = v
}
return localsettings
} }
// DefaultAllSettings returns a map of all settings and their
// default values (both local and global settings)
func DefaultAllSettings() map[string]interface{} { func DefaultAllSettings() map[string]interface{} {
global := DefaultGlobalSettings() allsettings := make(map[string]interface{})
local := DefaultLocalSettings() for k, v := range defaultCommonSettings {
for k, v := range global { allsettings[k] = v
local[k] = v
} }
return local for k, v := range defaultGlobalSettings {
allsettings[k] = v
}
for k, v := range defaultLocalSettings {
allsettings[k] = v
}
return allsettings
} }
func GetNativeValue(option string, realValue interface{}, value string) (interface{}, error) { func GetNativeValue(option string, realValue interface{}, value string) (interface{}, error) {

View File

@@ -2,7 +2,7 @@ local runtime = import("runtime")
local filepath = import("path/filepath") local filepath = import("path/filepath")
local shell = import("micro/shell") local shell = import("micro/shell")
local buffer = import("micro/buffer") local buffer = import("micro/buffer")
local micro = import("micro") local config = import("micro/config")
local linters = {} local linters = {}
@@ -66,6 +66,13 @@ function init()
makeLinter("switfc", "swift", "xcrun", {"swiftc", "%f"}, "%f:%l:%d+:.+: %m", {"darwin"}, true) makeLinter("switfc", "swift", "xcrun", {"swiftc", "%f"}, "%f:%l:%d+:.+: %m", {"darwin"}, true)
makeLinter("switfc", "swiftc", {"%f"}, "%f:%l:%d+:.+: %m", {"linux"}, true) makeLinter("switfc", "swiftc", {"%f"}, "%f:%l:%d+:.+: %m", {"linux"}, true)
makeLinter("yaml", "yaml", "yamllint", {"--format", "parsable", "%f"}, "%f:%l:%d+:.+ %m") makeLinter("yaml", "yaml", "yamllint", {"--format", "parsable", "%f"}, "%f:%l:%d+:.+ %m")
config.MakeCommand("lint", "linter.lintCmd", config.NoComplete)
end
function lintCmd(bp)
bp:Save()
runLinter(bp.Buf)
end end
function contains(list, element) function contains(list, element)
@@ -107,7 +114,6 @@ function runLinter(buf)
end end
function onSave(bp) function onSave(bp)
micro.Log("SAVE")
runLinter(bp.Buf) runLinter(bp.Buf)
return false return false
end end
@@ -119,8 +125,6 @@ function lint(buf, linter, cmd, args, errorformat)
end end
function onExit(output, buf, linter, errorformat) function onExit(output, buf, linter, errorformat)
micro.Log("ONEXIT")
micro.Log(output)
local lines = split(output, "\n") local lines = split(output, "\n")
local regex = errorformat:gsub("%%f", "(..-)"):gsub("%%l", "(%d+)"):gsub("%%m", "(.+)") local regex = errorformat:gsub("%%f", "(..-)"):gsub("%%l", "(%d+)"):gsub("%%m", "(.+)")