From 6f11d4ea0de1f41b495ef5fabfb0a53d08ed5b88 Mon Sep 17 00:00:00 2001 From: Paul Ackersviller Date: Sat, 24 Nov 2007 23:05:31 +0000 Subject: Merge of 23759: a few improvements to pick-web-browser. --- Doc/Zsh/contrib.yo | 80 +++++++++++++++---- Functions/MIME/pick-web-browser | 166 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 16 deletions(-) create mode 100644 Functions/MIME/pick-web-browser diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index a5b62e1f5..68a922aca 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -1462,28 +1462,76 @@ example(autoload -U pick-web-browser alias -s html=pick-web-browser) It is provided as an intelligent front end to dispatch a web browser. -It will check if an X Windows display is available, and if so -if there is already a browser running which can accept a remote -connection. In that case, the file will be displayed in that browser; -you should check explicitly if it has appeared in the running browser's -window. Otherwise, it will start a new browser according to a builtin -set of preferences. - -Alternatively, tt(pick-web-browser) can be run as a zsh script. - -Two styles are available to customize the choice of browsers: -tt(x-browsers) when running under the X Windows System, and -tt(tty-browsers) otherwise. These are arrays in decreasing order -of preference consiting of the command name under which to start the +It may be run as either a function or a shell script. The status +255 is returned if no browser could be started. + +Various styles are available to customize the choice of browsers: + +startitem() +item(tt(browser-style))( +The value of the style is an array giving preferences in decreasing order +for the type of browser to use. The values of elements may be + +startitem() +item(tt(running))( +Use a GUI browser that is already running when an X Window display is +available. The browsers listed in the tt(x-browsers) style are tried +in order until one is found; if it is, the file will be displayed in +that browser, so the user may need to check whether it has appeared. +If no running browser is found, one is not started. Browsers other than +Firefox, Opera and Konqueror are assumed to understand the Mozilla +syntax for opening a URL remotely. +) +item(tt(x))( +Start a new GUI browser when an X Window display is available. Search for +the availability of one of the browsers listed in the tt(x-browsers) style +and start the first one that is found. No check is made for an already +running browser. +) +item(tt(tty))( +Start a terminal-based browser. Search for the availability of one +of the browsers listed in the tt(tty-browsers) style and start the +first one that is found. +) +enditem() + +If the style is not set the default tt(running x tty) is used. +) +item(tt(x-browsers))( +An array in decreasing order +of preference of browsers to use when running under the X Window System. +The array consists of the command name under which to start the browser. They are looked up in the context tt(:mime:) (which may be extended in future, so appending `tt(*)' is recommended). For example, -example(zstyle ':mime:*' x-browsers opera konqueror netscape) +example(zstyle ':mime:*' x-browsers opera konqueror firefox) specifies that tt(pick-web-browser) should first look for a runing -instance of Opera, Konqueror or Netscape, in that order, and if it -fails to find any should attempt to start Opera. +instance of Opera, Konqueror or Firefox, in that order, and if it +fails to find any should attempt to start Opera. The default is +tt(firefox mozilla netscape opera konqueror). +) +item(tt(tty-browsers))( +An array similar to tt(x-browsers), except that it gives browsers to +use use when no X Window display is available. The default is +tt(elinks links lynx). +) +item(tt(command))( +If it is set this style is used to pick the command +used to open a page for a browser. The context is +tt(:mime:browser:new:$browser:) to start a new browser or +tt(:mime:browser:running:$browser:) to open a URL in a browser already +runing on the current X display, where tt($browser) is the value matched +in the tt(x-browsers) or tt(tty-browsers) style. The escape sequence +tt(%b) in the style's value will be replaced by the browser, while tt(%u) +will be replaced by the URL. If the style is not set, the default for all +new instances is equivalent to tt(%b %u) and the defaults for using running +browsers are equivalent to the values tt(kfmclient openURL %u) for +Konqueror, tt(firefox -new-tab %u) for Firefox, tt(opera -newpage %u) +for Opera, and tt(%b -remote "openUrl+LPAR()%u+RPAR()") for all others. +) +enditem() ) enditem() diff --git a/Functions/MIME/pick-web-browser b/Functions/MIME/pick-web-browser new file mode 100644 index 000000000..fe42c0bf5 --- /dev/null +++ b/Functions/MIME/pick-web-browser @@ -0,0 +1,166 @@ +# Function to find a web browser to run on a URL or file. +# Can also be run as a script. It is suitable for use as +# a suffix alias: +# alias -s html=pick-web-browser +# +# The single argument is the URL or file name which may be of any type. +# The only processing which occurs is that if the argument is a file, +# it is converted into a URL. As the function takes account of +# any necessary conversions to the file name (for example, if it +# contains spaces), it is generally preferable to pass in raw file +# names rather than convert them to URLs elsewhere. +# +# The function takes account of the fact that many X Windows browsers +# which are already running on the current display can take a command +# to pass the URL to that process for handling. A typical sign +# that this has happened is that apparently nothing happens --- you +# need to check the browser window. +# +# If no $DISPLAY is set, the function tries to start a terminal-based +# browser instead. + +emulate -L zsh +setopt extendedglob cbases nonomatch warncreateglobal + +zmodload -i zsh/zutil + +local -a xbrowsers ttybrowsers + +# X Windows browsers which might be running and can accept +# a remote URL. +zstyle -a :mime: x-browsers xbrowsers || + xbrowsers=(firefox mozilla netscape opera konqueror) +# Preferred command line browsers. +zstyle -a :mime: tty-browsers ttybrowsers || + ttybrowsers=(elinks links lynx) +# Characters in addition to alphanumerics which can appear literally +# in a URL. `-' should be the first if it appears, so append others +# to the end. +local litc="-_./" + +local -a windows remoteargs match mbegin mend +local url browser command + +url=$1 +if [[ -f $url ]]; then + if [[ $url = *[^-_[:alnum:]]* ]]; then + # Convert special characters into hex escapes. + local sofar + while [[ $url = (#b)([${litc}[:alnum:]]#)([^${litc}[:alnum:]])(*) ]] + do + sofar+="$match[1]%${$(( [#16] ##$match[2] ))##0x}" + url=$match[3] + done + url="$sofar$url" + fi + + # Turn this into a local URL + if [[ $url = /* ]]; then + url=file://$url + else + url=file://$PWD/$url + fi +fi + +local bstyle +local -a bstyles +zstyle -a :mime: browser-styles bstyles || bstyles=(running x tty) + +for bstyle in $bstyles; do + case $bstyle in + (running) + [[ -z $DISPLAY ]] && continue + # X Windows running + + # Get the name of all windows running; use the internal name, not + # the friendly name, which is less useful. + # + # The nasty but portable version. + # The nice but non-portable version uses Perl, even though perl + # is more portable. + # windows=(${(f)"$(xwininfo -root -all | + # sed -ne 's/.*".*": ("\(.*\)" ".*").*/\1/p' |sort | uniq)"}) + + windows=(${(f)"$(xwininfo -root -all | + perl -ne '/.*"(.*)": \("(.*)" "(.*)"\).*/ and $w{$2} = 1; + END { print join("\n", keys %w), "\n" }')"}) + + # Is any browser we've heard of running? + for browser in $xbrowsers; do + # Some browser executables call themselves -bin + if [[ $windows[(I)(#i)$browser(|[.-]bin)] -ne 0 ]]; then + if zstyle -s ":mime:browser:running:${browser}:" command command; then + # The (q)'s here and below are pure paranoia: no browser + # name is going to include metacharacters, and we already + # converted difficult characters in the URL to hex. + zformat -f command $command b:${(q)browser} u:${(q)url} + eval $command + else + case $browser in + (konqueror) + # kfmclient is less hairy and better supported than direct + # use of dcop. Run kfmclient --commands + # for more information. Note that as konqueror is a fully + # featured file manager, this will actually do complete + # MIME handling, not just web pages. + kfmclient openURL $url || + dcop $(dcop|grep konqueror) default openBrowserWindow $url + ;; + + (firefox) + # open in new tab + $browser -new-tab $url + ;; + + (opera) + $browser -newpage $url + ;; + + (*) + # Mozilla bells and whistles are described at: + # http://www.mozilla.org/unix/remote.html + $browser -remote "openURL($url)" + ;; + esac + fi + return + fi + done + ;; + + (x) + [[ -z $DISPLAY ]] && continue + # Start our preferred X Windows browser in the background. + for browser in $xbrowsers; do + if eval "[[ =$browser != \\=$browser ]]"; then + if zstyle -s ":mime:browser:new:${browser}:" command command; then + zformat -f command $command b:${(q)browser} u:${(q)url} + eval $command "&" + else + # The following is to make the job text more readable. + eval ${(q)browser} ${(q)url} "&" + fi + return + fi + done + ;; + + (tty) + # Start up dumb terminal browser. + for browser in $ttybrowsers; do + if eval "[[ =$browser != \\=$browser ]]"; then + if zstyle -s ":mime:browser:new:${browser}" command command; then + zformat -f command $command b:${(q)browser} u:${(q)url} + eval $command + else + $browser $url + fi + return + fi + done + ;; + esac +done + +# No eligible browser. +return 255 -- cgit 1.4.1