<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: aldama</title>
    <description>The latest articles on DEV Community by aldama (@ram535).</description>
    <link>https://dev.to/ram535</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F62284%2Fd391ded9-19f9-4528-8217-b44a0ee54f97.png</url>
      <title>DEV Community: aldama</title>
      <link>https://dev.to/ram535</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ram535"/>
    <language>en</language>
    <item>
      <title>Vterm completion for files, directories, command history and programs in Emacs</title>
      <dc:creator>aldama</dc:creator>
      <pubDate>Sat, 07 Aug 2021 04:24:07 +0000</pubDate>
      <link>https://dev.to/ram535/vterm-completion-for-files-directories-command-history-and-programs-in-emacs-1d9d</link>
      <guid>https://dev.to/ram535/vterm-completion-for-files-directories-command-history-and-programs-in-emacs-1d9d</guid>
      <description>&lt;p&gt;This is a naive solution. Feel free to suggest alternative solutions or&lt;br&gt;
improvements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/ram535/a2153fb86f33ecec587d593c1c5e1623"&gt;https://gist.github.com/ram535/a2153fb86f33ecec587d593c1c5e1623&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;When pressing &lt;code&gt;TAB&lt;/code&gt; in vterm terminal, we should get a list of&lt;br&gt;
suggestion. The suggestion list should either be a file, a directory, a&lt;br&gt;
history command or a program name.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we need
&lt;/h2&gt;

&lt;p&gt;This is the list of what we need for the solution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  emacs&lt;/li&gt;
&lt;li&gt;  vterm&lt;/li&gt;
&lt;li&gt;  bash&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 - Get the list of program
&lt;/h2&gt;

&lt;p&gt;If you go to the terminal and run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;compgen -c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will get a list of all the programs under the PATH environment&lt;br&gt;
variable.&lt;/p&gt;

&lt;p&gt;Let's get that list using elisp.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(shell-command-to-string "compgen -c")
;; "emacs\nnano\nneovim\nvim......."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This gives us a long string.&lt;/p&gt;

&lt;p&gt;Let's split that long string into a list of string.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(split-string (shell-command-to-string "compgen -c") "\n" t )
;; ("emacs" "nano" "neovim" "vim".......)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have a list of the programs of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Choose a program from the list of programs
&lt;/h2&gt;

&lt;p&gt;Now we can choose an item from that list of programs using the&lt;br&gt;
&lt;code&gt;completing-read&lt;/code&gt; build-in emacs function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(completing-read "Command " (split-string (shell-command-to-string "compgen -c") "\n" t ))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 3 - Send the chosen program to vterm
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(vterm-send-string
 (completing-read "Command "
                  (split-string (shell-command-to-string "compgen -c") "\n" t )))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 4 - Get the list of files and directories in the CWD
&lt;/h2&gt;

&lt;p&gt;If you go to the terminal and run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;compgen -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will get the list of files and directories in the current working&lt;br&gt;
directory (CWD).&lt;/p&gt;

&lt;p&gt;Let's get that list using elisp.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(shell-command-to-string "compgen -f")
;; "Documents\nDownload\nMusic\nProjects......."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This gives us a long string.&lt;/p&gt;

