--
#!/bin/rc
. 9.rc
. $PLAN9/lib/acme.rc
# Preserve tabs and newlines, when tokenizing readme
tmpifs = $ifs
ifs = ' '
# README in form of here document
readme = `{cat <<EOF}
ACMEBROWSE(1)
NAME
acmebrowse - mouse driven interface for edbrowse
DESCRIPTION
This document can be accessed in acme by executing a window title
in the tag: clicking a mouse button 2 on "acmebrowse". Some
familiarity with acme(1) and edbrowse(1) is assumed.
First of all win(1) isn't used. Instead events emitted by acme
are parsed using acmeevent(1). This allows to assign a new context
to the mouse actions. The result is an interface that can be used
almost without a keyboard.
The basic usage is very simple. The text executed with a button two
is send to edbrowse as a literal command with an additional lookup
for custom commands in this script. In a similar fashion button
three is used for sending the selected text as a regular expression.
Example. After launching acmebrowse, an address can by typed in the
tag. Clicking "b http://the-brannons.com/edbrowse/" with a button
two will send text as a literal command, edbrowse will open this
page (not much to see, beside a status information). "Print" after
a button two click will be translated to "," command, which will
print a whole site. The text in a window can be clicked with a
button three to send a search query e.g. "{user's guide}" will be
translated to "/{user's guide}/". The first line with a phrase
will be printed. "Go" clicked with a button two will be send as
"g1" and "," commands - edbrowse will follow a first link in the
line and then print a whole page.
This is pretty much it. Commands with an exclamation mark need some
explanation. The way acme works, a button two click on "Quit!" will
select only "Quit". This quirk/feature is used to prevent an
accidental execution of a command. Whole phrase "Quit!" must be
drag-selected with a button two. In some cases it is used to
provide an alternative version of command e.g. "Go!" will follow
a link without printing.
"Quit!" is used to clear things up, when exiting including closing
of tmux session running in background.
IMPLEMENTATION NOTES
The script is written in rc(1), since acme is needed anyway, this
was hardly a choice. Acme and edbrowse are bridged together using
tmux. Detached session of tmux is spawned, edbrowse is started
inside. Then flow of the script goes as follow:
- capture the input from acme using acmeevent
- parse and then send commands to edbrowse using tmux send-keys
- block till edbrowse is done using tmux wait-for
- select the whole text in acme window, so it will be overwritten
- pipe the buffer from edbrowse to acme using tmux capture-pane
- jump to the top/beginning of a text in acme
- erase the buffer in tmux using clear-history
FILES
~/.eb/bookmarks
EXAMPLES
Managing the bookmarks. "URLs" command will print the HTML version
of links on a specified line. "Bookmarks!" will append the content
of a buffer to a bookmark file. Those commands combined will add
a new entry in bookmarks.
SEE ALSO
acme(1), acmeevent(1), edbrowse(1), tmux(1), rc(1), acme(4)
CAVEATS
Not implemented yet:
- support for multiple sessions (not the ones in edbrowse)
- sanitizing regexps sent to edbrowse
BUGS
"Paste" and "Edit" aren't working properly (sometimes?).
EOF
# End of README
# Set $ifs back to default value
ifs = $tmpifs
# Target_window for tmux
twindow = browse
target = (-t ed: ^ $twindow)
fn tsend {
tmux send-keys $target $*
}
# man acmeevent(1)
fn event {
# $1 - c1 origin of event
# $2 - c2 type of action
# $3 - q0 beginning of selection
# $4 - q1 end of selection
# $5 - eq0 beginning of expanded selection
# $6 - eq1 end of expanded selection
# $7 - flag
# $8 - nr number of runes in $9
# $9 - text
# $10 - chorded argument
# $11 - origin of chorded argument
switch ($1$2) {
case E* # write to body or tag
case F* # generated by ourselves; ignore
case K* # type away we do not care
case Mi # mouse: text inserted in tag
case MI # mouse: text inserted in body
case Md # mouse: text deleted from tag
case MD # mouse: text deleted from body
# We don't care about those events
winwriteevent $*
case Mx MX # button 2 in tag or body
if (~$9 Cut Look Paste Snarf)
winwriteevent $*
if not if (~$9 acmebrowse)
echo -n $readme
if not {
parsecmd $9
pipetowin
}
case Ml ML # button 3 in tag or body
# Send selection as regexp to edbrowse
tmux send-keys -l $target /$9/ ';' \
send-keys $target Enter
pipetowin
}
}
fn parsecmd {
switch ($1) {
case Back # Go back one level
tsend '^' Enter
case Bookmarks # Open bookmark file and print
tsend 'b ~/.eb/bookmarks' Enter , Enter
case Bookmarks! # Add bookmark, used together with URLs command.
tsend 'w+ ~/.eb/bookmarks' Enter
case DDG* # Searching in duckduckgo.com
ddg = `{echo $1}
ddg = $ddg(2-)
ddg = 'b http://ddg.gg/lite?q=' ^ $"ddg
tmux send-keys -l $target $ddg ';' \
send-keys $target Enter , Enter
case Go # Follow 1st link in the line and print
tsend g1 Enter , Enter
case Go2 # Follow 2nd link and...
tsend g2 Enter , Enter
case Go! # Follow without print - for binary files etc
tsend g1 Enter
case Go2!
tsend g2 Enter
case Info # Show title and address of current page
tsend ft Enter f Enter
case Interrupt # Send Ctrl-C to edbrowse
tsend C-c
case Javascript # Toggle off/on javascript
tsend js Enter
case Print # Print whole file
tsend , Enter
case Quit! # With exclamation mark, must be drag-selected.
tsend qt Enter
windel sure
exit
case Refresh # Refresh page - can be useful for JS
tsend rf Enter
case URLs # Show addresses behind links in selected line.
tsend A Enter , Enter
case Write! # Save (binary) file to disk.
tsend w/ Enter
case * # Send selection as plain command to edbrowse
tmux send-keys -l $target $1 ';' \
send-keys $target Enter
}
}
fn pipetowin {
# Block till edbrowse opens web page.
tmux send-keys $target '!tmux wait-for -S ' ^ $twindow Enter ';' \
wait-for $twindow
# Select content of window in acme, so writing to data will erase it.
echo -n , | winwrite addr
winctl 'dot=addr'
# Pipe output from tmux pane to acme window
tmux capture-pane -p -S -10000 $target | winwrite data
# Jump to the top/beginning of text in acme
echo -n 0 | winwrite addr
winctl 'dot=addr'
winctl show
# Erase visible part (pane) and scrollback in tmux
tmux send-keys -R $target ';' clear-history $target
}
fn tmuxinit {
# Unset $TMUX (in case it's running) and create detached session.
TMUX=() tmux new-session -d -s ed -n dummy
# Set history-limit to 10k lines - for long web pages.
tmux set-option -q -t ed history-limit 10000
# Postpone starting of edbrowse, otherwise history-limit won't work.
tmux new-window -a -t ed:dummy -n $twindow edbrowse
# Close dummy window
tmux send-keys -t ed:dummy exit Enter
}
fn acmeinit {
# Create new window in acme, change name
newwindow
winname acmebrowse
# Add commands to tag in acme
echo '| i? i* i= | DDG | b http://' | winwrite tag
echo -n 'Back Refresh | Print Go! Go2! | Info URLs Bookmarks!' \
' Write! | Javascript Interrupt | Quit!' | winwrite tag
}
# Initialize tmux, acme and start loop
tmuxinit
acmeinit
pipetowin
wineventloop
--
Paul Onyschuk
Received on Thu Jul 24 2014 - 23:15:35 CEST
This archive was generated by hypermail 2.3.0 : Thu Jul 24 2014 - 23:24:07 CEST