pianocomposer321 / yabs.nvim Goto Github PK
View Code? Open in Web Editor NEWYet Another Build System/Code Runner for Neovim, written in lua
License: GNU Affero General Public License v3.0
Yet Another Build System/Code Runner for Neovim, written in lua
License: GNU Affero General Public License v3.0
When I use output = "quickfix", I got the following error:
Error executing lua .vim\plugged\yabs.nvim\lua\yabs\util.lua:58: bad argument #1 to 'new_pipe' (boolean expected, got no value)
I am using this config:
python = {
tasks = {
run = {
command = "dtx-env\Scripts\python %",
output = "quickfix",
}
},
},
on neovim 5.1 on windows 10.
My guess that this is related to windows, hence the title.
P.S. Great plugin! I am using it even without quickfix.
What i am trying to say is, basically let's say i'm building a GUI app getting the output of that app inside a neovim buffer is not exactly what i would want, what i would like instead is starting the GUI app.
Kinda like how IDEs like Visual Studio/Jetbrains etc do.
I have the following error:
Error executing lua ...nvim/pack/plugins/start/yabs.nvim/lua/yabs/task/init.lua:41: Vim(luafile):E5113: Error while calling lua chunk: ...nfig/nvim/pack/plugins/start/yabs.nvim/lua/yabs/init.lua:42: bad argument #1 to 'pairs' (table expected, got nil)
with the following configuration:
require('yabs'):setup({
tasks = {
build = {
command = 'echo 1',
output = 'quickfix',
},
},
})
I am working on neovim-cmake for working with CMake project. I am currently using Asynctaks to run / build the selected target. But I would like to switch from Asynctasks to yabs as a dependency for my plugin to avoid having two similar plugins (right now I using yabs in my configuration).
Could you add an API to run a command using Yabs?
Instead of having just one command to run with require(“yabs”):build()
, I would like to have multiple “tasks” available to run, a la vscode or asynctasks.vim. Setup would look something like this:
require(“yabs”):setup {
languages = {
cpp = {
default_task = “build&run”,
tasks = {
build = {
command = “g++ main.cpp -std=c++17 -o main”,
output = “quickfix”
},
run = {
command = “./main”
output = “terminal”
}
}
}
}
}
To run a task, you would do something like require(“yabs”):run_task(“build”)
. There may be some special syntax available to run more than one task, similar to the shell &&
. So to build and run, maybe something like require(“yabs”):run_task(“build&run”)
. If this feature is implemented, it would likely have some sort of error checking so that if one command fails, subsequent ones are not run anyway.
Probably there would be a way to set global tasks, which would be useful in a .yabs
file. These would override the language-specific ones in that project.
.yabs
file to .yabs.json
Having a file automatically detected and run as a lua script is a potential security risk. Making the config file a json file instead would alleviate that, but could require some luarocks dependencies, which is something I have yet to look into, or require the use of some more obscure vim functions, which may not be very easy to work with from lua.
CC: @Shatur, Ref: #3 (comment)
For languages like CPP and Python many tasks do not depend on the language, but on the chosen infrastructure (e.g., CMake vs Make vs Meson and Poetry / Pipenv). Generally each of these file has its own configuration file placed in the project directory. The same is true for a lot of other tools such as formatters, linters, and testers.
For these applications it would be great to make tasks available when their configuration files are found. This ensures they do not have to be defined when not possible, but they can be shared even between different languages.
P.S. This neovim plugin was really missing in my setup, and I'm really enjoying it so far. I hope you don't mind it I create a few issues with features that I would love to have.
Basically the mechanics used in asynctask.vim. They have strings to detect project roots(we may also have functions), user can also specify whether to run under curent dir, or file's directory, or project's root.
I have a couple of "random" suggestions that I think may help improve this project:
doctoc
hat is useful for automatically generating such tables.(btw https://github.com/casey/just)
the .yabs
file is interesting but its specific to this plugin, a more compatible method would be to gather tasks from common build systems.
cmake, make, just, npm, meson, etc
All this commands should have some way of running them to get a list of targets/tasks. We could create an even more flexible system where users register commands to run and some simple parsing function to extract a list of tasks and commands.
What do you think about this idea?
Full error
Error executing luv callback:
vim/shared.lua:0: E5560: vimL function must not be called in a lua loop callback
stack traceback:
[C]: at 0x55e8668c1030
vim/shared.lua: in function 'tbl_map'
...b/.local/share/nvim/plugged/yabs.nvim/lua/yabs/utils.lua:6: in function 'expand'
...eb/.local/share/nvim/plugged/yabs.nvim/lua/yabs/task.lua:55: in function 'run'
...local/share/nvim/plugged/yabs.nvim/lua/yabs/language.lua:89: in function 'run_task'
[string ":lua"]:18: in function '_user_on_exit'
...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:243: in function '_shutdown'
...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:46: in function <...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:37>
[C]: in function 'nvim_command'
...are/nvim/plugged/yabs.nvim/lua/yabs/outputs/quickfix.lua:11: in function ''
vim/_editor.lua: in function <vim/_editor.lua:0>
My config
require('yabs'):setup({
languages = {
cs = {
tasks = {
build = {
command = "dotnet build",
output = "quickfix",
},
run = {
command = "./bin/Debug/net6.0/example",
condition = require("yabs.conditions").file_exists(".vimspector.json"),
},
build_and_run = {
command = function()
require("yabs"):run_task("build", {
on_exit = function(Job, exit_code)
if exit_code == 0 then
require("yabs").languages.cs:run_task("run")
end
end,
})
end,
type = "lua",
condition = require("yabs.conditions").file_exists(".vimspector.json"),
},
},
},
},
})
This just happens when I run :lua require("yabs"):run_task("build_and_run")
I basically copied this from the example config so I have no idea why it's unable to execute the run task. Building works just fine though.
Hi! Thank you a lot for you plugin!
I have a suggestion. There is asynctasks.vim and it allows to display the output directly in quickfix. It's super useful because you allows to navigate errors directly. It would be nice to have the ability to use a quickfix instead of consolation.nvim
when you build something that can be used for error navigation.
Hello!
Thank you for this great plugin!
the following is my setup file for cpp:
local cpp_config = {
default_task = "build_and_run",
tasks = {
build = {
command = function()
return "g++ -std=c++11 "
.. vim.fn.expand("%:t")
.. " -Wall -ggdb -o "
.. vim.fn.expand("%:t:r")
.. ".out"
end,
output = "quickfix",
opts = { open_on_run = "auto" },
},
run = {
command = function()
return "time ./" .. vim.fn.expand("%:t:r") .. ".out"
end,
output = "terminal",
},
},
}
require("yabs"):setup({
languages = {
cpp = cpp_config,
},
})
Everything works fine,
but when a file is compiled, I sometimes don't know if the build is done or not, especially when there are no warnings at all.
I expect it can :
Thank you!
The following configuration:
require('yabs'):setup({
tasks = {
build = {
command = 'echo 1',
output = 'quickfix',
},
run = {
command = 'echo 2',
output = 'quickfix',
},
},
})
Causes E5108: Error executing lua ...ns/start/yabs.nvim/lua/yabs/defaults/output/quickfix.lua:21: attempt to index field 'output_types' (a nil value)
As discussed here, I believe it would be convenient for several of us more "old school" neovim users to have a vimscript based API. Something like:
Plug 'pianocomposer321/yabs.nvim'
" Perhaps something like this
" (Or config through json file?)
let g:yabs_config = {
\ 'languages': {
\ 'rust': ...
\ }
\}
nmap ... <plug>(yabs-run-default-task)
nnoremap ... :call yabs#run_task('build')<cr>
nnoremap ... :call yabs#run_command(...)<cr>
Full error
Error executing luv callback:
...eb/.local/share/nvim/plugged/yabs.nvim/lua/yabs/init.lua:91: E5560: nvim_buf_get_option must not be called in a lua loop callback
stack traceback:
[C]: in function '__index'
...eb/.local/share/nvim/plugged/yabs.nvim/lua/yabs/init.lua:91: in function 'get_current_language'
...eb/.local/share/nvim/plugged/yabs.nvim/lua/yabs/init.lua:157: in function 'run_task'
[string ":lua"]:31: in function '_user_on_exit'
...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:243: in function '_shutdown'
...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:46: in function <...ocal/share/nvim/plugged/plenary.nvim/lua/plenary/job.lua:37>
[C]: in function 'nvim_command'
...are/nvim/plugged/yabs.nvim/lua/yabs/outputs/quickfix.lua:11: in function ''
vim/_editor.lua: in function <vim/_editor.lua:0>
My config
require('yabs'):setup({
languages = { -- List of languages in vim's `filetype` format
cs = {
tasks = {
build = {
command = "dotnet build",
output = "quickfix",
},
},
},
rust = {
tasks = {
build = {
command = "cargo build",
output = "quickfix",
},
},
},
},
tasks = {
run = {
command = "call vimspector#Continue()",
type = "vim",
condition = require("yabs.conditions").file_exists(".vimspector.json"),
},
build_and_run = {
command = function()
require("yabs"):run_task("build", {
on_exit = function(Job, exit_code)
if exit_code == 0 then
require("yabs"):run_task("run")
end
end,
})
end,
type = "lua",
condition = require("yabs.conditions").file_exists(".vimspector.json"),
},
},
})
Another issue with the callbacks. This time I'm not sure if it's my config and I just overlooked something. I've tried changing stuff around but it keeps going back to that error so I'm guessing it's something to do with global tasks since that's the same function in build_and_run
as I had before in cs where it was working fine.
For example, some build tools may not output the compile output to the standard output. Instead it might write it to a file. On such scenario we many need to finish the build command first and then check the status of the build and then run another task which reads the error file and redirect it as the output
Is there an easy way to do it under current framework?
I've been playing with the rewrite and was struggling with the cryptic error attempt to index a nil value
. After some digging, I came to realize it's because there are no runners or outputs registered by default, and the built in ones have to be registered with register_runner
and register-output
. I think it would be a good idea to have the default runners and outputs already registered, but wasn't sure how you wanted to approach this.
If I try to get the task list (:Telescope yabs tasks
) for a file without tasks, I get the following error:
Error executing lua ...nfig/nvim/pack/plugins/start/yabs.nvim/lua/yabs/init.lua:80: attempt to index a nil value
Hi, I am setting up the configuration for this amazing plugin but I ran into an issue where if I run a chained task that consist of a build and a run task(which is run after the build task is finished) I get this error.
build_and_run
is the chained task in question.
Running NVIM v0.6.1, thanks.
Error executing luv callback:
vim/shared.lua:191: E5560: vimL function must not be called in a lua loop callback
stack traceback:
[C]: in function 'func'
vim/shared.lua:191: in function 'tbl_map'
...nvim/site/pack/packer/start/yabs.nvim/lua/yabs/utils.lua:6: in function 'expand'
.../nvim/site/pack/packer/start/yabs.nvim/lua/yabs/task.lua:55: in function 'run'
...m/site/pack/packer/start/yabs.nvim/lua/yabs/language.lua:89: in function 'run_task'
[string "..."]: in function '_user_on_exit'
.../site/pack/packer/start/plenary.nvim/lua/plenary/job.lua:243: in function '_shutdown'
.../site/pack/packer/start/plenary.nvim/lua/plenary/job.lua:46: in function <.../site/pack/packer/start/plenary.nvim/lua/plenary/job.lua:37>
[C]: in function 'setqflist'
...ack/packer/start/yabs.nvim/lua/yabs/outputs/quickfix.lua:9: in function 'cb'
vim.lua:285: in function <vim.lua:285>
Here is my configuration.
{
'pianocomposer321/yabs.nvim',
requires = { 'nvim-lua/plenary.nvim' },
config = function ()
require('yabs'):setup({
languages = { -- List of languages in vim's `filetype` format
cpp = {
default_task = 'build_and_run',
tasks = {
build = {
command = 'make -j12',
output = 'quickfix', -- Where to show output of the
-- command. Can be `buffer`,
-- `consolation`, `echo`,
-- `quickfix`, `terminal`, or `none`
opts = { -- Options for output (currently, there's only
-- `open_on_run`, which defines the behavior
-- for the quickfix list opening) (can be
-- `never`, `always`, or `auto`, the default)
open_on_run = 'never',
},
},
run = { -- You can specify as many tasks as you want per
-- filetype
command = './build/izg_lab_02',
output = 'quickfix',
opts = { -- Options for output (currently, there's only
-- `open_on_run`, which defines the behavior
-- for the quickfix list opening) (can be
-- `never`, `always`, or `auto`, the default)
open_on_run = 'never',
}
},
build_and_run = { -- Setting the type to lua means the command
-- is a lua function
command = function()
-- The following api can be used to run a task when a
-- previous one finishes
-- WARNING: this api is experimental and subject to
-- changes
require('yabs'):run_task('build', {
-- Job here is a plenary.job object that represents
-- the finished task, read more about it here:
-- https://github.com/nvim-lua/plenary.nvim#plenaryjob
on_exit = function(Job, exit_code)
-- The parameters `Job` and `exit_code` are optional,
-- you can omit extra arguments or
-- skip some of them using _ for the name
if exit_code == 0 then
require('yabs').languages.cpp:run_task('run')
end
end,
})
end,
type = 'lua',
output = 'quickfix',
opts = { -- Options for output (currently, there's only
-- `open_on_run`, which defines the behavior
-- for the quickfix list opening) (can be
-- `never`, `always`, or `auto`, the default)
open_on_run = 'never',
}
},
},
},
},
-- tasks = { -- Same values as `language.tasks`, but global
-- build = {
-- command = 'echo building project...',
-- output = 'terminal',
-- },
-- run = {
-- command = 'echo running project...',
-- output = 'echo',
-- },
-- optional = {
-- command = 'echo runs on condition',
-- -- You can specify a condition which determines whether to enable a
-- -- specific task
-- -- It should be a function that returns boolean,
-- -- not a boolean directly
-- -- Here we use a helper from yabs that returns such function
-- -- to check if the files exists
-- condition = require('yabs.conditions').file_exists('filename.txt'),
-- },
-- },
-- opts = { -- Same values as `language.opts`
-- output_types = {
-- quickfix = {
-- open_on_run = 'always',
-- },
-- },
-- },
})
end
},
As you may know, the vim.lsp.diagnostic
module was recently moved to vim.diagnostic
so that other sources can use the same interface, and you can interact with them the way you did for vim.lsp.diagnostic
.
I think this plugin could output to vim.diagnostic
then we would get things like virtual text and vim.diagnostic.goto_next
etc
You've added good documentation in the README, but I think a mature Vim/neovim plugin should also be documented in the integrated help system. See :help help-writing
for related info.
I think this would make this plugin a lot more use friendly
Hey, I'm working on something similar to this, but instead of defining the tasks in lua code I'm defining them on yaml, something like this:
taskname:
command: make start
output: quickfix
env:
- ENV_VAR: value
This allow the user to define tasks specifics to a project or global, kind like asynctasks.vim. Do you think this would be useful to yabs?
Sometimes we want to improve on existing tasks in specific project, it would be handy if there's some kind of mechanics to generate a default one.
It's good to assign some task to autocmds, so user don't have to run them by hand. I assume such tasks should also be possible to specify in .yabs, so there should be some changes in this plugin I guess.
Telescope integration is cool, but some of us still linger in "the old ways". Perhaps you could make an fzf integration as well?
Probably allow the user to specify bot
, vert
etc in a config option somewhere
See #5 (comment):
I have 3 tasks for cpp: build, run and clean and default_task is { "build", "run", "clean" }. However it looks like they run out of order sometimes. i.e clean then run then build
This happens because the tasks, which are asynchronous by design, don’t wait for the previous ones to finish before starting. This means that if earlier commands take any amount of time to complete, subsequent ones will start before they are finished executing.
This is a very difficult problem, because the solution is different depending on the output type. Most of the output types use luv under the hood, but terminal
and consolation
do not. For those using luv, I could probably figure something out that would work for all of them, but that would not solve the problem for terminal outputs. It is possible that I could hack something together by checking the pids of the child processes of the terminals, but this is not without issues of its own (mostly portability). Not to mention, even if the hack did work (which is a big if), it wouldn’t solve the problem for user-defined outputs.
I’m really not sure how to go about solving this one. Short of a massive redesign of pretty much the entire plugin, there’s not much we can do. Unless I think of something or someone else suggests something else that I haven’t thought of, there may not be much of a choice but to remove the default task being defined as multiple subtasks feature all together.
Although I understand that the .yabs files are just LUA files, I would love to see more documentation or an example on how to use these files. How do you extend your neovim configuration with new tasks for the project?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.