From 6545eebfa72e0c9af872c646a7e6cf6b72be7bb5 Mon Sep 17 00:00:00 2001 From: Andy Fingerhut Date: Wed, 29 Feb 2012 09:48:55 -0800 Subject: [PATCH] On non-Mac OS system, use xdg-open in browse-url if available This allows the usage of freedesktop.org's xdg-open which is present on basically any Linux and BSD system nowadays. Another slight improvement is that on Mac OS X, /usr/bin/open is tried first, so no icon pops up in the dock due to the JVM switching to becoming a GUI app (unless it was a GUI app before browse-url was called). This patch has been tested on the following OSes, all with 1.6.0_ JVMs: Mac OS X 10.6.8 Windows XP SP3, both from CMD.EXE and in a Cygwin bash shell Ubuntu Linux 10.04 LTS The test consisted of the following commands typed into a REPL, run inside the Clojure root directory where readme.txt and epl-v10.html files are: (use 'clojure.java.browse) (browse-url "http://www.yahoo.com") (browse-url "readme.txt") (browse-url "epl-v10.html") --- src/clj/clojure/java/browse.clj | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/clj/clojure/java/browse.clj b/src/clj/clojure/java/browse.clj index 1acda37..6fcc650 100644 --- a/src/clj/clojure/java/browse.clj +++ b/src/clj/clojure/java/browse.clj @@ -10,14 +10,34 @@ ^{:author "Christophe Grand", :doc "Start a web browser from Clojure"} clojure.java.browse - (:require [clojure.java.shell :as sh]) + (:require [clojure.java.shell :as sh] + [clojure.string :as str]) (:import (java.net URI))) (defn- macosx? [] (-> "os.name" System/getProperty .toLowerCase (.startsWith "mac os x"))) -(def ^:dynamic *open-url-script* (when (macosx?) "/usr/bin/open")) +(defn- xdg-open-loc [] + ;; try/catch needed to mask exception on Windows without Cygwin + (let [which-out (try (:out (sh/sh "which" "xdg-open")) + (catch Exception e ""))] + (if (= which-out "") + nil + (str/trim-newline which-out)))) + +(defn- open-url-script-val [] + (if (macosx?) + "/usr/bin/open" + (xdg-open-loc))) + +;; We could assign (open-url-script-val) to *open-url-script* right +;; away in the def below, but clojure.java.shell/sh creates a future +;; that causes a long wait for the JVM to exit during Clojure compiles +;; (unless we can somehow here make it call (shutdown-agents) later). +;; Better to initialize it when we first need it, in browse-url. + +(def ^:dynamic *open-url-script* (atom :uninitialized)) (defn- open-url-in-browser "Opens url (a string) in the default system web browser. May not @@ -47,6 +67,10 @@ "Open url in a browser" {:added "1.2"} [url] - (or (open-url-in-browser url) - (when *open-url-script* (sh/sh *open-url-script* (str url)) true) - (open-url-in-swing url))) + (let [script @*open-url-script* + script (if (= :uninitialized script) + (reset! *open-url-script* (open-url-script-val)) + script)] + (or (when script (sh/sh script (str url)) true) + (open-url-in-browser url) + (open-url-in-swing url)))) -- 1.7.9.2