mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-25 18:07:07 +09:00
Full extensible linter support
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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) {
|
||||||
|
|||||||
@@ -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", "(.+)")
|
||||||
|
|||||||
Reference in New Issue
Block a user