3 ;;;; lilypond-invoke-editor.scm -- Invoke an editor in file:line:column mode
5 ;;;; Copyright (C) 2005--2011 Jan Nieuwenhuizen <janneke@gnu.org>
7 ;;;; This file is part of LilyPond, the GNU music typesetter.
9 ;;;; LilyPond is free software: you can redistribute it and/or modify
10 ;;;; it under the terms of the GNU General Public License as published by
11 ;;;; the Free Software Foundation, either version 3 of the License, or
12 ;;;; (at your option) any later version.
14 ;;;; LilyPond is distributed in the hope that it will be useful,
15 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;;;; GNU General Public License for more details.
19 ;;;; You should have received a copy of the GNU General Public License
20 ;;;; along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
23 ;; (define (exit x) (system "sleep 10"))
32 (define PROGRAM-NAME "lilypond-invoke-editor")
33 (define TOPLEVEL-VERSION "@TOPLEVEL_VERSION@")
34 (define DATADIR "@datadir@")
35 (define COMPILE-TIME-PREFIX
36 (format #f "~a/lilypond/~a" DATADIR TOPLEVEL-VERSION))
38 ;; argv0 relocation -- do in wrapper?
40 (define LILYPOND_DATADIR
42 (or (getenv "LILYPOND_DATADIR")
43 (dirname (dirname (car (command-line)))))))
46 (if (eq? prefix (dirname DATADIR)) COMPILE-TIME-PREFIX
47 (format #f "~a/share/lilypond/~a"
48 prefix TOPLEVEL-VERSION))))
50 (define-public _ gettext)
52 (define (show-version port)
53 (format port "~a (GNU LilyPond) ~a\n" PROGRAM-NAME TOPLEVEL-VERSION))
55 (define (show-help port)
56 (format port (_ "Usage: lilypond-invoke-editor [textedit://]FILE:LINE:CHAR:COLUMN
58 Visit a file and position the cursor.
61 -h, --help show this help
62 -v, --version show version
65 (define (parse-options args)
66 (let* ((options (getopt-long args
67 '((help (single-char #\h))
68 (version (single-char #\v)))))
69 (files (cdr (assq '() options))))
70 (if (assq 'help options)
72 (show-version (current-output-port))
73 (show-help (current-output-port))
75 (if (assq 'version options)
76 (begin (show-version (current-output-port)) (exit 0)))
77 (show-version (current-error-port))
80 (define (re-sub re sub string)
81 (regexp-substitute/global #f re string 'pre sub 'post))
83 ;; FIXME: I'm going slowly but certainly mad; I really cannot find the
84 ;; scm library function for this.
85 (define (unquote-uri uri)
86 (re-sub "%([A-Fa-f0-9]{2})"
88 (string (integer->char (string->number (match:substring m 1) 16))))
91 (define (is-textedit-uri? uri)
92 (string-match "^textedit://" uri))
95 (define (dissect-uri uri)
96 (let* ((match (string-match "textedit://(.*):([^:]+):([^:]+):(.*)$" uri)))
98 (list (unquote-uri (match:substring match 1))
99 (match:substring match 2)
100 (match:substring match 3)
101 (match:substring match 4))
103 (format (current-error-port) (_ "invalid textedit URI: ~a") uri)
104 (newline (current-error-port))
105 (format (current-error-port) (_ "expect: textedit://FILE:LINE:CHAR:COLUMN"))
106 (newline (current-error-port))
112 (car (string-tokenize (vector-ref (uname) 0) char-set:letter)))))
114 (define (running-from-gui?)
115 (let ((have-tty? (isatty? (current-input-port))))
116 ;; If no TTY and not using safe, assume running from GUI.
119 (define (run-editor uri)
121 ((command (apply get-editor-command (dissect-uri uri)))
122 (status (system command)))
123 (if (not (= status 0))
125 (format (current-error-port)
126 (_ "failed to invoke editor: ~a") command)
129 (define (run-browser uri)
131 (if (getenv "BROWSER")
132 (format "~a ~a" (getenv "BROWSER") uri)
133 (format #f "firefox -remote 'OpenURL(~a,new-tab)'" uri))))
136 (define (strip-framework-path var)
137 (define pat "lilypond/usr")
141 (paths (string-split val #\:))
142 (without (remove (lambda (s) (string-contains s pat))
145 (if (not (= (length without)
147 (setenv var (string-join without ":"))))))
150 (let ((files (parse-options args)))
151 (if (running-from-gui?)
152 (redirect-port (current-error-port)
153 (open-file (string-append
157 "/lilypond-invoke-editor.log") "a")))
158 (if (not (= (length files) 1))
160 (show-help (current-error-port))
162 (set! %load-path (cons LILYPOND_DATADIR %load-path))
164 (primitive-eval '(use-modules (scm editor)))
166 (strip-framework-path "LD_LIBRARY_PATH")
167 (let* ((uri (car files)))
168 (if (is-textedit-uri? uri)
170 (run-browser uri)))))
172 (main (command-line))