mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-15 21:37:09 +09:00
Better plugin docs
This commit is contained in:
@@ -1,23 +1,76 @@
|
||||
# Plugins
|
||||
|
||||
Micro supports creating plugins with a simple Lua system. Every plugin has a
|
||||
main script which is run at startup which should be placed in
|
||||
`~/.config/micro/plugins/pluginName/pluginName.lua`.
|
||||
Micro supports creating plugins with a simple Lua system. Plugins are
|
||||
folders containing Lua files and possibly other source files placed
|
||||
in `~/.config/micro/plug`. The plugin directory (within `plug`) should
|
||||
contain at least one Lua file and an `info.json` file. The info file
|
||||
provides additional information such as the name of the plugin, the
|
||||
plugin's website, dependencies, etc... Here is an example info file
|
||||
from the go plugin, which has the following file structure:
|
||||
|
||||
There are a number of callback functions which you can create in your plugin to
|
||||
run code at times other than startup. The naming scheme is `onAction(view)`. For
|
||||
example a function which is run every time the user saves the buffer would be:
|
||||
```
|
||||
~/.config/micro/plug/go-plugin
|
||||
go.lua
|
||||
info.json
|
||||
```
|
||||
|
||||
info.json:
|
||||
```
|
||||
{
|
||||
"name": "go",
|
||||
"description": "Go formatting and tool support",
|
||||
"website": "https://github.com/micro-editor/go-plugin",
|
||||
"install": "https://github.com/micro-editor/go-plugin",
|
||||
"version": "1.0.0",
|
||||
"require": [
|
||||
"micro >= 2.0.0"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
All fields are simply interpreted as strings, so the version does not
|
||||
need to be a semantic version, and the dependencies are also only
|
||||
meant to be parsed by humans. The name should be an identifier, and
|
||||
the website should point to a valid website. The install field should
|
||||
provide info about installing the plugin, or point to a website that
|
||||
provides information.
|
||||
|
||||
## Lua callbacks
|
||||
|
||||
Plugins use Lua but also have access to many functions both from micro
|
||||
and from the Go standard library. Many callbacks are also defined which
|
||||
are called when certain events happen. Here is the list of callbacks
|
||||
which micro defines:
|
||||
|
||||
* `init()`: this function should be used for your plugin initialization.
|
||||
|
||||
* `onBufferOpen(buf)`: runs when a buffer is opened. The input contains
|
||||
the buffer object.
|
||||
|
||||
* `onBufPaneOpen(bufpane)`: runs when a bufpane is opened. The input
|
||||
contains the bufpane object.
|
||||
|
||||
* `onAction(bufpane)`: runs when `Action` is triggered by the user, where
|
||||
`Action` is a bindable action (see `> help keybindings`). A bufpane
|
||||
is passed as input and the function should return a boolean defining
|
||||
whether the view should be relocated after this action is performed.
|
||||
|
||||
* `preAction(bufpane)`: runs immediately before `Action` is triggered
|
||||
by the user. Returns a boolean which defines whether the action should
|
||||
be canceled.
|
||||
|
||||
For example a function which is run every time the user saves the buffer
|
||||
would be:
|
||||
|
||||
```lua
|
||||
function onSave(view)
|
||||
function onSave(bp)
|
||||
...
|
||||
return false
|
||||
end
|
||||
```
|
||||
|
||||
The `view` variable is a reference to the view the action is being executed on.
|
||||
This is almost always the current view, which you can get with `CurView()` as
|
||||
well.
|
||||
The `bp` variable is a reference to the bufpane the action is being executed within.
|
||||
This is almost always the current bufpane.
|
||||
|
||||
All available actions are listed in the keybindings section of the help.
|
||||
|
||||
@@ -31,191 +84,96 @@ function onMousePress(view, event)
|
||||
end
|
||||
```
|
||||
|
||||
These functions should also return a boolean specifying whether the view should
|
||||
These functions should also return a boolean specifying whether the bufpane should
|
||||
be relocated to the cursor or not after the action is complete.
|
||||
|
||||
Note that these callbacks occur after the action has been completed. If you want
|
||||
a callback before the action is executed, use `preAction()`. In this case the
|
||||
boolean returned specifies whether or not the action should be executed after
|
||||
the lua code completes.
|
||||
## Accessing micro functions
|
||||
|
||||
Another useful callback to know about which is not an action is
|
||||
`onViewOpen(view)` which is called whenever a new view is opened and the new
|
||||
view is passed in. This is useful for setting local options based on the
|
||||
filetype, for example turning off `tabstospaces` only for Go files when they are
|
||||
opened.
|
||||
Some of micro's internal information is exposed in the form of packages which
|
||||
can be imported by Lua plugins. A package can be imported in Lua and a value
|
||||
within it can be accessed using the following syntax:
|
||||
|
||||
---
|
||||
```lua
|
||||
local micro = import("micro")
|
||||
micro.Log("Hello")
|
||||
```
|
||||
|
||||
There are a number of functions and variables that are available to you in order
|
||||
to access the inner workings of micro. Here is a list (the type signatures for
|
||||
functions are given using Go's type system):
|
||||
The packages and functions are listed below:
|
||||
|
||||
* `OS`: variable which gives the OS micro is currently running on (this is the
|
||||
same as Go's GOOS variable, so `darwin`, `windows`, `linux`, `freebsd`...)
|
||||
* `micro`
|
||||
- `TermMessage(msg interface{}...)`
|
||||
- `TermError()`
|
||||
- `InfoBar()`
|
||||
- `Log(msg interface{}...)`
|
||||
- `SetStatusInfoFn`
|
||||
* `micro/config`
|
||||
- `MakeCommand`
|
||||
- `FileComplete`
|
||||
- `HelpComplete`
|
||||
- `OptionComplete`
|
||||
- `OptionValueComplete`
|
||||
- `NoComplete`
|
||||
- `TryBindKey`
|
||||
- `Reload`
|
||||
- `AddRuntimeFilesFromDirectory`
|
||||
- `AddRuntimeFileFromMemory`
|
||||
- `AddRuntimeFile`
|
||||
- `ListRuntimeFiles`
|
||||
- `ReadRuntimeFile`
|
||||
- `RTColorscheme`
|
||||
- `RTSyntax`
|
||||
- `RTHelp`
|
||||
- `RTPlugin`
|
||||
- `RegisterCommonOption`
|
||||
- `RegisterGlobalOption`
|
||||
* `micro/shell`
|
||||
- `ExecCommand`
|
||||
- `RunCommand`
|
||||
- `RunBackgroundShell`
|
||||
- `RunInteractiveShell`
|
||||
- `JobStart`
|
||||
- `JobSpawn`
|
||||
- `JobStop`
|
||||
- `JobStop`
|
||||
- `RunTermEmulator`
|
||||
- `TermEmuSupported`
|
||||
* `micro/buffer`
|
||||
- `NewMessage`
|
||||
- `NewMessageAtLine`
|
||||
- `MTInfo`
|
||||
- `MTWarning`
|
||||
- `MTError`
|
||||
- `Loc`
|
||||
- `BTDefault`
|
||||
- `BTLog`
|
||||
- `BTRaw`
|
||||
- `BTInfo`
|
||||
- `NewBufferFromFile`
|
||||
- `ByteOffset`
|
||||
* `micro/util`
|
||||
- `RuneAt`
|
||||
- `GetLeadingWhitespace`
|
||||
- `IsWordChar`
|
||||
|
||||
* `configDir`: contains the path to the micro configuration files
|
||||
|
||||
* `tabs`: a list of all the tabs currently in use
|
||||
|
||||
* `curTab`: the index of the current tabs in the tabs list
|
||||
|
||||
* `messenger`: lets you send messages to the user or create prompts
|
||||
|
||||
* `NewBuffer(text, path string) *Buffer`: creates a new buffer from a given
|
||||
reader with a given path
|
||||
|
||||
* `NewBufferFromFile(path string) *Buffer`: creates a new buffer from a given
|
||||
path
|
||||
|
||||
* `GetLeadingWhitespace() bool`: returns the leading whitespace of the given
|
||||
string
|
||||
|
||||
* `IsWordChar(str string) bool`: returns whether or not the string is a 'word
|
||||
character'
|
||||
|
||||
* `RuneStr(r rune) string`: returns a string containing the given rune
|
||||
|
||||
* `Loc(x, y int) Loc`: returns a new `Loc` struct
|
||||
|
||||
* `WorkingDirectory() string`: returns a rooted path name to the current working
|
||||
directory
|
||||
|
||||
* `JoinPaths(dir... string) string`: combines multiple directories to a full
|
||||
path
|
||||
|
||||
* `DirectoryName(path string)`: returns all but the last element of path,
|
||||
typically the path's directory
|
||||
|
||||
* `GetOption(name string)`: returns the value of the requested option
|
||||
|
||||
* `AddOption(name string, value interface{})`: sets the given option with the
|
||||
given value (`interface{}` means any type in Go)
|
||||
|
||||
* `SetOption(option, value string)`: sets the given option to the value. This
|
||||
will set the option globally, unless it is a local only option.
|
||||
|
||||
* `SetLocalOption(option, value string, view *View)`: sets the given option to
|
||||
the value locally in the given buffer
|
||||
|
||||
* `BindKey(key, action string)`: binds `key` to `action`
|
||||
|
||||
* `MakeCommand(name, function string, completions ...Completion)`:
|
||||
creates a command with `name` which will call `function` when executed. Use 0
|
||||
for completions to get NoCompletion.
|
||||
|
||||
* `MakeCompletion(function string)`:
|
||||
creates a `Completion` to use with `MakeCommand`
|
||||
|
||||
* `CurView()`: returns the current view
|
||||
|
||||
* `HandleCommand(cmd string)`: runs the given command
|
||||
|
||||
* `ExecCommand(name string, args []string) (string, error)`: exec a (shell) command with the
|
||||
given arguments. Returns the command's output and a possible error.
|
||||
|
||||
* `RunShellCommand(cmd string) (string, error)`: Run a shell command. This uses `ExecCommand`
|
||||
under the hood but also does some parsing for the arguments (i.e. quoted arguments). The
|
||||
function returns the command's output and a possible error.
|
||||
|
||||
* `RunBackgroundShell(cmd string)`: Run a shell command in the background.
|
||||
|
||||
* `RunInteractiveShell(cmd string, wait bool, getOutput bool) (string, error)`: Run a shell command
|
||||
by closing micro and running the command interactively. If `wait` is true, a prompt will be
|
||||
used after the process exits to prevent the terminal from immediately returning to micro, allowing
|
||||
the user to view the output of the process. If `getOutput` is true, the command's standard output
|
||||
will be returned. Note that if `getOutput` is true, some interactive commands may not behave
|
||||
normally because `isatty` will return false.
|
||||
|
||||
* `RunTermEmulator(cmd string, wait bool, getOutput bool, callback string) error`: Same as
|
||||
`RunInteractiveShell` except the command is run within the current split in a terminal emulator.
|
||||
The `callback` input is a string callback to a lua function which will be called when the process
|
||||
exits. The output of the process will be provided as the first and only argument to the callback
|
||||
(it will be empty if `getOutput` is false).
|
||||
Note that this functionality is only supported on some operating systems (linux, darwin, dragonfly,
|
||||
openbsd, freebsd). Use the `TermEmuSupported` (see below) boolean to determine if the current
|
||||
system is supported.
|
||||
|
||||
* `TermEmuSupported`: Boolean specifying if the terminal emulator is supported on the version of
|
||||
micro that is running.
|
||||
|
||||
* `ToCharPos(loc Loc, buf *Buffer) int`: returns the character position of a
|
||||
given x, y location
|
||||
|
||||
* `Reload`: (Re)load everything
|
||||
|
||||
* `ByteOffset(loc Loc, buf *Buffer) int`: exactly like `ToCharPos` except it it
|
||||
counts bytes instead of runes
|
||||
|
||||
* `JobSpawn(cmdName string, cmdArgs []string, onStdout, onStderr, onExit string, userargs ...string)`:
|
||||
Starts running the given process in the background. `onStdout` `onStderr` and
|
||||
`onExit` are callbacks to lua functions which will be called when the given
|
||||
actions happen to the background process. `userargs` are the arguments which
|
||||
will get passed to the callback functions
|
||||
|
||||
* `JobStart(cmd string, onStdout, onStderr, onExit string, userargs ...string)`:
|
||||
Starts running the given shell command in the background. Note that the
|
||||
command execute is first parsed by a shell when using this command. It is
|
||||
executed with `sh -c`.
|
||||
|
||||
* `JobSend(cmd *exec.Cmd, data string)`: send a string into the stdin of the job
|
||||
process
|
||||
|
||||
* `JobStop(cmd *exec.Cmd)`: kill a job
|
||||
|
||||
This may seem like a small list of available functions but some of the objects
|
||||
returned by the functions have many methods. `CurView()` returns a view object
|
||||
which has all the actions which you can call. For example
|
||||
`CurView():Save(false)`. You can see the full list of possible actions in the
|
||||
keybindings help topic. The boolean on all the actions indicates whether or not
|
||||
the lua callbacks should be run. I would recommend generally sticking to false
|
||||
when making a plugin to avoid recursive problems, for example if you call
|
||||
`CurView():Save(true)` in `onSave()`. Just use `CurView():Save(false)` so that
|
||||
it won't call `onSave()` again.
|
||||
returned by the functions have many methods. The Lua plugin may access any
|
||||
public methods of an object returned by any of the functions above. For example,
|
||||
with a BufPane object called `bp`, you could called the `Save` function in Lua
|
||||
with `bp:Save()`.
|
||||
|
||||
Using the view object, you can also access the buffer associated with that view
|
||||
by using `CurView().Buf`, which lets you access the `FileType`, `Path`,
|
||||
`Name`...
|
||||
|
||||
The possible methods which you can call using the `messenger` variable are:
|
||||
|
||||
* `messenger.Message(msg ...interface{})`
|
||||
* `messenger.Error(msg ...interface{})`
|
||||
* `messenger.YesNoPrompt(prompt string) (bool,bool)`
|
||||
* `messenger.Prompt(prompt, historyType string, completionType Completion) (string, bool)`
|
||||
* `messenger.AddLog(msg ...interface{})`
|
||||
|
||||
#### Note
|
||||
|
||||
Go function signatures use `.` and lua uses `:` so
|
||||
Note that Lua uses the `:` syntax to call a function rather than Go's `.` syntax.
|
||||
|
||||
```go
|
||||
messenger.Message()
|
||||
micro.InfoBar().Message()
|
||||
```
|
||||
|
||||
turns to
|
||||
|
||||
```lua
|
||||
messenger:Message()
|
||||
micro.InfoBar():Message()
|
||||
```
|
||||
|
||||
If you want a standard prompt, just use
|
||||
|
||||
```lua
|
||||
messenger:Prompt(prompt, "", 0)
|
||||
```
|
||||
|
||||
Debug or logging your plugin can be done with below lua example code.
|
||||
|
||||
```lua
|
||||
messenger:AddLog("Message goes here ",pluginVariableToPrintHere)
|
||||
```
|
||||
|
||||
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
|
||||
@@ -226,11 +184,12 @@ Simply import the package you'd like and then you can use it. For example:
|
||||
```lua
|
||||
local ioutil = import("io/ioutil")
|
||||
local fmt = import("fmt")
|
||||
local micro = import("micro")
|
||||
|
||||
local data, err = ioutil.ReadFile("SomeFile.txt")
|
||||
|
||||
if err ~= nil then
|
||||
messenger:Error("Error reading file: SomeFile.txt")
|
||||
micro.InfoBar():Error("Error reading file: SomeFile.txt")
|
||||
else
|
||||
-- Data is returned as an array of bytes
|
||||
-- Using Sprintf will convert it to a string
|
||||
@@ -282,7 +241,6 @@ files to the runtime. To read the content of a runtime file use
|
||||
`ReadRuntimeFile(fileType, name string)` or `ListRuntimeFiles(fileType string)`
|
||||
for all runtime files.
|
||||
|
||||
|
||||
## Autocomplete command arguments
|
||||
|
||||
See this example to learn how to use `MakeCompletion` and `MakeCommand`
|
||||
@@ -313,7 +271,6 @@ end
|
||||
MakeCommand("foo", "example.foo", MakeCompletion("example.complete"))
|
||||
```
|
||||
|
||||
|
||||
## Default plugins
|
||||
|
||||
For examples of plugins, see the default `autoclose` and `linter` plugins
|
||||
@@ -321,7 +278,6 @@ For examples of plugins, see the default `autoclose` and `linter` plugins
|
||||
plugins that are stored in the official channel
|
||||
[here](https://github.com/micro-editor/plugin-channel).
|
||||
|
||||
|
||||
## Plugin Manager
|
||||
|
||||
Micro also has a built in plugin manager which you can invoke with the
|
||||
|
||||
Reference in New Issue
Block a user