michaelmacinnis / oh

A new Unix shell.
MIT License
1.36k stars 55 forks source link

augmenting built in command behaviour (cd) #40

Closed gdiazlo closed 5 years ago

gdiazlo commented 5 years ago

While working on my dot files I got trouble trying to augment cd behavior. For reference here is my progress:

bash version: https://github.com/gdiazlo/acme/blob/master/profile oh version: https://github.com/gdiazlo/acme/blob/master/ohrc

I need to execute an additional command on each cd, only if I'm inside my editor terminal (basically when TERM=dumb)

I tried something like:

define cd: method(:args) = {
    builtin cd @$args
    if (eq $TERM dumb) {
        command awd
    }
}

But the builtin usage is wrong. I also tried something like:

define acd: method(:args) = {
    cd @$args
    if (eq $TERM dumb) {
        command awd
    }
  }

But when acd returns, the current directory remains unchanged.

What would be the way to change or augment the behavior of a builtin command?

I had a look at boot.oh, but still I can't figure out how to do it.

michaelmacinnis commented 5 years ago

The command cd behaves a little differently than other commands as it needs to set some variables in the current environment. To create a new cd you want something like:

define lcd: syntax (: args) e = {
    define l: cons cd $args # Construct the command.
    write $l                # Write the command so we can see it.
    e::eval $l              # Evaluate it in the calling environment.
}
michaelmacinnis commented 5 years ago

If you want to reuse the name cd, you have to save the old value somewhere:

export oldcd = $cd
define cd: syntax (: args) e = {
    define l: cons oldcd $args
    write $l
    e::eval $l
}
gdiazlo commented 5 years ago

Cool! that solved it. thanks