3 ;;;; lilypond-invoke-editor.scm -- Invoke an editor in file:line:column mode
5 ;;;; source file of the GNU LilyPond music typesetter
7 ;;;; (c) 2005--2008 Jan Nieuwenhuizen <janneke@gnu.org>
10 ;; (define (exit x) (system "sleep 10"))
19 (define PROGRAM-NAME "lilypond-invoke-editor")
20 (define TOPLEVEL-VERSION "@TOPLEVEL_VERSION@")
21 (define DATADIR "@datadir@")
22 (define COMPILE-TIME-PREFIX
23 (format #f "~a/lilypond/~a" DATADIR TOPLEVEL-VERSION))
25 ;; argv0 relocation -- do in wrapper?
27 (define LILYPOND_DATADIR
29 (or (getenv "LILYPOND_DATADIR")
30 (dirname (dirname (car (command-line)))))))
33 (if (eq? prefix (dirname DATADIR)) COMPILE-TIME-PREFIX
34 (format #f "~a/share/lilypond/~a"
35 prefix TOPLEVEL-VERSION))))
39 ;; gettext wrapper for guile < 1.7.2
40 (if (defined? 'gettext)
41 (define-public _ gettext)
42 (define-public (_ x) x))
44 (define (show-version port)
45 (format port "~a (GNU LilyPond) ~a\n" PROGRAM-NAME TOPLEVEL-VERSION))
47 (define (show-help port)
48 (format port (_ "Usage: lilypond-invoke-editor [textedit://]FILE:LINE:CHAR:COLUMN
50 Visit a file and position the cursor.
53 -h, --help show this help
54 -v, --version show version
57 (define (parse-options args)
58 (let* ((options (getopt-long args
59 '((help (single-char #\h))
60 (version (single-char #\v)))))
61 (files (cdr (assq '() options))))
62 (if (assq 'help options)
64 (show-version (current-output-port))
65 (show-help (current-output-port))
67 (if (assq 'version options)
68 (begin (show-version (current-output-port)) (exit 0)))
69 (show-version (current-error-port))
72 (define (re-sub re sub string)
73 (regexp-substitute/global #f re string 'pre sub 'post))
75 ;; FIXME: I'm going slowly but certainly mad; I really cannot find the
76 ;; scm library function for this.
77 (define (unquote-uri uri)
78 (re-sub "%([A-Fa-f0-9]{2})"
80 (string (integer->char (string->number (match:substring m 1) 16))))
83 (define (is-textedit-uri? uri)
84 (string-match "^textedit://" uri))
87 (define (dissect-uri uri)
88 (let* ((match (string-match "textedit://(.*):([^:]+):([^:]+):(.*)$" uri)))
90 (list (unquote-uri (match:substring match 1))
91 (match:substring match 2)
92 (match:substring match 3)
93 (match:substring match 4))
95 (format (current-error-port) (_ "invalid textedit URI: ~a") uri)
96 (newline (current-error-port))
97 (format (current-error-port) (_ "expect: textedit://FILE:LINE:CHAR:COLUMN"))
98 (newline (current-error-port))
104 (car (string-tokenize (vector-ref (uname) 0) char-set:letter)))))
106 (define (running-from-gui?)
107 (let ((have-tty? (isatty? (current-input-port))))
108 ;; If no TTY and not using safe, assume running from GUI.
111 (define (run-editor uri)
113 ((command (apply get-editor-command (dissect-uri uri)))
114 (status (system command)))
115 (if (not (= status 0))
117 (format (current-error-port)
118 (_ "failed to invoke editor: ~a") command)
121 (define (run-browser uri)
123 (if (getenv "BROWSER")
124 (format "~a ~a" (getenv "BROWSER") uri)
125 (format #f "firefox -remote 'OpenURL(~a,new-tab)'" uri))))
128 (define (strip-framework-path var)
129 (define pat "lilypond/usr")
133 (paths (string-split val #\:))
134 (without (remove (lambda (s) (string-contains s pat))
137 (if (not (= (length without)
139 (setenv var (string-join without ":"))))))
142 (let ((files (parse-options args)))
143 (if (running-from-gui?)
144 (redirect-port (current-error-port)
145 (open-file (string-append
149 "/lilypond-invoke-editor.log") "a")))
150 (if (not (= (length files) 1))
152 (show-help (current-error-port))
154 (set! %load-path (cons LILYPOND_DATADIR %load-path))
156 (primitive-eval '(use-modules (scm editor)))
158 (strip-framework-path "LD_LIBRARY_PATH")
159 (let* ((uri (car files)))
160 (if (is-textedit-uri? uri)
162 (run-browser uri)))))
164 (main (command-line))