diff options
-rw-r--r-- | README | 13 | ||||
-rw-r--r-- | doc/cd-after-exit.txt | 161 | ||||
-rwxr-xr-x | ranger.py | 21 | ||||
-rw-r--r-- | ranger/__init__.py | 2 | ||||
-rw-r--r-- | ranger/__main__.py | 14 | ||||
-rw-r--r-- | ranger/core/fm.py | 1 |
6 files changed, 22 insertions, 190 deletions
diff --git a/README b/README index ff1e3788..4525d94c 100644 --- a/README +++ b/README @@ -122,3 +122,16 @@ information, check out the source code. Also, see the file HACKING for more detailed instructions on modifying the program. + + +Tips +---- + +Change the directory of your parent shell when you exit ranger: + +ranger() { + $(which ranger) $@ && + cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)" +} + +This can be put into your ~/.bashrc or something similar. diff --git a/doc/cd-after-exit.txt b/doc/cd-after-exit.txt deleted file mode 100644 index ee300518..00000000 --- a/doc/cd-after-exit.txt +++ /dev/null @@ -1,161 +0,0 @@ -The "cd-after-exit" Feature -=========================== - -Abstract --------- - -This document explains the troublesome implementation of the "cd-after-exit" -feature. - -This is written for developers who wonder how it's working. - - -Specification -------------- - -When the feature is enabled, ranger will attempt to change the directory of -the parent shell (from which ranger is run) to the last visited directory -when ranger is exited. - -This task is, by its nature, shell dependent. As a bash or zsh user, -I focused on the implementation for those two shells and left the -addition of support for csh, ksh, and other shells to those who actually use -those shells. - - -What's the problem? -------------------- - -Shells have several limitations, the implementation could not be done easily -because: - -1. It is not possible to use something like system('cd xyz') at the end. -This command would run in a new shell and wouldn't change the directory -of the parent shell at all. - -2. Using exec('cd xyz') is not possible either, since 'cd' is a command -which is directly integrated in to the shell and can not be run this way. - - -Redirection of streams ----------------------- - -The only way I found is using cd `program` from inside the shell to change -the directory to whatever `program` prints to the stdout: - - bash$ cd `echo ..` - -Since the user interface still has to be printed, we simply redirect it to -the stderr. It is not sufficient however to change sys.stdout to sys.stderr, -since curses seems not to be aware of sys.stdout and continues to print out -the interface to the actual stdout. - -So what I did was swap the stdout and stderr of the whole ranger process on -the shell command line by using: - - bash$ cd `ranger 3>&1 1>&2 2>&3 3>&-` - -Since errors are now printed to the stdout, we have do this in ranger: - sys.stderr = sys.__stdout__ - -And at the end, write the current directory to the stdout, which is now -reachable via sys.__stderr__ due to the redirections: - sys.__stderr__.write(last_visited_directory) - -To inform the ranger process about these changes, we add a --cd-after-exit -switch which: - bash$ cd `ranger --cd-after-exit 3>&1 1>&2 2>&3 3>&-` - - -Argument passing ----------------- - -This works well enough, but there are two remaining problems: - -1. How to pass arguments to ranger? - -2. How to memorize that line? Although you can just copy+paste it -into your bashrc and create an alias, the complexity of the line -could lead to errors. - -Both problems are solved by putting the command in a file: - -run.sh: - cd "`ranger --cd-after-exit \"$@\" 3>&1 1>&2 2>&3 3>&-`" - -The $@ is responsible for argument passing. By using the source command, -the file will be evaluated without creating a distinct new shell. - - bash$ source run.sh arg1 ... argN - -To add flexibility, replace the name "ranger" in the command to the first -argument. Now it requires you to pass the name of the ranger command to -the script as the first argument: - -run.sh: - RANGER="$1" - shift - cd "`$RANGER --cd-after-exit \"$@\" 3>&1 1>&2 2>&3 3>&-`" - - -Put it in a nutshell --------------------- - -I didn't want to have 2 files for the main program and wanted just one -file at /usr/bin/ranger. So I used this trick to merge both files into one: - - #!/usr/bin/python - """": - <shell code> - """ - <python code> - -If you run this file with python, or simply by typing ranger, the program will -run normally. If you, however, run this file by sourcing it into the shell, -like you did with run.sh, the cd-after-exit mode will be activated. - -Now the way of running ranger with the cd-after-exit feature is: - - bash$ source /path/to/ranger.py /path/to/ranger.py - -or, if properly installed: - - bash$ source ranger ranger - -A convenient way of using this feature is adding this line to your bashrc: - - alias rn='source ranger ranger' - - -Open issues ------------ - -Unfortunately there is some redundancy: you have to type the path to ranger -twice. I know of no way to fix this, because it is not possible to get the -filename of the file currently being sourced. - -Example: - - bash$ echo 'source sourced.sh' > main.sh - bash$ echo 'echo $0 $@' > sourced.sh - bash$ bash main.sh - main.sh - -If you find a way to make this print out 'sourced.sh', let me know. :) - -Another thing: If Ctrl+C is pressed anywhere in the program, the execution -of the sourced shell script is stopped and the feature stops working. - -This was handled by using a script like that: - - ranger_exec="$1" - shift - trap "" INT - exec 3< <($ranger_exec --cd-after-exit $@ 3>&1 1>&2 2>&3 3>&-) - while read ranger_output; do false; done <&3 - cd "$ranger_output" - #...and some clean ups - -but that won't work in zsh for some reason, so I took it out again. - -Dec 25, 2009 diff --git a/ranger.py b/ranger.py index 0a9d54c9..1c06f125 100755 --- a/ranger.py +++ b/ranger.py @@ -19,20 +19,15 @@ # # ---------------------------------------------------------------------------- # -# An embedded shell script. It allows you to change the directory -# of the parent shell to the last visited directory in ranger after exit. -# For more information, check out doc/cd-after-exit.txt -# To enable this, start ranger with: -# source /path/ranger /path/ranger +# An embedded shell script for backwards compatibility. """": -if [ $1 ]; then - ranger_exec="$1" - shift - cd "`exec $ranger_exec --cd-after-exit $@ 3>&1 1>&2 2>&3 3>&-`" - unset ranger_exec -else - echo "usage: source path/to/ranger.py path/to/ranger.py" -fi +echo "Warning: the cd-after-exit feature has been removed." +echo "You can get the functionality by using such a function:" +echo 'ranger() {' +echo ' $(which ranger) $@ &&' +echo ' cd "$(grep \^\'"'"' ~/.ranger/bookmarks | cut -b3-)"' +echo '}' +$1 return 1 """ diff --git a/ranger/__init__.py b/ranger/__init__.py index d1300cb4..f46a1e76 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -34,7 +34,7 @@ USAGE = '%prog [options] [path/filename]' DEFAULT_CONFDIR = '~/.ranger' RANGERDIR = os.path.dirname(__file__) LOGFILE = '/tmp/errorlog' -arg = OpenStruct(cd_after_exit=False, +arg = OpenStruct( debug=False, clean=False, confdir=DEFAULT_CONFDIR, mode=0, flags='', targets=[]) diff --git a/ranger/__main__.py b/ranger/__main__.py index 9b932bd3..32f28e12 100644 --- a/ranger/__main__.py +++ b/ranger/__main__.py @@ -29,13 +29,6 @@ def parse_arguments(): parser = OptionParser(usage=USAGE, version='ranger ' + __version__) - # Instead of using this directly, use the embedded - # shell script by running ranger with: - # source /path/to/ranger /path/to/ranger - parser.add_option('--cd-after-exit', - action='store_true', - help=SUPPRESS_HELP) - parser.add_option('-d', '--debug', action='store_true', help="activate debug mode") @@ -58,9 +51,6 @@ def parse_arguments(): arg.confdir = os.path.expanduser(arg.confdir) - if arg.cd_after_exit: - sys.stderr = sys.__stdout__ - if not arg.clean: try: os.makedirs(arg.confdir) @@ -133,7 +123,6 @@ def main(): try: my_ui = UI() my_fm = FM(ui=my_ui) - my_fm.stderr_to_out = arg.cd_after_exit # Run the file manager my_fm.initialize() @@ -143,9 +132,6 @@ def main(): # Finish, clean up if 'my_ui' in vars(): my_ui.destroy() - if arg.cd_after_exit: - try: sys.__stderr__.write(my_fm.env.cwd.path) - except: pass if __name__ == '__main__': top_dir = os.path.dirname(sys.path[0]) diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 994447b0..94d0d85d 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -35,7 +35,6 @@ TICKS_BEFORE_COLLECTING_GARBAGE = 100 class FM(Actions): input_blocked = False input_blocked_until = 0 - stderr_to_out = False def __init__(self, ui=None, bookmarks=None, tags=None): """Initialize FM.""" Actions.__init__(self) |