I recently published grunt-idk on npm. As the name implies, it's a grunt task for when you just aren't sure what task you need to run. Maybe you have multiple test suites with similar grunt task names, maybe you have aliases that compose tasks in a variety of confusing ways, maybe you just don't run certain tasks often enough to remember them. Whatever the reason, grunt-idk is for you.

grunt-idk actually began as a local task with no dependencies that included a lot of assumptions, magic numbers, and weird edge cases. It was always my intent to refactor it into it's own, published node module, and when I set out to do that finally, I just used inquirer instead of the manual stuff I was doing before. That made the task significantly simpler and more reliable. Here's an example of the task within the grunt-idk repo itself:

grunt idk


As you can see, grunt idk has three steps: choose tasks to run, choose targets on those tasks, and choose the final order of task execution.

I won't break this out into subpoints with headings as I normally would because there's just not that much to say. If you've ever used a command-line tool that uses inquirer, grunt-idk is going to be very familiar to you. Just use up and down or j and k to navigate the choices and spacebar to select. There's also a to select all and i to inverse, but you probably won't need those in a tool like this. My guess is more than 90% of use cases will be in the vein of "I forgot the name of the task (or target) I need to run."

After you choose tasks, you'll need to choose targets for those tasks (unless those tasks aren't multitasks or only have one target). This step could actually be multiple prompts depending on how many tasks you chose in step 1 because you'll get a separate prompt for the targets of each task you chose. Use the same navigation keys to make selections. If you choose all the targets in a task, grunt-idk will just run the task with no target (as that will cause all the targets to run). I haven't decided yet if this is the right behavior because it does mean that you can't order the targets of the tasks, so it's possible this behavior will change in the future. If this is the incorrect behavior for you, please visit the repo on Github to see if that's still the current behavior (as that's likely to stay more up to date than this), and if so, open a pull request asking for a change.

After you've chosen your targets, you'll get a final list with all the tasks and targets that are about to run, and you'll have a chance to organize them, since task execution order matters in grunt. Thanks to a third-party inquirer plugin, inquirer-orderedcheckbox, this was easy to add. Because up and down navigate up and down, those keys aren't used for moving items. Instead, use left or h to move items higher and right or l to move them lower. If you use vim, this won't be too challenging, since h is left and l is right (which makes for convenient mnemonics). If you don't use vim, this might make less sense to you, but it is what it is. Third-party stuff always has it's quirks. Note that, in this step, everything is checked by default, but you can actually deselect tasks if you decide you don't want to run them after all. And that's it, when you hit enter to confirm your selection, the tasks you chose will run in the order you specified.


There are only two options you can add to your grunt configuration for this task, and they are used to control the number of items displayed at one time. The first is options.size which is the number of items to display if that many will fit on the screen at one time, but if they won't, grunt-idk attempts to do a little math to figure out how many will fit using the environment variables LINES and COLUMNS. Sidebar: I've found that I need to have export LINES=$LINES and export COLUMNS=$COLUMNS in my bashrc to get these to work reliably (possibly it's only in child processes that they don't work . . . I haven't investigated fully). You can also set options.offset to indicate how many buffer lines to leave at the bottom of the screen when doing said math. I'll leave you with some simple configuration examples to conclude this post.

// Use default options. Pretty straight forward.
  // Technically, you can omit this line and
  // everything will still work if you've done
  // grunt.loadNpmTasks('grunt-idk')
  idk: {}

// Alternatively
  idk: {
    size: 25,
    offset: 4

Thanks for reading! If you enjoyed this post, consider sharing it using the social sharing buttons below.