This file: http://angg.twu.net/eev-current/eepitch.readme.html http://angg.twu.net/eev-current/eepitch.readme documents this elisp module: http://angg.twu.net/eev-current/eepitch.el.html http://angg.twu.net/eev-current/eepitch.el Author: Eduardo Ochs Version: 2011nov25 / 2012mar26 License: GPL3   Warning (2013sep14):   this text is obsolete!   You want this: http://angg.twu.net/eev-intros/find-eepitch-intro.html (find-eepitch-intro) [End of the recent part.] Quick index: «.introduction» (to "introduction") «.loading» (to "loading") «.the-trivial-case» (to "the-trivial-case") «.real-F8» (to "real-F8") «.red-stars» (to "red-stars") «.red-star-lines» (to "red-star-lines") «.eepitch-blocks» (to "eepitch-blocks") «.M-T» (to "M-T") «.eepitch-shell» (to "eepitch-shell") «.eepitch-prepare» (to "eepitch-prepare") «.indirection» (to "indirection") «.eepitch-comint» (to "eepitch-comint") «.eek-and-windows» (to "eek-and-windows") «.gdb-preparation» (to "gdb-preparation") «.gdb-3-windows» (to "gdb-3-windows") «.gdb-4-windows» (to "gdb-4-windows") «.rcirc» (to "rcirc") «.org-babel» (to "org-babel") «.emacs-starter-kit» (to "emacs-starter-kit") «.load-trick» (to "load-trick") «.several-shells» (to "several-shells") «introduction» (to ".introduction") Introduction ============ Let's look at a certain common situation first, and then generalize. Suppose that we want to download, compile, and run a certain program. This involves a non-trivial series of shell commands and is somewhat error-prone, so we would like to keep a record of all the steps. We can compare that with solving a puzzle: there's an initial position, a final position, we may learn about what we need to do along the way - for example, by reading an "install.txt" that only becomes available after unpacking a tarball -, we may have to backtrack at some points after committing errors, and some steps are going to be harder to undo than others, and we may get stuck and wish to ask for help... The final series of steps can be something like this: cd /tmp/ wget http://www.lua.org/ftp/lua-5.1.4.tar.gz rm -Rv /tmp/lua-5.1.4/ tar -C /tmp/ -xvzf /tmp/lua-5.1.4.tar.gz cd /tmp/lua-5.1.4/ make generic test local cd /tmp/lua-5.1.4/ ./bin/lua test/fib.lua 10 ./bin/lua -- Here we should be in the Lua read-eval-print loop... foo = function () local storage return function () return storage end, function (x) storage = x; return x end end get1, set1 = foo() get2, set2 = foo() print(set1(22), get1()) --> 22 22 print(set2(33), get1(), get2()) --> 33 22 33 os.exit() We will focus on this simpler example, with just three lines, first: echo "_$PWD" cd /tmp/ pwd We are going to see a way to edit these lines on an Emacs buffer and send them to an _interactive_ shell _one by one_. «loading» (to ".loading") Loading eepitch --------------- Just download this: http://angg.twu.net/eev-current/eepitch.el and load that file, by eval'ing something like this in emacs: (load "/tmp/eepitch.el") The file will define several functions, set two global keybindings, F8 to eepitch-this-line M-T (meta-shift-t) to eepitch-wrap and set a glyph in the standard display table - char 15, i.e., ^O, will be displayed as a red star. In what follows I will suppose that you have loaded eepitch.el. «the-trivial-case» (to ".the-trivial-case") The trivial case ---------------- The action of `eepitch-this-line' - we will refer to it as just `F8', to abbreviate - is, in a first approximation, to "send the current line to the target buffer, as if the user had typed it there". In the most typical case, the "target buffer" is a shell buffer being displayed in a different window. We will call the current buffer - the one where we wrote the lines that will be sent - the "e-script buffer". The initial situation in shown in this (faked) screenshot; note that we refer as the point in the selected window as the "cursor". ___ ______________emacs_________|-|X| <-- Frame title/buttons. | | \ | echo "@$PWD"_ | | The "e-script window". | cd /tmp/ | | The cursor is at the "_". | pwd | | | | / |--:** NOTES (Fundamental) ------| <-- Its modeline. | | \ | /home/edrx# _ | | The "target window". | | | Its point is at the "_", | | | but this it is not the | | | selected window. | | / |--:** *shell* (Shell:run) ------| <-- Its modeline. |_________________________________| <-- The minibuffer. After typing F8 once we get this: ___ ______________emacs_________|-|X| | | \ | echo "@$PWD" | | The e-script window. | cd /tmp/_ | | Note that the cursor has | pwd | | moved down one line. | | / |--:** NOTES (Fundamental) ------| | | \ The target window. | /home/edrx# echo "@$PWD" | | <- Note the command, | @/home/edrx | | <- its output, | /home/edrx# _ | | <- and a new prompt. | | | | | / |--:** *shell* (Shell:run) ------| |_________________________________| By typing F8 twice more we get this: ___ ______________emacs_________|-|X| | | | echo "@$PWD" | | cd /tmp/ | | pwd | | _ | <- cursor |--:** NOTES (Fundamental) ------| | | | /home/edrx# echo "@$PWD" | <- first command | @/home/edrx | <- its output | /home/edrx# cd /tmp/ | <- second command | /tmp# pwd | <- third command | /tmp | <- its output | /tmp# _ | <- prompt and point | | |--:** *shell* (Shell:run) ------| |_________________________________| «real-F8» (to ".real-F8") How F8 really works ------------------- The description of F8 as just "send the current line to the other window and move down" is a simplification in two ways. The real F8 1) behaves specially when the current line begins with a red star - red star lines are executed as Lisp instead of being sent, and 2) before F8 sends a line it runs "eev-prepare", that makes sure that the current frame is split, and that the buffer shown in the other window is the intended "target buffer". «red-stars» (to ".red-stars") Red stars --------- When you load eepitch it tells Emacs that occurences of the character 15 ("control-O", usually displayed as "^O") in buffers are to be displayed in a special way - as red stars, like this: "". You can enter a red star in a buffer by inserting a char 15 literally, with C-q C-o. «red-star-lines» (to ".red-star-lines") Red star lines -------------- Lines that start with a "" are "executed as Lisp" instead of being "sent to the target buffer". The main use for that is setting up the right target buffer, but all kinds of special actions are possible. Try to run this block of red star lines, by typing F8 on each one:  (eepitch-shell) ; Set the target to "*shell*" # This is sent to "*shell*"  (eepitch-shell2) ; Set the target to "*shell 2*" # This is sent to "*shell 2*"  (eepitch-shell) ; Set the target to "*shell*" again # We're back to "*shell*"  (eepitch-kill) ; Kills the current target, "*shell*"  (eepitch-shell) ; Reconstruct "*shell*" # This is sent to a new "*shell*"  (eepitch-shell2) ; Sets the target to "*shell 2*" again # This is sent to the old "*shell 2*" «eepitch-blocks» (to ".eepitch-blocks") Eepitch blocks -------------- Red star lines are commonly used in blocks of three, like this:  (eepitch-shell)  (eepitch-kill)  (eepitch-shell) # This line will be sent to a new "*shell*" Here the "(eepitch-shell)" makes sure that the current target is "*shell*", and that asserts that the "(eepitch-kill)" will kill "*shell*" and not something else - for example, "*shell 2*". The last "(eepitch-shell)" creates a "*shell*" target, and we can then be sure that it is a new one, with no garbage on the screen left from a previous run. «M-T» (to ".M-T") Creating eepitch blocks ----------------------- (find-eev "eepitch.el" "eepitch-wrap") «eepitch-shell» (to ".eepitch-shell") What eepitch-shell really does ------------------------------ The low-level view:  (setq eepitch-code '(shell))  (setq eepitch-buffer-name "*shell*")  (setq eepitch-window-show '(eepitch-window-show))  (setq eepitch-kill '(eepitch-kill))  (eepitch-prepare) «eepitch-prepare» (to ".eepitch-prepare") What eepitch-prepare really does -------------------------------- See: (find-eev "eepitch.el" "eepitch-prepare") [Describe the notion of the system being "prepared", and how running (eepitch-prepare) puts the system in a prepared state] «indirection» (to ".indirection") Cheap indirections ------------------ Several functions in eepitch are "indirect" - they are usually called by `eval'-ing a variable with the same name. For example, `eepitch-kill' (...) [The conventions for the naming of these functions and variables will probably change soon.] «eepitch-comint» (to ".eepitch-comint") Using eepitch-comint -------------------- (find-eev "eepitch.el" "eepitch-comint") «eek-and-windows» (to ".eek-and-windows") Note, 2012mar26: all the code for alternative window settings has been moved to: (find-eev "eev-multiwindow.el") http://angg.twu.net/eev-current/eev-multiwindow.el.html I never completed these sections - on multiple windows and GDB - so please ignore them! =\ Alternative window settings --------------------------- # (find-eev "eepitch.el" "eek") # (find-eev "eepitch.el" "at-nth-window")  (eek "C-x 1")  (eek "C-x 3 C-x 2")  (eek "C-x 1") «gdb-preparation» (to ".gdb-preparation") GDB examples: preparation ------------------------- ;; Hi Marc, ;; please run the block below to prepare the system for the GDB tests... ;; It downloads a lua-5.1.4 tarball and compile it with debug symbols. ;; To clean up after running all tests, delete: ;; ~/.psne.log ;; ~/snarf/ ;; ~/usrc/ '(  (setenv "S" (concat (getenv "HOME") "/snarf"))  (eepitch-shell)  (eepitch-kill)  (eepitch-shell) mkdir -p $S/http/www.lua.org/ftp/ cd $S/http/www.lua.org/ftp/ wget -N 'http://www.lua.org/ftp/lua-5.1.4.tar.gz' echo 'http://www.lua.org/ftp/lua-5.1.4.tar.gz' >> ~/.psne.log mkdir ~/usrc/ rm -Rfv ~/usrc/lua-5.1.4/ mkdir ~/usrc/lua-5.1.4/ tar -C ~/usrc/ -xvzf $S/http/www.lua.org/ftp/lua-5.1.4.tar.gz cd ~/usrc/lua-5.1.4/ make CFLAGS="-g -O2 -Wall" ansi test local ) «gdb-3-windows» (to ".gdb-3-windows") GDB with three windows ---------------------- ;; For non-CVS Emacs. ;; Non-CVS Emacs uses the "plain gud", in which the gdb interaction ;; buffer and the buffer used for i/o of the debugged program are the ;; same. ;; _________________________ ;; | | | ;; | | | ;; | e-script | | ;; | | | ;; |_____________| program | ;; | | source | ;; | GDB prompt | | ;; | and | | ;; | program I/O | | ;; |_____________|___________| '(  (load "~/eev-current/eepitch.el")  (setq eepitch-gdb-fmt "gdb --annotate=3 %s")  (eepitch-kill)  (eepitch-gdb-3 "~/usrc/lua-5.1.4/bin/lua") br main run p printf("Hello\n") p argv[0] p printf(argv[0]) tbr math_sin cont print "Hello" = math.sin(2) bt ) «gdb-4-windows» (to ".gdb-4-windows") GDB with four windows --------------------- Recent builds of Emacs (to simplify: "CVS Emacs") use a ;; For CVS Emacs. ;; CVS Emacs uses gdb-mi, which requires a 4-window setup. ;; ________________________ ;; | | | ;; | e-script | program | ;; | | source | ;; |____________|___________| ;; | | | ;; | GDB | program | ;; | prompt | I/O | ;; |____________|___________| '(  (load "~/eev-current/eepitch.el")  (setq eepitch-gdb-fmt "gdb -i=mi %s")  (eepitch-kill)  (eepitch-gdb-4 "~/usrc/lua-5.1.4/bin/lua") br main run p printf("Hello\n") ;; ^ Yields "Problem parsing arguments: interpreter-exec console" p argv[0] p printf(argv[0]) tbr math_sin cont  (setq eepitch-buffer-name eepitch-i/o-buffer-name) print "Hello" = math.sin(2)  (setq eepitch-buffer-name eepitch-gdb-buffer-name) bt ) «rcirc» (to ".rcirc") Rcirc ----- Rcirc is an IRC client for Emacs that is quite easy to configure, and which connects to Freenode by default when invoked as `M-x rcirc'. As it takes a long time to connect to a server - about 10 seconds - we want to protect the buffer associated to an IRC connection to make it harder to kill it by accident. Look at the source code for `eepitch-freenode' to see how it redefines `eepitch-kill'.  (eepitch-freenode)  (eepitch-kill)  (eepitch-freenode) /join #eev  (eepitch-to-buffer "#eev@irc.freenode.net") «org-babel» (to ".org-babel") Org-babel --------- See: http://orgmode.org/worg/org-contrib/babel/index.html http://orgmode.org/worg/org-contrib/babel/intro.html http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-screen.html Note that org-babel-screen was inspired by eechannel, http://angg.twu.net/eev-current/anim/channels.anim.html which was an ancestor of eepitch, and a part of eev. Most people who tried eev found it too complex and too weird and gave up, so I've split eepitch out from the rest of eev in an attempt to make eev more approachable. «emacs-starter-kit» (to ".emacs-starter-kit") The Emacs Starter Kit --------------------- One of the goals of the eev project was to implement something like the Emacs Starter Kit: http://eschulte.github.com/emacs-starter-kit/ a tutorial on Lua that can be run with eepitch - it has lots of eev-isms, but they can be ignored - can be found at: http://angg.twu.net/eev-puro/mini-lua-intro.e.html http://angg.twu.net/eev-puro/mini-lua-intro.e «load-trick» (to ".load-trick") The "load" trick ---------------- [Explain how to put e-scripts in multi-line comments in source files; the trick is that we can begin them with a "load", that loads the functions defined in the enclosing file. As it is impossible to define functions in Haskell in interactive mode this is the only way to use Haskell with eepitch.] Two examples: (find-angg "dednat5/eoo.lua" "test-eoo") (find-angg "HASKELL/mergesort.hs") [The examples based on TeX are much harder] «several-shells» (to ".several-shells") Handling several shells at once ------------------------------- ___ ______________emacs_________|-|X| | | \ |  (eepitch '(shell)) | | Let's call this the | cd /tmp/ | | "e-script window". | ls | | The point is at the "_". | _ | | | | / |--:** NOTES (Fundamental) ------| <-- Its modeline. | | \ | /home/edrx# cd /tmp/ | | Let's call this the | /tmp# ls | | "target window". | ./ ../ foo.txt | | | /tmp# | | | | / |--:** *shell* (Shell:run) ------| <-- Its modeline. |_________________________________| <-- The minibuffer. (info "(emacs)Interactive Shell") # (find-file "/tmp/lua-5.1.4/") # (find-file "/tmp/lua-5.1.4/INSTALL") # (find-file "/tmp/lua-5.1.4/Makefile") # (find-file "/tmp/lua-5.1.4/bin/") # (find-file "/tmp/lua-5.1.4/bin/") make linux test local and if we don't make it to the end mkdir ~/usrc/ rm -Rfv ~/usrc/lua-5.1.4/ mkdir ~/usrc/lua-5.1.4/ tar -C ~/usrc/ -xvzf $S/http/www.lua.org/ftp/lua-5.1.4.tar.gz cd ~/usrc/lua-5.1.4/ find * -name '*.[ch]' | sort > .files.ch ;# (find-lua51file ".files.ch") etags $(<.files.ch) ;# (find-lua51file "TAGS") ~/bin/patch-lua-5.1.3 ;# (find-angg "bin/patch-lua-5.1.3") #make linux test local |& tee omltl ;# (find-lua51file "omltl") See: (info "(emacs)Interactive Shell") Problems ======== echo, block, prompt ------------------- Some programs - for example, zsh - echo their input. The usual fix for that is to set a comint variable, by running this after creating the comint buffer: (setq comint-process-echoes t) but this makes Emacs wait for the echo after a RET, which makes emacs block in gud and slime ------------- inferior modes -------------- passwords --------- tabs ---- ansi-term --------- eshell ------ ;; Local Variables: ;; coding: raw-text-unix ;; End: