This is just an idea, its not even a “thing” yet, but here’s some of the ideas that have been stewing in my skull for some time now.

Prior Art

Before even glancing at this project, check out Pry, Rubbish, and Rush. Pry in particular in incredible. For the moment I have rather different goals though.


So here’s the deal, years ago I read about the new fancy-shmancy Monad. Its goal, as I understood it boiled down to commands as objects. It was a fantastc concept. Naturally, as it has with many things, Microsoft failed to deliver.

And again, as it often does, the Oberon system did it first and better. I actually used the Oberon OS long before Monad was even thought of, but Monad is a more visible example.

In both cases they assumed the underlying system was also an object system and then gave you immense power over those elements, accessible from the commandline just like a standard shell. At this time of this writing, I am not working on my own operating system so I have no such luxury. However, unixy systems such as Linux, OS X, BSD, Hurd, and others provide a lot of process-level information and documentation that is exceedingly simple to access and parse. Provided you know where to look.

The Big Idea

I’d like to encapsulate commands and external processes as objects and replace most built-in bash commands with more object-oriented (and prettier) versions.

Use Cases

Alright, well met me give you a couple of examples of what I’d like to be able to do with cmdr. this is all pseudocode at the moment

Commands are Persistant Objects

$ ls
.git/  README.markdown
$ hist
1 ls <succeded a few seconds ago>
$ hist.raw
    {command: 'ls', output: [#<Cmdr::Output::Stdout: ".git/  README.markdown">], status: #<Cmdr::Status::External::Process: pid 82960 exit 0>, type: External, start_time: 011-08-24 00:27:59 -0700, exit_time: 011-08-24 00:27:59 -0700},
    {command: 'hist', output: [#<Cmdr::CommandHistory>], status: Success, type: Internal, start_time: 011-08-24 00:28:02 -0700, exit_time: 011-08-24 00:28:03 -0700},
    {command: 'hist.raw', output: [], status: Running, type: Internal, start_time: 011-08-24 00:28:05 -0700, exit_time: nil}
$ cmdhist[1].output
.git/  README.markdown

Robust Directory History

$ cd ~
$ cd /
$ cd.hist
pwd /
1   ~
2   /home/acook/pork/cmdr
$ back
$ pwd
$ cd.hist
0   /
pwd ~
1   ~
2   /home/acook/pork/cmdr
$ fore
$ pwd

Overridable Default Command Options

Much like what aliases are often used for in bash.

$ ls.opts.defaults << '1'
$ ls
$ ls.opts.only :b
.git/  README.markdown

Session environment persistance

$ x = 1
x = 1
$ ls
.git/  README.markdown
$ exit                    # exit cmdr
sh-3.2$ cmdr              # rerun cmdr from sh
cmdr v0.1
$ hist
1 x = 1 <succeeded about a minute ago>
2 ls    <succeeded less than a minute ago>
3 exit  <succedded less than a minute ago>
$ x
=> 1