diff --git a/README.md b/README.md new file mode 100644 index 0000000..335be08 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# vimdowner - A markdown to vim help text converter + +# Usage +``` +vimdowner [OPTIONS...] files...(default: 'README.md') + -m MODULE NAME --module-name=MODULE NAME Name of the library module + -o FILEPATH --output-path=FILEPATH Output of generated docs (default: './doc/') + -d --debug Print debug info + -u --unicode Enable Unicode Characters + -T TEXT --tagline=TEXT Tagline of the module + -l LENGTH --line-break-length=LENGTH Length of line breaks (default: 120) + --stdout-only Send output to STDOUT only + --no-toc Do not add a Table of Contents +``` + +# Sample + ![](img/2022-07-18-17-17-19.png) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..b35841b --- /dev/null +++ b/examples/README.md @@ -0,0 +1,335 @@ +# 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 + +```vim +Plug 'nvim-lua/plenary.nvim' +``` + +## Modules + +- `plenary.async` +- `plenary.async_lib` +- `plenary.job` +- `plenary.path` +- `plenary.scandir` +- `plenary.context_manager` +- `plenary.test_harness` +- `plenary.filetype` +- `plenary.strings` + +### 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) +- [gitsigns.nvim](https://github.com/lewis6991/gitsigns.nvim) +- [vgit.nvim](https://github.com/tanvirtin/vgit.nvim) +- [neogit](https://github.com/TimUntersberger/neogit) + +### plenary.async_lib + +Please use `plenary.async` instead. This was version 1 and is just here for compatibility reasons. + +### 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 + +`plenery.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 + +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 `PlenaryTestFile`. For example: + +``` +nmap t PlenaryTestFile +``` + +To run a whole directory from the command line, you could do something like: + +``` +nvim --headless -c "PlenaryBustedDirectory tests/plenary/ {minimal_init = 'tests/minimal_init.vim'}" +``` + +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. + +The second argument is a Lua option table with the following fields: +- `minimal_init`: specify an init.vim to use for this instance, uses `--noplugin` +- `minimal`: uses `--noplugin` without an init script (overrides `minimal_init`) +- `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 debuggin 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. You can see the + current limit with `ulimit -n` and set it with `ulimit -n 4096`. (macos might + work different) diff --git a/examples/doc/plenary.txt b/examples/doc/plenary.txt new file mode 100644 index 0000000..c950c70 --- /dev/null +++ b/examples/doc/plenary.txt @@ -0,0 +1,408 @@ +plenary.txt All the lua functions I don't want to write twice. + +==================================================================================================== + +==================================================================================================== +plenary.vim *PLENARY.VIM-CONTENTS* + +1. Installation |Installation| +2. Modules |Modules| +3. plenary.async |plenary.async| +4. plenary.async_lib |plenary.async_lib| +5. plenary.job |plenary.job| +6. plenary.path |plenary.path| +7. plenary.scandir |plenary.scandir| +8. plenary.context_manager |plenary.context_manager| +9. plenary.test_harness |plenary.test_harness| +10. plenary.filetype |plenary.filetype| +11. plenary.strings |plenary.strings| +12. plenary.profile |plenary.profile| +13. plenary.popup |plenary.popup| +14. plenary.window |plenary.window| +15. plenary.collections |plenary.collections| +16. Troubleshooting |Troubleshooting| +17. plenary.neorocks |plenary.neorocks| +18. FAQ |FAQ| + +│ 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 *Installation* + + > + Plug 'nvim-lua/plenary.nvim' +< + +---------------------------------------------------------------------------------------------------- +Modules *Modules* + + - `plenary.async` + - `plenary.async_lib` + - `plenary.job` + - `plenary.path` + - `plenary.scandir` + - `plenary.context_manager` + - `plenary.test_harness` + - `plenary.filetype` + - `plenary.strings` + +plenary.async *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 *Getting-started* + + You can do + + > + 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 *A-quick-example* + + Libuv luv provides this example of reading a file. + + > + 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: + + > + 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 *Plugins-using-this* + - telescope.nvim: (https://github.com/nvim-telescope/telescope.nvim) + - gitsigns.nvim: (https://github.com/lewis6991/gitsigns.nvim) + - vgit.nvim: (https://github.com/tanvirtin/vgit.nvim) + - neogit: (https://github.com/TimUntersberger/neogit) + +plenary.async_lib *plenary.async_lib* + + Please use `plenary.async` instead. This was version 1 and is just here for compatibility + reasons. + +plenary.job *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. + + > + 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 *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* + + `plenery.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. + + > + 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 *plenary.context_manager* + + Implements `with` and `open` just like in Python. For example: + + > + 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 *plenary.test_harness* + + 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 + `PlenaryTestFile`. For example: + + > + nmap t PlenaryTestFile +< + + + To run a whole directory from the command line, you could do something like: + + > + nvim --headless -c "PlenaryBustedDirectory tests/plenary/ {minimal_init = 'tests/minimal_init.vim'}" +< + + + 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. + + + The second argument is a Lua option table with the following fields: + + - `minimal_init`: specify an init.vim to use for this instance, uses `--noplugin` + - `minimal`: uses `--noplugin` without an init script (overrides `minimal_init`) + - `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 *Colors* + + You no longer need nvim-terminal to get this to work. We use `nvim_open_term` now. + +plenary.filetype *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: + + > + 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 *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 *plenary.profile* + + Thin wrapper around LuaJIT's `jit.p` profiler: + (https://blast.hk/moonloader/luajit/ext_profiler.html). + + > + 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 *plenary.popup* + + See popup documentation: (./POPUP.md) for both progress tracking and implemented APIs. + +plenary.window *plenary.window* + + Window helper functions to wrap some of the more difficult cases. Particularly for floating + windows. + + + Status: WIP + +plenary.collections *plenary.collections* + + Contains pure lua implementations for various standard collections. + + > + 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 *Troubleshooting* + + If you're having trouble / things are hanging / other problems: + + > + $ export DEBUG_PLENARY=true +< + + + This will enable debuggin for the plugin. + +plenary.neorocks *plenary.neorocks* + + DELETED: Please use packer.nvim or other lua-rocks wrapper instead. This no longer exists. + +FAQ *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. You can see the current limit with `ulimit -n` and set it with `ulimit -n 4096`. (macos might +work different) + + +vim:tw=78:ts=8:ft=help:norl: diff --git a/examples/doc/tags b/examples/doc/tags new file mode 100644 index 0000000..88dd037 --- /dev/null +++ b/examples/doc/tags @@ -0,0 +1,18 @@ +Installation plenary.vim /*Installation* +Modules plenary.vim /*Modules* +plenary.async plenary.vim /*plenary.async* +plenary.async_lib plenary.vim /*plenary.async_lib* +plenary.job plenary.vim /*plenary.job* +plenary.path plenary.vim /*plenary.path* +plenary.scandir plenary.vim /*plenary.scandir* +plenary.context_manager plenary.vim /*plenary.context_manager* +plenary.test_harness plenary.vim /*plenary.test_harness* +plenary.filetype plenary.vim /*plenary.filetype* +plenary.strings plenary.vim /*plenary.strings* +plenary.profile plenary.vim /*plenary.profile* +plenary.popup plenary.vim /*plenary.popup* +plenary.window plenary.vim /*plenary.window* +plenary.collections plenary.vim /*plenary.collections* +Troubleshooting plenary.vim /*Troubleshooting* +plenary.neorocks plenary.vim /*plenary.neorocks* +FAQ plenary.vim /*FAQ* diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a28b911 --- /dev/null +++ b/flake.lock @@ -0,0 +1,436 @@ +{ + "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1640353650, + "narHash": "sha256-N1t6M3/wqj90AEdRkeC8i923gQYUpzSr8b40qVOZ1Rk=", + "owner": "haskell", + "repo": "cabal", + "rev": "942639c18c0cd8ec53e0a6f8d120091af35312cd", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1641652457, + "narHash": "sha256-BlFPKP4C4HRUJeAbdembX1Rms1LD380q9s0qVDeoAak=", + "owner": "haskell", + "repo": "cabal", + "rev": "f27667f8ec360c475027dcaee0138c937477b070", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1656928814, + "narHash": "sha256-RIFfgBuKz6Hp89yRr7+NR5tzIAbn52h8vT6vXkYjZoM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "7e2a3b3dfd9af950a856d66b0a7d01e3c18aa249", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1658106754, + "narHash": "sha256-rYxCkPJwyRuUJVw/XXqXHzqHZ4DKYcOQKKmTzVF/8Dc=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "a5393328352ea96bf4be2c78b8cac2478fec9de9", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskellNix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-utils": "flake-utils_2", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "hackage": "hackage", + "hpc-coveralls": "hpc-coveralls", + "hydra": "hydra", + "nix-tools": "nix-tools", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-2205": "nixpkgs-2205", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1658106909, + "narHash": "sha256-eQso2VHbQBxGBKE+OR27EjWdpAHNsiDvSE0MUPwk3BI=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "8955cbd1e12773e0b4a34f8e8924b0988ddfe65a", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "hydra": { + "inputs": { + "nix": "nix", + "nixpkgs": [ + "haskellNix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1646878427, + "narHash": "sha256-KtbrofMtN8GlM7D+n90kixr7QpSlVmdN+vK5CA/aRzc=", + "owner": "NixOS", + "repo": "hydra", + "rev": "28b682b85b7efc5cf7974065792a1f22203a5927", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1643066034, + "narHash": "sha256-xEPeMcNJVOeZtoN+d+aRwolpW8mFSEQx76HTRdlhPhg=", + "owner": "NixOS", + "repo": "nix", + "rev": "a1cd7e58606a41fcf62bf8637804cf8306f17f62", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.6.0", + "repo": "nix", + "type": "github" + } + }, + "nix-tools": { + "flake": false, + "locked": { + "lastModified": 1649424170, + "narHash": "sha256-XgKXWispvv5RCvZzPb+p7e6Hy3LMuRjafKMl7kXzxGw=", + "owner": "input-output-hk", + "repo": "nix-tools", + "rev": "e109c94016e3b6e0db7ed413c793e2d4bdb24aa7", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "nix-tools", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1632864508, + "narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "82891b5e2c2359d7e58d08849e4c89511ab94234", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.05-small", + "type": "indirect" + } + }, + "nixpkgs-2003": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1655034179, + "narHash": "sha256-rf1/7AbzuYDw6+8Xvvf3PtEOygymLBrFsFxvext5ZjI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "046ee4af7a9f016a364f8f78eeaa356ba524ac31", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1656782578, + "narHash": "sha256-1eMCBEqJplPotTo/SZ/t5HU6Sf2I8qKlZi9MX7jv9fw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "573603b7fdb9feb0eb8efc16ee18a015c667ab1b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205": { + "locked": { + "lastModified": 1657876628, + "narHash": "sha256-URmf0O2cQ/3heg2DJOeLyU/JmfVMqG4X5t9crQXMaeY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "549d82bdd40f760a438c3c3497c1c61160f3de55", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "indirect" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1657888067, + "narHash": "sha256-GnwJoFBTPfW3+mz7QEeJEEQ9OMHZOiIJ/qDhZxrlKh8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "65fae659e31098ca4ac825a6fef26d890aaf3f4e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "haskellNix": "haskellNix", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ] + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1658106847, + "narHash": "sha256-xcq/FgP1eNxaq7BaI+k0bkXfy+MFGib5I44VGGFQZdQ=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "0fbfc3a3fb735e6bd5c81f614d8ed5308e501496", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..6cdc911 --- /dev/null +++ b/flake.nix @@ -0,0 +1,39 @@ +{ + description = "A Markdown to Vim Help Text converter"; + inputs = { + haskellNix.url = "github:input-output-hk/haskell.nix"; + nixpkgs.follows = "haskellNix/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, haskellNix }: + flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ] (system: + let + overlays = [ + haskellNix.overlay + (final: prev: { + # This overlay adds our project to pkgs + vimdowner = + final.haskell-nix.project' { + src = ./.; + compiler-nix-name = "ghc902"; + shell.tools = { + cabal = { }; + hlint = { }; + haskell-language-server = { }; + }; + + shell.buildInputs = with pkgs; [ + nixpkgs-fmt + ]; + + + }; + }) + ]; + pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; }; + flake = pkgs.vimdowner.flake {}; + in + flake // { + }); +} diff --git a/img/2022-07-18-17-17-19.png b/img/2022-07-18-17-17-19.png new file mode 100644 index 0000000..0fca5ac Binary files /dev/null and b/img/2022-07-18-17-17-19.png differ diff --git a/md-minimal.md b/md-minimal.md deleted file mode 100644 index 137e82e..0000000 --- a/md-minimal.md +++ /dev/null @@ -1,18 +0,0 @@ -# plenary.nvim -All the lua functions I don't want to write twice. - -# func 1 -sample - -> plenary: -> -> full; complete; entire; absolute; unqualified. - - -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 - -```vim -Plug 'nvim-lua/plenary.nvim' -``` diff --git a/md-sample.md b/md-sample.md deleted file mode 100644 index 3885460..0000000 --- a/md-sample.md +++ /dev/null @@ -1,157 +0,0 @@ -An h1 header -============ - -Paragraphs are separated by a blank line. - - -# Ofcourse it is -2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists -look like: - - * this one - * that one - * the other one - -Note that --- not considering the asterisk --- the actual text -content starts at 4-columns in. - -> Block quotes are -> written like so. -> -> They can span multiple paragraphs, -> if you like. - -Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all -in chapters 12--14"). Three dots ... will be converted to an ellipsis. -Unicode is supported. ☺ - - - -An h2 header ------------- - -Here's a numbered list: - - 1. first item - 2. second item - 3. third item - -Note again how the actual text starts at 4 columns in (4 characters -from the left side). Here's a code sample: - - # Let me re-iterate ... - for i in 1 .. 10 { do-something(i) } - -As you probably guessed, indented 4 spaces. By the way, instead of -indenting the block, you can use delimited blocks, if you like: - -~~~ -define foobar() { - print "Welcome to flavor country!"; -} -~~~ - -(which makes copying & pasting easier). You can optionally mark the -delimited block for Pandoc to syntax highlight it: - -~~~python -import time -# Quick, count to ten! -for i in range(10): - # (but not *too* quick) - time.sleep(0.5) - print i -~~~ - - - -### An h3 header ### - -Now a nested list: - - 1. First, get these ingredients: - - * carrots - * celery - * lentils - - 2. Boil some water. - - 3. Dump everything in the pot and follow - this algorithm: - - find wooden spoon - uncover pot - stir - cover pot - balance wooden spoon precariously on pot handle - wait 10 minutes - goto first step (or shut off burner when done) - - Do not bump wooden spoon or it will fall. - -Notice again how text always lines up on 4-space indents (including -that last line which continues item 3 above). - -Here's a link to [a website](http://foo.bar), to a [local -doc](local-doc.html), and to a [section heading in the current -doc](#an-h2-header). Here's a footnote [^1]. - -[^1]: Footnote text goes here. - -Tables can look like this: - -| Item | Price | # In stock | -|--------------|:----------|:----------:| -| Juicy Apples | 1.99 | *7* | -| Bananas | **1.89** | 5234 | -| asdasd | **4.89** | 2394 | -| kjkjklj | **2332** | 0994 | - -Table: Shoes, their sizes, and what they're made of - -(The above is the caption for the table.) Pandoc also supports -multi-line tables: - -|keyword |text -|--------|----------------------- -|red |Sunsets, apples, and -| |other red or reddish -| |things. -|green |Leaves, grass, frogs -| |and other things it's -| |not easy being. - -A horizontal rule follows. - -*** - -Here's a definition list: - -apples - : Good for making applesauce. -oranges - : Citrus! -tomatoes - : There's no "e" in tomatoe. - -Again, text is indented 4 spaces. (Put a blank line between each -term/definition pair to spread things out more.) - -Here's a "line block": - -| Line one -| Line too -| Line tree - -and images can be specified like so: - -![example image](example-image.jpg "An exemplary image") - -Inline math equations go in like so: $\omega = d\phi / dt$. Display -math should get its own line and be put in in double-dollarsigns: - -$$I = \int \rho R^{2} dV$$ - -And note that you can backslash-escape any punctuation characters -which you wish to be displayed literally, ex.: \`foo\`, \*bar\*, etc. diff --git a/src/Filetype.hs b/src/Filetype.hs index 5a4612c..8435687 100644 --- a/src/Filetype.hs +++ b/src/Filetype.hs @@ -1,3 +1,2 @@ module Filetype where -import qualified Data.Text as T diff --git a/src/Main.hs b/src/Main.hs index 9a4fc2c..53ef97f 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -12,23 +12,19 @@ import Control.Lens import qualified Data.Text as T import qualified Data.Text.IO as T -import qualified System.Console.Terminal.Size as Term import System.Directory import System.FilePath.Posix -import Control.Applicative import Control.Arrow import Control.Monad -import Data.Function import Data.List import qualified Data.List.NonEmpty as L import Data.Maybe import Numeric.Natural import System.Console.GetOpt -import System.Environment -import System.IO import Text.Printf +import System.Environment import Text.Read @@ -40,6 +36,7 @@ import Util data Flags = Flags { _files :: [FilePath] + , _outputPath :: FilePath , _debug :: Bool , _breakLen :: Natural , _stdoutOnly :: Bool @@ -47,6 +44,7 @@ data Flags = Flags , _unicode :: Bool , _moduleName :: String , _tagLine :: T.Text + , _noToc :: Bool } deriving Show @@ -59,6 +57,8 @@ defaultFlags = Flags { _files = [] , _unicode = False , _moduleName = "" , _tagLine = "" + , _noToc = False + , _outputPath = "doc" } makeLenses ''Flags @@ -69,6 +69,10 @@ options = [ ["module-name"] (ReqArg (moduleName .~) "MODULE NAME") "Name of the library module" + , Option ['o'] + ["output-path"] + (ReqArg (moduleName .~) "FILEPATH") + "Output of generated docs (default: './doc/')" , Option ['d'] ["debug"] (NoArg (debug .~ True)) "Print debug info" , Option ['u'] ["unicode"] (NoArg (unicode .~ True)) "Enable Unicode Characters" , Option ['T'] @@ -86,6 +90,7 @@ options = [ ) "Length of line breaks (default: 120)" , Option [] ["stdout-only"] (NoArg (stdoutOnly .~ True)) "Send output to STDOUT only" + , Option [] ["no-toc"] (NoArg (noToc .~ True)) "Do not add a Table of Contents" ] compileOpts :: [String] -> IO (Flags, [String]) @@ -93,7 +98,7 @@ compileOpts argv = do case getOpt RequireOrder options argv of (flags, args, [] ) -> return (foldl (flip id) defaultFlags flags, args) (_ , _ , errs) -> ioError (userError (concat errs ++ usageInfo header options)) - where header = "Usage: vimHelpGen [OPTIONS...] files...(default: 'README.md')" + where header = "Usage: vimdowner [OPTIONS...] files...(default: 'README.md')" unAbbr :: String -> String unAbbr = \case @@ -110,11 +115,10 @@ main = do -- Checks for a lua directory and chooses one of the available folders modName <- if null $ flags ^. moduleName then - (\xs -> choose (L.fromList xs) "Choose name of module: ") - =<< ( listDirectory "." - >>= maybe (return mempty) listDirectory - . ((== "lua") `find`) - ) + (\xs -> if null xs + then ioError (userError "No 'lua/' directory found and no `--module` argument provided") + else choose (L.fromList xs) "Choose name of module: ") + =<< (listDirectory "." >>= maybe (return mempty) listDirectory . ((== "lua") `find`)) else return [] return -- For processing arguments after Parsing @@ -134,14 +138,17 @@ main = do , V._breakText = flags ^. breakText , V._tagLine = flags ^. tagLine , V._unicode = flags ^. unicode + , V._nested = False + , V._noTOC = flags ^. noToc } let output (helpTxt, tags) = if flags ^. stdoutOnly then mapM_ T.putStrLn [helpTxt, tags] else do - createDirectoryIfMissing True "doc/" - T.writeFile (("doc/"++) $ (`replaceExtensions` "txt") $ flags ^. moduleName) helpTxt - T.writeFile "doc/tags" tags + let docPath = mappend ((flags ^. outputPath) <> "/") + createDirectoryIfMissing True (docPath "") + T.writeFile ((docPath "" ++) $ (`replaceExtensions` "txt") $ flags ^. moduleName) helpTxt + T.writeFile (docPath "tags") tags case fileType of "markdown" -> T.readFile file >>= output . M.converter convertInfo diff --git a/src/Markdown.hs b/src/Markdown.hs index 8e86996..e88aba9 100644 --- a/src/Markdown.hs +++ b/src/Markdown.hs @@ -11,322 +11,229 @@ import qualified Control.Monad.State.Lazy as ST import qualified Data.Text as T import System.FilePath.Posix -import Control.Arrow -import Data.Bits ( Bits(xor) ) -import Data.Char import Data.Function -import GHC.Read -import Text.Printf -import Text.Read import Data.List import Data.Maybe -import GHC.IO -import Numeric.Natural import VimHelpSyntax import Util -import Data.Traversable -log' :: Show a => a -> a -log' x = unsafePerformIO $ print x >> return x - -logIf :: Show a => Bool -> a -> a -logIf True x = log' x -logIf False x = x - -logWith :: (Show a, Show b) => b -> a -> a -logWith b a = unsafePerformIO $ print a >> print b >> return a - -logPass :: (Show a) => a -> b -> b -logPass a b = unsafePerformIO $ print a >> return b - nodesToVimHelp :: [Node] -> ST.State ConvertInfo [T.Text] ---nodesToVimHelp (x: (Node _ SOFTBREAK _): xs) = - --(ix 0 %~) - -- <$> ((<>) . (<> " ") . head <$> nodesToVimHelp [x]) -- Becomes equal to (<> (x <> " ")) - -- <*> nodesToVimHelp xs - ---nodesToVimHelp ((Node _ _) : xs) = do - --x <- ST.get <&> (`T.replicate` "=") . fromIntegral . _lineBreakLength - --(x :) <$> nodesToVimHelp xs - ---nodesToVimHelp ((Node _ (HEADING level) conts) : xs) = do - --(headerText, tagText) <- case conts of - --[] -> return ("", Nothing) - --[Node _ (TEXT text) conts, Node _ (HTML_INLINE tag) _] -> - --return (text, T.strip <$> (T.stripSuffix "-->" =<< T.stripPrefix "" =<< T.stripPrefix "" =<< T.stripPrefix "