Instalar Emacs como servicio
Table of Contents
Los usarios de emacs tenemos un complejo de inferioridad respecto del tiempo de arranque de la aplicación. Se han hecho muchos intentos para mejorarlo, como el portable dumper o profile-dot-emacs, pero es innegable que vi y vscode arrancan más rápido.
Al final, la mejor solución no es reducir el tiempo de arranque, sino camuflarlo. La mayoría de usuarios de emacs no abren una instancia cada vez que lo necesitan, sino que emacs está corriendo permanentemente y se abren nuevas frames o windows. La forma de trabajo sería la siguiente
- Abrir una instancia de emacs y arrancar el servidor.
- Cuando se necesite abrir un fichero, no se ejecuta una nueva instancia de emacs, sino que se utiliza emacsclient. Este se conecta a la instancia inicial.
El hack final es hacer que la instancia de emacs se arranque automáticamente al iniciar sesión, o mejor aún, cuando se inicia el sistema como un servicio.
Utilizo este mismo fichero org para publicar esta entrada y para configurar mis ordenadores GNU Linux, con literate programming. Para activar la ejecución de bloques shell necesito ejecutar el siguiente bloque elisp:
(org-babel-do-load-languages
'org-babel-load-languages
'(
(shell . t)))
1. Servicio
Basado en https://www.emacswiki.org/emacs/EmacsAsDaemon, utilizo la versión de centos, ya que funciona en centos y ubuntu. La diferencia está en el directorio que uso para dejar la unit:
- En centos es
/usr/lib/systemd/system/emacs@.service - Ubuntu es
/lib/systemd/system/emacs@.service
Este bloque de código se ejecuta en el directorio /sudo::, lo que indica a emacs que debe ejecutarlo con sudo utilizando TRAMP.
SERVICEFILE=/lib/systemd/system/emacs@.service EMACSDIR=/usr/local/bin sudo tee > $SERVICEFILE <<EOF [Unit] Description=Emacs: the extensible, self-documenting text editor [Service] Type=forking ExecStart=$EMACSDIR/emacs --daemon --user %i ExecStop=$EMACSDIR/emacsclient --eval "(progn (setq kill-emacs-hook 'nil) (kill-emacs))" Restart=always User=%i WorkingDirectory=/home/%i [Install] WantedBy=multi-user.target EOF chmod u+r,g+r,o+r $SERVICEFILE sudo systemctl daemon-reload sudo systemctl enable emacs@alvaro
2. Cliente
2.1. fichero .desktop
Sistemas con Gnome o KDE utilizan ficheros .desktop para añadir aplicaciones a sus menús de inicio. Voy a añadir una nueva aplicación para emacsclient, basándome en el fichero .desktop que ya viene con emacs y la documentación en https://specifications.freedesktop.org/desktop-entry-spec/latest/index.html
EMACSDIR=/usr/local/bin cat > ~/.local/share/applications/emacsclient.desktop <<EOF #!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Name=GNU Emacs Client GenericName=Text Editor Comment=View and edit files MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; Exec=$EMACSDIR/emacsclient --create-frame --alternate-editor "" %F Type=Application Icon=$HOME/.local/share/applications/emacsclient.svg Terminal=false Categories=Utility;Development;TextEditor; StartupWMClass=Emacs EOF
2.2. Icono
Para estar seguro de que el icono existe, copio el fichero svg que tengo para emacs26 al lado del fichero .desktop.
cat > ~/.local/share/applications/emacsclient.svg <<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
id="svg4768"
viewBox="0.171 0.201 512 512"
height="48"
width="48"
version="1.0"><metadata
id="metadata70"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><!-- Gnu Emacs Icon
Copyright (C) 2008-2019 Free Software Foundation, Inc.
Author: Nicolas Petton <nicolas@petton.fr>
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
--><!-- Created with Inkscape (http://www.inkscape.org/) --><defs
id="defs4770"><linearGradient
id="linearGradient4292"><stop
id="stop4294"
offset="0"
style="stop-color:#411f5d;stop-opacity:1" /><stop
id="stop4296"
offset="1"
style="stop-color:#5b2a85;stop-opacity:1" /></linearGradient><linearGradient
id="linearGradient4284"><stop
offset="0"
style="stop-color:#8381c5;stop-opacity:1"
id="stop4286" /><stop
id="stop4290"
style="stop-color:#7e55b3;stop-opacity:0.99607843"
offset="0.56639391" /><stop
offset="1"
style="stop-color:#a52ecb;stop-opacity:0.99215686"
id="stop4288" /></linearGradient><linearGradient
id="linearGradient4898"><stop
id="stop4278"
style="stop-color:#bab8db;stop-opacity:1"
offset="0" /><stop
id="stop4280"
style="stop-color:#5955a9;stop-opacity:0.99159664"
offset="1" /></linearGradient><linearGradient
id="linearGradient3294"><stop
offset="0"
style="stop-color:#6376e6;stop-opacity:1"
id="stop3296" /><stop
offset="0.50094414"
style="stop-color:#222989;stop-opacity:1"
id="stop3302" /><stop
offset="1"
style="stop-color:#00003d;stop-opacity:1"
id="stop3298" /></linearGradient><linearGradient
id="linearGradient3284"><stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3286" /><stop
offset="0.84845906"
style="stop-color:#000000;stop-opacity:0.49803922"
id="stop3292" /><stop
offset="1"
style="stop-color:#000000;stop-opacity:0"
id="stop3288" /></linearGradient><linearGradient
id="linearGradient3274"><stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3276" /><stop
offset="1"
style="stop-color:#000000;stop-opacity:0"
id="stop3278" /></linearGradient><linearGradient
id="linearGradient3262"><stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop3264" /><stop
offset="1"
style="stop-color:#000000;stop-opacity:0"
id="stop3266" /></linearGradient><linearGradient
id="linearGradient3242"><stop
offset="0"
style="stop-color:#282828;stop-opacity:1"
id="stop3244" /><stop
offset="0.39253417"
style="stop-color:#808080;stop-opacity:1"
id="stop3252" /><stop
offset="1"
style="stop-color:#d9d9d9;stop-opacity:1"
id="stop3246" /></linearGradient><linearGradient
id="linearGradient3202"><stop
offset="0"
style="stop-color:#2b2b2b;stop-opacity:1"
id="stop3204" /><stop
offset="0.5"
style="stop-color:#828383;stop-opacity:1"
id="stop3250" /><stop
offset="1"
style="stop-color:#dadbdb;stop-opacity:1"
id="stop3206" /></linearGradient><linearGradient
id="linearGradient4966"><stop
offset="0"
style="stop-color:#b6b3d8;stop-opacity:1"
id="stop4968" /><stop
offset="1"
style="stop-color:#b6b3d8;stop-opacity:0"
id="stop4970" /></linearGradient><linearGradient
id="linearGradient4938"><stop
offset="0"
style="stop-color:#000000;stop-opacity:1"
id="stop4940" /><stop
offset="1"
style="stop-color:#000000;stop-opacity:0"
id="stop4942" /></linearGradient><linearGradient
id="linearGradient4282"><stop
offset="0"
style="stop-color:#bab8db;stop-opacity:1"
id="stop4900" /><stop
offset="1"
style="stop-color:#5955a9;stop-opacity:0.99159664"
id="stop4902" /></linearGradient><linearGradient
id="linearGradient4876"><stop
offset="0"
style="stop-color:#d3d2e8;stop-opacity:1"
id="stop4878" /><stop
offset="1"
style="stop-color:#5955a9;stop-opacity:0.99159664"
id="stop4880" /></linearGradient><radialGradient
gradientTransform="matrix(0.6817439,0,0,0.5905355,-3.8523706,-28.935273)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4898"
id="radialGradient4892"
fy="-108.96888"
fx="20.951529"
r="266.76535"
cy="-108.96888"
cx="20.951529" /><radialGradient
gradientTransform="matrix(1,0,0,0.1854103,0,383.88493)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4938"
id="radialGradient4944"
fy="471.26172"
fx="233.8876"
r="170.49393"
cy="471.26172"
cx="233.8876" /><radialGradient
gradientTransform="matrix(1,0,0,0.9121621,0,32.654948)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4966"
id="radialGradient4972"
fy="371.76376"
fx="299.70135"
r="76.696358"
cy="371.76376"
cx="299.70135" /><radialGradient
gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,346.95314,49.479585)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3202"
id="radialGradient3210"
fy="390.45248"
fx="289.44067"
r="17.67668"
cy="390.45248"
cx="289.44067" /><radialGradient
gradientTransform="matrix(0.414705,0.3300575,-0.5059004,0.6356454,448.41009,-65.398074)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3202"
id="radialGradient3238"
fy="382.14804"
fx="283.50717"
r="17.67668"
cy="382.14804"
cx="283.50717" /><radialGradient
gradientTransform="matrix(-6.5565014e-2,-5.9721765e-2,1.6871024,-1.8521705,171.90774,540.51473)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3242"
id="radialGradient3248"
fy="181.18982"
fx="418.45551"
r="63.068935"
cy="181.18982"
cx="418.45551" /><radialGradient
gradientTransform="matrix(0.4055116,-3.3440123e-2,0.1034174,4.3988695,177.23251,-1191.6649)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3262"
id="radialGradient3268"
fy="357.33591"
fx="354.51709"
r="33.712105"
cy="357.33591"
cx="354.51709" /><radialGradient
gradientTransform="matrix(-0.1339874,-0.1146812,0.3079048,-0.3597394,444.23592,395.03849)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3274"
id="radialGradient3280"
fy="223.55537"
fx="510.58469"
r="132.28336"
cy="223.55537"
cx="510.58469" /><radialGradient
gradientTransform="matrix(-1.2497569,1.3798305,-9.6289463e-2,-7.2974479e-2,674.3826,-70.590682)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3284"
id="radialGradient3290"
fy="-158.17821"
fx="284.4671"
r="110.2972"
cy="-158.17821"
cx="284.4671" /><radialGradient
gradientTransform="matrix(-0.1008165,-8.0872321e-2,1.0745309,-1.3395252,13.843287,784.79288)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient3294"
id="radialGradient3300"
fy="356.62274"
fx="425.51019"
r="143.34167"
cy="356.62274"
cx="425.51019" /><filter
height="1.088351"
y="-0.044175496"
width="1.0892536"
x="-0.044626798"
id="filter4350"
style="color-interpolation-filters:sRGB"><feGaussianBlur
id="feGaussianBlur4352"
stdDeviation="8.7848425" /></filter><linearGradient
y2="300.73987"
x2="236.61363"
y1="-161.8512"
x1="-122.20192"
spreadMethod="pad"
gradientTransform="matrix(0.87385837,0,0,0.82818057,246.00762,250.28138)"
gradientUnits="userSpaceOnUse"
id="linearGradient4245"
xlink:href="#linearGradient4284" /><linearGradient
y2="66.018341"
x2="173.94518"
y1="396.6066"
x1="447.80933"
gradientTransform="matrix(0.98684959,0,0,0.98684959,3.0344187,2.5250397)"
gradientUnits="userSpaceOnUse"
id="linearGradient4247"
xlink:href="#linearGradient4292" /></defs><rect
style="fill:none;display:none"
id="rect4772"
y="0.20100001"
x="0.171"
height="512"
width="512" /><g
style="display:none"
id="g4788"><g
style="display:inline"
id="g4790" /></g><g
style="display:none"
id="g4806"><g
style="display:inline"
id="g4808"><path
style="fill:#050505;display:none"
id="path4810"
d="M 349.098,256.651 C 348.833,256.397 386.735,284.256 388.519,281.663 C 394.881,272.411 470.565,188.526 473.303,165.427 C 473.545,163.424 472.787,161.331 472.787,161.331 C 472.787,161.331 471.597,161.187 466.462,157.017 C 463.77,154.825 460.979,152.436 460.979,152.436 C 444.925,153.434 403.094,193.995 349.917,256.004" /></g></g><path
style="opacity:0.40500004;fill:#211f46;fill-opacity:0.99607843;stroke:#0a0b1b;stroke-width:8.53333378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4350)"
id="path4233"
d="m 491.66937,257.75916 c 0,131.79436 -105.76,238.63481 -236.22155,238.63481 -130.46155,0 -236.221539,-106.84045 -236.221539,-238.63481 0,-131.79437 105.759989,-238.634808 236.221539,-238.634808 130.46155,0 236.22155,106.840438 236.22155,238.634808 z"
transform="matrix(0.98684957,0,0,0.98684957,3.0344041,2.5250397)" /><path
d="m 488.23812,256.89456 c 0,130.06121 -104.3692,235.49665 -233.1151,235.49665 -128.7459,0 -233.115201,-105.43544 -233.115201,-235.49665 0,-130.06123 104.369301,-235.49666 233.115201,-235.49666 128.7459,0 233.1151,105.43543 233.1151,235.49666 z"
id="path4235"
style="opacity:1;fill:url(#linearGradient4245);fill-opacity:1;stroke:url(#linearGradient4247);stroke-width:13.33816814;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
d="m 175.0003,422.31057 c 0,0 19.7385,1.39634 45.1312,-0.84159 10.2834,-0.9063 49.3267,-4.74128 78.5169,-11.14289 0,0 35.5899,-7.61669 54.6301,-14.63335 19.9225,-7.34185 30.7636,-13.57304 35.6433,-22.40243 -0.2128,-1.80907 1.5024,-8.22438 -7.685,-12.07788 -23.4887,-9.85199 -50.73,-8.06998 -104.6338,-9.21285 -59.7772,-2.05391 -79.6627,-12.05971 -90.2556,-20.11838 -10.1579,-8.17519 -5.05,-30.79254 38.4742,-50.71499 21.9244,-10.60898 107.8705,-30.18698 107.8705,-30.18698 -28.9451,-14.30725 -82.9186,-39.45893 -94.0134,-44.89023 -9.7308,-4.76348 -25.303,-11.93595 -28.6785,-20.61368 -3.8271,-8.33089 9.0383,-15.50726 16.2248,-17.56236 23.1448,-6.67602 55.8182,-10.82538 85.5548,-11.29122 14.9472,-0.23417 17.3734,-1.19586 17.3734,-1.19586 20.6243,-3.42116 34.2014,-17.53175 28.5446,-39.87876 -5.0783,-22.81046 -31.8617,-36.21365 -57.3138,-31.57361 -23.9682,4.36956 -81.7378,21.15007 -81.7378,21.15007 71.4075,-0.61803 83.3592,0.57378 88.697,8.03676 3.1523,4.40742 -1.4324,10.45068 -20.4765,13.56099 -20.733,3.38616 -63.8312,7.46399 -63.8312,7.46399 -41.3449,2.4554 -70.4682,2.61974 -79.203,21.11314 -5.7065,12.08196 6.0854,22.7633 11.2538,29.4493 21.8407,24.28905 53.3882,37.38879 73.6948,47.03553 7.6405,3.62963 30.0586,10.48407 30.0586,10.48407 -65.8782,-3.62335 -113.4003,16.6055 -141.2764,39.89622 -31.5288,29.16261 -17.581403,63.92354 47.0124,85.3268 38.1517,12.6416 57.0725,18.58695 113.9815,13.46232 33.52,-1.80673 38.8041,-0.73155 39.1383,2.01892 0.4705,3.87242 -37.2311,13.49165 -47.524,16.4606 -26.1853,7.55306 -94.8276,22.80438 -95.1712,22.87835 z"
id="path4237"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></svg>
EOF
3. Problemas
- emacsclient no encuentra el socket: añadir el parámetro
-scon/tmp/emacs1000/server. El número1000indica el identificador del usuario. También puede especificarse la variableserver-socket-diral iniciar el servidor.