-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
📝 Rewrite documentation for denops v6
- Loading branch information
1 parent
d804221
commit 6aedf69
Showing
49 changed files
with
5,093 additions
and
435 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# FAQ | ||
|
||
## How to Check Denops Startup Time | ||
|
||
To check the startup time of Denops or Denops plugins, utilize | ||
[denops-startup-recorder]. This plugin visualizes the timing of events related | ||
to Denops and Denops plugin startup. | ||
|
||
[denops-startup-recorder]: https://github.com/vim-denops/denops-startup-recorder.vim | ||
|
||
It shows the result in echo area like: | ||
|
||
![](./img/faq-1.png) | ||
|
||
## How to Check Denops Performance | ||
|
||
To assess Denops performance, employ [denops-benchmark]. This plugin measures | ||
the number of operations or characters that can be processed in milliseconds. | ||
|
||
[denops-benchmark]: https://github.com/vim-denops/denops-benchmark.vim | ||
|
||
It shows the result in a buffer like: | ||
|
||
![](./img/faq-2.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Getting Started | ||
|
||
[Denops] ([/ˈdiːnoʊps/](http://ipa-reader.xyz/?text=%CB%88di%CB%90no%CA%8Aps), | ||
pronounced `dee-nops`) is an ecosystem for [Vim] / [Neovim] that empowers | ||
developers to write plugins in [TypeScript] / [JavaScript] powered by [Deno]. | ||
|
||
Let's start by creating a simple plugin to learn how to develop Denops plugins. | ||
|
||
## Create a Plugin | ||
|
||
Create a directory named `denops-getting-started` in your home directory and a file named `main.ts` within it, under `denops/denops-getting-started/`: | ||
|
||
``` | ||
$HOME | ||
└── denops-getting-started | ||
└── denops | ||
└── denops-getting-started | ||
└── main.ts | ||
``` | ||
|
||
Next, write the following TypeScript code in `main.ts`: | ||
|
||
```typescript | ||
import type { Denops } from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
export function main(denops: Denops): void { | ||
denops.dispatcher = { | ||
async hello() { | ||
await denops.cmd(`echo "Hello, Denops!"`); | ||
}, | ||
}; | ||
} | ||
``` | ||
|
||
## Activate the Plugin | ||
|
||
Add the following line to your Vim or Neovim configuration file (e.g., `~/.vimrc` or `~/.config/nvim/init.vim`): | ||
|
||
```vim | ||
set runtimepath+=~/denops-getting-started | ||
``` | ||
|
||
Or Neovim Lua configuration file (e.g., `~/.config/nvim/init.lua`): | ||
|
||
```lua | ||
vim.opt.runtimepath:append("~/denops-getting-started") | ||
``` | ||
|
||
## Try the Plugin | ||
|
||
Restart Vim/Neovim and execute the following command: | ||
|
||
```vim | ||
:call denops#request('denops-getting-started', 'hello', []) | ||
``` | ||
|
||
You should see "Hello, Denops!" displayed on the screen like: | ||
|
||
![](./img/README-01.png) | ||
|
||
[Denops]: https://github.com/vim-denops/denops.vim | ||
[Vim]: https://www.vim.org/ | ||
[Neovim]: https://neovim.io/ | ||
[TypeScript]: https://www.typescriptlang.org/ | ||
[JavaScript]: https://developer.mozilla.org/en-US/docs/Web/JavaScript | ||
[Deno]: https://deno.land/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
# Explanation of the Getting Started | ||
|
||
In this section, we'll provide detailed information about the Getting Started. If you find it too detailed, feel free to skip this section and move on to the next chapter, especially if your goal is to start developing a Denops plugin promptly. | ||
|
||
## What is Denops? | ||
|
||
Denops claims to be an ecosystem for developing Vim / Neovim (hereafter, when we | ||
refer to Vim without restriction, we also include Neovim) plugins using Deno, | ||
but, in reality, it is a Vim plugin with the following features: | ||
|
||
- Detection and registration of Denops plugins | ||
- Launching and connecting to Deno processes | ||
- Calling Deno process-side functions from Vim via RPC (Remote Procedure Call) | ||
- Calling Vim features from Deno process-side via RPC | ||
|
||
By utilizing this plugin, you can control Vim from code written in TypeScript | ||
(Denops plugins). | ||
|
||
> [!NOTE] | ||
> | ||
> [RPC (Remote Procedure Call)](https://en.wikipedia.org/wiki/Remote_procedure_call) | ||
> is used, and while Vim uses a | ||
> [JSON-based custom specification](https://vim-jp.org/vimdoc-en/channel.html#channel-use), | ||
> Neovim uses [MessagePack-RPC](https://github.com/msgpack-rpc/msgpack-rpc) (a | ||
> slightly modified specification). However, Denops abstracts away these | ||
> differences, so Denops plugin developers don't need to be aware of the RPC | ||
> specification differences between Vim and Neovim. | ||
## What is a Vim Plugin? | ||
|
||
When Vim starts, it searches for files named `plugin/*.vim` in directories | ||
specified in `runtimepath`. Additionally, if a function like `foo#bar#hoge()` is | ||
called, it searches for files named `autoload/foo/bar.vim` in the `runtimepath` | ||
and reads the file, calling the `foo#bar#hoge()` function defined within. | ||
|
||
A Vim plugin is a set of predefined features provided to users, utilizing the | ||
functionality mentioned above. Typically, an entry point is defined in | ||
`plugin/{plugin_name}.vim`, and detailed features are implemented in | ||
`autoload/{plugin_name}.vim` or `autoload/{plugin_name}/*.vim`. For example, | ||
here is the directory structure for a Vim plugin named `hello`: | ||
|
||
``` | ||
vim-hello | ||
├── autoload | ||
│ └── hello.vim # Defines the function `hello#hello()` | ||
└── plugin | ||
└── hello.vim # Defines the `Hello` command | ||
``` | ||
|
||
> [!NOTE] | ||
> | ||
> For more detailed information on creating Vim plugins, refer to | ||
> `:help write-plugin`. | ||
## What is a Denops Plugin? | ||
|
||
When Denops is installed, in addition to Vim plugins, files named | ||
`denops/*/main.ts` are also searched when Vim starts. If a corresponding file is | ||
found, Denops registers the parent directory name (`foo` in the case of | ||
`denops/foo/main.ts`) as the plugin name. Then, it imports the corresponding | ||
file as a TypeScript module and calls the function named `main`. | ||
|
||
A Denops plugin, similar to a Vim plugin, provides a set of features written in | ||
TypeScript to users. Since Denops plugins typically include both | ||
TypeScript and Vim script code, the directory structure looks like an | ||
extension of the Vim plugin structure with an added `denops` directory. For | ||
example, here is the directory structure for a Denops plugin named `hello`: | ||
|
||
``` | ||
denops-hello | ||
├── autoload | ||
│ └── hello.vim # Tasks better written in Vim script (may not exist) | ||
├── denops | ||
│ └── hello | ||
│ └── main.ts # Entry point for the Denops plugin (mandatory) | ||
└── plugin | ||
└── hello.vim # Entry point written in Vim script (optional) | ||
``` | ||
|
||
In the Getting Started, we created a file named `denops/denops-getting-started/main.ts` and added its | ||
parent directory (`denops-getting-started`) to `runtimepath`. There were no `autoload` or | ||
`plugin` directories because we didn't provide an entry point that Vim could | ||
easily call. | ||
|
||
## Understanding the Code in Getting Started | ||
|
||
In the Getting Started, we wrote the following code in the `main.ts` file: | ||
|
||
```typescript | ||
import type { Denops } from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
export function main(denops: Denops): void { | ||
denops.dispatcher = { | ||
async hello() { | ||
await denops.cmd(`echo "Hello, Denops!"`); | ||
}, | ||
}; | ||
} | ||
``` | ||
|
||
Let's break down this code step by step. | ||
|
||
### About Imports | ||
|
||
```typescript | ||
import type { Denops } from "https://deno.land/x/[email protected]/mod.ts"; | ||
``` | ||
|
||
The first line imports the `Denops` type from the [denops_std] standard library. | ||
You can find detailed information about the library by checking the URL: | ||
`https://deno.land/x/[email protected]` (remove `/mod.ts`). We fixed the version | ||
in the import URL, so it's recommended to check for details and update to the | ||
latest version URL. | ||
|
||
Note that we use `import type` syntax, which is part of TypeScript's | ||
[Type-Only Imports and Export](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). | ||
This syntax can be written as `import { type Denops }` with the same meaning. | ||
Using `import { Denops }` for a type-only import is also valid. | ||
|
||
> [!NOTE] | ||
> | ||
> Denops plugins are dynamically imported, so there might be differences | ||
> in Denops versions between development and usage. Therefore, to minimize | ||
> differences between Denops versions, only the `Denops` type information is | ||
> exposed. The implementation can be found in | ||
> [`denops/@denops-private/denops.ts`](https://github.com/vim-denops/denops.vim/blob/main/denops/%40denops-private/denops.ts), | ||
> but it is not publicly exposed for the reasons mentioned above. | ||
> | ||
> This type information is provided by [denops_core], and [denops_std] simply | ||
> re-exports the type information from [denops_core]. However, [denops_core] is | ||
> intended to be referenced only by [denops.vim] and [denops_std], so Denops | ||
> plugin developers don't need to use it directly. | ||
### About Entry Point | ||
|
||
```typescript | ||
export function main(denops: Denops): void { | ||
// Omitted... | ||
} | ||
``` | ||
|
||
The above code exports the `main` function. The `main` function is called by | ||
Denops, and it takes the | ||
[Denops instance](https://deno.land/x/denops_std/mod.ts?s=Denops) (`denops`) as | ||
an argument. Denops plugins use this `denops` to add user-defined APIs or call | ||
Vim's features. | ||
|
||
### About User-Defined APIs | ||
|
||
```typescript | ||
denops.dispatcher = { | ||
async hello() { | ||
// Omitted... | ||
}, | ||
}; | ||
``` | ||
|
||
The code above adds a user-defined API named `hello` to `denops.dispatcher`. | ||
`denops.dispatcher` is defined as follows, and each method takes `unknown` types | ||
for both arguments and return values: | ||
|
||
```typescript | ||
interface Dispatcher { | ||
[key: string]: (...args: unknown[]) => unknown; | ||
} | ||
``` | ||
|
||
By defining methods in `denops.dispatcher`, you can freely define APIs. Since | ||
the methods registered in `denops.dispatcher` are always called with `await`, | ||
you can make them asynchronous by returning a `Promise`. | ||
|
||
The methods defined in `denops.dispatcher` can be called from Vim using the | ||
following functions: | ||
|
||
| Function | Description | | ||
| ---------------------- | -------------------------------------------------------------------------------- | | ||
| `denops#request` | Synchronously calls a user-defined API and returns the result. | | ||
| `denops#request_async` | Asynchronously calls a user-defined API and passes the result to callbacks. | | ||
| `denops#notify` | Calls a user-defined API without waiting for completion and discards the result. | | ||
|
||
At the end of the Getting Started, we used | ||
`denops#request('denops-getting-started', 'hello', [])` to call the user-defined API | ||
named `hello` in `denops-getting-started` plugin. | ||
|
||
### About Calling Vim's features | ||
|
||
```typescript | ||
await denops.cmd(`echo "Hello, Denops!"`); | ||
``` | ||
|
||
With the received `denops`, you can call Vim functions, execute Vim commands, or | ||
evaluate Vim expressions. In the example above, the `hello` API internally uses | ||
`denops.cmd` to execute the `echo` command in Vim. The `denops` object provides | ||
several methods: | ||
|
||
| Method | Description | | ||
| ---------- | ---------------------------------------------------------------------------------------------------------- | | ||
| `call` | Calls a Vim function and returns the result. | | ||
| `batch` | Calls multiple Vim functions in bulk and returns the results in bulk. | | ||
| `cmd` | Executes a Vim command. If `ctx` is provided, it is expanded as local variables. | | ||
| `eval` | Evaluate a Vim expression and returns the result. If `ctx` is provided, it is expanded as local variables. | | ||
| `dispatch` | Calls a user-defined API of another Denops plugin and returns the result. | | ||
|
||
Although `denops` provides low-level interfaces, [denops_std] combines these | ||
low-level interfaces to offer higher-level interfaces. Therefore, it's | ||
recommended to use [denops_std] to call Vim's features in actual plugin | ||
development. | ||
|
||
For example, use | ||
[`function` module](https://deno.land/x/[email protected]/function/mod.ts) to | ||
call Vim's function instead of `denops.call` like: | ||
|
||
```typescript | ||
import * as fn from "https://deno.land/x/[email protected]/function/mod.ts"; | ||
|
||
// Bad (result1 is `unknown`) | ||
const result1 = await denops.call("expand", "%"); | ||
|
||
// Good (result2 is `string`) | ||
const result2 = await fn.expand(denops, "%"); | ||
``` | ||
|
||
If developers use `function` module instead, they can benefit from features like | ||
auto-completion and type checking provided by LSP (Language Server Protocol). | ||
|
||
## Next Steps | ||
|
||
In the next step, follow the tutorial to learn how to develop a minimum Denops | ||
plugin. | ||
|
||
- [Tutorial (Hello World)](../tutorial/helloworld/README.md) | ||
- [Tutorial (Maze)](../tutorial/maze/README.md) | ||
- [API reference](https://deno.land/x/denops_std/mod.ts) | ||
|
||
[denops.vim]: https://github.com/vim-denops/denops.vim | ||
[denops_std]: https://deno.land/x/denops_std | ||
[denops_core]: https://deno.land/x/denops_core |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.