-
-
Notifications
You must be signed in to change notification settings - Fork 299
/
Copy pathREADME.md
398 lines (279 loc) · 11.1 KB
/
README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# plenary.nvim
All the lua functions I don't want to write twice.
> plenary:
>
> full; complete; entire; absolute; unqualified.
Note that this library is useless outside of Neovim since it requires Neovim functions. It should be usable with any recent version of Neovim though.
At the moment, it is very much in pre-alpha :smile: Expect changes to the way some functions are structured. I'm hoping to finish some document generators to provide better documentation for people to use and consume and then at some point we'll stabilize on a few more stable APIs.
## Installation
[](https://luarocks.org/modules/Conni2461/plenary.nvim)
Using [plug](https://github.com/junegunn/vim-plug):
```vim
Plug 'nvim-lua/plenary.nvim'
```
Using [packer](https://github.com/wbthomason/packer.nvim):
```
use "nvim-lua/plenary.nvim"
```
## Modules
- [plenary.async](#plenaryasync)
- [plenary.async_lib](#plenaryasync_lib)
- [plenary.job](#plenaryjob)
- [plenary.path](#plenarypath)
- [plenary.scandir](#plenaryscandir)
- [plenary.context_manager](#plenarycontext_manager)
- [plenary.test_harness](#plenarytest_harness)
- [plenary.filetype](#plenaryfiletype)
- [plenary.strings](#plenarystrings)
### plenary.async
A Lua module for asynchronous programming using coroutines. This library is built on native lua coroutines and `libuv`. Coroutines make it easy to avoid callback hell and allow for easy cooperative concurrency and cancellation. Apart from allowing users to perform asynchronous io easily, this library also functions as an abstraction for coroutines.
#### Getting started
You can do
```lua
local async = require "plenary.async"
```
All other modules are automatically required and can be accessed by indexing `async`.
You needn't worry about performance as this will require all the submodules lazily.
#### A quick example
Libuv luv provides this example of reading a file.
```lua
local uv = vim.loop
local read_file = function(path, callback)
uv.fs_open(path, "r", 438, function(err, fd)
assert(not err, err)
uv.fs_fstat(fd, function(err, stat)
assert(not err, err)
uv.fs_read(fd, stat.size, 0, function(err, data)
assert(not err, err)
uv.fs_close(fd, function(err)
assert(not err, err)
callback(data)
end)
end)
end)
end)
end
```
We can write it using the library like this:
```lua
local a = require "plenary.async"
local read_file = function(path)
local err, fd = a.uv.fs_open(path, "r", 438)
assert(not err, err)
local err, stat = a.uv.fs_fstat(fd)
assert(not err, err)
local err, data = a.uv.fs_read(fd, stat.size, 0)
assert(not err, err)
local err = a.uv.fs_close(fd)
assert(not err, err)
return data
end
```
#### Plugins using this
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- [vgit.nvim](https://github.com/tanvirtin/vgit.nvim)
- [neogit](https://github.com/TimUntersberger/neogit)
- [neo-tree.nvim](https://github.com/nvim-neo-tree/neo-tree.nvim)
### plenary.async_lib
Please use `plenary.async` instead. This was version 1 and is just here for compatibility reasons.
### plenary.async.control.channel.oneshot
Creates a oneshot channel. It can only send data one time.
The sender is not async while the receiver is.
Example:
```lua
local a = require'plenary.async'
local tx, rx = a.control.channel.oneshot()
a.run(function()
local ret = long_running_fn()
tx(ret)
end)
local ret = rx()
```
### plenary.async.control.channel.mpsc
Creates a multiple producer single consumer channel.
Example:
```lua
local a = require'plenary.async'
local sender, receiver = a.control.channel.mpsc()
a.run(function()
sender.send(10)
sender.send(20)
end)
a.run(function()
sender.send(30)
sender.send(40)
end)
for _ = 1, 4 do
local value = receiver.recv()
print('received:', value)
end
```
### plenary.job
A Lua module to interact with system processes. Pass in your `command`, the desired `args`, `env` and `cwd`.
Define optional callbacks for `on_stdout`, `on_stderr` and `on_exit` and `start` your Job.
Note: Each job has an empty environment.
```lua
local Job = require'plenary.job'
Job:new({
command = 'rg',
args = { '--files' },
cwd = '/usr/bin',
env = { ['a'] = 'b' },
on_exit = function(j, return_val)
print(return_val)
print(j:result())
end,
}):sync() -- or start()
```
### plenary.path
A Lua module that implements a bunch of the things from `pathlib` from Python, so that paths are easy to work with.
### plenary.scandir
`plenary.scandir` is fast recursive file operations. It is similar to unix `find` or `fd` in that it can do recursive scans over a given directory, or a set of directories.
It offers a wide range of opts for limiting the depth, show hidden and more. `plenary.scan_dir` can be ran synchronously and asynchronously and offers `on_insert(file, typ)` and `on_exit(files)` callbacks. `on_insert(file, typ)` is available for both while `on_exit(files)` is only available for async.
```lua
local scan = require'plenary.scandir'
scan.scan_dir('.', { hidden = true, depth = 2 })
```
This module also offers `ls -la` sync and async functions that will return a formated string for all files in the directory.
Why? Just for fun
### plenary.context_manager
Implements `with` and `open` just like in Python. For example:
```lua
local with = context_manager.with
local open = context_manager.open
local result = with(open("README.md"), function(reader)
return reader:read()
end)
assert(result == "# plenary.nvim")
```
### plenary.test_harness
`:help plenary-test`
Supports (simple) busted-style testing. It implements a mock-ed busted interface, that will allow you to run simple
busted style tests in separate neovim instances.
To run the current spec file in a floating window, you can use the keymap `<Plug>PlenaryTestFile`. For example:
```
nmap <leader>t <Plug>PlenaryTestFile
```
In this case, the test is run with a minimal configuration, that includes in
its runtimepath only plenary.nvim and the current working directory.
To run a whole directory from the command line, you could do something like:
```
nvim --headless -c "PlenaryBustedDirectory tests/plenary/ {options}"
```
Where the first argument is the directory you'd like to test. It will search for files with
the pattern `*_spec.lua` and execute them in separate neovim instances.
Without second argument, `PlenaryBustedDirectory` is also run with a minimal
configuration. Otherwise it is a Lua option table with the following fields:
- `nvim_cmd`: specify the command to launch this neovim instance (defaults to `vim.v.progpath`)
- `init`: specify an init.vim to use for this instance
- `minimal_init`: as for `init`, but also run the neovim instance with `--noplugin`
- `sequential`: whether to run tests sequentially (default is to run in parallel)
- `keep_going`: if `sequential`, whether to continue on test failure (default true)
- `timeout`: controls the maximum time allotted to each job in parallel or
sequential operation (defaults to 50,000 milliseconds)
The exit code is 0 when success and 1 when fail, so you can use it easily in a `Makefile`!
NOTE:
So far, the only supported busted items are:
- `describe`
- `it`
- `pending`
- `before_each`
- `after_each`
- `clear`
- `assert.*` etc. (from luassert, which is bundled)
OTHER NOTE:
We used to support `luaunit` and original `busted` but it turns out it was way too hard and not worthwhile
for the difficulty of getting them setup, particularly on other platforms or in CI. Now, we have a dep free
(or at least, no other installation steps necessary) `busted` implementation that can be used more easily.
Please take a look at the new APIs and make any issues for things that aren't clear. I am happy to fix them
and make it work well :)
OTHER OTHER NOTE:
Take a look at some test examples [here](TESTS_README.md).
#### Colors
You no longer need nvim-terminal to get this to work. We use `nvim_open_term` now.
### plenary.filetype
Will detect the filetype based on `extension`/`special filename`/`shebang` or `modeline`
- `require'plenary.filetype'.detect(filepath, opts)` is a function that does all of above and exits as soon as a filetype is found
- `require'plenary.filetype'.detect_from_extension(filepath)`
- `require'plenary.filetype'.detect_from_name(filepath)`
- `require'plenary.filetype'.detect_from_modeline(filepath)`
- `require'plenary.filetype'.detect_from_shebang(filepath)`
Add filetypes by creating a new file named `~/.config/nvim/data/plenary/filetypes/foo.lua` and register that file with
`:lua require'plenary.filetype'.add_file('foo')`. Content of the file should look like that:
```lua
return {
extension = {
-- extension = filetype
-- example:
['jl'] = 'julia',
},
file_name = {
-- special filenames, likes .bashrc
-- we provide a decent amount
-- name = filetype
-- example:
['.bashrc'] = 'bash',
},
shebang = {
-- Shebangs are supported as well. Currently we provide
-- sh, bash, zsh, python, perl with different prefixes like
-- /usr/bin, /bin/, /usr/bin/env, /bin/env
-- shebang = filetype
-- example:
['/usr/bin/node'] = 'javascript',
}
}
```
### plenary.strings
Re-implement VimL funcs to use them in Lua loop.
* `strings.strdisplaywidth`
* `strings.strcharpart`
And some other funcs are here to deal with common problems.
* `strings.truncate`
* `strings.align_str`
* `strings.dedent`
### plenary.profile
Thin wrapper around LuaJIT's [`jit.p` profiler](https://blast.hk/moonloader/luajit/ext_profiler.html).
```lua
require'plenary.profile'.start("profile.log")
-- code to be profiled
require'plenary.profile'.stop()
```
You can use `start("profile.log", {flame = true})` to output the log in a
flamegraph-compatible format. A flamegraph can be created from this using
https://github.com/jonhoo/inferno via
```
inferno-flamegraph profile.log > flame.svg
```
The resulting interactive SVG file can be viewed in any browser.
Status: WIP
### plenary.popup
See [popup documentation](./POPUP.md) for both progress tracking and implemented APIs.
### plenary.window
Window helper functions to wrap some of the more difficult cases. Particularly for floating windows.
Status: WIP
### plenary.collections
Contains pure lua implementations for various standard collections.
```lua
local List = require 'plenary.collections.py_list'
local myList = List { 9, 14, 32, 5 }
for i, v in myList:iter() do
print(i, v)
end
```
Status: WIP
### Troubleshooting
If you're having trouble / things are hanging / other problems:
```
$ export DEBUG_PLENARY=true
```
This will enable debugging for the plugin.
### plenary.neorocks
DELETED: Please use packer.nvim or other lua-rocks wrapper instead. This no longer exists.
### FAQ
1. Error: Too many open files
- \*nix systems have a setting to configure the maximum amount of open file
handles. It can occur that the default value is pretty low and that you end up
getting this error after opening a couple of files. On Linux you can see the
current limit with `ulimit -n` and set it with `ulimit -n 4096`. If you're on
macOS the command is `sudo launchctl limit maxfiles 4096 4096`.