about summary refs log tree commit diff stats
path: root/doc/cd-after-exit.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/cd-after-exit.txt')
-rw-r--r--doc/cd-after-exit.txt161
1 files changed, 0 insertions, 161 deletions
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