Closed andsens closed 11 years ago
Balls, this is of course not possible. We can't change anything in the calling shell from the executing shell. Best we can do is echo the location of the castle, hmpf.
We can simulate popd/pushd with a subshell:
https://github.com/andsens/homeshick/pull/39#issuecomment-23518962
Your code from the PR is definitely worth considering:
#!/bin/bash
CASTLE="$HOME/.homesick/repos/$1"
if [[ -n "$1" && -d "$CASTLE" ]]; then
export PS1="(Castle:`basename \"$CASTLE\"`)\n$PS1"
cd $CASTLE
$SHELL
fi
exit 0
I was thinking something along the lines of chrooting so people don't forget that they are in a subshell, but then you don't have git and it's generally just going to get messy.
I haven't tried this yet, when invoking the subshell do things like completion etc. still work? I assume everything is the same except for the prompt, correct?
ehhhhh, this method needs some tuning. I think your .bashrc, etc files aren't getting sourced when you call the subshell.
For zsh you can use ZDOTDIR=$HOME/.zshrc zsh
and for bash bash --rcfile $HOME/.bashrc
.
I guess $SHELL could be invoked with $HOMESHICK_SHELL_OPTS
I guess $SHELL could be invoked with $HOMESHICK_SHELL_OPTS
Why add complexity? The init file locations are constant, what would you need that variable for?
My thinking was you don't know which shell invoked homeshick.
On Thursday, August 29, 2013, Anders Ingemann wrote:
I guess $SHELL could be invoked with $HOMESHICK_SHELL_OPTS
Why add complexity? The init file locations are constant, what would you need that variable for?
— Reply to this email directly or view it on GitHubhttps://github.com/andsens/homeshick/issues/30#issuecomment-23530291 .
Or rather, you'd have to case each shell that could invoke homeshick.
On Thursday, August 29, 2013, Chris Keating wrote:
My thinking was you don't know which shell invoked homeshick.
On Thursday, August 29, 2013, Anders Ingemann wrote:
I guess $SHELL could be invoked with $HOMESHICK_SHELL_OPTS
Why add complexity? The init file locations are constant, what would you need that variable for?
— Reply to this email directly or view it on GitHubhttps://github.com/andsens/homeshick/issues/30#issuecomment-23530291 .
Well, there are quite a few shells, true. But really, if we support bash, sh, zsh, csh, dash and fish I think we're good. We can just use bash as a fallback for the rest. It's really just about the init file, it's not mission critical (ie. the feature can work without this).
Ok I'm going to refactor my PR into a proper homeshick command.
You could potentially have the cd
affect the current shell if you start out by sourcing a small helper script that does the cd
(or similar operations where the helper is needed), and later passes control to the main script for anything else. This could add a fair amount of complexity since you'd probably need shell-specific helpers (well, one for the Bourne family and one for [t]csh, at least), but maybe there is some clever way to make this not too dirty. Just putting it out there...
I appreciate the input, though I am not entirely sure what you mean. Some pseudo-code maybe?
Your comment got me thinking, it's not a working solution, but I thought I'd throw it out ther.
You could technically achieve something similar to the storm command by making a homeshick dir CASTLE
command, which echoes the path to a given castle and then have an alias
alias homeshick_cd=cd $(homeshick dir)
This won't work of course because you can't really pass $1
into the $(homeshick dir)
part.
As far as I can see though, aliasing to cd would be the only way, since cd
is a bash/zsh built-in and you can't emulate it by anything that spawns as a subprocess.
Here's a very barebones implementation (saved in the file $HOME/.homesick/repos/homeshick/home/homeshick-helper.sh
):
if [ "$1" = "cd" ]; then
cd $HOME/.homesick/repos/$2
else
$HOME/.homesick/repos/homeshick/home/.homeshick "$@"
fi
To make this work, you'd have to set this alias in bash
:
alias homeshick="source $HOME/.homesick/repos/homeshick/home/homeshick-helper.sh"
The command homeshick cd homeshick
would then go to the repo directory for homeshick
.
Of course, you could rename things to taste, or use pushd
instead of cd
, or whatever. And you'd need another version of the helper for [t]csh or whatever other family of shells you'd like to support, which is where things start getting a bit more complicated. Actually, I had feared that there would be more logic to finding the repo directory, but I guess it's not too unreasonable to hardcode the expected location.
Ooooh, that is neat! I never thought of that! Now I also understand what you mean by complicated. hm, you could cover pretty much any bourne shell if you did this:
test "$1" -eq "cd" && cd $HOME/.homesick/repos/$2 || $HOME/.homesick/repos/homeshick/home/.homeshick "$@"
For C shells you simply change the $@
to $argv[*]
. All you need are two scripts/aliases.
@pdex what do you think? This would be much simpler and also get around the problem of having to source the init-file.
I don't understand how this is getting invoked. @jjlin are you proposing that the helper file be sourced every time you want to run homeshick? @jjlin Could you spike this out?
@pdex Yes, that's exactly what would happen. The helper just implements the parts that the helper is needed for (currently, just the cd
part). For anything else, it just forwards all the arguments to the main script, and then everything proceeds exactly as before. In fact, I think this scheme could be made such that if a user did not care to have the cd
functionality, they could just ignore the helper and use the main script exactly as they do now. I'm not sure what you mean by "spike this out"?
Sorry, using work terminology (http://agiledictionary.com/209/spike/)
Basically I was saying I didn't understand how this was supposed to work and could you provide a Pull Request with what you had in mind.
I might have time to do an implementation at some point in the next week or two, unless someone else wants to get to it first.
I sent a PR with what I outlined above, with support for csh/tcsh and Bourne-family shells. I decided to keep things simple and just always do a cd
-- you could just do a pushd .
beforehand if you really cared, anyway.
One somewhat neat feature I thought of (but probably won't be implementing anytime soon) is to have the cd
command handle the no-argument case by figuring out whether the current directory is part of a homeshick repo and if so, changing into it. So for example, if I were in ~/.emacs
, then homeshick cd
would figure out that it's part of my emacs
repo and go there. If there's any ambiguity, then it could just bail out (maybe listing what the possibilities are first).
W00T W00T. Fixed!
Add a
homeshick cd CASTLE
command so users can easily enter a castle and do git stuff. Not sure whetherpushd
should be used instead though? This way users can writepopd
to get back to where they were.