<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux Sin Humo (Publicaciones sobre tutorials)</title><link>https://sergiobelkin.com/</link><description></description><atom:link href="https://sergiobelkin.com/categories/cat_tutorials.xml" rel="self" type="application/rss+xml"></atom:link><language>es</language><copyright>Contents © 2026 &lt;a href="mailto:sebelk@gmail.com"&gt;sebelk&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"&gt;&lt;/a&gt;
</copyright><lastBuildDate>Mon, 18 May 2026 00:35:29 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Una introducción pragmática al uso de plugins en Neovim</title><link>https://sergiobelkin.com/posts/una-introduccion-pragmatica-al-uso-de-plugins-en-neovim/</link><dc:creator>sebelk</dc:creator><description>&lt;p&gt;Ya me he referido a Neovim alguna vez en el pasado: &lt;a href="https://sergiobelkin.com/posts/2017/11/20/lo-viejo-lo-bueno-y-lo-nuevo-en-neovim/"&gt;Lo viejo, lo bueno y lo nuevo en Neovim &lt;/a&gt;. 
Se pueden extender las funcionalidades de neovim, mediante plugins, de manera similar a las de su predecesor, el editor Vim. 
&lt;strong&gt;En este artículo propongo un modo muy sencillo y lo más transparente posible para el uso de plugins en Neovim.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hay dos tipos de plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Globales&lt;/strong&gt;: Funcionan para todo tipo de archivos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filetype&lt;/strong&gt;: Sirven para un tipo particular de archivos**.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El siguiente listado muestra plugins globales que forman parte del core de neovim:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;ls -l /usr/share/nvim/runtime/plugin&lt;/span&gt;
&lt;span class="n"&gt;total 60&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  411 mar 26 10:48 editorconfig.lua&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 3677 mar 26 10:48 gzip.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  904 mar 26 10:48 man.lua&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  138 mar 26 10:48 matchit.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 7966 mar 26 10:48 matchparen.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  152 mar 26 10:48 netrwPlugin.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 2160 mar 26 10:48 osc52.lua&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 2017 mar 26 10:48 rplugin.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 1778 mar 26 10:48 shada.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  236 mar 26 10:48 spellfile.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 2527 mar 26 10:48 tarPlugin.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  442 mar 26 10:48 tohtml.lua&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root  202 mar 26 10:48 tutor.vim&lt;/span&gt;
&lt;span class="n"&gt;-rw-r--r-- 1 root root 2642 mar 26 10:48 zipPlugin.vim&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;Funcionalidad&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;editorconfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Busca y lee archivos .editorconfig para aplicar reglas de indentación, fines de línea  y codificación&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gzip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Editar archivos comprimidos con gzip&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;man&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Abrir páginas del manual en el editor&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;matchit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Extiende la funcionalidad del comando&lt;/em&gt; &lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;matchparen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Resalta paréntesis coincidentes&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netrwPlugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Maneja la transferencia de archivos y listado de directorios remotos a través de una red&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;osc52&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Detecta si es posible usar el código de escape ANSI para copir desde vim a otras terminales para poder copiar texto desde neovim usand el clipboard del sistema&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rplugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Gestiona, migra, actualiza y carga remote plugins automáticamente (están escritos en otros lenguajes como Python, Ruby, Node.js, etc y que se manejan de manera independiente del editor sin afectar el rendimiento)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shada&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Datos Compartidos entre las sesiones de neovim&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;spellfile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Descarga de archivos de ortografía&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tarPlugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Exploración de tarballs&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tohtml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Conversor a html&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tutor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Tutorial&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zipPlugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;Exploración de archivos zip&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Los scripts en vimL pueden contener comandos de edición, estructuras de control, funciones, manejo de listas, diccionarios, y puede simular objetos mediante diccionarios con referencias a funciones. El otro lenguaje nativo que incorpora neovim es &lt;strong&gt;Lua&lt;/strong&gt;. Los desarrolladores de neovim consideran que ese lenguaje es más eficiente, tiene una sintaxis más moderna y estándar, maneja mejor los errores, permite que sea extendido fácilmente con plugins y módulos complejos, sin necesidad de depender de procesos externos o hacks.&lt;/p&gt;
&lt;p&gt;Si consideramos el archivo del plugin &lt;strong&gt;man&lt;/strong&gt; contiene lo siguiente:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;loaded_man&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt;
&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;loaded_man&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nvim_create_user_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Man'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;man&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;bang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;man&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init_pager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;man&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;smods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;fargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man.lua: '&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;levels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;bang&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;bar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'other'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;nargs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;man_complete&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;augroup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nvim_create_augroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nvim.man'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;

