{"id":570,"date":"2014-03-05T22:42:15","date_gmt":"2014-03-05T20:42:15","guid":{"rendered":"http:\/\/www.blackhats.es\/wordpress\/?p=570"},"modified":"2022-08-20T18:25:37","modified_gmt":"2022-08-20T16:25:37","slug":"ejecucion-de-swank-servidor-lisp-y-emacs-como-cliente","status":"publish","type":"post","link":"https:\/\/www.blackhats.es\/wordpress\/?p=570","title":{"rendered":"Ejecucion de Swank (servidor Lisp) y Emacs (como cliente)"},"content":{"rendered":"<p>SLIME esta implementado de tal forma que puede ejecutarse el cliente Emacs desde un lado (<strong>slime.el<\/strong>) mientras el servidor Lisp en otra maquina distinta. Asi que en un host ejecutaremos emacs y le diremos a SLIME que conecte a una maquina remota.<\/p>\n<p><span style=\"color: #ff6600;\"><strong>Conectando a un Lisp remoto<\/strong><\/span><\/p>\n<pre>Si queremos cargar swank sin ejecutar emacs de manera habitual, debemos ejecutar lo siguiente:<\/pre>\n<pre style=\"padding-left: 30px;\"><em>(load \"\/path\/to\/swank-loader.lisp\")\r\n(swank-loader:init)<\/em><\/pre>\n<pre>Dentro de la imagen lisp que se esta ejecutando, tan solo debemos iniciar el servidor swank.<\/pre>\n<pre style=\"padding-left: 30px;\"><em>(swank:create-server)<\/em><\/pre>\n<p>Como vamos a tener tunneling en nuestra conexion mediante ssh, podemos indicar a sawnk que no use una conexion extra para la salida, de la siguiente forma:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(setf swank:*use-dedicated-output-stream* nil)<\/em><\/pre>\n<p>Si debemos realizar ciertas tareas tales como reconectar a swank, debemos mirar en otros argumentos de swank:create-server. Estos argumentos son:<\/p>\n<p style=\"padding-left: 30px;\"><strong><span style=\"color: #008000;\">:PORT<\/span><\/strong> : Puerto del servidor de escucha (por defecto es 4005).<\/p>\n<p style=\"padding-left: 30px;\"><strong><span style=\"color: #008000;\">:STYLE<\/span><\/strong> : Estilo de comunicacion<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #008000;\"><strong>:DONT-CLOSE<\/strong> <\/span>: Valor booleano que indica si el servidor continua aceptando conexiones despues de recibir la primera (por defecto es NIL). Util si tenemos procesos lisp ejecutandose por largo periodo de tiempo, donde conectariamos en diferentes momentos, en dicho caso deberiamos especificar :dont-close t.<\/p>\n<p style=\"padding-left: 30px;\"><strong><span style=\"color: #008000;\">:CODING-SYSTEM<\/span><\/strong> : Sistema de codificacion usado para la comunicacion entre Emacs y Lisp.<\/p>\n<p>Un ejemplo completo con estos argumentos:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(swank:create-server :port 4005  :dont-close t :coding-system \"utf-8-unix\")<\/em><\/pre>\n<p>Mientras que en el lado de emacs deberiamos usar esto para dicha configuracion:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(setq slime-net-coding-system 'utf-8-unix)\r\n(slime-connect \"127.0.0.1\" 4005)<\/em><\/pre>\n<p><span style=\"color: #ff6600;\"><strong>Configurando el cliente Emacs<\/strong><\/span><\/p>\n<p>Desde aqui necesitamos crear un tunel ssh en el puerto 4005 desde nuestra maquina local hasta el puerto 4005 en la maquina remota.<\/p>\n<p style=\"padding-left: 30px;\"><strong>$ ssh -L4005:127.0.0.1:4005 username@remote.example.com<\/strong><\/p>\n<p>Despues de esto podemos ejecutar SLIME mediante <strong>M-x slime-connect.<\/strong><\/p>\n<p><span style=\"color: #ff6600;\"><strong>Configurando las translaciones pathname<\/strong><\/span><\/p>\n<p>Cuando ejecutamos swank remotamente, Emacs asume que los ficheros que se vayan a encontrar son ficheros normales. Sin embargo, si queremos <span style=\"text-decoration: underline;\">slime-compile-and-load-file<\/span> (<strong>C-c C-k<\/strong>) y <span style=\"text-decoration: underline;\">slime-edit-definition<\/span> (<strong>M-.<\/strong>) para trabajar correctamente, necesitamos encontrar algun modo de decirle a nuestro Emacs local que debe referirse a ficheros remotos.<\/p>\n<p>Existen principalmente dos formas de hacer esto. La primera es usar mount, NFS o similar, el disco duro de la maquina remota sera visible en nuestro sistema de ficheros local como cualquier otro fichero. Sin embargo NFS es realmente lento, con bugs etc. Es por eso que la mejor forma es tener una conexion ssh y emacs con tramp-mode para hacer el resto. Lo que hacemos es decirle a Emacs como debe coger el fichero en una maquina remota y traducirlo en algo que tramp puede entender y acceder. cl:machine-instance devuelve el \u00abhostname\u00bb para una maquina remota como hostname.domain.com.\u00a0 Por lo que podemos tener algo asi:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(add-to-list 'slime-filename-translations\r\n             (slime-create-filename-translator\r\n              :machine-instance \"hostname\"\r\n              :remote-host \"hostname.domain.com\"\r\n              :username \"user\"))<\/em><\/pre>\n<p><span style=\"color: #ff6600;\"><strong>Redireccion global de todo IO al REPL<\/strong><\/span><\/p>\n<p>Por defecto SLIME no cambia <span style=\"color: #ff00ff;\">*standard-output*<\/span>\u00a0 y variantes fuera del REPL. Por lo que si tenemos cualquier otro thread el cual llama format, write-string, etc. La salida solo sera vista en <span style=\"color: #ff00ff;\">*inferior-lisp*<\/span> buffer o en la terminal. Por lo que podemos hacer es:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(run-in-new-thread\r\n  (lambda ()\r\n    (write-line \"In some random thread.~%\" *standard-output*)))<\/em><\/pre>\n<p>Para enviar la salida al buffer REPL de SLIME, de manera contraria a <span style=\"color: #ff00ff;\">*inferior-lisp*<\/span>, configuramos <span style=\"color: #ff00ff;\">swank:*globally-redirect-io*<\/span> a T.<\/p>\n<p>El valor de esta variable solo es checkeado una vez cuando swank acepta la conexion. Por lo que debemos configurarlo mediante <strong>~\/.swank.lisp<\/strong>, ya que sino necesitaremos llamar a <span style=\"color: #ff00ff;\">swank::globally-redirect-io-to-connection<\/span> manualmente.<\/p>\n<p><span style=\"color: #ff6600;\"><strong>Conectando a SLIME de manera automatica<\/strong><\/span><\/p>\n<p>Para hacer que SLIME conecte a nuestro Lisp cualquiera que sea nuestro fichero lisp abierto, debemos anadir esto en nuestro <strong>.emacs<\/strong>:<\/p>\n<pre style=\"padding-left: 30px;\"><em>(add-hook 'slime-mode-hook\r\n          (lambda ()\r\n            (unless (slime-connected-p)\r\n              (save-excursion (slime)))))<\/em><\/pre>\n<p>Para entender un poco mejor la arquitectura de SLIME, Swank y Emacs podemos visualizar el siguiente grafico:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.blackhats.es\/wordpress\/?attachment_id=580\" rel=\"attachment wp-att-580\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter  wp-image-580\" alt=\"slime_swank\" src=\"https:\/\/www.blackhats.es\/wordpress\/wp-content\/uploads\/2014\/03\/slime_swank.jpg\" width=\"640\" height=\"286\" srcset=\"https:\/\/www.blackhats.es\/wordpress\/wp-content\/uploads\/2014\/03\/slime_swank.jpg 800w, https:\/\/www.blackhats.es\/wordpress\/wp-content\/uploads\/2014\/03\/slime_swank-300x133.jpg 300w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>SLIME esta implementado de tal forma que puede ejecutarse el cliente Emacs desde un lado (slime.el) mientras el servidor Lisp en otra maquina distinta. Asi que en un host ejecutaremos emacs y le diremos a SLIME que conecte a una maquina remota. Conectando a un Lisp remoto Si queremos cargar swank sin ejecutar emacs de [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[297],"tags":[312,309,311,67,8,313,66,173,310,314,306],"class_list":["post-570","post","type-post","status-publish","format-standard","hentry","category-advanced","tag-advanced-emacs","tag-client","tag-cliente-emacs","tag-elisp","tag-emacs","tag-emacs-avanzado","tag-lisp","tag-server","tag-servidor-lisp","tag-slime-architecture","tag-swank"],"_links":{"self":[{"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/570"}],"collection":[{"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=570"}],"version-history":[{"count":5,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions"}],"predecessor-version":[{"id":745,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/570\/revisions\/745"}],"wp:attachment":[{"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blackhats.es\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}