4 ;;;; lilypond-invoke-editor.scm -- Invoke an editor in file:line:column mode
6 ;;;; source file of the GNU LilyPond music typesetter
8 ;;;; (c) 2005 Jan Nieuwenhuizen <janneke@gnu.org>
11 ;; (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?
26 (define LILYPONDPREFIX
27 (or (getenv "LILYPONDPREFIX")
28 (let* ((bindir (dirname (car (command-line))))
29 (prefix (dirname bindir))
31 (if (eq? prefix (dirname DATADIR)) COMPILE-TIME-PREFIX
32 (format #f "~a/share/lilypond/~a"
33 prefix TOPLEVEL-VERSION))))
36 ;; gettext wrapper for guile < 1.7.2
37 (if (defined? 'gettext)
38 (define-public _ gettext)
39 (define-public (_ x) x))
41 (define (show-version port)
42 (format port "~a (GNU LilyPond) ~a \n" PROGRAM-NAME TOPLEVEL-VERSION))
44 (define (show-help port)
45 (format port (_ "Usage: lilypond-invoke-editor [textedit://]FILE:LINE:CHAR:COLUMN
47 Visit a file and position the cursor.
50 -h, --help show this help
51 -v, --version show version
54 (define (parse-options args)
55 (let* ((options (getopt-long args
56 '((help (single-char #\h))
57 (version (single-char #\v)))))
58 (files (cdr (assq '() options))))
59 (if (assq 'help options)
61 (show-version (current-output-port))
62 (show-help (current-output-port))
64 (if (assq 'version options)
65 (begin (show-version (current-output-port)) (exit 0)))
66 (show-version (current-error-port))
69 (define (re-sub re sub string)
70 (regexp-substitute/global #f re string 'pre sub 'post))
72 ;; FIXME: I'm going slowly but certainly mad, I really cannot find the
73 ;; scm library function for this.
74 (define (unquote-uri uri)
75 (re-sub "%([A-Fa-f0-9]{2})"
77 (string (integer->char (string->number (match:substring m 1) 16))))
80 (define (dissect-uri uri)
81 (let* ((ri "textedit://")
82 (file-name:line:char:column (re-sub ri "" uri))
83 (match (string-match "(.*):([^:]+):([^:]+):(.*)$" file-name:line:char:column)))
85 (list (unquote-uri (match:substring match 1))
86 (match:substring match 2)
87 (match:substring match 3)
88 (match:substring match 4))
90 ;; FIXME: why be so strict wrt :LINE:COLUMN,
91 ;; esp. considering omitting textedit:// is explicitly
93 (format (current-error-port) (_ "invalid URI: ~a") uri)
94 (newline (current-error-port))
95 (format (current-error-port) (_ "expect: ~aFILE:LINE:CHAR:COLUMN") ri)
96 (newline (current-error-port))
102 (car (string-tokenize (vector-ref (uname) 0) char-set:letter)))))
104 (define (running-from-gui?)
105 (let ((have-tty? (isatty? (current-input-port))))
106 ;; If no TTY and not using safe, assume running from GUI.
110 (let ((files (parse-options args)))
111 (if (running-from-gui?)
112 (redirect-port (current-error-port)
113 (open-file (string-append
117 "/lilypond-invoke-editor.log") "a")))
118 (if (not (= (length files) 1))
120 (show-help (current-error-port))
122 (set! %load-path (cons LILYPONDPREFIX %load-path))
123 (primitive-eval '(use-modules (scm editor)))
124 (let* ((uri (car files))
125 (command (apply get-editor-command (dissect-uri uri)))
126 (status (system command)))
127 (if (not (= status 0))
129 (format (current-error-port)
130 (_ "failed to invoke editor: ~a") command)