There are quite a few commands that take subcommands (e.g., git, or task from taskwarrior). Sometimes I have a terminal window that is devoted entirely to running this command with varying subcommands. What I wish is that I would not always need to type the main command. Let me explain this with an example from taskwarrior (a “todo list manager”):

$ task add proj:job +hard Refactor the API -- Add task to project 'job' tagged 'hard'
$ task proj:job +easy add prio:H Fix typo in README -- Tag is 'easy', priority 'high'
$ task proj:job next -- List tasks in project 'job', ordered by 'urgency'

As you can see, task is quite flexible in where the subcommand (e.g., add or next) can be placed. Now, if I'm working on a certain project (say 'job') then I would like to drill down. Something like:

$ CONTEXT="task proj:job"
[task proj:job] $ add +hard Refactor the API
[task proj:job] $ +easy add prio:H Fix typo in README
[task proj:job] $ next

The title of this question is very broad (suggesting you might want to run a sed-script over your command before executing it). However, I would be very happy with one of the following:

  1. I can set some variable (like CONTEXT in the example) whose value is prepended to every command, before running it.
  2. Alternatively, and even better, the value of CONTEXT could be filled in on the command line before I start typing my commands. In that way, I can occasionaly hit backspace or Ctrl-U if I want to run a command outside of my context.

Q. Is there a shell (preferably bash-like, for example zsh) that has the described feature?

  • At least in the case of the task add command it looks like half of $CONTEXT goes after the add. – muru Apr 23 '18 at 4:50
  • According to tho taskwarrior documentation, it allows you to switch contexts with task context <contextname>. – Kusalananda Apr 23 '18 at 5:43
  • @muru No, not really. Maybe I want to work on a project, ignore blocked tasks, and tasks for which I need to be online. Then it does no harm prepending everything with task proj:X -BLOCKED -online. – jmc Apr 23 '18 at 6:30
  • @Kusalananda, thanks, that's good to know. But I just took taskwarrior as an example. I can imagine other commands might also use this approach. – jmc Apr 23 '18 at 6:31
  • Not really what? That the proj:job half of $CONTEXT doesn't come after add in task add proj:job? Or that this question asking how to modify commands before running them is not a dupe of a question asking how to modify commands before executing them? – muru Apr 23 '18 at 6:33

Addressing your workflow rather than the precise question asked, I would use a function for this kind of situation:

t() { task proj:job "$@"; }

t add +hard Refactor the API
t +easy add prio:H Fix typo in README
t next

The advantage of a function over an alias is that the placeholder can be put anywhere in the command template rather than only at the end of the line.

From your command about wanting to avoid the overhead of the leading t, I suppose you could try something like this:

add() { task proj:job add "$@"; }
next() { task proj:job next; }

add +hard Refactor the API
add +easy prio:H Fix typo in README
| improve this answer | |
  • I guess I could do something like that. But I'dd still rather shave of those two characters (or actually, the mental burden)... – jmc Apr 23 '18 at 7:39
  • @jmc answer updated – roaima Apr 23 '18 at 11:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.