X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=runtime%2Fhelp%2Fplugins.md;h=e68df426b0fbe7c904ff5a3c173be0c02a11ae37;hb=f3e8413e772924947238bdb9f928375e24ff7213;hp=3af94798c8416f043796d16898e8b5305f799f65;hpb=d7b7cc954a2bc25c8bb1b7d5e23c32c6026181cb;p=micro.git diff --git a/runtime/help/plugins.md b/runtime/help/plugins.md index 3af94798..e68df426 100644 --- a/runtime/help/plugins.md +++ b/runtime/help/plugins.md @@ -1,204 +1,309 @@ # 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: - -```lua -function onSave(view) - ... - return false -end +``` +~/.config/micro/plug/go-plugin/ + go.lua + info.json + help/ + go-plugin.md ``` -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 `go.lua` file contains the main code for the plugin, though the +code may be distributed across multiple Lua files. The `info.json` +file contains information about the plugin such as the website, +description, version, and any requirements. Plugins may also +have additional files which can be added to micro's runtime files, +of which there are 5 types: -All available actions are listed in the keybindings section of the help. +* Colorschemes +* Syntax files +* Help files +* Plugin files +* Syntax header files -These functions should also return a boolean specifying whether the view -should be relocated to the cursor or not after the action is complete. +In most cases, a plugin will want to add help files, but in certain +cases a plugin may also want to add colorschemes or syntax files. It +is unlikely for a plugin to need to add plugin files at runtime or +syntax header files. No directory structure is enforced but keeping +runtime files in their own directories is good practice. -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. +# Info file -Another useful callback to know about which is not a 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. +The `info.json` for the Go plugin is the following: ---- +``` +{ + "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" + ] +} +``` -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): +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. -* `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`...) +Note that the name of the plugin is defined by the name field in +the `info.json` and not by the installation path. Some functions micro +exposes to plugins require passing the name of the plugin. -* `configDir`: contains the path to the micro configuration files +## Lua callbacks -* `tabs`: a list of all the tabs currently in use +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: -* `curTab`: the index of the current tabs in the tabs list +* `init()`: this function should be used for your plugin initialization. -* `messenger`: lets you send messages to the user or create prompts +* `onBufferOpen(buf)`: runs when a buffer is opened. The input contains + the buffer object. -* `RuneStr(r rune) string`: returns a string containing the given rune +* `onBufPaneOpen(bufpane)`: runs when a bufpane is opened. The input + contains the bufpane object. -* `Loc(x, y int) Loc`: returns a new `Loc` struct +* `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. -* `JoinPaths(dir... string) string` combines multiple directories to a full path +* `preAction(bufpane)`: runs immediately before `Action` is triggered + by the user. Returns a boolean which defines whether the action should + be canceled. -* `GetOption(name string)`: returns the value of the requested option +For example a function which is run every time the user saves the buffer +would be: -* `AddOption(name string, value interface{})`: sets the given option with the given - value (`interface{}` means any type in Go) +```lua +function onSave(bp) + ... + return false +end +``` -* `SetOption(option, value string)`: sets the given option to the value. This will - set the option globally, unless it is a local only option. +The `bp` variable is a reference to the bufpane the action is being executed within. +This is almost always the current bufpane. -* `SetLocalOption(option, value string, buffer *Buffer)`: sets the given option to - the value locally in the given buffer +All available actions are listed in the keybindings section of the help. -* `BindKey(key, action string)`: binds `key` to `action` +For callbacks to mouse actions, you are also given the event info: -* `MakeCommand(name, function string, completions ...Completion)`: - creates a command with `name` which will call `function` when executed. - Use 0 for completions to get NoCompletion. +```lua +function onMousePress(view, event) + local x, y = event:Position() -* `MakeCompletion(function string)`: - creates a `Completion` to use with `MakeCommand` + return false +end +``` -* `CurView()`: returns the current view +These functions should also return a boolean specifying whether the bufpane should +be relocated to the cursor or not after the action is complete. -* `HandleCommand(cmd string)`: runs the given command +## Accessing micro functions -* `HandleShellCommand(shellCmd string, interactive bool, waitToClose bool)`: runs the given shell - command. The `interactive` bool specifies whether the command should run in the background. The - `waitToClose` bool only applies if `interactive` is true and means that it should wait before - returning to the editor. +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: -* `JobStart(cmd string, onStdout, onStderr, onExit string, userargs ...string)`: - Starts running the given shell command 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 +```lua +local micro = import("micro") +micro.Log("Hello") +``` -* `JobSend(cmd *exec.Cmd, data string)`: send a string into the stdin of the job process +The packages and functions are listed below (in Go type signatures): + +* `micro` + - `TermMessage(msg interface{}...)` + - `TermError()` + - `InfoBar()` + - `Log(msg interface{}...)` + - `SetStatusInfoFn(fn string)` +* `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` -* `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. - -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`... +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. Unfortunately +it is not possible to list all the available functions on this page. Please +go to the internal documentation at https://godoc.org/github.com/zyedidia/micro +to see the full list of available methods. Note that only methods of types that +are available to plugins via the functions above can be called from a plugin. +For an even more detailed reference see the source code on Github. -The possible methods which you can call using the `messenger` variable are: +For example, with a BufPane object called `bp`, you could call the `Save` function +in Lua with `bp:Save()`. -* `messenger.Message(msg ...interface{})` -* `messenger.Error(msg ...interface{})` -* `messenger.YesNoPrompt(prompt string) (bool, bool)` -* `messenger.Prompt(prompt, historyType string, completionType Completion) (string, bool)` +Note that Lua uses the `:` syntax to call a function rather than Go's `.` syntax. -If you want a standard prompt, just use `messenger.Prompt(prompt, "", 0)` - -# Adding help files, syntax files, or colorschemes in your plugin +```go +micro.InfoBar().Message() +``` -You can use the `AddRuntimeFile(name, type, path string)` function to add various kinds of -files to your plugin. For example, if you'd like to add a help topic and to your plugin -called `test`, you would create the `test.md` file for example, and runt the function: +turns to ```lua -AddRuntimeFile("test", "help", "test.md") +micro.InfoBar():Message() ``` -Use `AddRuntimeFilesFromDirectory(name, type, dir, pattern)` to add a number of files -to the runtime. +## Accessing the Go standard library -# Autocomplete command arguments +It is possible for your lua code to access many of the functions in the Go +standard library. -See this example to learn how to use `MakeCompletion` and `MakeCommand` +Simply import the package you'd like and then you can use it. For example: ```lua -local function StartsWith(String,Start) - String = String:upper() - Start = Start:upper() - return string.sub(String,1,string.len(Start))==Start -end +local ioutil = import("io/ioutil") +local fmt = import("fmt") +local micro = import("micro") -function complete(input) - local allCompletions = {"Hello", "World", "Foo", "Bar"} - local result = {} - - for i,v in pairs(allCompletions) do - if StartsWith(v, input) then - table.insert(result, v) - end - end - return result -end +local data, err = ioutil.ReadFile("SomeFile.txt") -function foo(arg) - messenger:Message(arg) +if err ~= nil then + 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 + local str = fmt.Sprintf("%s", data) + + -- Do something with the file you just read! + -- ... end +``` -MakeCommand("foo", "example.foo", MakeCompletion("example.complete")) +Here are the packages from the Go standard library that you can access. +Nearly all functions from these packages are supported. For an exact +list of which functions are supported you can look through `lua.go` +(which should be easy to understand). + +``` +fmt +io +io/ioutil +net +math +math/rand +os +runtime +path +filepath +strings +regexp +errors +time ``` -# Default plugins - -For examples of plugins, see the default plugins `linter`, `go`, and `autoclose`. -They are stored in Micro's GitHub repository [here](https://github.com/zyedidia/micro/tree/master/runtime/plugins). - -# Plugin Manager - -Micro also has a built in plugin manager which you can invoke with the `> plugin ...` command. - -For the valid commands you can use, see the `command` help topic. - -The manager fetches plugins from the channels (which is simply a list of plugin metadata) -which it knows about. By default, micro only knows about the official channel which is located -at github.com/micro-editor/plugin-channel but you can add your own third-party channels using -the `pluginchannels` option and you can directly link third-party plugins to allow installation -through the plugin manager with the `pluginrepos` option. - -If you'd like to publish a plugin you've made as an official plugin, you should upload your -plugin online (to Github preferably) and add a `repo.json` file. This file will contain the -metadata for your plugin. Here is an example: - -```json -[{ - "Name": "pluginname", - "Description": "Here is a nice concise description of my plugin", - "Tags": ["python", "linting"], - "Versions": [ - { - "Version": "1.0.0", - "Url": "https://github.com/user/plugin/archive/v1.0.0.zip", - "Require": { - "micro": ">=1.0.3" - } - } - ] -}] +For documentation for each of these functions, see the Go standard +library documentation at https://golang.org/pkg/ (for the packages +exposed to micro plugins). The Lua standard library is also available +to plugins though it is rather small. + +## Adding help files, syntax files, or colorschemes in your plugin + +You can use the `AddRuntimeFile(name string, type config.RTFiletype, path string)` +function to add various kinds of files to your plugin. For example, if you'd +like to add a help topic to your plugin called `test`, you would create a +`test.md` file, and call the function: + +```lua +config = import("micro/config") +config.AddRuntimeFile("test", config.RTHelp, "test.md") ``` -Then open a pull request at github.com/micro-editor/plugin-channel adding a link to the -raw `repo.json` that is in your plugin repository. -To make updating the plugin work, the first line of your plugins lua code should contain the version of the plugin. (Like this: `VERSION = "1.0.0"`) -Please make sure to use [semver](http://semver.org/) for versioning. \ No newline at end of file +Use `AddRuntimeFilesFromDirectory(name, type, dir, pattern)` to add a number of +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. In addition, there is `AddRuntimeFileFromMemory` which +adds a runtime file based on a string that may have been constructed at +runtime. + +## Default plugins + +There are 6 default plugins that come pre-installed with micro. These are + +* `autoclose`: automatically closes brackets, quotes, etc... +* `comment`: provides automatic commenting for a number of languages +* `ftoptions`: alters some default options depending on the filetype +* `linter`: provides extensible linting for many languages +* `literate`: provides advanced syntax highlighting for the Literate + programming tool. +* `status`: provides some extensions to the status line (integration with + Git and more). + +These are good examples for many use-cases if you are looking to write +your own plugins. + +## Plugin Manager + +Micro's plugin manager is you! Ultimately the plugins that are created +for micro are quite simple and don't require a complex automated tool +to manage them. They should be "git cloned" or somehow placed in the +`~/.config/micro/plug` directory, and that is all that's necessary +for installation. In the rare case that a more complex installation +process is needed (such as dependencies, or additional setup) the +plugin creator should provide the additional instructions on their +website and point to the link using the `install` field in the `info.json` +file.