&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'BufReadCmd'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;augroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'man://*'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;nested&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;callback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man://(.*)'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'man.lua: '&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;levels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="mini-resumen-conceptual-manlua"&gt;📝 Mini resumen conceptual — man.lua&lt;/h3&gt;
&lt;h4 id="que-hace-el-plugin"&gt;✔ ¿Qué hace el plugin?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Define &lt;strong&gt;cómo abrir manpages&lt;/strong&gt; usando comandos (&lt;code&gt;:Man&lt;/code&gt;) y URIs (&lt;code&gt;man://...&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Define &lt;strong&gt;cómo manejar errores&lt;/strong&gt; (usa &lt;code&gt;vim.notify&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="como-funciona"&gt;✔ ¿Cómo funciona?&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Previene carga múltiple&lt;/strong&gt; con &lt;code&gt;vim.g.loaded_man&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crea un comando&lt;/strong&gt; &lt;code&gt;:Man&lt;/code&gt; con opciones (bang, autocompletado, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crea un autocmd&lt;/strong&gt; que detecta buffers con URI &lt;code&gt;man://&lt;/code&gt; y carga la manpage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usa funciones&lt;/strong&gt; (&lt;code&gt;open_page&lt;/code&gt;, &lt;code&gt;init_pager&lt;/code&gt;, &lt;code&gt;read_page&lt;/code&gt;, &lt;code&gt;man_complete&lt;/code&gt;) definidas en el módulo &lt;code&gt;man&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Muestra errores&lt;/strong&gt; con &lt;code&gt;vim.notify&lt;/code&gt; si algo falla.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="que-flujo-sigue"&gt;✔ ¿Qué flujo sigue?&lt;/h4&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;Usuario → :Man o :edit man:// → función del módulo man → buffer con la manpage
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="el-plugin-es-100-todo-lua"&gt;✅ El plugin es 100% todo Lua&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Usa &lt;strong&gt;API moderna&lt;/strong&gt; de Neovim:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim.api.nvim_create_user_command&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim.api.nvim_create_autocmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim.notify&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;variables globales Lua&lt;/strong&gt;: &lt;code&gt;vim.g.loaded_man&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Usa funciones Lua: &lt;code&gt;string.match&lt;/code&gt;, &lt;code&gt;require&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Es un plugin moderno, pensado para ser usado con Neovim o Vim con soporte de Lua.&lt;/p&gt;
&lt;h3 id="api-para-plugins-y-herramientas"&gt;API para plugins y herramientas&lt;/h3&gt;
&lt;p&gt;Además, neovim posee una API con la cual se pueden hacer desarrollos en otros lenguajes de programación y por eso existen plugins y/o herramientas relacionadas que no están escritos en vimL o LUA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/nvim-java/nvim-java"&gt;Painless Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://neovim.io/node-client/"&gt;neovimi (node.js)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neoclide/coc.nvim"&gt;Nodejs extension host for vim &amp;amp; neovim, load extensions like VSCode and host language servers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/neovim/pynvim"&gt;Cliente de python para escribir plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El plugin &lt;strong&gt;&lt;a href="https://github.com/brooth/far.vim"&gt;far.vim&lt;/a&gt;&lt;/strong&gt; está desarrollado en python:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/far-plugin.png"&gt;&lt;img src="https://sergiobelkin.com/images/far-plugin.thumbnail.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Se debe ejecutar &lt;code&gt;:UpdateRemotePlugins&lt;/code&gt; cada vez que un plugin remoto se instale, se actualice, o se borre. Esto generará o actualizará un archivo manifest, por ejemplo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nvim&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;rplugin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="s"&gt;" node plugins&lt;/span&gt;


&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;python3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;
&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;remote&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;RegisterPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;python3&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nvim&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;plugged&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;far&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vim&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;rplugin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;far&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;sync&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;_far_nvim_rpc_async_invoke&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;function&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}},&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


&lt;span class="s"&gt;" ruby plugins&lt;/span&gt;


&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="equivalencias-entre-vim-y-neovim"&gt;Equivalencias entre Vim y Neovim&lt;/h3&gt;
&lt;p&gt;Abro un paréntesis para recordar las equivalencias entre archivos de Vim y Neovim:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Elemento&lt;/th&gt;
&lt;th&gt;Vim&lt;/th&gt;
&lt;th&gt;Neovim&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Config principal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vimrc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.config/nvim/init.vim&lt;/code&gt; o &lt;code&gt;init.lua&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carpeta de configuración&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.config/nvim/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins (autoload)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/autoload/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/share/nvim/site/autoload/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins (paquetes)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/pack/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/share/nvim/site/pack/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datos de usuario (swap, undo, backup, etc.)&lt;/td&gt;
&lt;td&gt;Dentro de &lt;code&gt;~/.vim/&lt;/code&gt; o definido por el usuario&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/state/nvim/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swap files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/swapfiles/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/state/nvim/swap/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undo files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/undodir/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/state/nvim/undo/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backup files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/backup/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/state/nvim/backup/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;viminfo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.viminfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;No se usa directamente&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shada&lt;/td&gt;
&lt;td&gt;&lt;em&gt;No aplica (usa viminfo)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.local/share/nvim/shada/main.shada&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Colorschemes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/colors/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.config/nvim/colors/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After directory (sobreescribir plugins/config)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.vim/after/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/.config/nvim/after/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Nota sobre &lt;em&gt;shada&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vim usa &lt;code&gt;viminfo&lt;/code&gt; → &lt;code&gt;~/.viminfo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Neovim usa &lt;code&gt;shada&lt;/code&gt; → &lt;code&gt;~/.local/share/nvim/shada/main.shada&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No es recomendable hacer enlace simbólico entre estos dos archivos porque no son 100% compatibles.&lt;/p&gt;
&lt;h3 id="soporte-nativo-para-plugins-en-vim-8-y-en-adelante"&gt;Soporte nativo para plugins en Vim 8 (y en adelante)&lt;/h3&gt;
&lt;!--&lt;a class="image-reference" href="/images/"handy-wicaksono-brizG9kR6qI-unsplash.jpg&gt;&lt;img src="/images/handy-wicaksono-brizG9kR6qI-unsplash.thumbnail.jpg" alt="Paquetes"&gt;&lt;/a&gt;--&gt;