&lt;p&gt;Let's split that long string into a list of string.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(split-string (shell-command-to-string "compgen -f") "\n" t )
;; ("Documents" "Download" "Music" "Projects".......)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have a list of files and directories of the CWD.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - Choose a file or directory from the list of files and directories
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(completing-read "Choose " (split-string (shell-command-to-string "compgen -f") "\n" t ))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 6 - Send the chosen file or directory to vterm
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(vterm-send-string
 (completing-read "Choose "
                  (split-string (shell-command-to-string "compgen -f") "\n" t )))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 6.5 - There is a gotcha with getting the list of files and directories
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;default-directory&lt;/code&gt; emacs variable is never update when we move to&lt;br&gt;
different directories in a &lt;code&gt;vterm terminal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That can be solve calling this function.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun vterm-directory-sync ()
  "Synchronize current working directory."
  (interactive)
  (when vterm--process
    (let* ((pid (process-id vterm--process))
           (dir (file-truename (format "/proc/%d/cwd/" pid))))
      (setq default-directory dir))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Step 14 has been update with this solution and everything should work as intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7 - Get the list of bash history commands
&lt;/h2&gt;

&lt;p&gt;Bash history commands are save in the &lt;code&gt;.bash_history&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Let's create a temporary buffer and insert the content of&lt;br&gt;
&lt;code&gt;.bash_history&lt;/code&gt; file into it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(with-temp-buffer
  (insert-file-contents "~/.bash_history")
  (split-string (buffer-string) "\n" t))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's split the content of the temporary buffer into a list of strings.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(with-temp-buffer
  (insert-file-contents "~/.bash_history")
  (split-string (buffer-string) "\n" t))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have a list of bash command history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8 - Choose a command from the list of bash command history
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(completing-read "History" (with-temp-buffer
                                (insert-file-contents "~/.bash_history")
                                (split-string (buffer-string) "\n" t)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 9 - Send the chosen history command to vterm
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(vterm-send-string
   (completing-read "History" (with-temp-buffer
                                (insert-file-contents "~/.bash_history")
                                (split-string (buffer-string) "\n" t))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 10 - Combine the list of files, directories, history commands and programs into one list
&lt;/h2&gt;

&lt;p&gt;Let's combine the lists we got from step 1, 4 and 7 into one list.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(let ((program-list (split-string (shell-command-to-string "compgen -c") "\n" t ))
      (file-directory-list (split-string (shell-command-to-string "compgen -f") "\n" t ))
      (history-list (with-temp-buffer
                      (insert-file-contents "~/.bash_history")
                      (split-string (buffer-string) "\n" t))))

  (append program-list file-directory-list history-list))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's make it a function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun get-full-list ()
  (let ((program-list (split-string (shell-command-to-string "compgen -c") "\n" t ))
        (file-directory-list (split-string (shell-command-to-string "compgen -f") "\n" t ))
        (history-list (with-temp-buffer
                        (insert-file-contents "~/.bash_history")
                        (split-string (buffer-string) "\n" t))))

    (append program-list file-directory-list history-list)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 11 - Delete duplicates (optional)
&lt;/h2&gt;

&lt;p&gt;We are going to use &lt;code&gt;-distinct&lt;/code&gt; function from the dash.el package.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun get-full-list ()
  (let ((program-list (split-string (shell-command-to-string "compgen -c") "\n" t ))
        (file-directory-list (split-string (shell-command-to-string "compgen -f") "\n" t ))
        (history-list (with-temp-buffer
                        (insert-file-contents "~/.bash_history")
                        (split-string (buffer-string) "\n" t))))

    (-distinct (append program-list file-directory-list history-list))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 12 - Give suggestion for a partial word
&lt;/h2&gt;

&lt;p&gt;Imagine we type:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;em
  ^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;^&lt;/code&gt; is the position of the cursor. In this scenario we would like to&lt;br&gt;
have a suggestion of items that contain the letters "em".&lt;/p&gt;

&lt;p&gt;If we read the documentation of the function &lt;code&gt;completing-read&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(completing-read PROMPT COLLECTION &amp;amp;optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can see that we can give an &lt;code&gt;INITIAL-INPUT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But how do we get an &lt;code&gt;INITIAL-INPUT&lt;/code&gt;. That is where &lt;code&gt;thing-at-point&lt;/code&gt;&lt;br&gt;
build-in emacs function comes in handy.&lt;/p&gt;

&lt;p&gt;Let's see some examples:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;world
  ^

world
     ^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If we call &lt;code&gt;(thing-at-point 'word 'no-properties)&lt;/code&gt;, in either example,&lt;br&gt;
it returns "world". Now can use &lt;code&gt;(thing-at-point 'word 'no-properties)&lt;/code&gt;&lt;br&gt;
as out &lt;code&gt;INITIAL-INPUT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's go back to our scenario. We type "em" and evaluate the code below,&lt;br&gt;
it will give us suggestion of words that contain "em" from the the list&lt;br&gt;
we got in the &lt;code&gt;step 10&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(completing-read "Choose: " (get-full-list) nil nil (thing-at-point 'word 'no-properties))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's make it a function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defun vterm-completion-choose-item ()
(completing-read "Choose: " (get-full-list) nil nil (thing-at-point 'word 'no-properties)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 13 - Replace partial word with the chosen word
&lt;/h2&gt;

&lt;p&gt;First we check if there is a word at point.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(when (thing-at-point 'word))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If it is a word, let's delete it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(when (thing-at-point 'word)
(backward-kill-word 1))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;WARNING&lt;/code&gt; (backward-kill-word) will not work in vterm. You have to use&lt;br&gt;
&lt;code&gt;(vterm-send-meta-backspace)&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Let's insert the chosen item in a vterm terminal.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defvar vterm-chosen-item (vterm-completion-choose-item))

(when (thing-at-point 'word)
(vterm-send-meta-backspace))

(vterm-send-string vterm-chosen-item)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's make it a function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defvar vterm-chosen-item)

(defun vterm-completion ()
  (interactive)
  (setq vterm-chosen-item (vterm-completion-choose-item))
  (when (thing-at-point 'word)
    (vterm-send-meta-backspace))
  (vterm-send-string vterm-chosen-item))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 14 - Solution
&lt;/h2&gt;

&lt;p&gt;I use general.el for the keybindings and evil-mode.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(use-package vterm
  :config        
  (defun get-full-list ()
    (let ((program-list (split-string (shell-command-to-string "compgen -c") "\n" t ))
          (file-directory-list (split-string (shell-command-to-string "compgen -f") "\n" t ))
          (history-list (with-temp-buffer
                          (insert-file-contents "~/.bash_history")
                          (split-string (buffer-string) "\n" t))))

      (delete-dups (append program-list file-directory-list history-list))))

  (defun vterm-completion-choose-item ()
    (completing-read "Choose: " (get-full-list) nil nil (thing-at-point 'word 'no-properties)))

  (defun vterm-completion ()
    (interactive)
    (vterm-directory-sync)
   (let ((vterm-chosen-item (vterm-completion-choose-item)))
      (when (thing-at-point 'word)
         (vterm-send-meta-backspace))
      (vterm-send-string vterm-chosen-item)))

  (defun vterm-directory-sync ()
    "Synchronize current working directory."
    (interactive)
    (when vterm--process
      (let* ((pid (process-id vterm--process))
             (dir (file-truename (format "/proc/%d/cwd/" pid))))
        (setq default-directory dir))))

  :general
  (:states 'insert
           :keymaps 'vterm-mode-map
           "&amp;lt;tab&amp;gt;" 'vterm-completion))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Extra
&lt;/h2&gt;

&lt;p&gt;Increase the bash history command and do not store duplicate items.&lt;/p&gt;

&lt;p&gt;Add this in the &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export HISTSIZE=10000
export HISTFILESIZE=10000
export HISTCONTROL=ignoreboth:erasedups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>vterm</category>
      <category>emacs</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>KMonad and the power of infinite leader keys</title>
      <dc:creator>aldama</dc:creator>
      <pubDate>Fri, 06 Aug 2021 20:32:32 +0000</pubDate>
      <link>https://dev.to/ram535/kmonad-and-the-power-of-infinite-leader-keys-888</link>
      <guid>https://dev.to/ram535/kmonad-and-the-power-of-infinite-leader-keys-888</guid>
      <description>&lt;p&gt;First of all that was a title clickbait.&lt;br&gt;
Title clickbaits are still legal in Mexico (I think).&lt;/p&gt;

&lt;p&gt;Jokes aside, I will show you how every key in your keyboard can be a leader key.&lt;/p&gt;

&lt;p&gt;Since most of the Emacs community are keyboard driven freaks, I hope you will see the potential in your workflow.&lt;/p&gt;

&lt;p&gt;&lt;a id="orga9f6b1b"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is KMonad?
&lt;/h2&gt;

&lt;p&gt;It is a program that lets you remap the keys of your keyboard.&lt;/p&gt;

&lt;p&gt;&lt;a id="org6678310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install KMonad
&lt;/h2&gt;

&lt;p&gt;Download the executable from &lt;a href="https://github.com/kmonad/kmonad/releases"&gt;https://github.com/kmonad/kmonad/releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Put it somewhere your PATH enviroment variable points.&lt;/p&gt;

&lt;p&gt;In my case I like to put executables in &lt;code&gt;$HOME/bin&lt;/code&gt;.&lt;br&gt;
So I add this line &lt;code&gt;export PATH="$HOME/bin:$PATH"&lt;/code&gt; in the &lt;code&gt;.profile&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Then run the following commands.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add self to the input and uinput groups
sudo usermod -aG input $USER
sudo groupadd uinput
sudo usermod -aG uinput $USER

echo 'KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"' | sudo tee /etc/udev/rules.d/90-uinput.rules

# This seems to be needed because uinput isn't compiled as a loadable module these days.
# See https://github.com/chrippa/ds4drv/issues/93#issuecomment-265300511
echo uinput | sudo tee /etc/modules-load.d/uinput.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For more info check &lt;a href="https://github.com/kmonad/kmonad/issues/160#issuecomment-766121884"&gt;https://github.com/kmonad/kmonad/issues/160#issuecomment-766121884&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="orgfd88775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a KMonad configuration file
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p ~/.config/kmonad
touch ~/.config/kmonad/config.kbd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a id="orge23ec56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add system information
&lt;/h2&gt;

&lt;p&gt;On the top of &lt;code&gt;config.kbd&lt;/code&gt; add the next.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defcfg
  input  (device-file "&amp;lt;path to your keyboard input&amp;gt;")
  output (uinput-sink "KMonad kbd"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Go to &lt;code&gt;/dev/input/by-path/&lt;/code&gt; or &lt;code&gt;/dev/input/by-id/&lt;/code&gt; and look for any file ending in &lt;code&gt;kbd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I think if your keyboard is plugable, it should appear in &lt;code&gt;/dev/input/by-id/&lt;/code&gt;&lt;br&gt;
and your build-in laptop keyboard should appear in &lt;code&gt;/dev/input/by-path/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my case I am using my build-in laptop keyboard. This is what I added in the configuration file. Yours should be different, modify it with your information.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defcfg
  input  (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd")
  output (uinput-sink "KMonad kbd"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;uinput-sink&lt;/code&gt; will be the name given to the virtual keyboard that KMonad creates.&lt;br&gt;
You can write anything in there.&lt;/p&gt;

&lt;p&gt;&lt;a id="org604120b"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard blueprint
&lt;/h2&gt;

&lt;p&gt;Now we need to create the blueprint of our keyboard. The layouts that will create later will base of this blueprint.&lt;/p&gt;

&lt;p&gt;This is the blueprint of my keyboard. Modify it as you need.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defsrc
  esc   f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `     1    2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab   q    w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  caps  a    s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft  z    x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl  lmet lalt      spc       ralt cmps rctl                 left   down   rght
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a id="orge8f2fa4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Base layout (default)
&lt;/h2&gt;

&lt;p&gt;KMonad takes the first layout as the default layout.&lt;br&gt;
Let's create our first layout and named it &lt;code&gt;base&lt;/code&gt;.&lt;br&gt;
And let's also swap &lt;code&gt;capslock&lt;/code&gt; and &lt;code&gt;escape&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(deflayer base
  caps    f1    f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `       1     2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab     q     w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  esc     a     s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft    z     x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl    lmet  lalt      spc       ralt cmps rctl                 left   down   rght
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now if we run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kmonad ~/.config/kmonad/config.kbd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will notice that &lt;code&gt;capslock&lt;/code&gt; and &lt;code&gt;escape&lt;/code&gt; have been swaped.&lt;/p&gt;

&lt;p&gt;&lt;a id="org58d8a92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a second layout
&lt;/h2&gt;

&lt;p&gt;Let's call the second layout &lt;code&gt;syms&lt;/code&gt;, short for symbols.&lt;br&gt;
First lets modify our &lt;code&gt;base layout&lt;/code&gt; so when we hold &lt;code&gt;a&lt;/code&gt;, it calls the &lt;code&gt;syms&lt;br&gt;
layout&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(deflayer base
  caps    f1    f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `       1     2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab     q     w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  esc     (layer-toggle syms)  s    d    f    g    h    j    k    l    ;    '     \         pgdn
  lsft    z     x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl    lmet  lalt      spc       ralt cmps rctl                 left   down   rght
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But that is too messy. Let's create an alias for that command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defalias
  sym (layer-toggle syms))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And now we can modify out &lt;code&gt;base layout&lt;/code&gt; like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(deflayer base
  caps    f1    f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `       1     2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab     q     w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  esc     @sym  s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft    z     x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl    lmet  lalt      spc       ralt cmps rctl                 left   down   rght
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's create our &lt;code&gt;syms layout&lt;/code&gt;.&lt;br&gt;
We will start simple and just add two symbols to make everything more clear.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(deflayer syms
  _     _    _    _    _    _    _    _    _    _    _   _   _   _   _     _    _
  _     _    _    _    _    _    _    _    _    _    _   _   _   _              _
  _     _    _    _    _    _    _    _    _    _    _   _   _   _              _
  _     _    _    _    _    _    _    [    ]    _    _   _   _                  _
  _     _    _    _    _    _    _    _    _    _    _   _       _              _
  _     _    _         _         _    _    _                 _   _   _
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now if we if we run our configuration.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kmonad ~/.config/kmonad/config.kbd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When we hold &lt;code&gt;a&lt;/code&gt; and press &lt;code&gt;j&lt;/code&gt;, we get &lt;code&gt;[&lt;/code&gt;.&lt;br&gt;
And when we hold &lt;code&gt;a&lt;/code&gt; and press &lt;code&gt;k&lt;/code&gt;, we get &lt;code&gt;]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The bad news is that we lost the ability to type the letter &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="org58a9210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's use &lt;code&gt;a&lt;/code&gt; key  a leader key
&lt;/h2&gt;

&lt;p&gt;From our last example let's modify the alias we made for calling the &lt;code&gt;syms layout&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defalias
  sym (tap-next a (layer-toggle syms)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this modification, if we just tap &lt;code&gt;a&lt;/code&gt;, we get &lt;code&gt;a&lt;/code&gt;.&lt;br&gt;
But if we hold &lt;code&gt;a&lt;/code&gt; and press &lt;code&gt;j&lt;/code&gt;, we get &lt;code&gt;[&lt;/code&gt;.&lt;br&gt;
And also if we hold &lt;code&gt;a&lt;/code&gt; and press &lt;code&gt;k&lt;/code&gt;, we get &lt;code&gt;]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="org8be7d0a"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's create another leader key
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defcfg
  input  (device-file "&amp;lt;path to your keyboard input&amp;gt;")
  output (uinput-sink "KMonad kbd"))

(defalias
  sym (tap-next bspc (layer-toggle syms)))

(defsrc
  esc   f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `     1    2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab   q    w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  caps  a    s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft  z    x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl  lmet lalt      spc       ralt cmps rctl                 left   down   rght
  )

(deflayer base
  esc   f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `     1    2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab   q    w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  @sym  a    s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft  z    x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl  lmet lalt      spc       ralt cmps rctl                 left   down   rght
  )

(deflayer syms
  _     _    _    _    _    _    _    _    _    _    _   _   _   _   _     _    _
  _     _    _    _    _    _    _    _    _    _    _   _   _   _              _
  _     _    _    _    _    _    _    _    _    _    _   _   _   _              _
  _     _    _    _    _    _    _    [    ]    _    _   _   _                  _
  _     _    _    _    _    _    _    _    _    _    _   _       _              _
  _     _    _         _         _    _    _                 _   _   _
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That is a full configuration.&lt;br&gt;
In this configuration when we tap &lt;code&gt;caplocks&lt;/code&gt;, get a &lt;code&gt;backspace&lt;/code&gt;.&lt;br&gt;
If we hold &lt;code&gt;caplocks&lt;/code&gt; and press &lt;code&gt;j&lt;/code&gt;, we get &lt;code&gt;[&lt;/code&gt;.&lt;br&gt;
If we hold &lt;code&gt;caplocks&lt;/code&gt; and press &lt;code&gt;k&lt;/code&gt;, we get &lt;code&gt;]&lt;/code&gt;.&lt;br&gt;
And the good news is that we got rid of &lt;code&gt;caplocks&lt;/code&gt; previous life functionality.&lt;/p&gt;

&lt;p&gt;&lt;a id="org4903c05"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is much more you can do with KMonad.&lt;br&gt;
I suggest you to read the &lt;a href="https://github.com/kmonad/kmonad/blob/master/keymap/tutorial.kbd"&gt;official tutorial&lt;/a&gt; to learn more about KMonad.&lt;/p&gt;

&lt;p&gt;Now you know how covert every key in a leader key.&lt;/p&gt;

&lt;p&gt;One last thing. Since I use Linux Mint and Stumpwm.&lt;br&gt;
I added this line &lt;code&gt;kmonad $HOME/.config/kmonad/config.kbd &amp;amp;&lt;/code&gt; to my &lt;code&gt;.profile&lt;/code&gt; file, so kmonad starts when I log in.&lt;/p&gt;

&lt;p&gt;&lt;a id="orgb954da3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defcfg
  input  (device-file "&amp;lt;path to your keyboard input&amp;gt;")
  output (uinput-sink "KMonad kbd"))

(defalias
  d  (tap-hold-next 150 d [)
  f  (tap-hold-next 150 f ]))

(defsrc
  esc   f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `     1    2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab   q    w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  caps  a    s    d    f    g    h    j    k    l    ;    '     \                        pgdn
  lsft  z    x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl  lmet lalt      spc       ralt cmps rctl                 left   down   rght
  )

(deflayer base
  esc   f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11   f12    pause  prnt  ins  del
  `     1    2    3    4    5    6    7    8    9    0    -     =      bspc              home
  tab   q    w    e    r    t    y    u    i    o    p    [     ]      ret               pgup
  caps  a    s    @d   @f   g    h    j    k    l    ;    '     \                        pgdn
  lsft  z    x    c    v    b    n    m    ,    .    /    rsft         up                end
  lctl  lmet lalt      spc       ralt cmps rctl                 left   down   rght
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you hold &lt;code&gt;d&lt;/code&gt; more than 150 milliseconds, you will get &lt;code&gt;[&lt;/code&gt;.&lt;br&gt;
If you quickly tap &lt;code&gt;d&lt;/code&gt;, you will get &lt;code&gt;d&lt;/code&gt;.&lt;br&gt;
If you hold &lt;code&gt;f&lt;/code&gt; more than 150 milliseconds, you will get &lt;code&gt;]&lt;/code&gt;.&lt;br&gt;
If you quickly tap &lt;code&gt;f&lt;/code&gt;, you will get &lt;code&gt;f&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>linux</category>
      <category>kmonad</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
