2012-03-27 20 views
5

Estoy escribiendo un módulo elisp que requiere un archivo de texto externo.¿Cómo puedo empaquetar un archivo de texto "externo" en un módulo elisp?

Para lo curioso, el módulo integra the interactive JS REPL for Cscript.exe con modo shell en emacs. Me permite ejecutar un shell javascript interactivo en emacs, en Windows.

Esto fue motivado por js-comint.el, pero es una implementación independiente que depende de Windows y cscript.exe.

Actualmente está funcionando, pero hay dos archivos distintos: el archivo .el y el archivo .js. Prefiero tener solo un archivo.

La pregunta que tengo es esta: ¿cómo puedo empaquetar el archivo .js externo que es un requisito previo para esto, en el archivo .el, para que pueda tener una instalación de un solo archivo?

Imagino que podría simplemente definir una variable de cadena con el archivo js (quizás minificado) e insertarlo en el módulo .el. Supongo que habrá algunos problemas de escape de cadenas pero esto funcionará. ¿Es esa la mejor manera? ¿Cualquier otra sugerencia?

Respuesta

1

bien, no encontré una manera mejor de hacer esto. Pero sí decidí que insertar el código JavaScript en el módulo elisp como una cadena ... funcionó bastante bien.

Para hacerlo realidad, escribí una función elisp corta, que crea un nuevo módulo elisp. Selecciona un nuevo nombre basado en el nombre anterior - xxxx-bundle.el en lugar de xxxx.el. Luego escribe el contenido del archivo .el original en un archivo con el nuevo nombre. Luego escribe una declaración simple setq en el mismo archivo; todo el programa de Javascript es el valor de cadena literal en esa declaración. Lo que hace que el setq sea fácil es la función pp-to-string en elisp, que escapa a todo el código Javascript en una cadena literal adecuada para su uso en emacs.

El fn para generar el paquete se parece a esto:

(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")))))) 

El fn ayudante para minimizar el contenido simplemente se derrumba espacios en blanco y elimina los saltos de línea consecutivos, ese tipo de cosas.

El archivo .el resultante puede hacer referencia a la variable jsshell-js-src, que contiene la fuente minimizada de Javascript. Se ve así:

enter image description here

Quiero poner esto aquí porque creo que el enfoque sería probablemente útil en otros módulos, así - todo lo que necesita para empaquetar un archivo de datos separado.

Cuestiones relacionadas