Как я могу упаковать «внешний» текстовый файл в модуль elisp? - PullRequest
5 голосов
/ 27 марта 2012

Я пишу модуль elisp, для которого требуется внешний текстовый файл.

Для любопытных, модуль интегрирует интерактивный JS REPL для Cscript.exe с режимом оболочки в emacs.Это позволяет мне запускать интерактивную оболочку javascript в emacs, в Windows.

Это было мотивировано js-comint.el , но является отдельной реализацией, зависящей от Windows и cscript.exe.

В настоящее время он работает, но есть два разных файла: файл .el и файл .js.Я бы предпочел иметь только один файл.

У меня такой вопрос: как мне упаковать внешний файл .js, который необходим для этого, в файл .el, чтобыЯ могу установить один файл?

Я полагаю, я мог бы просто определить строковую переменную с помощью (возможно минимизированного) файла js и вставить ее в модуль .el.Я предполагаю, что будет несколько проблем с выходом строки, но это сработает.Это лучший способ?Любые другие предложения?

1 Ответ

1 голос
/ 28 марта 2012

хорошо, я не нашел лучшего способа сделать это. Но я решил, что встраивание кода Javascript в модуль elisp в виде строки ... работает довольно хорошо.

Чтобы это произошло, я написал короткую функцию elisp, которая создает новый модуль elisp. Он выбирает новое имя на основе старого имени - xxxx-bundle.el вместо xxxx.el. Затем он записывает содержимое исходного файла .el в файл с новым именем. Затем он записывает простое выражение setq в тот же файл; вся программа Javascript - это буквальное строковое значение в этом операторе. То, что делает setq простым, это функция pp-to-string в elisp, которая экранирует весь код Javascript в литеральную строку, подходящую для использования в emacs.

Fn для генерации пакета выглядит так:

(defun jsshell-produce-bundle (&optional jsshell-el bundle-el jsshell-js)
  "Produce a new .el file, which contains all the jsshell.el
function and also embeds the jsshell.js source as a string. The
resulting .el file will then be suitable for a one-file
distribution of JSShell.

JSShell depends on two pieces: jsshell.el and jsshell.js. Rather
than distributing and installing two distinct files, the bundle
embeds the .js file into the .el file, for a one-file
distribution option. This function produces that one file.

Most people will never need to use this function. It's useful only
after modifying either the original jsshell.el or the jsshell.js file,
when you want to produce a new distributable bundle. In other words, it's
useful for the developer of jsshell.el.

"
  (let ((jsshell-el (or jsshell-el
                        (concat (file-name-directory jsshell--load-path) "jsshell.el")

                        "jsshell.el")))
    (let ((bundle-el  (or bundle-el
                          (concat (file-name-directory jsshell-el) "jsshell-bundle.el")))
          (jsshell-js (or jsshell-js
                          (and jsshell-js-tmpf
                               (file-readable-p jsshell-js-tmpf)
                               jsshell-js-tmpf)
                          jsshell-location-of-jsshell-js ;; orig dev wkstation
                          (concat (file-name-directory jsshell-el) "jsshell.js")))
          jssrc)
      (with-temp-file bundle-el
        (insert (concat
                 ";;; "
                 (file-name-nondirectory bundle-el)
                 " -- JSShell generated bundle\n"))
        (insert (concat ";;\n;; generated " (current-time-string) "\n;;\n\n"))
        (insert-file-contents jsshell-el)
        (goto-char (point-max))
        (insert "\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n")
        (insert ";; this is the embedded Javascript code for the JS REPL\n\n")
        (setq jssrc (jsshell--minimized-js-contents jsshell-js))
        (goto-char (point-max))
        (insert (concat "(setq jsshell-js-src "
                        (pp-to-string jssrc)
                        ")\n"
                        "\n(provide '"
                        (file-name-sans-extension (file-name-nondirectory bundle-el))
                        ")\n"
                        "\n;;; "
                        (file-name-nondirectory bundle-el)
                        " ends\n"))))))

Помощник fn для минимизации содержимого просто разрушает пробелы и устраняет последовательные переводы строк, и тому подобное.

Полученный файл .el может затем ссылаться на переменную jsshell-js-src, которая содержит минимизированный источник Javascript. Это выглядит так:

enter image description here

Я публикую это здесь, потому что думаю, что этот подход, вероятно, будет полезен и для других модулей - всего, что требует объединения отдельного файла данных.

...