&lt;p&gt;&lt;img alt="Paquetes en Vim" class="img-izquierda-responsiva" src="https://sergiobelkin.com/images/handy-wicaksono-brizG9kR6qI-unsplash.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@handywicaksono?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Handy Wicaksono&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/package?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Desde Vim 8.0 el editor cuenta con soporte nativo para paquetes. En Vim un paquete no es otra cosa que un directorio de plugins. Es decir, considerando el siguiente escenario.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/native-packages.png"&gt;&lt;img src="https://sergiobelkin.com/images/native-packages.thumbnail.png" alt="Estructura de directorios de sistema nativo de plugins"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;El paquete &lt;em&gt;lightline.vim&lt;/em&gt; se va a cargar automáticamente al abrir el editor, mientras que el otro plugin &lt;em&gt;toggleterm&lt;/em&gt; podrá activarse con el comando &lt;code&gt;:packadd toggleterm.nvim&lt;/code&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h4 id="guia-rapida-para-el-metodo-nativo-de-vim-8"&gt;Guía rápida para el método nativo de Vim 8+&lt;/h4&gt;
&lt;p&gt;Mostraré como usar 2 plugins.&lt;/p&gt;
&lt;h5 id="1-crear-las-carpetas-necesarias"&gt;1. Crear las carpetas necesarias&lt;/h5&gt;
&lt;p&gt;Abrí tu terminal y ejecutá:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/.vim/pack/misplugins/&lt;span class="o"&gt;{&lt;/span&gt;start,opt&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Explicación rápida:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.vim/pack/&lt;/code&gt; → carpeta donde Vim busca paquetes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;misplugins&lt;/code&gt; → nombre del grupo que quieras (puede ser cualquier nombre).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;start/&lt;/code&gt; → indica que los plugins se &lt;strong&gt;cargan automáticamente&lt;/strong&gt; al abrir Vim.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;opt/&lt;/code&gt;   → indica que los plugins se cargarán bajo demanda con el comando &lt;code&gt;packadd&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h5 id="2-descargar-los-plugins"&gt;2. Descargar los plugins&lt;/h5&gt;
&lt;p&gt;Ahora dentro de &lt;code&gt;start/&lt;/code&gt;, cloná los repositorios de Git de los plugins:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/.vim/pack/misplugins/opt

&lt;span class="c1"&gt;# vim-fugitive (permite ejecutar y gestionar comandos de Git directamente dentro de Vim, como hacer commits, ver logs, ver diferencias (diffs) y manejar ramas sin salir del editor.)&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://tpope.io/vim/fugitive.git
vim&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;NONE&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"helptags fugitive/doc"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;q

&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/.vim/pack/misplugins/start

&lt;span class="c1"&gt;# lightline.vim (barra de estado mejorada)&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/itchyny/lightline.vim.git
&lt;span class="c1"&gt;# Usar el comando siguiente si lightline.vim se muestre sin colores y guardarlo en algún archivo de configuración del shell.&lt;/span&gt;
&lt;span class="c1"&gt;# export TERM=xterm-256color &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Con esto ya los tenés instalados.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id="3-configuracion-para-lightlinevim"&gt;3. Configuración para lightline.vim|&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;Podés agregar algunas líneas en tu &lt;code&gt;~/.vimrc&lt;/code&gt; para aprovechar lightline.vim:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c"&gt;" Opcional: configuración mínima para lightline&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;laststatus&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h5 id="4-listo"&gt;4. Listo&lt;/h5&gt;
&lt;p&gt;¡Abrí Vim y ya podés usar el plugin lightline.vim! &lt;/p&gt;
&lt;p&gt;Si querés cargar el plugin fugitive, lo hacés con:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;:&lt;/span&gt;packadd fugitive
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Importante: Los plugins escritos en lua no funcionarán en Vim&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Algo interesante en Vim y Neovim es que podemos ver los plugins que ya vienen con el editor con el comando &lt;code&gt;:help standard-plugin-list&lt;/code&gt; y con &lt;code&gt;:help local-additions&lt;/code&gt; los plugins que vamos agregando:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/plugin-lists.gif"&gt;&lt;img src="https://sergiobelkin.com/images/plugin-lists.thumbnail.gif" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;O si preferimos algo más sofisticado, para ver nuestros plugins:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;:echo join(keys(g:plugs), ' ')&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Si bien esta funcionalidad también existe en Neovim,  podemos administrar los plugins de manera más flexible y automatizada. Esto nos lleva a considerar el uso de gestores de plugins.&lt;/p&gt;
&lt;h3 id="gestores-de-plugins"&gt;Gestores de plugins&lt;/h3&gt;
&lt;p&gt;Existen varios gestores de plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Shougo/dein.vim"&gt;Shougo/dein.vim: Dark powered Vim/Neovim plugin manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/VundleVim/Vundle.vim"&gt;VundleVim/Vundle.vim: Vundle, the plug-in manager for Vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/junegunn/vim-plug"&gt;junegunn/vim-plug: Minimalist Vim Plugin Manager&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Me parece muy recomendable &lt;strong&gt;vim-plug&lt;/strong&gt; porque:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requiere muy poca configuración: una lista con los paquetes de plugins deseados.&lt;/li&gt;
&lt;li&gt;Instala y actualiza todos los paquetes de nuestra lista o los que seleccionemos.&lt;/li&gt;
&lt;li&gt;Detecta y elimina plugins que borramos de nuestra lista. &lt;/li&gt;
&lt;li&gt;Muestra el estado de los plugins.&lt;/li&gt;
&lt;li&gt;Genera instantáneas de nuestros paquetes con su configuración, con la posibilidad de restaurarlas.&lt;/li&gt;
&lt;li&gt;Posee atajos de teclado.&lt;/li&gt;
&lt;li&gt;Es compatible tanto con Vim como Neovim&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si queremos deshabilitar todos los plugins podemos ejecutar &lt;code&gt;nvim --noplugin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Neovim sigue los lineamientos de la XDG Base Directory Specification. &lt;strong&gt;Algo que puede ser muy útil&lt;/strong&gt;: poner el listado de plugins en un archivo separado. Esto es: creando un archivo &lt;code&gt;${XDG_CONFIG_HOME:-$HOME/.config}/nvim/plugins.vim&lt;/code&gt; y en el archivo &lt;code&gt;${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim&lt;/code&gt; teniendo una simple línea:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;runtime plugins.vim&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Entonces, comentando esa línea es una manera alternativa para desactivarlos.&lt;/p&gt;
&lt;p&gt;Pero hay más: supongamos que tenemos esta configuración en el archivo &lt;code&gt;${XDG_CONFIG_HOME:-$HOME/.config}/nvim/plugins.vim&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nx"&gt;Plug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;nyngwang&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;NeoTerm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lua&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;plug&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="s"&gt;" Esta es la manera de embeber código lua en un archivo de tipo vimL&lt;/span&gt;
&lt;span class="s"&gt;lua &amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="s"&gt;require("&lt;/span&gt;&lt;span class="nx"&gt;neo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;term&lt;/span&gt;&lt;span class="s"&gt;").setup {&lt;/span&gt;
&lt;span class="s"&gt;  exclude_filetypes = { "&lt;/span&gt;&lt;span class="nx"&gt;oil&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;EOF&lt;/span&gt;

&lt;span class="nx"&gt;nnoremap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;F4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;NeoTermToggle&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;tnoremap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;F4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="nx"&gt;NeoTermToggle&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;tnoremap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Esc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="nx"&gt;NeoTermEnterNormal&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CR&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Con esta configuración:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Al presionar &lt;strong&gt;F4&lt;/strong&gt; se abirá una terminal.&lt;/li&gt;
&lt;li&gt;Al presionar de vuelta &lt;strong&gt;F4&lt;/strong&gt; se cerrará la terminal.&lt;/li&gt;
&lt;li&gt;Con &lt;strong&gt;Esc&lt;/strong&gt; se vuelve al modo &lt;em&gt;Normal&lt;/em&gt; en la terminal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En tiempos en los que tanto se declama la agilidad, como contrasentido se ofrecen editores que consumen muchos recursos, con desarrollos no exentos de torpezas y caprichos impuestos de antemano. El minimalismo de Vim como de Neovim nos permite adaptarlo de acuerdo a lo que necesitemos, la posibilidad de agregar distintas funcionalidades, sea para desarrollo, mejor usabilidad y experiencia del usuario (sí: el desarrollador o sysadmin también es un usuario 😀).
Finalmente, si bien tanto Vim como Neovim poseen el soporte nativo para manejar paquetes de plugins, encuentro en vim-plugin una manera mucho más conveniente de hacerlo.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Carga de Plugins en Vim" class="img-izquierda-responsiva" src="https://sergiobelkin.com/images/CargaPlugins.png"&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Característica&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Sistema Nativo (Vim 8 &lt;code&gt;packages&lt;/code&gt;)&lt;/th&gt;
&lt;th style="text-align: left;"&gt;&lt;code&gt;vim-plug&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Instalación&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual (clonar repos en &lt;code&gt;pack/&lt;/code&gt;)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Automática vía script (&lt;code&gt;plug.vim&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Configuración&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;En &lt;code&gt;vimrc&lt;/code&gt;, usando &lt;code&gt;packadd&lt;/code&gt; o estructura &lt;code&gt;start/opt&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Declarativa en &lt;code&gt;vimrc&lt;/code&gt; con &lt;code&gt;Plug&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Carga diferida (lazy-loading)&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual con &lt;code&gt;packadd&lt;/code&gt; desde &lt;code&gt;opt/&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Incorporado: &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;cmd&lt;/code&gt;, &lt;code&gt;event&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Instalación de plugins&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual (&lt;code&gt;git clone&lt;/code&gt;)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;:PlugInstall&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Actualización&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual (&lt;code&gt;git pull&lt;/code&gt; en cada plugin)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;:PlugUpdate&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Desinstalación&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual (borrar carpeta)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;:PlugClean&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Gestión de dependencias&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;No soportado nativamente&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Limitada (tú defines el orden)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Soporte para branches/tags&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Manual (&lt;code&gt;git checkout&lt;/code&gt;)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Sí (&lt;code&gt;Plug 'user/repo', { 'branch': 'dev' }&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Paralelismo en instalación&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;No&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Sí (instala varios plugins a la vez)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Interfaz de usuario&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Ninguna&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Básica pero útil (durante instalación/update)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Velocidad en carga&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Muy rápida (carga solo en startup)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Muy rápida con lazy loading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Soporte oficial&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Parte de Vim 8+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Mantenido por la comunidad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Curva de aprendizaje&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Mayor (entender estructura &lt;code&gt;pack/&lt;/code&gt;)&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Muy simple y bien documentado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Compatibilidad&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Solo Vim 8+&lt;/td&gt;
&lt;td style="text-align: left;"&gt;Compatible con Vim 7.4+, Neovim&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="conclusion"&gt;Conclusión&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Metáfora de las bibliotecas" class="img-izquierda-responsiva" src="https://sergiobelkin.com/images/metafora-de-la-bibliotecas.webp"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El soporte nativo de Vim/Neovim es como una biblioteca física organizada con dos tipos de estantes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;start/&lt;/code&gt;&lt;/strong&gt;: son los libros que se abren automáticamente apenas entrás a la biblioteca —es decir, los plugins que se cargan al iniciar Vim/Neovim.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;opt/&lt;/code&gt;&lt;/strong&gt;: son libros que están en los estantes, pero que &lt;strong&gt;vos tenés que buscar y abrir manualmente&lt;/strong&gt; usando el comando &lt;code&gt;:packadd&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este sistema te da control total, pero también requiere que te ocupes de la instalación, organización y carga de cada plugin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Los gestores de plugins, como &lt;code&gt;vim-plug&lt;/code&gt;, funcionan como un sistema de préstamo digital moderno:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Suscripción básica:&lt;/strong&gt;
   Declarás qué libros (plugins) querés en una lista de solicitudes (&lt;code&gt;Plug 'autor/plugin'&lt;/code&gt;), y al ejecutar un comando como &lt;code&gt;PlugInstall&lt;/code&gt;, el sistema los descarga automáticamente y los organiza en las secciones correspondientes del runtimepath.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dependencias = citas bibliográficas que debés declarar manualmente:&lt;/strong&gt;
   Si el libro A necesita al libro B para entenderse correctamente, &lt;strong&gt;vos tenés que pedir ambos explícitamente&lt;/strong&gt;.
   A diferencia de gestores como &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt; o &lt;code&gt;cargo&lt;/code&gt;, &lt;strong&gt;no hay resolución automática de dependencias&lt;/strong&gt;: nadie deduce relaciones por vos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Actualizaciones periódicas:&lt;/strong&gt;
   Usando el comando &lt;code&gt;PlugUpdate&lt;/code&gt;, podés sincronizar tu colección con las últimas ediciones disponibles.
   Eso sí: estos comandos actualizan lo que ya tenés, &lt;strong&gt;pero no agregan automáticamente nuevos plugins a menos que los declares en tu configuración.&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ahora cabe preguntarse dos cosas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;¿Cómo podemos empezar a usar &lt;strong&gt;Lua&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Más allá de que &lt;code&gt;vim-plug&lt;/code&gt; es una excelente opción: ¿Es actualmente la mejor para &lt;strong&gt;Neovim&lt;/strong&gt;?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="mas-recursos"&gt;Más Recursos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://neovim.io/doc/user/develop.html"&gt;Nvim documentation: develop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html"&gt;Variables de Entorno de XDG Base Directory Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/brooth/far.vim"&gt;brooth/far.vim: Find And Replace Vim plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vimawesome.com/"&gt;Vim Awesome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opensource.com/article/20/2/how-install-vim-plugins"&gt;How to install Vim plugins | Opensource.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://shapeshed.com/vim-packages/#vim-8-brings-native-third-party-package-loading"&gt;Vim: So long Pathogen, hello native package loading | George Ornbo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category>Neovim</category><category>sysadmin</category><guid>https://sergiobelkin.com/posts/una-introduccion-pragmatica-al-uso-de-plugins-en-neovim/</guid><pubDate>Sun, 04 May 2025 19:22:12 GMT</pubDate></item><item><title>Tutorial: Cifrar $HOME con gocryptfs</title><link>https://sergiobelkin.com/posts/tutorial-cifrar-un-directorio-con-gocryptfs/</link><dc:creator>sebelk</dc:creator><description>&lt;p&gt;En un artículo anterior: &lt;strong&gt;&lt;a href="https://sergiobelkin.com/posts/tutorial-de-fscrypt-para-cifrar-archivos/"&gt;Tutorial de fscrypt para cifrar archivos&lt;/a&gt;&lt;/strong&gt;, habíamos visto como cifrar archivos con &lt;strong&gt;fscrypt&lt;/strong&gt; y ext4. Ahora aprenderemos otro método independiente del sistema de archivos utilizado, se trata de una herramienta llamada &lt;strong&gt;gocryptfs&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conocimientos previos necesarios:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uso habitual de línea de comandos en Linux (incluyendo entre otros manejo de propietarios y permisos)&lt;/li&gt;
&lt;li&gt;Instalación y desinstalación de paquetes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En el ejemplo en cuestión estoy usando Debian Buster (te recomiendo primero instalarla en una máquina virtual para hacer pruebas), de modo que los pasos a seguir pueden ser un poco diferentes en otras distribuciones, pero los principios generales se mantienen.
&lt;strong&gt;Todos los pasos hasta que lo pruebes como usuario común deben hacerse con privilegios de superusuario.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Es muy importante contar espacio suficiente para copiar temporalmente los archivos del directorio que se desea cifrar.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;He cambiado el shell del usuario sergio que es &lt;em&gt;dash&lt;/em&gt; (predeterminado en Debian) por &lt;strong&gt;bash&lt;/strong&gt;, ya que el primero no está pensado para un uso interactivo habitual además de ser menos potente.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/rob-king-Au6eR7Yg9CY-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/rob-king-Au6eR7Yg9CY-unsplash.thumbnail.jpg" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="instalar-grocryptfs"&gt;Instalar grocryptfs&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;apt install grocryptfs&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="crear-el-directorio-para-cifrar"&gt;Crear el directorio para cifrar&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mkdir /home/sergio_cifrado&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="inicializar-el-directorio"&gt;Inicializar el directorio&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aquí seteamos la misma contraseña que la del usuario&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;gocryptfs --init /home/sergio_cifrado/
Choose a password for protecting your files.
Password: 
Repeat: 

Your master key is:

    9c43faf4-16a07508-42213628-50a5c55e-
    e0c17483-c41453a0-6355f9f0-897b3aa9

If the gocryptfs.conf file becomes corrupted or you ever forget your password,
there is only one hope for recovery: The master key. Print it to a piece of
paper and store it in a drawer. This message is only printed once.

The gocryptfs filesystem has been created successfully.
You can now mount it using: gocryptfs /home/sergio_cifrado MOUNTPOINT
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="montar-el-directorio"&gt;Montar el directorio&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;mkdir /home/sergio_montaje_temporario &amp;amp;&amp;amp; chmod 750 /home/sergio_montaje_temporario &amp;amp;&amp;amp; chown sergio. /home/sergio_temporario &amp;amp;&amp;amp;
gocryptfs /home/sergio_cifrado/ /home/sergio_temporario/
Password: 
Decrypting master key
Filesystem mounted and ready.
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="ajustamos-los-propietarios-y-permisos"&gt;Ajustamos los propietarios y permisos&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;chown -R sergio. /home/sergio{_cifrado} &amp;amp;&amp;amp; chmod 750 /home/sergio_cifrado&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="copiar-todos-los-archivos-del-directorio-del-usuario-al-directorio-temporal"&gt;Copiar todos los archivos del directorio del usuario al directorio temporal&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cp -Tav /home/sergio /home/sergio_temporario&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="borrar-el-contenido-del-directorio-del-usuario-por-favor-realizar-previamente-un-backup"&gt;Borrar el contenido del directorio del usuario (por favor realizar previamente un backup)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rm -rf /home/sergio&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="desmontar-el-directorio-cifrado"&gt;Desmontar el directorio cifrado&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;fusermount -u /home/sergio_temporario&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="le-cambiamos-el-nombre-al-directorio-temporario-por-el-original"&gt;Le cambiamos el nombre al directorio temporario por el original&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mv /home/sergio_temporario /home/sergio&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Todo lo que viene a continuación es necesario cuando queremos que el directorio se monte de manera automática en el momento del login.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="instalamos-el-modulo-de-pam-para-montaje-de-volumenes"&gt;Instalamos el módulo de PAM para montaje de volúmenes&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;apt install -y libpam-mount&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="ejecutamos-el-configurador-de-pam"&gt;Ejecutamos el configurador de pam&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pam-auth-update&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pam_auth_update.png"&gt;&lt;img src="https://sergiobelkin.com/images/pam_auth_update.thumbnail.png" alt="pam-auth-update"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;y presionamos en &lt;strong&gt;Aceptar&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;En otras distribuciones y configuraciones, puede ser necesario editar otros archivos del directorio /etc/pam.d.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Luego hay que editar el archivo &lt;code&gt;/etc/security/pam_mount.conf.xml&lt;/code&gt; agregando lo siguiente antes de &lt;code&gt;&amp;lt;/pam_mount&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sergio"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fstype&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fuse"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nodev,nosuid,quiet,nonempty,allow_other"&lt;/span&gt;
&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/usr/bin/gocryptfs#/home/%(USER)_cifrado"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mountpoint&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/home/%(USER)"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="configuramos-fuse"&gt;Configuramos FUSE&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="gh"&gt;#&lt;/span&gt; /etc/fuse.conf - Configuration file for Filesystem in Userspace (FUSE)

&lt;span class="gh"&gt;#&lt;/span&gt; Set the maximum number of FUSE mounts allowed to non-root users.
&lt;span class="gh"&gt;#&lt;/span&gt; The default is 1000.
&lt;span class="gh"&gt;#&lt;/span&gt;mount_max = 1000

&lt;span class="gh"&gt;#&lt;/span&gt; Allow non-root users to specify the allow_other or allow_root mount options.
&lt;span class="gh"&gt;#&lt;/span&gt; Modificamos aquí:
user_allow_other
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Eso es todo, felicitaciones si llegaste hasta aquí 😀,  podemos reiniciar y probar la configuración:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/aFezsKg2iRY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Para login gráfico:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/wwwVL8k_bes" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;

&lt;h3 id="conclusion"&gt;Conclusión&lt;/h3&gt;
&lt;p&gt;De esta manera pudiste configurar el cifrado automática de un directorio $HOME de un usuario. Este método es principalmente útil para equipos donde trabaja un solo usuario (podría ser tu laptop de trabajo diario por ejemplo).&lt;/p&gt;
&lt;h3 id="fuentes-y-mas-recursos"&gt;Fuentes y más recursos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nuetzlich.net/gocryptfs/"&gt;gocryptfs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rfjakob/gocryptfs"&gt;rfjakob/gocryptfs: Encrypted overlay filesystem written in Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pam-mount.sourceforge.net/"&gt;pam_mount — Pluggable Authentication Module to mount volumes for a user session&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category>criptografia</category><guid>https://sergiobelkin.com/posts/tutorial-cifrar-un-directorio-con-gocryptfs/</guid><pubDate>Wed, 12 May 2021 18:11:58 GMT</pubDate></item><item><title>Tutorial de fscrypt para cifrar archivos</title><link>https://sergiobelkin.com/posts/tutorial-de-fscrypt-para-cifrar-archivos/</link><dc:creator>sebelk</dc:creator><description>&lt;h4 id="conocimientos-previos-necesarios"&gt;Conocimientos previos necesarios:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Instalación de Linux.&lt;/li&gt;
&lt;li&gt;Uso habitual de línea de comandos en Linux (incluyendo entre otros manejo de propietarios y permisos).&lt;/li&gt;
&lt;li&gt;Instalación y desinstalación de paquetes.&lt;/li&gt;
&lt;li&gt;Montaje de sistemas de archivos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/alex-motoc-Y83nsKGkxSw-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/alex-motoc-Y83nsKGkxSw-unsplash.thumbnail.jpg" alt="Cifrado de archivos"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;El sistema ext4 proporciona cifrado de bloques de datos y nombres de archivos. Veremos a continuación de algunas reglas generales para cifrar el directorio /home de un usuario.&lt;/p&gt;
&lt;p&gt;En el ejemplo en cuestión estoy usando Debian Buster (te recomiendo primero instalarla en una máquina virtual para hacer pruebas), de modo que los pasos a seguir pueden ser un poco diferentes en otras distribuciones, pero los principios generales se mantienen.&lt;/p&gt;
&lt;p&gt;¡Manos a la obra!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Los comandos precedidos por &lt;code&gt;sudo&lt;/code&gt; indican que necesitan privilegios de root. Si querés usar sudo, sencillamente ejecutá como root:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;usermod -aG sudo sergio&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Obviamente aquí y en cada caso reemplazalo con tu usuario común.&lt;/p&gt;
&lt;h3 id="preparacion-del-sistema-de-archivos"&gt;Preparación del sistema de archivos&lt;/h3&gt;
&lt;p&gt;Algo que tendremos que hacer es habilitar la funcionalidad de cifrado, suponiendo que la partición de cifrado es /dev/sda1, haríamos:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo tune2fs -O encrypt /dev/sda1&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="descarga-y-compilacion"&gt;Descarga y compilación&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt build-dep fscrypt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;do apt -y install git &amp;amp;&amp;amp; go get -d github.com/google/fscrypt/...&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd go/src/github.com/google/fscrypt/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;make &amp;amp;&amp;amp; sudo make install PREFIX=/usr&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="configuracion"&gt;Configuración&lt;/h3&gt;
&lt;p&gt;Tenemos que actualizar la configuración de PAM, que servirán para desbloquear directorios al loguearse, bloquear al desloguearse, y cambiar contraseñas de acceso a los recursos cifrados.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo pam-auth-update&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pam-auth-update-fscrypt.png"&gt;&lt;img src="https://sergiobelkin.com/images/pam-auth-update-fscrypt.thumbnail.png" alt="pam-auth-update"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Para configurar globalmente:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo fscrypt setup&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No se puede cifrar un directorio que ya tiene contenido, de manera que hay que crear un nuevo directorio, y luego migrar el contenido del directorio del usuario:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo mkdir /home/sergio_temp &amp;amp;&amp;amp; sudo chown sergio.sergio /home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fscrypt encrypt /home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Allí podríamos elegir entre la contraseña del usuario, una passphrase o bien un archivo con clave 256-bit. En nuestro elegimos la primera opción, siempre teniendo en cuenta lo importante que es contar con una buena contraseña.&lt;/p&gt;
&lt;p&gt;Luego chequeamos que esté todo en orden:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fscrypt status /home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ahora sí, migramos el contenido:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cp -av -T /home/sergio /home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Bloqueamos el contenido del directorio&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo fscrypt lock /home/sergio_temp --user=/home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Probamos desbloquear&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fscrypt unlock /home/sergio_temp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Si funciona podemos reemplazarlo por el nuevo directorio:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo su -&lt;/code&gt;
&lt;code&gt;mv /home/sergio{,_para-borrar}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mv /home/sergio{_temp,}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Luego al reiniciar podemos probar:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;reboot&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;¿Cómo se ven los archivos cifrados?&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/fscrypt-access.png"&gt;&lt;img src="https://sergiobelkin.com/images/fscrypt-access.thumbnail.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="mas-recursos"&gt;Más Recursos&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/google/fscrypt"&gt;fscrypt: Go tool for managing Linux filesystem encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/Fscrypt"&gt;fscrypt - ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kernel.org/doc/html/v4.18/filesystems/fscrypt.html"&gt;Filesystem-level encryption (fscrypt) — The Linux Kernel documentation&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;</description><category>criptografia</category><category>seguridad</category><guid>https://sergiobelkin.com/posts/tutorial-de-fscrypt-para-cifrar-archivos/</guid><pubDate>Sat, 24 Apr 2021 13:30:29 GMT</pubDate></item><item><title>Tutorial de LXC</title><link>https://sergiobelkin.com/posts/tutorial-de-lxc/</link><dc:creator>sebelk</dc:creator><description>&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/frank-mckenna-tjX_sniNzgQ-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/frank-mckenna-tjX_sniNzgQ-unsplash.thumbnail.jpg" alt="Containers"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Photo by frank mckenna on Unsplash&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LXC es una herramienta extraordinaria, algo intermedio entre un chroot y una máquina virtualizada completamente. Usando el mismo kernel que el sistema anfitrión podemos tener sistemas operativos invitados en el propio filesystem. Es decir, cada SO invitado en un directorio. Pero la documentación y la interacción de los distintos componentes puede tornar algo &lt;em&gt;tricky&lt;/em&gt; el proceso. Cansado de lidiar con documentación desperdigada por aquí y por allá decidí crear mi propio tutorial. Intentando en lo posible ser distro-agnóstico.&lt;/p&gt;
&lt;p&gt;Aquí está:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/lkcu8o8gus8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;¡Espero que lo disfruten!&lt;/p&gt;</description><category>contenedores</category><guid>https://sergiobelkin.com/posts/tutorial-de-lxc/</guid><pubDate>Mon, 15 Jun 2020 00:59:38 GMT</pubDate></item><item><title>Tutorial: Autenticación en SSH con clave pública</title><link>https://sergiobelkin.com/posts/tutorial-autenticacion-con-clave-publica/</link><dc:creator>sebelk</dc:creator><description>&lt;p&gt;Este es un tutorial para que empecemos a usar claves públicas para autenticarnos. El único requisito es que hayamos ingresado a un servidor o host remoto con ssh. En nuestro ejemplo ese host tiene la ip 10.0.3.11.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/jametlene-reskp-9DdOrQpMsUs-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/jametlene-reskp-9DdOrQpMsUs-unsplash.thumbnail.jpg" alt=""&gt;&lt;/a&gt;i
&lt;br&gt;
&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="https://sergiobelkin.com/posts/tutorial-autenticacion-con-clave-publica/#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;El uso de autenticación por clave pública, tal como vimos en el &lt;a href="https://sergiobelkin.com/posts/guia-breve-ssh-con-clave-publica/"&gt;post anterior&lt;/a&gt; tiene la ventaja de no tener que ingresar usuario y contraseña. Esto puede ser útil en casos en que necesitemos realizar alguna tarea en un host remoto de manera no interactiva. Por ejemplo podríamos crear una tarea programada que ejecute todos los días un script de backup.
Veremos paso a paso como conseguirlo.
Lo primero que tendremos que hacer es generar un par de claves. Para ellos ejecutaremos el siguiente comando:
&lt;code&gt;ssh-keygen&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Como se ve en la imagen de abajo se nos preguntará la ruta de la clave privada, aceptamos la predeterminada presionando la tecla Enter.
&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-keygen.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-keygen.thumbnail.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;y además se nos pedirá una passphrase. La passphrase es una frase que sea fácil de recordar para uno mismo, pero a la vez difícil de adivinar para otros. El propósito es cifrar la clave privada. Si te estás preguntando ¿para qué hacer todo esto si de todas maneras tendré que ingresa una passphrase para autenticarme. La respuesta es que tenemos técnicas como veremos un poco más abajo, para evitar la necesidad del ingreso de la frase una y otra vez.
Ingresamos la frase una vez después de la otra:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-keygen-2.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-keygen-2.thumbnail.png" alt=""&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Esto generará dos archivos en el directorio &lt;code&gt;~/.ssh&lt;/code&gt;: &lt;code&gt;id_rsa&lt;/code&gt; y &lt;code&gt;id_rsa.pub&lt;/code&gt; que son la clave privada y la clave pública respectivamente. Como sus nombres lo indican la clave privada no debe compartirse, en cambio la clave pública es la que nosirve para identificarnos como usuarios frente a otros hosts y se puede compartir.&lt;/p&gt;
&lt;p&gt;En este momento tenemos que copiar la clave pública al host que funciona como servidor ssh. La manera más fácil y ráṕida de hacerlo es con el comando siguiente:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-copy-id.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-copy-id.thumbnail.png" alt="ssh-copy-id"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ingresamos la contraseña de root y luego presionamos la tecla Enter. Lo que hace este comando es agregar la clave pública del archivo &lt;code&gt;id_rsa.pub&lt;/code&gt; al archivo /root/.ssh/authorized_keys del servidor ssh.&lt;/p&gt;
&lt;p&gt;Ahora lo que hacemos es reemplazar la shell actual con el agente de ssh y re-ejecutando la shell bash. El agente de ssh será el encargado de guardar las claves privadas en memoria para que no tengamos que ingresar más de una vez la passphrase:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-agent.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-agent.thumbnail.png" alt="ssh-agent"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Luego ejecutamos el comando &lt;code&gt;ssh-add&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-add.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-add.thumbnail.png" alt="ssh-add"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Se nos pedirá la frase, la ingresamos y le damos Enter.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ssh-passwordless.png"&gt;&lt;img src="https://sergiobelkin.com/images/ssh-passwordless.thumbnail.png" alt="ssh sin contraseña"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;A través de este tutorial mencionamos varios conceptos que podés ampliar recurriendo a los siguientes enlaces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.unixwiz.net/techtips/ssh-agent-forwarding.html"&gt;An Illustrated Guide to SSH Agent Forwarding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blakesmith.me/2010/02/08/understanding-public-key-private-key-concepts.html"&gt;understanding public key private key concepts » Blake Smith&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.learningtree.com/ways-manage-ssh-keys-identities/"&gt;Ways to Manage Your SSH Keys and Identities | Learning Tree Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Photo by Jametlene Reskp on Unsplash &lt;a class="footnote-backref" href="https://sergiobelkin.com/posts/tutorial-autenticacion-con-clave-publica/#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><category>criptografia</category><category>ssh</category><guid>https://sergiobelkin.com/posts/tutorial-autenticacion-con-clave-publica/</guid><pubDate>Fri, 08 Nov 2019 12:12:36 GMT</pubDate></item></channel></rss>