<?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: Boone Cabal</title>
    <description>The latest articles on DEV Community by Boone Cabal (@boonecabal).</description>
    <link>https://dev.to/boonecabal</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%2F1392552%2Fb3a53f1b-2a24-44fb-a535-60f8c79bed52.jpg</url>
      <title>DEV Community: Boone Cabal</title>
      <link>https://dev.to/boonecabal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/boonecabal"/>
    <language>en</language>
    <item>
      <title>How to Make DigitalOcean Markdown Vim Plugin</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 05 Jun 2025 22:02:45 +0000</pubDate>
      <link>https://dev.to/boonecabal/how-to-make-digitalocean-markdown-vim-plugin-3cja</link>
      <guid>https://dev.to/boonecabal/how-to-make-digitalocean-markdown-vim-plugin-3cja</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Welcome to the world of vim plugins. In this tutorial you will create a plugin for generating markdown–specifically, DigitalOcean markdown–by exposing a set of insert-mode mappings for efficient markdown creation. Additionally, you will create a function that uses a vim API to search and reposition the cursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You should be comfortable using a Linux terminal. Have a look at &lt;a href="https://www.digitalocean.com/community/tutorials/an-introduction-to-the-linux-terminal" rel="noopener noreferrer"&gt;An Introduction to the Linux Terminal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Experience using vim and some knowledge about creating mappings. Here is a good resource for that: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-vim-for-advanced-editing-of-plain-text-or-code-on-a-vps-2" rel="noopener noreferrer"&gt;How To Use Vim for Advanced Editing of Plain Text or Code on a VPS&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up Plugin Files and Directories
&lt;/h2&gt;

&lt;p&gt;In this section you will install vim and set up all the requisite files and directories. Let’s begin by installing vim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One -- Installing Vim
&lt;/h2&gt;

&lt;p&gt;Install vim using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;vim-gtk3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verity the vim version using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Two -- Creating &lt;code&gt;.vimrc&lt;/code&gt; and &lt;code&gt;.vim&lt;/code&gt; Directories
&lt;/h2&gt;

&lt;p&gt;You need a &lt;code&gt;.vimrc&lt;/code&gt; file and a &lt;code&gt;.vim/plugin&lt;/code&gt; directory structure. &lt;code&gt;.vimrc&lt;/code&gt; is a configuration file with settings like mappings, syntax highlighting, and line numbers. Let’s create it first.&lt;/p&gt;

&lt;p&gt;Change to your home directory using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the &lt;code&gt;ls -al&lt;/code&gt; command to look for &lt;code&gt;.vimrc&lt;/code&gt; and &lt;code&gt;.vim&lt;/code&gt;. If you don’t see one or the other, you will create them. Let’s assume you don’t see them, so you’ll create them. Use the following command to create &lt;code&gt;.vimrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .vimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use&lt;code&gt;mkdir&lt;/code&gt; with a &lt;code&gt;-p&lt;/code&gt; flag to create both the &lt;code&gt;.vim&lt;/code&gt; and &lt;code&gt;.vim/plugin&lt;/code&gt; folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.vim/plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your plugin goes in &lt;code&gt;~/.vim/plugin&lt;/code&gt; and can be composed of a single file or a directory with multiple files. Your plugin will have multiple files, so create a directory for it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.vim/plugin/do_markdown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Three –- Creating and Sourcing Plugin File
&lt;/h2&gt;

&lt;p&gt;Change to your plugin directory and create your plugin file &lt;code&gt;do_markdown.vim&lt;/code&gt; using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.vim/plugin/do_markdown
&lt;span class="nb"&gt;touch &lt;/span&gt;do_markdown.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To activate your plugin every time vim starts up, you need to modify &lt;code&gt;.vimrc&lt;/code&gt; and source it. Edit &lt;code&gt;.vimrc&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.vimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following line of code to the end of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;plugin&lt;span class="sr"&gt;/do_markdown/&lt;/span&gt;do_markdown&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit vim using the &lt;code&gt;:x&lt;/code&gt; command Good job! You just created all the plugin boilerplate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Plugin
&lt;/h2&gt;

&lt;p&gt;Markdown is a language used to format text documents with basic styles like headings, bold and italic, and block quotes. For instance, you can make text bold by surrounding–or bracketing–it with double asterisks as in **Alert**.&lt;/p&gt;

&lt;p&gt;DigitalOcean (DO) has its own cool looking markdown that works well with formatting code blocks and callouts. This plugin will generate DO markdown.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This plugin only generates a subset of the DO markdown. Feel free to add the rest!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This plugin creates two types of markdown: brackets and blocks. Brackets surround a string of text with symbols that apply formatting to it, and blocks are multiline sections of text enclosed in symbols. Let’s tackle brackets first.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are Mappings?
&lt;/h3&gt;

&lt;p&gt;Your plugin exposes a collection of mappings. A mapping is a shortcut that automates some repetitive task. Working efficiently is all about reducing keystrokes, and that is exactly what mappings do for you. As you know, vim has multiple modes of operation: insert, normal, command, and visual. Well, you can create mappings for each mode: imap, nmap, cmap, and vmap. For simplicity, this article refers to all of these generically as mappings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One -- Creating Bracket Mappings
&lt;/h2&gt;

&lt;p&gt;It’s tedious to repeatedly type closing brackets, so your plugin will generate the closing bracket for you and move the cursor between the brackets. Change to your plugin’s directory and edit your plugin file using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.vim/plugin/do_markdown
vim do_markdown.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the following code to the bottom of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following table shows what happens when you test the imap by entering insert-mode and typing &lt;code&gt;**&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;strong&gt;_&lt;/strong&gt; character represents the cursor location.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type:&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;td&gt;**&lt;strong&gt;_&lt;/strong&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As the table illustrates, when you type &lt;code&gt;**&lt;/code&gt; in insert-mode, the mapping inserts four &lt;code&gt;*&lt;/code&gt; characters and places the cursor between both pairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Problem With This Map
&lt;/h3&gt;

&lt;p&gt;There is a problem with this imap: Once you finish typing &lt;code&gt;Note:&lt;/code&gt; the cursor remains between the brackets as follows:&lt;/p&gt;

&lt;p&gt;**Note:&lt;strong&gt;_&lt;/strong&gt;**&lt;/p&gt;

&lt;p&gt;Now you have to use &lt;code&gt;&amp;lt;esc&amp;gt;A&lt;/code&gt; to move past the closing bracket. Wouldn’t it be easier if instead you could stay in insert-mode , type &lt;code&gt;;;&lt;/code&gt;, and achieve the same thing--moving the cursor to the end of the line in insert-mode? Fortunately, you can create an imap to do this. The problem with using &lt;code&gt;&amp;lt;esc&amp;gt;A&lt;/code&gt; is you have to move your hand off the home row, reach up and press &lt;code&gt;&amp;lt;esc&amp;gt;&lt;/code&gt;, reposition your hand on the home row, then do a &lt;code&gt;&amp;lt;shift&amp;gt;a&lt;/code&gt;. With an imap all you do is move your right pinky finger over slightly and press &lt;code&gt;;;&lt;/code&gt;. Add the following imap to your plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following table illustrates the result of using imap &lt;code&gt;;;&lt;/code&gt; in conjunction with the bracket &lt;code&gt;imap **&lt;/code&gt;. Begin by entering insert-mode.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Type:&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1.&lt;/td&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;td&gt;**&lt;strong&gt;_&lt;/strong&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.&lt;/td&gt;
&lt;td&gt;Note:&lt;/td&gt;
&lt;td&gt;**Note:&lt;strong&gt;_&lt;/strong&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3.&lt;/td&gt;
&lt;td&gt;;;&lt;/td&gt;
&lt;td&gt;**Note:*&lt;em&gt;**_&lt;/em&gt;*&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Observe the position of the cursor &lt;strong&gt;&lt;code&gt;_&lt;/code&gt;&lt;/strong&gt; during each step. When you test these macros, you’ll see what I mean firsthand.&lt;/p&gt;

&lt;p&gt;There is another problem to solve: After typing &lt;code&gt;;;&lt;/code&gt; you still have to tap &lt;code&gt;&amp;lt;space&amp;gt;&lt;/code&gt; at the end. If you type &lt;code&gt;**&lt;/code&gt; in insert-mode, and then type "Don't forget to save", this is what will happen:&lt;/p&gt;

&lt;p&gt;**Note:**Don't forget to save&lt;/p&gt;

&lt;p&gt;It's somewhat hard to notice, but there is no whitespace before "Don't". We need a space after it.&lt;/p&gt;

&lt;p&gt;**Note:** Don't forget to save&lt;/p&gt;

&lt;p&gt;To insert a space after **Note:**, update the imap as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mappings
&lt;/h3&gt;

&lt;p&gt;Finally, here are all of the bracket imaps in this plugin. Copy them into your plugin file.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;map&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;inoremap ** ****2hi&lt;/td&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;td&gt;**&lt;strong&gt;_&lt;/strong&gt;**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inoremap &lt;code&gt;\&lt;/code&gt;`&lt;/td&gt;
&lt;td&gt;`&lt;/td&gt;
&lt;td&gt;&lt;code&gt;**_**\&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inoremap _ __&lt;/td&gt;
&lt;td&gt;_&lt;/td&gt;
&lt;td&gt;__&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inoremap ^ &amp;lt;^&amp;gt;&amp;lt;^&amp;gt;3hi&lt;/td&gt;
&lt;td&gt;^&lt;/td&gt;
&lt;td&gt;&amp;lt;^&amp;gt;&lt;strong&gt;_&lt;/strong&gt;&amp;lt;^&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Save and exit using the following vim command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;wq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updated &lt;code&gt;do_markdown.vim&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" UTILITIES&lt;/span&gt;
inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;" BRACKETS&lt;/span&gt;
inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
inoremap ` ``&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap _ __&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ^ &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; ^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Two – Creating Block Templates and Mappings
&lt;/h2&gt;

&lt;p&gt;Now you’ll create your block imaps, which generate multiline blocks of text using simple parameterized templates. Consider the following DO markdown code block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will create a template that substitutes XXX in sections that you will edit. Create a template named &lt;code&gt;code.txt&lt;/code&gt; using the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim code.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the following text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...XXX
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and close the file using the following vim command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;wq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reopen your plugin file using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim do_markup.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you will create an &lt;code&gt;imap&lt;/code&gt; that reads the template file into the active buffer. Add this to your plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;read&lt;/span&gt; code&lt;span class="p"&gt;.&lt;/span&gt;txt&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;kdd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The normal-mode &lt;code&gt;kdd&lt;/code&gt; command deletes the blank line that gets added when you read file contents in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Test it by entering insert-mode and typing &lt;code&gt;code&amp;lt;cr&amp;gt;&lt;/code&gt;. It should dump the contents of &lt;code&gt;code.txt&lt;/code&gt; at the cursor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated &lt;code&gt;do_markdown.vim&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" UTILITIES&lt;/span&gt;
inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;" BRACKETS&lt;/span&gt;
inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
inoremap ` ``&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap _ __&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ^ &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; ^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;

&lt;span class="c"&gt;" BLOCKS&lt;/span&gt;
inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;read&lt;/span&gt; code&lt;span class="p"&gt;.&lt;/span&gt;txt&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;kdd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the most tedious part. You need to create all of the templates for all of the block imaps. Here are the download links for each file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/code.txt" rel="noopener noreferrer"&gt;code.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/out.txt" rel="noopener noreferrer"&gt;out.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/lab.txt" rel="noopener noreferrer"&gt;lab.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/crp.txt" rel="noopener noreferrer"&gt;crp.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/ecod.txt" rel="noopener noreferrer"&gt;ecod.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/elab.txt" rel="noopener noreferrer"&gt;elab.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/out.txt" rel="noopener noreferrer"&gt;eout.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/out.txt" rel="noopener noreferrer"&gt;ecpr.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/nowa.txt" rel="noopener noreferrer"&gt;nowa.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/note.txt" rel="noopener noreferrer"&gt;note.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/warn.txt" rel="noopener noreferrer"&gt;warn.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/info.txt" rel="noopener noreferrer"&gt;info.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/drft.txt" rel="noopener noreferrer"&gt;drft.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/col.txt" rel="noopener noreferrer"&gt;col.txt&lt;/a&gt;&lt;br&gt;
&lt;a href="https://raw.githubusercontent.com/boonecabaldev/BC-Portfolio/refs/heads/main/DigitalOceanVimPlugin/dets.txt" rel="noopener noreferrer"&gt;dets.txt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will create the rest of the block &lt;code&gt;imap&lt;/code&gt;s later in the tutorial.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step Three -- Making Function to Load Templates
&lt;/h2&gt;

&lt;p&gt;You’re going to make a lot of these &lt;code&gt;imap&lt;/code&gt;s, so it wouldn’t hurt to use the following function to avoid code duplication. Add this to your plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;template_filename&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;silent&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s1"&gt;'read '&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_filename&lt;/span&gt;
  normal kdd

&lt;span class="k"&gt;endfunction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your &lt;code&gt;imap code&amp;lt;cr&amp;gt;&lt;/code&gt; to invoke &lt;code&gt;LoadTemplate&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'code.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the basic structure you will use to create all of the block imaps in this plugin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated &lt;code&gt;do_markdown.vim&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" UTILITIES&lt;/span&gt;
inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;template_filename&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;silent&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s1"&gt;'read '&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_filename&lt;/span&gt;
  normal kdd

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="c"&gt;" BRACKETS&lt;/span&gt;
inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
inoremap ` ``&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap _ __&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ^ &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; ^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;

&lt;span class="c"&gt;" BLOCKS&lt;/span&gt;
inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'code.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Four – Creating Cursor Movement Function
&lt;/h2&gt;

&lt;p&gt;After inserting the template file contents into the buffer, the next step is to move the cursor to the next XXX and replace it with the cursor in insert-mode. To accomplish this, you are going to create a function named &lt;code&gt;ToEndOrNext&lt;/code&gt; that does the job of your &lt;code&gt;imap ;;&lt;/code&gt; plus the aforementioned functionality. Below is the pseudo code for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If there is no template_param in the file
  Move cursor to end of line in insert-mode
Else
  Move cursor to next template_param
Replace template_param with cursor in insert-mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code to your plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;template_param&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a:template_param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s2"&gt;"normal! /"&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_param&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"\r"&lt;/span&gt;
    normal diw
    &lt;span class="k"&gt;startinsert&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;startinsert&lt;/span&gt;
  &lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses the &lt;code&gt;search&lt;/code&gt; VimL API to search for &lt;code&gt;template_param&lt;/code&gt;. Using the &lt;code&gt;n&lt;/code&gt; option allows you to search for a string without moving the cursor to the match–a look-ahead search, if you will.&lt;/p&gt;

&lt;p&gt;Let’s test it. Save and source the plugin using the following vim commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new buffer using the following vim command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter insert-mode and type &lt;code&gt;code&amp;lt;cr&amp;gt;&lt;/code&gt;. This will read in the &lt;code&gt;code.txt&lt;/code&gt; template. Now, use the following vim command to test &lt;code&gt;ToEndOrNext&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cursor should have replaced the first XXX.  Use &lt;code&gt;:call ToEndOrNext('XXX')&lt;/code&gt; again.  The next XXX should be replaced by the cursor. At this point both XXX strings should be gone. Now test &lt;code&gt;ToEndOrNext&lt;/code&gt; by moving the cursor to the middle of a line, enter insert-mode, then use &lt;code&gt;&amp;lt;esc&amp;gt;:call ToEndOrNext('XXX')&amp;lt;cr&amp;gt;&lt;/code&gt;. The cursor should move to the end of the line in insert-mode.&lt;/p&gt;

&lt;p&gt;Next, update your &lt;code&gt;imap ;;&lt;/code&gt; to invoke &lt;code&gt;ToEndOrNext&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Almost there. After you load a template using &lt;code&gt;imap code&amp;lt;cr&amp;gt;&lt;/code&gt;, you want it to move to the next XXX and replace it with the cursor in insert-mode.  Hence, you call &lt;code&gt;ToEndOrNext&lt;/code&gt; from within &lt;code&gt;LoadTemplate&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updated &lt;code&gt;do_markdown.vim&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" UTILITIES&lt;/span&gt;
inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;template_filename&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;silent&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s1"&gt;'read '&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_filename&lt;/span&gt;
  normal kdd

  &lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;template_param&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a:template_param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s2"&gt;"normal! /"&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_param&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"\r"&lt;/span&gt;
    normal diw
    &lt;span class="k"&gt;startinsert&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;startinsert&lt;/span&gt;
  &lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="c"&gt;" BRACKETS&lt;/span&gt;
inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
inoremap ` ``&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap _ __&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ^ &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; ^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;

&lt;span class="c"&gt;" BLOCKS&lt;/span&gt;
inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'code.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tying It All Together
&lt;/h2&gt;

&lt;p&gt;The final step is to create the rest of your block imaps.  Remember when you downloaded all of the template files earlier?  Now it is only a matter of calling your &lt;code&gt;LoadTemplate&lt;/code&gt; function, passing the name of the template file. Here is your complete plugin with the block imaps and everything else:&lt;/p&gt;

&lt;h3&gt;
  
  
  Blocks
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;inoremap code&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('code.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  code.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;..._
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap out&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('out.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  out.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
[secondary_label Output]
_
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap lab&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('lab.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  lab.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
[label _]
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap cpr&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('crp.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  crp.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...custom_prefix(_)
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Environment Variations
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;inoremap ecod&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('ecod.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  ecod.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;..._
[environment XXX]
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap elab&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('elab.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  elab.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
[environment _]
[label XXX]
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap eout&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('eout.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  eout.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
[environment _]
[secondary_label Output] XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap ecpr&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('ecpr.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  ecpr.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...custom_prefix(XXX)
[environment XXX]
XXX
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Callouts
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;inoremap nowa&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('nowa.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  nowa.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;$&amp;gt;[_]
**XXX:** XXX
&amp;lt;$&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap note&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('note.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  note.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;$&amp;gt;[note]
**Note:** _
&amp;lt;$&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap warn&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('warn.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  warn.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;$&amp;gt;[warning]
**Warning:** _
&amp;lt;$&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap info&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('info.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  info.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;$&amp;gt;[info]
**Info:** _
&amp;lt;$&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap drft&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('drft.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  drft.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;$&amp;gt;[draft]
**Draft:** _
&amp;lt;$&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Formatting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;inoremap col&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('col.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  col.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[column
_
]
[column
XXX
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;inoremap dets&amp;lt;cr&amp;gt; &amp;lt;esc&amp;gt;:call LoadTemplate('dets.txt')&amp;lt;cr&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  dets.txt
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[details _
XXX
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updated do_markup.vim
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" UTILITIES&lt;/span&gt;
inoremap ;; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;template_filename&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;silent&lt;/span&gt; &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s1"&gt;'read '&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_filename&lt;/span&gt;
  normal kdd

  &lt;span class="k"&gt;call&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'XXX'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; ToEndOrNext&lt;span class="p"&gt;(&lt;/span&gt;template_param&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a:template_param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;execute&lt;/span&gt; &lt;span class="s2"&gt;"normal! /"&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;a:template_param&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"\r"&lt;/span&gt;
    normal diw
    &lt;span class="k"&gt;startinsert&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;startinsert&lt;/span&gt;
  &lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="k"&gt;endfunction&lt;/span&gt;

&lt;span class="c"&gt;" BRACKETS&lt;/span&gt;
inoremap ** ****&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;
inoremap ` ``&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap _ __&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ^ &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; ^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;^&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;hi&lt;/span&gt;

&lt;span class="c"&gt;" BLOCKS&lt;/span&gt;
inoremap code&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'code.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap out&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'out.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap &lt;span class="k"&gt;lab&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'lab.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap cpr&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'crp.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ecod&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ecod.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap elab&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'elab.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap eout&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'eout.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ecpr&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ecpr.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap &lt;span class="nb"&gt;nowa&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nowa.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap note&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'note.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap &lt;span class="nb"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'warn.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap info&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'info.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap drft&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'drft.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap &lt;span class="k"&gt;col&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'col.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap dets&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; LoadTemplate&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dets.txt'&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How I Use This Plugin
&lt;/h2&gt;

&lt;p&gt;I use this plugin from VS Code. Using an extension called &lt;em&gt;Markdown Preview&lt;/em&gt;, I preview a markdown file. Files dock to the top by default. Next, I open the markdown file in vim from a terminal, which docks to the bottom by default. Now, any time I change and save the markdown file in vim, the preview updates to reflect the change.&lt;/p&gt;

&lt;p&gt;I typically use the following normal- and insert-mode mappings to quickly save the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;nnoremap ;s &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
inoremap ;s &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You’ve learned a little bit about mappings and VimL. I hope you use this knowledge to experiment with your own vim plugins. Have fun, friend.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>neovim</category>
      <category>linux</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Changing Keyboard Layouts - Let's Build a Browser Extension</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 05 Jun 2025 18:36:33 +0000</pubDate>
      <link>https://dev.to/boonecabal/changing-keyboard-layouts-lets-build-a-browser-extension-5ca6</link>
      <guid>https://dev.to/boonecabal/changing-keyboard-layouts-lets-build-a-browser-extension-5ca6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Imagine sitting at a shared computer, your fingers poised to type in Colemak, only to realize the system is locked to QWERTY. Frustrating, right? For Colemak users, who enjoy its ergonomic benefits, this is a common hurdle in environments with strict IT policies. Enter "To-Colemak," a browser extension I'm developing to let you switch from QWERTY or Dvorak to Colemak directly in your browser, no system changes needed.&lt;/p&gt;

&lt;p&gt;In this article, I'll guide you through building "To-Colemak," from its core functionality to its Model-View-Controller (MVC) architecture, testing setup, and installation. The repository is available &lt;a href="https://github.com/boonecabaldev/To-Colemak/tree/dev" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Whether you're a Colemak enthusiast or a curious developer, let's create a tool to make typing a breeze!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This article assumes a basic understanding of HTML, CSS, and JavaScript, along with a general idea of how browser extensions work. If you're new to these, check out these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/techcrafted/html-css-your-gateway-to-building-stunning-websites-2hff"&gt;HTML &amp;amp; CSS: Your Gateway to Building Stunning Websites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/qmenoret/browser-extension-extension-architecture-13m1"&gt;Browser Extension - Extension Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/boonecabal/how-to-rapidly-build-browser-extensions-with-ai-1ml6"&gt;How to Rapidly Build Browser Extensions With AI&lt;/a&gt; (An article I wrote that you might find helpful!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The core idea is simple: activate the extension via its popup menu (by clicking the extension icon) or the &lt;code&gt;Ctrl+L&lt;/code&gt; shortcut. Once active, text typed into input fields or textareas on a webpage converts to the Colemak layout.&lt;/p&gt;

&lt;p&gt;Here's a typical use case:&lt;/p&gt;

&lt;p&gt;First, click the extension icon to open the popup, and then check the "Enable Key Conversion" checkbox.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeoyun7rr2scmxzi4vcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeoyun7rr2scmxzi4vcb.png" alt="Screenshot of To-Colemak popup with 'Enable Key Conversion' checked" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last, click any text input field on a webpage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9e3usgsvxtp3vcxkqfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9e3usgsvxtp3vcxkqfs.png" alt="Screenshot of a text input field with a red border indicating active Colemak conversion" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the red border around the active input field; when you type, you're using the Colemak layout!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This extension is a work in progress. Earlier versions may not fully support elements like &lt;code&gt;contenteditable&lt;/code&gt; &lt;code&gt;divs&lt;/code&gt;, &lt;code&gt;iframes&lt;/code&gt;, or &lt;code&gt;inputs&lt;/code&gt; in shadow DOM. Future versions may use &lt;code&gt;MutationObservers&lt;/code&gt; or &lt;code&gt;postMessage&lt;/code&gt; to address these challenges.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Here's the directory structure for the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📂 doc
  📄 article.md
  📄 README.md
📂 icons
  📄 keyboard128.png
  📄 keyboard16.png
  📄 keyboard24.png
  📄 keyboard32.png
  📄 keyboard64.png
📂 src
  📄 background.js
  📄 content.js
  📄 controller.js
  📄 model.js
  📄 popup.html
  📄 popup.js
  📄 view.js
📂 tests
  📄 model.test.js
  📄 view.test.js
📄 .gitignore
📄 .hintrc
📄 manifest.json
📄 package-lock.json
📄 package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;code&gt;11.4.1&lt;/code&gt;, &lt;code&gt;jest&lt;/code&gt;, and &lt;code&gt;test&lt;/code&gt; entries in the original structure were removed as they seemed to be placeholders or unrelated to the project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using the Model-View-Controller (MVC) Architecture
&lt;/h2&gt;

&lt;p&gt;The extension uses the Model-View-Controller (MVC) pattern for a clean separation of concerns, making the code modular and testable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model (&lt;code&gt;model.js&lt;/code&gt;)&lt;/strong&gt;: Manages the extension's state (e.g., whether conversion is active, the source layout like QWERTY or Dvorak) and stores keyboard layout mappings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View (&lt;code&gt;view.js&lt;/code&gt;)&lt;/strong&gt;: Handles DOM manipulations, such as highlighting active input fields with a red border or displaying overlay messages for state changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controller (&lt;code&gt;controller.js&lt;/code&gt;, &lt;code&gt;content.js&lt;/code&gt;)&lt;/strong&gt;: Acts as the intermediary, listening for user interactions (e.g., key presses) or browser events, processing them with Model data, and updating the View.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, when the user toggles the extension via the popup (View), the Controller updates the Model's &lt;code&gt;isActive&lt;/code&gt; state and saves it to storage. The View then listens for this change and adds a red border to the active input field.&lt;/p&gt;

&lt;p&gt;The key conversion logic lies in the &lt;code&gt;convertToColemak&lt;/code&gt; function in the Controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;convertToColemak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Skip conversion if extension is inactive or modifier keys are pressed&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;altKey&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metaKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Map the pressed key to its Colemak equivalent&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colemakKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyboardLayout&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;colemakKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Exit if no mapping exists&lt;/span&gt;

  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Prevent default keypress behavior&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;handled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Traverse DOM to find input or contentEditable element&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isContentEditable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Insert text into contentEditable elements&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insertText&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;colemakKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;handled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INPUT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TEXTAREA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Insert text into standard input or textarea&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectionStart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectionEnd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;colemakKey&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSelectionRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;colemakKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;colemakKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;handled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Fallback: insert text if no specific input was found&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;handled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insertText&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;colemakKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checks if the extension is active and no modifier keys (Ctrl, Alt, Meta) are pressed.&lt;/li&gt;
&lt;li&gt;Maps the pressed key to its Colemak equivalent using the Model's keyboard layout.&lt;/li&gt;
&lt;li&gt;Prevents the original keypress and inserts the Colemak key into the active input field or contenteditable element.&lt;/li&gt;
&lt;li&gt;Updates the cursor position for smooth typing.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;document.execCommand&lt;/code&gt; is deprecated. Future versions may explore the Clipboard API or &lt;code&gt;InputEvent&lt;/code&gt; for better compatibility. For more details, check the &lt;a href="https://github.com/boonecabaldev/To-Colemak/tree/dev" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Building and Running Unit Tests
&lt;/h2&gt;

&lt;p&gt;Unit testing ensures the extension's reliability. I chose Jest for its simplicity, built-in mocking, and widespread use in JavaScript projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up the Development Environment
&lt;/h3&gt;

&lt;p&gt;To set up the testing environment (example for Windows using Conda):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Miniconda (or Anaconda) if not already present.&lt;/li&gt;
&lt;li&gt;Open the Anaconda Prompt (or a Conda-configured terminal).&lt;/li&gt;
&lt;li&gt;Create a new Conda environment with Node.js:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;conda create &lt;span class="nt"&gt;-n&lt;/span&gt; to-colemak-env nodejs
conda activate to-colemak-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Navigate to the project directory and install Jest:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Non-Windows users can use &lt;code&gt;nvm&lt;/code&gt; or a direct Node.js installation instead of Conda.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Writing and Running Tests
&lt;/h3&gt;

&lt;p&gt;Tests are organized by component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tests/model.test.js&lt;/code&gt;: Verifies state management and layout settings in the Model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tests/view.test.js&lt;/code&gt;: Tests UI updates, such as border styling, by simulating DOM interactions with mock elements (e.g., &lt;code&gt;document.createElement("input")&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an example test from &lt;code&gt;view.test.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;handleFocus does not set borderColor if Model is inactive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Set the model to inactive&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Create a mock input element&lt;/span&gt;
  &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleFocus&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// Call the function under test&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Assert that the border color was not changed&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test ensures &lt;code&gt;View.handleFocus&lt;/code&gt; only applies a border color when &lt;code&gt;Model.isActive&lt;/code&gt; is true.&lt;/p&gt;

&lt;p&gt;To run the tests (from the project root with the Conda environment activated):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For detailed output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx jest &lt;span class="nt"&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(to-colemak-env) C:\Users\unity1\dev\To-Colemak&amp;gt;npx jest --verbose
 PASS  tests/model.test.js
  Model
    √ setLayout sets QWERTY mapping (6 ms)
    √ setLayout sets Dvorak mapping
    √ setActive updates isActive and persists (2 ms)
    √ load sets state from storage (1 ms)

 PASS  tests/view.test.js
  View
    √ handleFocus sets borderColor to red if active (10 ms)
    √ handleBlur resets borderColor if active (1 ms)
    √ updateHighlight highlights active input (3 ms)
    √ showToggleMessage creates and removes overlay (22 ms)
    √ handleFocus does not set borderColor if Model is inactive (1 ms)
    √ typing in textbox converts keys to Colemak when Model.isActive is true (5 ms)

Test Suites: 2 passed, 2 total
Tests:       10 passed, 10 total
Snapshots:   0 total
Time:        1.035 s, estimated 4 s
Ran all test suites.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The test suite provides basic coverage. Future tests could cover edge cases like special characters or complex DOM structures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Installing the Extension for Development
&lt;/h2&gt;

&lt;p&gt;To test "To-Colemak" during development, load it as an unpacked extension in a Chromium-based browser (e.g., Chrome, Brave, Edge):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your browser.&lt;/li&gt;
&lt;li&gt;Navigate to the extensions page:

&lt;ul&gt;
&lt;li&gt;Chrome/Brave: &lt;code&gt;chrome://extensions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Edge: &lt;code&gt;edge://extensions&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enable "Developer mode" (top-right toggle).&lt;/li&gt;
&lt;li&gt;Click "Load unpacked" and select the project folder ( Hawkins the &lt;code&gt;manifest.json&lt;/code&gt; file).&lt;/li&gt;
&lt;li&gt;Pin the extension to the toolbar for easy access (via the puzzle piece icon).&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This extension is designed for Chromium-based browsers. Firefox support is planned for a future release.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Testing the Extension Manually
&lt;/h2&gt;

&lt;p&gt;After installation, verify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The overlay message ("Colemak Conversion Enabled/Disabled") appears when toggling the extension via the popup or &lt;code&gt;Ctrl+L&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The focused textbox border is highlighted red when active and resets when inactive or focus is lost.&lt;/li&gt;
&lt;li&gt;Typing in QWERTY (or Dvorak, if selected) converts to Colemak in text fields when active.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;We've explored "To-Colemak," a browser extension that brings the Colemak keyboard layout to environments where system-level changes are restricted. By leveraging the MVC architecture, robust unit tests, and browser capabilities, it empowers users to type comfortably in challenging settings. Whether you're a Colemak enthusiast or a budding developer, I hope this guide inspires you to build your own extensions.&lt;/p&gt;

&lt;p&gt;Explore the &lt;a href="https://github.com/boonecabaldev/To-Colemak/tree/dev" rel="noopener noreferrer"&gt;repository&lt;/a&gt;, try the extension, or contribute by tackling tasks like improving shadow DOM support or adding new layouts in the &lt;a href="https://github.com/boonecabaldev/To-Colemak/issues" rel="noopener noreferrer"&gt;GitHub issues&lt;/a&gt;. Happy typing!&lt;/p&gt;

</description>
      <category>extensions</category>
      <category>javascript</category>
      <category>browser</category>
      <category>html</category>
    </item>
    <item>
      <title>How to Rapidly Build Browser Extensions With AI</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Sun, 25 May 2025 14:14:43 +0000</pubDate>
      <link>https://dev.to/boonecabal/how-to-rapidly-build-browser-extensions-with-ai-1ml6</link>
      <guid>https://dev.to/boonecabal/how-to-rapidly-build-browser-extensions-with-ai-1ml6</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this tutorial, let's create a browser extension that highlights text on a webpage using AI code generation technologies. We’ll leverage the &lt;strong&gt;Google Gemini Coding Partner gem&lt;/strong&gt; and &lt;strong&gt;DeepSeek&lt;/strong&gt; to streamline code generation for our browser extension. When you are done reading this article, you will understand how massive a paradigm shift AI code generators are.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1 — Generating Project Code Using &lt;code&gt;README.MD&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Much of our code generation revolves around creating and updating a &lt;code&gt;README.MD&lt;/code&gt; file, serving as a dynamic features document that guides your extension’s development.&lt;/p&gt;

&lt;p&gt;Let's begin by executing the following &lt;code&gt;README.MD&lt;/code&gt; features in Gemini:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Browser Extension - Simple Page Text Highlighter  &lt;/span&gt;

&lt;span class="gu"&gt;## Features  &lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Custom bullseye Browser-Action icon  
&lt;span class="p"&gt;-&lt;/span&gt; Highlights any text you have selected on the webpage  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this as a prompt generated a lot of output. We are only going to focus on a couple of excerpts--the first recommends organizing your project with the structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HighlighterExtension/  
├── manifest.json  
├── background.js  
├── content.js  
└── icons/  
    ├── icon16.png  
    ├── icon64.png  
    └── icon128.png  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For the Browser-Action extension icon, I downloaded PNG files from &lt;a href="https://www.flaticon.com" rel="noopener noreferrer"&gt;Flaticon&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, Gemini generated the core extension files; copy the code over to your project.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;manifest.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Simple Page Text Highlighter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Highlights any text you have selected on the webpage."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&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="s2"&gt;"activeTab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scripting"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"background"&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="nl"&gt;"service_worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"background.js"&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="nl"&gt;"action"&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="nl"&gt;"default_icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon128.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Highlight Selected Text"&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="nl"&gt;"icons"&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="nl"&gt;"128"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon128.png"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;background.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClicked&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Execute the content.js script on the current active tab&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content script injected successfully!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to inject content script:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;content.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rangeCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRangeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// You can change this color&lt;/span&gt;
      &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Add some styling, if you like&lt;/span&gt;

      &lt;span class="c1"&gt;// Wrap the selected content with the span&lt;/span&gt;
      &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;surroundContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Clear the selection after highlighting&lt;/span&gt;
      &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAllRanges&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please select some text to highlight!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Execute the highlight function&lt;/span&gt;
  &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2 — Installing and Testing Your Extension&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Follow these steps to test your extension in Chrome:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Chrome Extensions Page&lt;/strong&gt;&lt;br&gt;
Navigate to &lt;code&gt;chrome://extensions&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable Developer Mode&lt;/strong&gt;&lt;br&gt;
Toggle &lt;strong&gt;Developer Mode&lt;/strong&gt; on (top right).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load Unpacked Extension&lt;/strong&gt;&lt;br&gt;
Click &lt;strong&gt;Load Unpacked&lt;/strong&gt; and select your &lt;code&gt;HighlighterExtension&lt;/code&gt; folder.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test It Out&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open any webpage (e.g., Google).&lt;/li&gt;
&lt;li&gt;Select text with your mouse.&lt;/li&gt;
&lt;li&gt;Click the extension icon in your toolbar.&lt;/li&gt;
&lt;li&gt;The selected text should now be highlighted in yellow!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3 — Adding a Toggle Feature&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now, let’s refine the extension by making highlighted text &lt;strong&gt;toggleable&lt;/strong&gt;. When I was building this extension, Gemini failed to implement this feature, so I switched to &lt;strong&gt;DeepSeek&lt;/strong&gt;, which successfully generated a functional solution.&lt;/p&gt;

&lt;p&gt;First, I updated my &lt;code&gt;README.MD&lt;/code&gt;, adding the toggling feature just described:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated README.MD:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Browser Extension - Simple Page Text Highlighter  &lt;/span&gt;

&lt;span class="gu"&gt;## Features  &lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Custom bullseye Browser-Action icon  
&lt;span class="p"&gt;-&lt;/span&gt; Highlights any text you have selected on the webpage  
&lt;span class="p"&gt;-&lt;/span&gt; Clicking the icon will:  
&lt;span class="p"&gt;  1.&lt;/span&gt; Highlight the selected text if it isn’t already highlighted.  
&lt;span class="p"&gt;  2.&lt;/span&gt; Unhighlight selected text if it’s already highlighted.  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing this prompt in DeepSeek generated a new &lt;code&gt;content.js&lt;/code&gt;, which (partially) unhighlighted text:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;content.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;simple-page-text-highlighter-highlight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rangeCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRangeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;selectedText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please select some text to highlight or unhighlight!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Check if selection is already highlighted&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parentElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commonAncestorContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Function to check if node or its parents have our highlight class&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasHighlight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ELEMENT_NODE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="c1"&gt;// Check start and end containers&lt;/span&gt;
      &lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endContainer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Unhighlight the selected text&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;spans&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Check if this span is within our selection&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spanRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;spanRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectNodeContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersectsNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Unwrap the span&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Highlight the selected text&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// First, try the simple approach&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collapsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;surroundContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// If surroundContents fails, try a more robust approach&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Could not surround contents directly. Trying alternative method:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="c1"&gt;// Extract the selected text nodes&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textNodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;walker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTreeWalker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commonAncestorContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SHOW_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;acceptNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersectsNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; 
                  &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_ACCEPT&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_REJECT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;walker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nextNode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;textNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="c1"&gt;// Process each text node&lt;/span&gt;
          &lt;span class="nx"&gt;textNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textNode&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Skip already highlighted nodes&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Clear the selection after highlighting/unhighlighting&lt;/span&gt;
      &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAllRanges&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please select some text to highlight or unhighlight!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4 — Fixing the Unhighlighting Bug&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Our implementation fails when unhighlighting &lt;strong&gt;one word&lt;/strong&gt; within multiple highlighted words. Unhighlighting one word in a highlighted range of three erroneously unhighlights all three words.&lt;/p&gt;

&lt;p&gt;To solve this, I gave Gemini the last &lt;code&gt;README.MD&lt;/code&gt; prompt and had it generate a much better, more detailed revision:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;README.MD&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Browser Extension: Simple Page Text Highlighter
&lt;/h2&gt;

&lt;p&gt;This extension will enable users to highlight and unhighlight selected text on a webpage.&lt;/p&gt;
&lt;h3&gt;
  
  
  Functionality Details
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser-Action Icon:&lt;/strong&gt; The extension will have a custom "bullseye" icon displayed in the browser's toolbar.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interaction Trigger:&lt;/strong&gt; The core functionality activates when a user performs two sequential actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Selects text on a webpage.&lt;/li&gt;
&lt;li&gt;Clicks the custom browser-action icon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highlighting Logic (On Icon Click):&lt;/strong&gt; Upon clicking the browser-action icon with text selected, the extension will evaluate the selected text and perform one of two actions:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action 1 (Highlight):&lt;/strong&gt; If the currently selected text is not highlighted, apply a highlight to that specific text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action 2 (Unhighlight):&lt;/strong&gt; If the currently selected text is highlighted, remove the highlight from only that specific selected text.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Granularity of Action:&lt;/strong&gt; The highlighting or unhighlighting action applies exclusively to the text currently selected by the user. For example, if a user selects one word within a previously highlighted phrase of three words, only the selected word will be unhighlighted, leaving the other two words in the phrase highlighted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I find this approach to be a novel solution because instead of writing a prompt that generates code, we are writing a prompt that generates an improved prompt.&lt;/p&gt;

&lt;p&gt;Now, executing this improved prompt in DeepSeek generates the following &lt;code&gt;content.js&lt;/code&gt;, which correctly unhighlights ranges of highlighted words:  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;content.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;simple-page-text-highlighter-highlight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Helper function to get the intersection between two ranges&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getIntersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;START_TO_START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;START_TO_START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startOffset&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startOffset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;END_TO_END&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endContainer&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;END_TO_END&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endOffset&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endOffset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;START_TO_END&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="nx"&gt;range1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compareBoundaryPoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;END_TO_START&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// No intersection&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startOffset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endOffset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rangeCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRangeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;selectedText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please select some text to highlight or unhighlight!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Check if selection is already highlighted&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parentElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commonAncestorContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasHighlight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ELEMENT_NODE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;hasHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endContainer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAlreadyHighlighted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;spans&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spanRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;spanRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectNodeContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getIntersection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spanRange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cloneContents&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

          &lt;span class="c1"&gt;// Split the span into three parts: before, selected, and after&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;beforeRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;beforeRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;beforeRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startOffset&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;beforeContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;beforeRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cloneContents&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;afterRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRange&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;afterRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endOffset&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;afterRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;afterContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;afterRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cloneContents&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

          &lt;span class="c1"&gt;// Replace the original span with the split parts&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fragment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createDocumentFragment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;beforeRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;beforeSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;beforeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;beforeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;beforeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;beforeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;beforeContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;beforeSpan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="nx"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;afterRange&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;afterSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;afterSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;afterSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;afterSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;afterSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;afterContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;afterSpan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Highlight the selected text (original code)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collapsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;surroundContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Could not surround contents directly. Trying alternative method:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;e&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textNodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;walker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTreeWalker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commonAncestorContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SHOW_TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;acceptNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersectsNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_ACCEPT&lt;/span&gt;
                  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NodeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FILTER_REJECT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;walker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nextNode&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;textNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="nx"&gt;textNodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGHLIGHT_CLASS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&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;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAllRanges&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please select some text to highlight or unhighlight!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;highlightSelectedText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and test it, fiend. Highlight two words, and then unhighlight one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bro Tips&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;💡 &lt;strong&gt;Tip 1: Write Clear AI Prompts&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep your &lt;code&gt;README.MD&lt;/code&gt; updated, adding &lt;strong&gt;one&lt;/strong&gt; feature at a time.
&lt;/li&gt;
&lt;li&gt;Use AI-generated code &lt;strong&gt;to implement specific features&lt;/strong&gt; incrementally.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🛠️ &lt;strong&gt;Tip 2: Undo AI Code Mistakes&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;If AI assistance fails:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Revert&lt;/strong&gt; files to the last &lt;strong&gt;Git commit&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start a new chat session&lt;/strong&gt; with an AI assistant.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload project files&lt;/strong&gt; and paste your README.MD for fresh results.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🔄 &lt;strong&gt;Tip 3: Use Multiple AI Assistants&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;If one fails, try another! &lt;strong&gt;DeepSeek&lt;/strong&gt; often delivers better code than &lt;strong&gt;Gemini&lt;/strong&gt; or &lt;strong&gt;Grok&lt;/strong&gt;.  &lt;/p&gt;

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

&lt;p&gt;If you made it this far, congratulations—you’re highly irregular. Nevertheless, thanks for reading, friend. Now leave, please. 🚀  &lt;/p&gt;

</description>
      <category>ai</category>
      <category>extensions</category>
      <category>gemini</category>
      <category>deepseek</category>
    </item>
    <item>
      <title>Mastering Vim: Buffers, Windows, and Your Text Editing Arsenal</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 22 May 2025 23:04:37 +0000</pubDate>
      <link>https://dev.to/boonecabal/mastering-vim-buffers-windows-and-your-text-editing-arsenal-28ai</link>
      <guid>https://dev.to/boonecabal/mastering-vim-buffers-windows-and-your-text-editing-arsenal-28ai</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we will cover the basics of working with buffers and windows (called panes) in Vim using an example-driven approach. To get the most out of it, I strongly recommend that you keep Vim open and follow each step. Do not skip any steps. Just be patient and do each step, one at a time. Actively doing it will reinforce the concepts, making it easier to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Buffers: Your Textual Workspaces
&lt;/h2&gt;

&lt;p&gt;A buffer is an area in memory that stores text. Every time you open a file, its contents are read into a buffer, allowing you to make changes to that buffer without affecting the original file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Viewing Buffers
&lt;/h3&gt;

&lt;p&gt;Let's begin by opening Vim. By default, you will have one unnamed buffer.  You can view all your buffers using &lt;code&gt;:ls&lt;/code&gt; or &lt;code&gt;:buffers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;:ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The buffer list produced by &lt;code&gt;:ls&lt;/code&gt; uses the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Number Indicator    Name                          Line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;     &lt;span class="m"&gt;1&lt;/span&gt;        %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of these fields are self-explanatory except for Indicator. Here is an excerpt from the Vim help for &lt;code&gt;:ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;u    an unlisted buffer (only displayed when [!] is used)
        |unlisted-buffer|
 %   the buffer in the current window
 #   the alternate buffer for ":e #" and CTRL-^
 a   an active buffer: it is loaded and visible
 h   a hidden buffer: It is loaded, but currently not
        displayed in a window |hidden-buffer|
  -  a buffer with 'modifiable' off
  =  a readonly buffer
  R  a terminal buffer with a running job
  F  a terminal buffer with a finished job
  ?  a terminal buffer without a job: `:terminal NONE`
  +  a modified buffer
  x  a buffer with read errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Indicator in the above &lt;code&gt;:ls&lt;/code&gt; output is &lt;code&gt;%a&lt;/code&gt;, which specifies that the buffer is active (&lt;code&gt;a&lt;/code&gt;) and in the current window or pane (&lt;code&gt;%&lt;/code&gt;). &lt;code&gt;+&lt;/code&gt; is useful; it tells you if a buffer is modified. We'll cover another useful one, &lt;code&gt;#&lt;/code&gt;, later.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;:ls&lt;/code&gt; Helper Function
&lt;/h3&gt;

&lt;p&gt;Throughout this article, we will be issuing command-line commands followed by the &lt;code&gt;:ls&lt;/code&gt; command, like &lt;code&gt;:bd | ls&lt;/code&gt;. As a convenience, I recommend adding the following function to your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" You must specify 'normal' for all normal-mode commands to work.&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; ExeCmdLs&lt;span class="p"&gt;(&lt;/span&gt;cmd&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;a:cmd&lt;/span&gt; &lt;span class="p"&gt;=~&lt;/span&gt; &lt;span class="s1"&gt;'^normal'&lt;/span&gt;
    exe &lt;span class="nv"&gt;a:cmd&lt;/span&gt;
    &lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="k"&gt;elseif&lt;/span&gt; &lt;span class="nb"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a:cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    exe &lt;span class="nv"&gt;a:cmd&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="s1"&gt;' | ls'&lt;/span&gt;
  &lt;span class="k"&gt;endif&lt;/span&gt;
&lt;span class="k"&gt;endfunction&lt;/span&gt;

nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;space&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ExeCmdLs&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code includes a useful normal-mode mapping, &lt;code&gt;&amp;lt;space&amp;gt;c&lt;/code&gt;, which places you in command-line mode, types &lt;code&gt;:call ExeCmdLs('_')&lt;/code&gt;, and places your cursor at the &lt;code&gt;_&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the rest of the article, wherever you see &lt;code&gt;:[command] | ls&lt;/code&gt;, this translates to using the &lt;code&gt;&amp;lt;space&amp;gt;c[command]&lt;/code&gt; macro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving Buffers to Files
&lt;/h3&gt;

&lt;p&gt;Before we can create a new buffer, we need to save the active buffer to a file, You can do this using &lt;code&gt;:w&lt;/code&gt;. Add the text &lt;code&gt;File a.txt&lt;/code&gt; to the buffer, and then use &lt;code&gt;:w a.txt | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"a.txt" [New] 1L, 11B written&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it has a name of &lt;code&gt;a.txt&lt;/code&gt;, a number of 1, and an indicator of &lt;code&gt;%a&lt;/code&gt;,  telling you it is the active buffer in the current window.&lt;/p&gt;

&lt;p&gt;In addition to &lt;code&gt;:w&lt;/code&gt;, you can save all open buffers using &lt;code&gt;:wa&lt;/code&gt;, which stands for "write all."&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Buffers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;:enew&lt;/code&gt; creates a new, unnamed buffer. Use &lt;code&gt;:enew | ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ExeCmdLs&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'enew'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #    &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have named buffer &lt;code&gt;a.txt&lt;/code&gt; (1) and an unnamed buffer (3); buffer 3 is the active buffer. Enter the text &lt;code&gt;File b.txt&lt;/code&gt;, then use &lt;code&gt;:w b.txt | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" [New] 1L, 11B written&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;      &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have two files to work with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting Buffers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;:bd&lt;/code&gt; deletes the active buffer. Delete buffer &lt;code&gt;b.txt&lt;/code&gt; (3) using &lt;code&gt;:bd | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"a.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're back to buffer &lt;code&gt;a.txt&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Opening Files Into Buffers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;:e&lt;/code&gt; opens a file in the active buffer. Open &lt;code&gt;b.txt&lt;/code&gt; using &lt;code&gt;:e b.txt | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #    &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h4&gt;
  
  
  The &lt;code&gt;#&lt;/code&gt; Indicator
&lt;/h4&gt;

&lt;p&gt;Notice that buffer &lt;code&gt;a.txt&lt;/code&gt; (1) has an indicator of &lt;code&gt;#&lt;/code&gt;. This is the&lt;br&gt;
last edited buffer. You can use &lt;code&gt;:e #&lt;/code&gt; to toggle between the current&lt;br&gt;
and last edited buffers. Use &lt;code&gt;:e # | ls&lt;/code&gt; a few times and notice how&lt;br&gt;
the indicators change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Navigating Between Buffers
&lt;/h3&gt;

&lt;p&gt;The following commands allow you to navigate between buffers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:[N]bnext [N]&lt;/code&gt; or &lt;code&gt;:[N]bn [N]&lt;/code&gt;: move to next buffer, where N is the buffer number.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:[N]bprev [N]&lt;/code&gt; or &lt;code&gt;:[N]bp [N]&lt;/code&gt;: move to the previous buffer, where N is the buffer number.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:[N]buffer [N]&lt;/code&gt; or &lt;code&gt;:[N]b [N]&lt;/code&gt;: move to specified buffer N, where N is the buffer number.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:bf[irst]&lt;/code&gt;: move first buffer in buffer list.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:bl[ast]&lt;/code&gt;: move to last buffer in buffer list.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:buffer [N]&lt;/code&gt; or &lt;code&gt;:b [N]&lt;/code&gt;: move to buffer &lt;code&gt;[N]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the previous &lt;code&gt;:ls&lt;/code&gt; command, we have buffers &lt;code&gt;a .txt&lt;/code&gt; (1) and &lt;code&gt;b.txt&lt;/code&gt; (3) open, with &lt;code&gt;b.txt&lt;/code&gt; (3) being the active buffer. Use &lt;code&gt;:bp | ls&lt;/code&gt; to navigate to buffer &lt;code&gt;a.txt&lt;/code&gt; (1).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"a.txt" 1L, 10B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; #    &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;%a&lt;/code&gt; indicator tells you that buffer &lt;code&gt;a.txt&lt;/code&gt; (1) is the active buffer. Now use &lt;code&gt;:bp | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #    &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Buffer &lt;code&gt;b.txt&lt;/code&gt; (3) is now active. &lt;/p&gt;

&lt;p&gt;You can navigate to a specific buffer using &lt;code&gt;:buffer&lt;/code&gt; or &lt;code&gt;:b&lt;/code&gt;. Use &lt;code&gt;:b 1 | ls&lt;/code&gt; to navigate to buffer &lt;code&gt;a.txt&lt;/code&gt; (1).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"a.txt" 1L, 10B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; #    &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Iterating Over Buffers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;:bufdo [command]&lt;/code&gt; allows you to perform a command over each buffer. Use &lt;code&gt;:bufdo bd&lt;/code&gt; to delete all buffers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One use of &lt;code&gt;:bufdo s/File/&amp;amp;:/ | update&lt;/code&gt; is to perform search-and-replace across multiple buffers. Open &lt;code&gt;a.txt&lt;/code&gt; and &lt;code&gt;b.txt&lt;/code&gt; using &lt;code&gt;:e a.txt | e b.txt | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #    &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contents of &lt;code&gt;a.txt&lt;/code&gt; and &lt;code&gt;b.txt&lt;/code&gt; are &lt;code&gt;File a.txt&lt;/code&gt; and &lt;code&gt;File b.txt&lt;/code&gt;, respectively. Let's search-and-replace &lt;code&gt;File&lt;/code&gt; with &lt;code&gt;File:&lt;/code&gt;. Use &lt;code&gt;:bufdo! s/File/&amp;amp;:/ | update&lt;/code&gt;. Now, if you navigate between buffers using &lt;code&gt;:bn&lt;/code&gt; and &lt;code&gt;:bp&lt;/code&gt;, you will see that both files have been changed.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;:bufdo!&lt;/code&gt; prevents the &lt;code&gt;No write since last change&lt;/code&gt; error.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;:update&lt;/code&gt; is a smarter version of &lt;code&gt;:w&lt;/code&gt; in that it only saves the file if changes have been made.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Exiting Vim
&lt;/h3&gt;

&lt;p&gt;You can exit Vim using the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:q&lt;/code&gt;: Quit the current window, which can be either the pane or the Vim window. Fails when changes have been made.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:wq&lt;/code&gt;: Write current file and close window. Quit after the last edit. Writing fails when the buffer is unnamed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:x&lt;/code&gt;: Like &lt;code&gt;:wq&lt;/code&gt;, except write only when changes have been made.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at a caveat of using quit commands. Save the active buffer and quit Vim using &lt;code&gt;:wq&lt;/code&gt;. Now reopen &lt;code&gt;a.txt&lt;/code&gt; and &lt;code&gt;b.txt&lt;/code&gt; in Vim using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim a.txt b.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;:ls&lt;/code&gt; shows both files are open.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to quit Vim using &lt;code&gt;:q&lt;/code&gt;. It will say &lt;code&gt;E173: 1 more file to edit&lt;/code&gt;. It turns out you have to activate every buffer before you can quit.  Use &lt;code&gt;:bn | q&lt;/code&gt; to navigate to the next buffer &lt;code&gt;b.txt&lt;/code&gt; (2) and then quit. Now you shouldn't have this problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I noticed this problem when I tried to save all buffers and quit Vim using &lt;code&gt;:wa | q&lt;/code&gt;, which failed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Buffer States
&lt;/h3&gt;

&lt;p&gt;Buffer states are complex. It took me a while to understand them. Let's cover each of the six buffer states.&lt;/p&gt;

&lt;h4&gt;
  
  
  Unlisted
&lt;/h4&gt;

&lt;p&gt;An unlisted buffer does not appear in the buffer list. You can utilize an unlisted buffer whenever you want a temporary area in which to edit text. Once you're done, you can delete the buffer and discard the changes. The following code creates an unlisted buffer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Create a listed buffer&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;enew&lt;/span&gt; 
&lt;span class="c"&gt;" Make active buffer unlisted&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;nobuflisted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;:ls!&lt;/code&gt; and &lt;code&gt;:ls u&lt;/code&gt; display all buffers, both listed and unlisted. Using &lt;code&gt;:ls!&lt;/code&gt; produces the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #    &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="k"&gt;u&lt;/span&gt;%&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;u&lt;/code&gt; portion of buffer 3's indicator means unlisted.&lt;/p&gt;

&lt;h4&gt;
  
  
  Inactive
&lt;/h4&gt;

&lt;p&gt;An inactive buffer is not displayed in any pane. For example, using &lt;code&gt;:new&lt;/code&gt; creates a new pane and buffer, making the previously active buffer inactive.&lt;/p&gt;

&lt;h4&gt;
  
  
  Active
&lt;/h4&gt;

&lt;p&gt;An active buffer is any buffer currently displayed in any pane. Therefore, you can have multiple active buffers opened in multiple panes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hidden
&lt;/h4&gt;

&lt;p&gt;You can have multiple buffers loaded in memory, but you can only display one buffer per pane. In other words, any buffer not displayed in any pane is hidden. You can make a buffer hidden using &lt;code&gt;:hide&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Loaded
&lt;/h4&gt;

&lt;p&gt;A loaded buffer contains the contents of a file. For instance, if you open a file using &lt;code&gt;:edit a.txt&lt;/code&gt;, that buffer is loaded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Unloaded
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;:bunload N&lt;/code&gt; unloads a buffer and its contents from memory, but it still appears in the buffer list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Windows (Panes): Viewing and Editing in Parallel
&lt;/h2&gt;

&lt;p&gt;While buffers store your text in memory, windows (panes) are sections within the Vim window that display it. Splitting the Vim window into multiple panes lets you simultaneously view and edit different buffers, streamlining your workflow without constantly switching between files. &lt;/p&gt;

&lt;h3&gt;
  
  
  Splitting and Navigating
&lt;/h3&gt;

&lt;p&gt;You can create panes using the following commands, each of which splits the Vim window into a new pane.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:new&lt;/code&gt;: create a new pane and start editing an unnamed buffer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:split {file}&lt;/code&gt; &lt;code&gt;sp&lt;/code&gt;: create a new pane and start editing file {file} in it. Works almost like &lt;code&gt;:split | edit {file}&lt;/code&gt; when &lt;code&gt;{file}&lt;/code&gt; is supplied.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:vsplit&lt;/code&gt; &lt;code&gt;vs&lt;/code&gt;: works like &lt;code&gt;:split&lt;/code&gt; but split vertically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:vnew&lt;/code&gt;: &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;:q&lt;/code&gt; closes the active pane but leaves the buffer in memory. If you want to close both the pane and its buffer, use &lt;code&gt;:bd&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Demonstrating &lt;code&gt;:new&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Close and reopen Vim, and then use &lt;code&gt;:new | ls&lt;/code&gt; to create a bottom-docked pane. Observe how both panes contain the same buffer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ExeCmdLs&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'new'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Whichever pane contains the cursor is the active pane.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Demonstrating &lt;code&gt;:vsplit&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Use &lt;code&gt;:vs&lt;/code&gt; to create a top-docked pane. This divides the bottom pane vertically into two sub-panes. Pretty cool, isn't it?&lt;/p&gt;

&lt;h4&gt;
  
  
  Demonstrating &lt;code&gt;:split&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Let's create a different layout. Reset the buffers using &lt;code&gt;:bd | ls&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;:vs&lt;/code&gt; to split Vim vertically into left- and right-docked panes. Next, use &lt;code&gt;:sp&lt;/code&gt; to split the right-docked pane horizontally into two sub-panes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Settings for &lt;code&gt;:new&lt;/code&gt;, &lt;code&gt;:sp&lt;/code&gt;, and &lt;code&gt;:vs&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;The following options control the behavior of &lt;code&gt;:split&lt;/code&gt; and &lt;code&gt;:vsplit&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;splitbelow&lt;/code&gt; or &lt;code&gt;sb&lt;/code&gt;: When on, splitting a pane will put the new pane below the current one.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;splitright&lt;/code&gt; or &lt;code&gt;spr&lt;/code&gt;: When on, splitting a pane will put the new pane right the current one.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can unset a Vim option by prepending the setting with &lt;code&gt;no&lt;/code&gt;. For example, unset &lt;code&gt;splitbelow&lt;/code&gt; using &lt;code&gt;:set nosplitbelow&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Navigating Between Panes
&lt;/h4&gt;

&lt;p&gt;You can navigate between panes using &lt;code&gt;:wincmd {arg}&lt;/code&gt;, with &lt;code&gt;{arg}&lt;/code&gt; being a normal-mode movement command like &lt;code&gt;k&lt;/code&gt; (up), &lt;code&gt;j&lt;/code&gt; (down), &lt;code&gt;l&lt;/code&gt; (right), and &lt;code&gt;h&lt;/code&gt; (left). Alternatively, you can use the hotkeys &lt;code&gt;:Ctrl-w h/j/k/l&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important to understand that both buffers and windows have numbers that identify them, and you can supply them as arguments to various Vim functions. Furthermore, understanding the difference between navigating between panes versus buffers will help you avoid getting lost when you have lots of open panes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Iterating Over Panes
&lt;/h4&gt;

&lt;p&gt;Similar to &lt;code&gt;:bufdo&lt;/code&gt;, &lt;code&gt;:windo&lt;/code&gt; lets you invoke a command for each buffer. For instance,, use &lt;code&gt;:windo echo winnr()&lt;/code&gt; to display the pane number of each pane.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deleting Panes
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;:x&lt;/code&gt;, &lt;code&gt;:bd&lt;/code&gt;, &lt;code&gt;:q&lt;/code&gt;, and &lt;code&gt;:wq&lt;/code&gt; close windows. Understand that you can delete a buffer or a buffer and a pane, but you can't delete a pane without deleting a buffer.&lt;/p&gt;

&lt;p&gt;Close and then reopen Vim with &lt;code&gt;a.txt&lt;/code&gt;. Next, use &lt;code&gt;:vs b.txt | ls&lt;/code&gt; to open &lt;code&gt;b.txt&lt;/code&gt; into a right-docked pane.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the Vim window is vertically divided between left- and right-docked panes. Each pane now has an active buffer, with buffer &lt;code&gt;b.txt&lt;/code&gt; in the current window (&lt;code&gt;%&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recall that the &lt;code&gt;%&lt;/code&gt; indicator defines the active window.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;:close&lt;/code&gt; closes the active pane without deleting its buffer. Use &lt;code&gt;:close | ls&lt;/code&gt; and notice how closing a pane doesn't delete a buffer.&lt;/p&gt;

&lt;p&gt;As a final example, use &lt;code&gt;:vs b.txt&lt;/code&gt; to open &lt;code&gt;b.txt&lt;/code&gt; into a right-docked pane and then &lt;code&gt;:bd | ls&lt;/code&gt; to delete it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;call&lt;/span&gt; ExeCmdLs&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'bd'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how this deletes buffer &lt;code&gt;b.txt&lt;/code&gt; and its pane. Again, it is important the distinguish between deleting panes and buffers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Using Buffers and Panes
&lt;/h2&gt;

&lt;p&gt;Let's walk through a comprehensive example using everything we've learned thus far. Begin by opening &lt;code&gt;a.txt&lt;/code&gt;, &lt;code&gt;b.txt&lt;/code&gt;, and &lt;code&gt;c.txt&lt;/code&gt; in Vim using the bash command &lt;code&gt;vim a.txt b.txt c.txt&lt;/code&gt;, and then use &lt;code&gt;:ls&lt;/code&gt;. Observe the indicators as you use the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;      &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;:vnew | new | ls&lt;/code&gt; to vertically split the Vim window into left- and right-docked panes, with the right-docked pane split horizontally between bottom- and top-docked sub-panes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;vnew&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;      &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;4&lt;/span&gt; #&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;5&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;:b c.txt | ls&lt;/code&gt; to navigate to buffer &lt;code&gt;c.txt&lt;/code&gt; and notice how this deletes buffer 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;b&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;txt
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;4&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;:winc k | ls&lt;/code&gt; to move the cursor to the top-right pane.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;winc&lt;/span&gt; &lt;span class="k"&gt;k&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; #&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;      &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;4&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"[No Name]"&lt;/span&gt;                    &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;b b.txt | ls&lt;/code&gt; to navigate to buffer &lt;code&gt;b.txt&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;b&lt;/span&gt; &lt;span class="k"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;txt
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
&lt;span class="c"&gt;"b.txt" 1L, 11B&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simplifying Commands
&lt;/h2&gt;

&lt;p&gt;Let's consolidate some commands. Using  &lt;code&gt;:vs b.txt | sp c.txt | ls&lt;/code&gt; achieves the same result as the previous example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; #&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;==&lt;/span&gt; Alternate &lt;span class="k"&gt;buffer&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;==&lt;/span&gt; Active &lt;span class="k"&gt;buffer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that buffer &lt;code&gt;b.txt&lt;/code&gt; (2) has the &lt;code&gt;#&lt;/code&gt; indicator, which represents the alternate toggle buffer. Use &lt;code&gt;:e # | ls&lt;/code&gt; to toggle to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"b.txt" 1 line --100%-- ((1) of 3)&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"b.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;==&lt;/span&gt; Active &lt;span class="k"&gt;buffer&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt; #    &lt;span class="s2"&gt;"c.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;==&lt;/span&gt; Alternate &lt;span class="k"&gt;buffer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now buffer &lt;code&gt;c.txt&lt;/code&gt; (3) is the alternate buffer.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;:e # | ls&lt;/code&gt; to toggle back to buffer &lt;code&gt;b.txt&lt;/code&gt; (2), and then use &lt;code&gt;:bd | bd | ls&lt;/code&gt; to delete buffers &lt;code&gt;b.txt&lt;/code&gt; (2) and &lt;code&gt;c.txt&lt;/code&gt; (3). Notice how deleting each buffer closes its associated panes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;bd&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;bd&lt;/span&gt;
&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;ls&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt; %&lt;span class="k"&gt;a&lt;/span&gt;   &lt;span class="s2"&gt;"a.txt"&lt;/span&gt;                        &lt;span class="nb"&gt;line&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customizing and Optimizing
&lt;/h2&gt;

&lt;p&gt;Beyond the fundamental commands, Vim offers many options to tailor your editing environment. By mastering buffer states (active, inactive, hidden, and unloaded), you gain a deeper understanding of Vim's text management and unlock further customization possibilities. Additionally, delve into creating and saving personalized window layouts, enabling you to craft a workspace perfectly suited to your specific tasks and preferences.&lt;/p&gt;

&lt;p&gt;The vibrant Vim community also offers a wealth of plugins that can further enhance your buffer and window management experience. Explore these plugins to discover tools that streamline navigation, improve organization, and add more powerful features to your arsenal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace the Journey of Mastery
&lt;/h2&gt;

&lt;p&gt;You made it! Hopefully, this tutorial has demystified using buffers and panes in Vim. This barely scratches the surface of Vim's capabilities. I strongly recommend that you experiment and descend rabbit holes using &lt;code&gt;:help&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Well done, friend. Now leave, please.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>linux</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Build Custom Filters with awk and sed Pipelines on Ubuntu 20.04</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 22 May 2025 22:57:13 +0000</pubDate>
      <link>https://dev.to/boonecabal/how-to-build-custom-filters-with-awk-and-sed-pipelines-on-ubuntu-2004-49ng</link>
      <guid>https://dev.to/boonecabal/how-to-build-custom-filters-with-awk-and-sed-pipelines-on-ubuntu-2004-49ng</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article is written for Linux administrators. It teaches you how to create pipelines on a terminal using &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt; commands. Combining these commands allows you to filter and analyze data, troubleshoot log files, and streamline your day-to-day workflow.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt; are essential for filtering and transforming text data. &lt;code&gt;awk&lt;/code&gt; works well with columns, and &lt;code&gt;sed&lt;/code&gt; excels at search-and-replace. The power of these tools lies in combining them into a pipeline. That will be the focus of this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To complete this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experience operating a Linux terminal.  DigitalOcean's &lt;a href="https://www.digitalocean.com/community/tutorials/a-linux-command-line-primer" rel="noopener noreferrer"&gt;A Linux Command Line Primer&lt;/a&gt; is a great place to start.&lt;/li&gt;
&lt;li&gt;Knowledge about regular expressions; how to interpret and create them.  Read &lt;a href="https://www.digitalocean.com/community/tutorials/an-introduction-to-regular-expressions" rel="noopener noreferrer"&gt;An Introduction to Regular Expressions&lt;/a&gt; to learn more.&lt;/li&gt;
&lt;li&gt;Experience using common command line tools like &lt;code&gt;cut&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt;, and so on.  Check out &lt;a href="https://www.digitalocean.com/community/tutorials/the-basics-of-using-the-sed-stream-editor-to-manipulate-text-in-linux" rel="noopener noreferrer"&gt;Sed Stream Editor to Manipulate Text in Linux&lt;/a&gt; and &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-the-awk-language-to-manipulate-text-in-linux" rel="noopener noreferrer"&gt;How To Use the AWK language to Manipulate Text in Linux&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your First Pipe and Filter using &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let us walk through a basic example of filtering specific data from a file with &lt;code&gt;awk&lt;/code&gt; and then formatting it for display with &lt;code&gt;sed&lt;/code&gt;.  You will use a pipeline to extract and then print the product names and prices for products with a price greater than ten dollars.&lt;/p&gt;

&lt;p&gt;First, create a &lt;code&gt;products.text&lt;/code&gt; file in Vim using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim products.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You don't have to use Vim; you can use whichever editor works best for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fill the file with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;123:T-Shirt:19.99
456:Coffee Mug:8.50
789:Headphones:49.95
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the full pipeline you are going to construct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;: &lt;span class="s1"&gt;'$3 &amp;gt; 10 {print $2 "\t" $3}'&lt;/span&gt; products.txt | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iName\tPrice'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Primer:&lt;/strong&gt; &lt;code&gt;awk&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's brush up on &lt;code&gt;awk&lt;/code&gt;.  &lt;code&gt;awk&lt;/code&gt; uses the syntax of &lt;em&gt;condition { action }&lt;/em&gt;. Here is an example of an &lt;code&gt;awk&lt;/code&gt; script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/^int/ { print "Found an integer." }&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;condition&lt;/em&gt;: &lt;code&gt;/^int/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;{ &lt;em&gt;action&lt;/em&gt; }: &lt;code&gt;print "Found an integer."&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how it works: For every line beginning with "&lt;code&gt;int&lt;/code&gt;", &lt;code&gt;awk&lt;/code&gt; prints the message, "Found an integer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let's break down each part of this pipeline.  Here is the  &lt;code&gt;awk&lt;/code&gt; portion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;: &lt;span class="s1"&gt;'$3 &amp;gt; 10 {print $2 "\t" $3}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;awk&lt;/code&gt; matches lines where the condition that the price (&lt;code&gt;$3&lt;/code&gt;) is greater than &lt;code&gt;10&lt;/code&gt;; the action prints the product name (&lt;code&gt;$2&lt;/code&gt;), followed by a tab, followed by the price.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-F:&lt;/code&gt; argument sets the delimiter to ‘&lt;code&gt;,&lt;/code&gt;’&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at the &lt;code&gt;sed&lt;/code&gt; portion of our pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iName\tPrice'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;1i&lt;/code&gt; inserts "Name"--before the first line of the output--followed by a tab, "Price", and a newline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the full pipeline. Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;: &lt;span class="s1"&gt;'$3 &amp;gt; 10 {print $2 "\t" $3}'&lt;/span&gt; products.txt | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iName\tPrice'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the resulting output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name    Price
T-Shirt 19.99
Headphones      49.95
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Straightforward enough, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  More Complex Filters and Transformations
&lt;/h2&gt;

&lt;p&gt;In this section, we will create some more complex filters and transformations using &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, and some other commands.  As we walk through each example pipeline, go slow, be patient, run every command, observe the output, and grasp what's happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering System Resource Usage by User
&lt;/h2&gt;

&lt;p&gt;Let's create a pipeline that analyzes process information generated by the &lt;code&gt;ps&lt;/code&gt; command.  As a system administrator, it behooves you to monitor resource usage per user, allowing you to discover users who consuming excessive memory, CPU usage, and so on.&lt;/p&gt;

&lt;p&gt;Here is the full pipeline you will construct, which filters resource usage by user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get process information&lt;/span&gt;
ps &lt;span class="nt"&gt;-eo&lt;/span&gt; pid,user,rss |

&lt;span class="c"&gt;# Filter by specific user and format output&lt;/span&gt;
&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$2 == "root" {print $1, "RSS:", $3/1024, "MB"}'&lt;/span&gt; |

&lt;span class="c"&gt;# Sort by memory usage&lt;/span&gt;
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iPID RSS(MB)'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nrk&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step One -- Outputting Process Info With &lt;code&gt;ps&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Begin this pipeline by generating process information using &lt;code&gt;ps&lt;/code&gt;.  Here is the first part of the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-eo&lt;/span&gt; pid,user,rss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Displays all processes using the &lt;code&gt;-e&lt;/code&gt; argument.&lt;/li&gt;
&lt;li&gt;Using the &lt;code&gt;-o&lt;/code&gt; argument, displays the &lt;code&gt;pid&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt;, and &lt;code&gt;rss&lt;/code&gt; columns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Running this command line produces the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    PID USER       RSS
      1 codespa+   640
      7 codespa+  1792
     42 root      3480
    322 codespa+  1408
    355 root      1664
    509 codespa+  1536
    518 codespa+ 131588
    560 codespa+ 54792
    981 codespa+ 62928
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have our fields of interest: PID, USER, and RSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two -- Filtering User Process Info With &lt;code&gt;awk&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let's move on to the next portion of our pipeline, which uses &lt;code&gt;awk&lt;/code&gt; to filter lines containing the “&lt;code&gt;root&lt;/code&gt;” user and calculate memory usage in megabytes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$2 == "root" {print $1, "RSS:", $3/1024, "MB"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The condition &lt;code&gt;$2 == "root"&lt;/code&gt; selects lines where the NAME is equal to "root".&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The action { &lt;code&gt;print $1, "RSS:", $3/1024, "MB"&lt;/code&gt; } displays output using the following format:&lt;/p&gt;

&lt;p&gt;[value of &lt;code&gt;pid&lt;/code&gt;] RSS: [file-size] MB&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Dividing the RSS value by 1024 demonstrates how &lt;code&gt;awk&lt;/code&gt; can perform calculations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Below is our updated pipeline. Run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-eo&lt;/span&gt; pid,user,rss | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$2 == "root" {print $1, "RSS:", $3/1024, "MB"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 RSS: 0.191406 MB
7 RSS: 0.148438 MB
8 RSS: 94.7695 MB
212 RSS: 7.16406 MB
821 RSS: 5.85938 MB
1883 RSS: 1.55469 MB
1884 RSS: 2.91016 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Three -- Sorting by Memory Usage
&lt;/h2&gt;

&lt;p&gt;Let's add some commands to our pipeline to sort the output by memory usage. Here is the &lt;code&gt;sed&lt;/code&gt; portion of the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iPID RSS(MB)'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nrk&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;'1iPID RSS(MB)'&lt;/code&gt; uses the '&lt;code&gt;i&lt;/code&gt;' to insert the column heading "PID RSS(MB)" followed by a newline.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PID RSS(MB)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sort -nrk&lt;/code&gt; sorts the text numerically (&lt;code&gt;-n&lt;/code&gt;), reverses the result (&lt;code&gt;-r&lt;/code&gt;), and sorts by the second column (&lt;code&gt;-k 2&lt;/code&gt;), which effectively sorts the output based on memory usage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Sorting by memory usage (column 2) in descending order helps identify resource-intensive processes efficiently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the pipeline thus far.  Go ahead and run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-eo&lt;/span&gt; pid,user,rss | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$2 == "root" {print $1, $3/1024, "MB"}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'1iPID RSS(MB)'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nrk&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PID RSS(MB)
821 5.88672 MB
8 95.1914 MB
7 0.148438 MB
212 7.16406 MB
2009 1.09375 MB
2008 1.08594 MB
2007 2.92969 MB
2006 3.14453 MB
1 0.191406 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Failed Login Counter
&lt;/h2&gt;

&lt;p&gt;Let's create a pipeline that analyzes an authentication log, searches for, and then counts failed login attempts.  Attention to events like this allows you to protect your system and respond to potential threats.  Here is the full pipeline we'll build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; auth.log | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/invalid user //'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;grep  "Failed password"&lt;/code&gt;: Filters the lines that contain “Failed password” from the authentication log.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sed 's/invalid user //'&lt;/code&gt;: Removes the “invalid user” part from the lines, if present.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;awk '{print $9}'&lt;/code&gt;: Prints the ninth field, which is typically the username.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt;: Sorts the usernames alphabetically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uniq -c&lt;/code&gt;: Counts the occurrences of each username.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort -nr&lt;/code&gt;: Sorts the counts in descending order.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's walk through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One -- Creating a Log File
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;auth.log&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fill the file with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feb 10 15:45:09 ubuntu-lts sshd[47341]: Failed password for tedbell from 103.106.189.143 port 60824 ssh2
Feb 10 15:45:11 ubuntu-lts sshd[47341]: Connection closed by authenticating user root 103.106.189.143 port 60824 [preauth]
Feb 10 15:45:11 ubuntu-lts sshd[47339]: Failed password for root from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:12 ubuntu-lts sshd[47343]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh user= rhost=103.106.189.143  user=root
Feb 10 15:45:14 ubuntu-lts sshd[47339]: Failed password for rhomboidgoatcabin from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:14 ubuntu-lts sshd[47343]: Failed password for root from 103.106.189.143 port 33990 ssh2
Feb 10 15:45:16 ubuntu-lts sshd[47343]: Connection closed by authenticating user root 103.106.189.143 port 33990 [preauth]
Feb 10 15:45:16 ubuntu-lts sshd[47339]: Received disconnect from 180.101.88.228 port 11349:11:  [preauth]
Feb 10 15:45:16 ubuntu-lts sshd[47339]: Disconnected from authenticating user root 180.101.88.228 port 11349 [preauth]
Feb 10 15:45:16 ubuntu-lts sshd[47339]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=180.101.88.228 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Two -- Finding Failed Passwords
&lt;/h2&gt;

&lt;p&gt;Below is the first part of the pipeline, which uses &lt;code&gt;grep&lt;/code&gt;  to filter lines containing “Failed password". Run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; auth.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feb 10 15:45:09 ubuntu-lts sshd[47341]: Failed password for tedbell from 103.106.189.143 port 60824 ssh2
Feb 10 15:45:11 ubuntu-lts sshd[47339]: Failed password for root from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:14 ubuntu-lts sshd[47339]: Failed password for rhomboidgoatcabin from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:14 ubuntu-lts sshd[47343]: Failed password for root from 103.106.189.143 port 33990 ssh2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have all the failed password entries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three -- Removing Invalid Users
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding a &lt;code&gt;sed&lt;/code&gt; command, which removes any “invalid user” parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; auth.log | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/invalid user //'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feb 10 15:45:09 ubuntu-lts sshd[47341]: Failed password for tedbell from 103.106.189.143 port 60824 ssh2
Feb 10 15:45:11 ubuntu-lts sshd[47339]: Failed password for root from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:14 ubuntu-lts sshd[47339]: Failed password for rhomboidgoatcabin from 180.101.88.228 port 11349 ssh2
Feb 10 15:45:14 ubuntu-lts sshd[47343]: Failed password for root from 103.106.189.143 port 33990 ssh2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Four -- Extracting Username
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding an &lt;code&gt;awk&lt;/code&gt; command to print the &lt;code&gt;username&lt;/code&gt; field (&lt;code&gt;$9&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; auth.log | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/invalid user //'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tedbell
root
rhomboidgoatcabin
root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are making progress!  Now you have all the usernames.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Five -- Sorting Usernames
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding the following &lt;code&gt;sort&lt;/code&gt; command to sort the usernames alphabetically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed password"&lt;/span&gt; auth.log | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/invalid user //'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rhomboidgoatcabin
root
root
tedbell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have an alphabetical list of usernames.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Six -- Counting Usernames
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;uniq&lt;/code&gt; commands.  Using &lt;code&gt;uniq&lt;/code&gt; with the &lt;code&gt;-c&lt;/code&gt; argument counts the occurrences of each username, and &lt;code&gt;sort&lt;/code&gt; sorts the usernames alphabetically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep "Failed password" auth.log | sed 's/invalid user //' | awk '{print $9}' | sort | uniq -c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 rhomboidgoatcabin
2 root
1 tedbell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a user count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Seven -- Sorting Output Again
&lt;/h2&gt;

&lt;p&gt;Finally, update the pipeline by adding another &lt;code&gt;sort&lt;/code&gt; command. Using the&lt;code&gt;-nr&lt;/code&gt; argument of &lt;code&gt;sort&lt;/code&gt; sorts the output by username count in descending order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep "Failed password" auth.log | sed 's/invalid user //' | awk '{print $9}' | sort | uniq -c | sort -nr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the full pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 root
1 rhomboidgoatcabin
1 tedbell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All done!&lt;/p&gt;

&lt;h2&gt;
  
  
  Disk Consumption Report
&lt;/h2&gt;

&lt;p&gt;Let's construct a pipeline that finds the top disk space-consuming directories and sorts them in descending order. It's important to be able to monitor disk usage, ensuring a smoother experience for users. Here is the complete pipeline you will construct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;disk_usage.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2, $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/G/ GB/'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k2&lt;/span&gt; &lt;span class="nt"&gt;-nr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;cat disk_usage.log&lt;/code&gt;: Outputs the content of disk_usage.log.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;awk '{print $2, $1}'&lt;/code&gt;: Swaps the columns so that the directory path comes first.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sed 's/G/ GB/'&lt;/code&gt;: Adds a space before the unit ‘G’ to standardize it to ‘GB’.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort -k2 -nr&lt;/code&gt;: Sorts the output based on the second column (disk space) in descending numerical order.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step One -- Creating Disk Usage File
&lt;/h2&gt;

&lt;p&gt;Begin by creating an input file called &lt;code&gt;disk_usage.txt&lt;/code&gt;, and fill it with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2.4G    /usr/local/bin
5.7G    /home/user
1.2G    /tmp
9.8G    /var/log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Two -- Outputting Contents of File
&lt;/h2&gt;

&lt;p&gt;Begin the pipeline by using the &lt;code&gt;cat&lt;/code&gt; command to send the contents of the disk usage file to standard output (screen).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;disk_usage.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Three -- Swapping Columns
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding an &lt;code&gt;awk&lt;/code&gt; command to rearrange the order of the columns, displaying the directory path first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;disk_usage.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2, $}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/local/bin 2.4G
/home/user 5.7G
/tmp 1.2G
/var/log 9.8G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Four -- Changing File Size Column Format
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding a &lt;code&gt;sed&lt;/code&gt; command to add a space before the unit ‘G’ to standardize it to ‘GB’:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;disk_usage.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2, $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/G/ GB/'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this pipeline should produce the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/local/bin 2.4 GB
/home/user 5.7 GB
/tmp 1.2 GB
/var/log 9.8 GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Five -- Sorting Output on Second Column
&lt;/h2&gt;

&lt;p&gt;Update the pipeline by adding a &lt;code&gt;sort&lt;/code&gt; command to sort the output based on the second column (disk space) in descending numerical order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;disk_usage.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2, $1}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/G/ GB/'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k2&lt;/span&gt; &lt;span class="nt"&gt;-nr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an explanation of the &lt;code&gt;sort&lt;/code&gt; options used above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;-k2&lt;/code&gt;: This flag specifies the column (field) for sorting. In this case, &lt;code&gt;2&lt;/code&gt; indicates the second column.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;-nr&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;-n&lt;/code&gt;: This flag tells &lt;code&gt;sort&lt;/code&gt; to perform a numeric sort on the specified column (second column in this case).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;-r&lt;/code&gt;: This flag reverses the sorting order, so it sorts in descending order instead of the default ascending order.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Running this pipeline produces output sorted by disk space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/log 9.8 GB
/home/user 5.7 GB
/usr/local/bin 2.4 GB
/tmp 1.2 GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice work, friend!&lt;/p&gt;

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

&lt;p&gt;In this tutorial, you have learned how to create sophisticated pipelines using &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, and other commands.  Now you are ready to start experimenting and creating your own pipelines and solving day-to-day system administration problems.&lt;/p&gt;

&lt;p&gt;I hope this tutorial helped.  Thanks for reading!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>programming</category>
      <category>bash</category>
    </item>
    <item>
      <title>How to Create a Lightweight Dotfiles Repository</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 22 May 2025 22:54:14 +0000</pubDate>
      <link>https://dev.to/boonecabal/how-to-create-a-lightweight-dotfiles-repository-28dh</link>
      <guid>https://dev.to/boonecabal/how-to-create-a-lightweight-dotfiles-repository-28dh</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Configuring your customizations can be tedious and repetitive. This tutorial will show you how to consolidate all your customizations in a dotfiles GitHub repository. Along the way, you will learn some handy Linux and Vim techniques. &lt;/p&gt;

&lt;p&gt;The goal is to create a minimalist, well-structured, boilerplate repository that you can augment as you see fit. Most of the tutorial entails building the repository one file at a time with commentary describing key points. When you're done, you will have created a generic repository with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good generic &lt;code&gt;.bashrc&lt;/code&gt; settings&lt;/li&gt;
&lt;li&gt;Small but powerful set of bash functions and aliases for navigation &lt;/li&gt;
&lt;li&gt;Good generic settings for Vim&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This is a fairly advanced tutorial. You should consider yourself an intermediate-level user of Linux and Vim.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be comfortable working in a Linux terminal. Start with the article &lt;a href="https://www.digitalocean.com/community/tutorials/a-linux-command-line-primer" rel="noopener noreferrer"&gt;A Linux Command Line Primer&lt;/a&gt;. It wouldn't hurt to check out the article &lt;a href="https://www.digitalocean.com/community/tutorials/linux-commands" rel="noopener noreferrer"&gt;Top 50+ Linux Commands You MUST Know&lt;/a&gt; either.&lt;/li&gt;
&lt;li&gt;Have a decent understanding of the Vim text editor. Check out the article &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-vim-for-advanced-editing-of-plain-text-or-code-on-a-vps-2" rel="noopener noreferrer"&gt;How To Use Vim for Advanced Editing of Plain Text or Code on a VPS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The article &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-git-to-manage-your-user-configuration-files-on-a-linux-vps" rel="noopener noreferrer"&gt;How To Use Git to Manage your User Configuration Files on a Linux VPS&lt;/a&gt; by Justin Ellingwood presents another solution to this problem using GitLab. I recommend reading it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dotfiles
&lt;/h2&gt;

&lt;p&gt;I conferred with my AI assistant, Google Gemini, about how to create a GitHub repository for my customizations. It recommended using a "dotfiles" repository. A dotfile refers to any hidden configuration file beginning with a &lt;code&gt;.&lt;/code&gt; character, like &lt;code&gt;.bashrc&lt;/code&gt;. This led me to research dotfiles, and I learned that this is a known issue with many solutions. The dotfiles solution you will create in this tutorial is the result of that research.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dotfiles Directory Structure
&lt;/h2&gt;

&lt;p&gt;It is essential to have a logically organized directory structure for your repository. For this tutorial, you will use the following directory structure, which divides the configuration files between bash and vim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotfiles
  shell
    .vars
    .prompt
    .aliases
    .functions

  .vim
    plugin
    set.vim
    maps.vim
    autoload.vim

  backups

  .bashrc
  .vimrc

  install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.bashrc&lt;/code&gt; is a configuration file for bash that can grow large and convoluted over time. We are going to solve this problem using a divide-and-conquer strategy by breaking &lt;code&gt;.bashrc&lt;/code&gt; into the smaller modules (files) &lt;code&gt;.vars&lt;/code&gt;, &lt;code&gt;.prompt&lt;/code&gt;, &lt;code&gt;.aliases&lt;/code&gt;, and &lt;code&gt;.functions&lt;/code&gt;; &lt;code&gt;.bashrc&lt;/code&gt; then loads each of these modules. We will use the same approach with &lt;code&gt;.vimrc&lt;/code&gt;, the primary configuration file for the text editor Vim, breaking it into the modules &lt;code&gt;set.vim&lt;/code&gt;, &lt;code&gt;maps.vim&lt;/code&gt;, and &lt;code&gt;autoload.vim&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Your setup might require you to use different configuration files like &lt;code&gt;.bash_profile&lt;/code&gt;. Make whatever changes you need to this repository.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Test Everything
&lt;/h2&gt;

&lt;p&gt;As you create each file, test it. Confirm it is doing exactly what you expect it to do, and do not proceed any further in the tutorial until you have. Making too many changes without testing them can be tedious. Be patient and take it one step at a time, friend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete Code Listings
&lt;/h2&gt;

&lt;p&gt;Including the full code listings for each file simplifies copying and pasting code as you proceed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One -- Creating the Files and Directories
&lt;/h2&gt;

&lt;p&gt;Let's start building your dotfiles repository. Log in to your GitHub account and create a new Codespace. Once VS Code finishes loading, open a terminal and use the following command to create all of your dotfiles directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .vim/plugin shell backups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the following command to create the files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .bashrc .vimrc install.sh shell/.&lt;span class="o"&gt;{&lt;/span&gt;functions,vars,aliases,prompt&lt;span class="o"&gt;}&lt;/span&gt; .vim/&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;,maps,autoload&lt;span class="o"&gt;}&lt;/span&gt;.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's pretty cool to create all these files in one command. The shell uses brace expansions to create every possible combination of the expressions in the braces. &lt;/p&gt;

&lt;p&gt;Confirm that all the directories and files have been created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two -- Creating &lt;code&gt;install.sh&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let's create an installation script that creates symbolic links from your dotfiles in your &lt;code&gt;dotfiles/&lt;/code&gt; directory to your home directory. Open the script using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code to your &lt;code&gt;install.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CS_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;DATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.bashrc &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bashrc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/backups/.bashrc.bak.&lt;/span&gt;&lt;span class="nv"&gt;$DATE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;mv&lt;/span&gt; –-no-clobber ~/.bashrc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.bashrc"&lt;/span&gt; 2&amp;gt;/dev/null
  &lt;span class="nb"&gt;rm&lt;/span&gt; ~/.bashrc
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.bashrc"&lt;/span&gt; ~/.bashrc

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.vimrc &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.vimrc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/backups/.vimrc.bak.&lt;/span&gt;&lt;span class="nv"&gt;$DATE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;mv&lt;/span&gt; –-no-clobber ~/.vimrc &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.vimrc"&lt;/span&gt; 2&amp;gt;/dev/null
  &lt;span class="nb"&gt;rm&lt;/span&gt; ~/.vimrc
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.vimrc"&lt;/span&gt; ~/.vimrc

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/shell 2&amp;gt;/dev/null
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/shell"&lt;/span&gt; ~/shell

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/.vim 2&amp;gt;/dev/null
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CS_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.vim"&lt;/span&gt; ~/.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script adds symbolic links to your home directory pointing to your dotfiles directory. Much of this code suppresses error messages.  The &lt;code&gt;--no-clobber&lt;/code&gt; option for &lt;code&gt;mv&lt;/code&gt; prevents it from overwriting, and &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; suppresses error messages by redirecting them to the trash can of &lt;code&gt;/dev/null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Every time you run &lt;code&gt;install.sh&lt;/code&gt;, it creates backups of &lt;code&gt;.bashrc&lt;/code&gt; and &lt;code&gt;.vimrc&lt;/code&gt; in the &lt;code&gt;backups/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Before you run this script, you need to give it execute permissions using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a moment to confirm that all your directories and files exist.&lt;/p&gt;

&lt;p&gt;Now would be a good time to add your project to source control.  Add all your changes, commit them with a meaningful message, and then push.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three -- Creating &lt;code&gt;.bashrc&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Change to the dotfiles directory and edit your &lt;code&gt;.bashrc&lt;/code&gt; file using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code to &lt;code&gt;.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Loop through files starting with a dot in the current directory&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;find &lt;span class="nt"&gt;-L&lt;/span&gt; ~/shell &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;".*"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

  &lt;span class="c"&gt;# Source the file using the dot (.) operator&lt;/span&gt;
  &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Sourced file: &lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This streamlined script loads every dotfile it finds in your &lt;code&gt;dotfiles/&lt;/code&gt; directory tree. Now, you can add more dotfiles without changing your &lt;code&gt;.bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the next steps, you will create each of the other &lt;code&gt;.bashrc&lt;/code&gt; modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before Continuing
&lt;/h3&gt;

&lt;p&gt;It's a good idea to use the following command every time you modify one of your &lt;code&gt;shell/&lt;/code&gt; dotfiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how you can activate your changes and test them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Four -- Creating &lt;code&gt;.functions&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Define all of your custom bash functions in &lt;code&gt;.functions&lt;/code&gt;. Open it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim shell/.functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have included some functions I have found useful. Add these to your &lt;code&gt;.functions&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-alF&lt;/span&gt; &lt;span class="nt"&gt;--color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;auto &lt;span class="nt"&gt;--color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | less &lt;span class="nt"&gt;-rEF&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

cl&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null

    &lt;span class="c"&gt;# check if cd was successful&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Error: Could not change directory to '&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;'.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;0
    &lt;span class="k"&gt;fi
  fi

  &lt;/span&gt;clear
  &lt;span class="nb"&gt;dir&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

hgrep&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;history&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

setenv&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Usage: setenv VAR VALUE&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;1
  &lt;span class="k"&gt;fi

  &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;2&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;dir&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;dir&lt;/code&gt; function generates a colored listing and pipes the output to &lt;code&gt;less&lt;/code&gt;, allowing you to scroll through a long listing.  To preserve the color in &lt;code&gt;less&lt;/code&gt;, use the &lt;code&gt;--color=always&lt;/code&gt; option for &lt;code&gt;ls&lt;/code&gt; and the &lt;code&gt;-r&lt;/code&gt; option for &lt;code&gt;less&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;cl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;cl&lt;/code&gt; combines &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;clear&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, and &lt;code&gt;less&lt;/code&gt;.  It changes to the argument directory--if one is provided--clears the screen, and then produces a detailed, colored listing.  Additionally, if the listing is larger than the viewport, the &lt;code&gt;less&lt;/code&gt; command takes over, allowing you to navigate the listing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;setenv&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;setenv&lt;/code&gt; is a quick way to create an environment variable.  Here is how you would use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;setenv X &lt;span class="s1"&gt;'thine dork lord'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;hgrep&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;hgrep&lt;/code&gt; function allows you to search your command history using &lt;code&gt;grep&lt;/code&gt;. Here is an example of using the it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hgrep &lt;span class="s1"&gt;'ls'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is some possible output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;85  cd dotfiles/
86  ll
87  cd ..
88  rm -r dotfiles/
89  ll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can execute the command &lt;code&gt;rm -r&lt;/code&gt; dotfiles/ using &lt;code&gt;!88&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;hgrep&lt;/code&gt; function makes use of &lt;code&gt;$@&lt;/code&gt;, which when evaluated in double quotes, represents all of the arguments passed in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I strongly recommend acquainting yourself with bash's command history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Five -- Creating &lt;code&gt;.vars&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;You will include your environment variables and miscellaneous settings in &lt;code&gt;.vars&lt;/code&gt;. Open it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim shell/.vars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include whichever settings you find amusing.  Here are some boilerplate settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# make less not clear screen at end&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LESS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-X"&lt;/span&gt;

&lt;span class="c"&gt;# restrict write permissions for others&lt;/span&gt;
&lt;span class="nb"&gt;umask &lt;/span&gt;0002

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LS_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'--color=auto'&lt;/span&gt;
&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dircolors&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;HISTCONTROL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ignoreboth
&lt;span class="nv"&gt;HISTSIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;999
&lt;span class="nv"&gt;HISTFILESIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1999

&lt;span class="c"&gt;# append to the history file, don't overwrite it&lt;/span&gt;
&lt;span class="nb"&gt;shopt&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; histappend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s look at the first three settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;export LESS="-X"&lt;/code&gt; alters the behavior of the &lt;code&gt;less&lt;/code&gt; command by preventing it from clearing the terminal once you reach the end of its output. Recall that we use &lt;code&gt;less&lt;/code&gt; in our &lt;code&gt;dir&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;export LS_OPTIONS='--color=auto'&lt;/code&gt; and &lt;code&gt;eval "$(dircolors -b)"&lt;/code&gt; change the color of the output of the &lt;code&gt;ls&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unmask 0002&lt;/code&gt; is a security setting that gives the owner (you) full permissions and restricts write permissions for others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The other settings affect your command history. By default bash adds your executed commands to a file called &lt;code&gt;.bash_history&lt;/code&gt;. Here are some settings affecting your command history:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HISTCONTROL=ignoreboth&lt;/code&gt; combines two other settings: &lt;code&gt;ignorespace&lt;/code&gt;, which ignores leading whitespace on commands, and &lt;code&gt;ignoredups&lt;/code&gt;, which prevents duplicate commands from being added to command history.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shopt -s histappend&lt;/code&gt; makes bash write all your current session's commands to &lt;code&gt;.bash_history&lt;/code&gt;, making them available in future sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step Six -- Creating &lt;code&gt;.prompt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;.prompt&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim shell/.prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;.prompt&lt;/code&gt; file produces a nice, colored prompt that also shows the current git branch if there is one. I like how it defines a variable for each color.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Define colors&lt;/span&gt;
&lt;span class="nv"&gt;RED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;31m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;32m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;BLUE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;34m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;PURPLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;35m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;CYAN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;36m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;YELLOW&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;33m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\0&lt;/span&gt;&lt;span class="s2"&gt;33[0m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Function to get the current Git branch&lt;/span&gt;
parse_git_branch&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    git branch 2&amp;gt; /dev/null | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'/^[^*]/d'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'s/* \(.*\)/ \(\1\)/'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Function to set the colored prompt&lt;/span&gt;
set_prompt&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Get the current Git branch&lt;/span&gt;
    &lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;parse_git_branch&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Set the prompt&lt;/span&gt;
    &lt;span class="nv"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GREEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BLUE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\h&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;YELLOW&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\w&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;PURPLE&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Call the set_prompt function whenever a new prompt is needed&lt;/span&gt;
&lt;span class="nv"&gt;PROMPT_COMMAND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;set_prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Credit goes to the Claude 3 A.I. for generating this prompt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This prompt appears as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(green)  username
(blue)   hostname
(orange) current-directory
(purple) git-branch

 username:hostname
 : current-directory (git-branch) $ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step Seven -- Creating &lt;code&gt;.aliases&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Your aliases go here. Open &lt;code&gt;.aliases&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim shell/.aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are some aliases I use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;sup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo apt-get update &amp;amp;&amp;amp; sudo apt-get upgrade -y'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;". ~/.bashrc"&lt;/span&gt;

&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cd ~-"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;l&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'cl'&lt;/span&gt;
&lt;span class="nb"&gt;alias&lt;/span&gt; ..&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'l ..'&lt;/span&gt;
&lt;span class="nb"&gt;alias&lt;/span&gt; ...&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'l ../..'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A couple of interesting things here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;alias b="cd ~-"&lt;/code&gt; uses the &lt;code&gt;~-&lt;/code&gt; expression, which represents the previous directory. This is a very nice back function.&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;l&lt;/code&gt;, &lt;code&gt;..&lt;/code&gt;, and &lt;code&gt;...&lt;/code&gt; aliases invoke our previously defined &lt;code&gt;cl&lt;/code&gt; function in &lt;code&gt;.functions&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step Eight -- Creating the Vim Files
&lt;/h2&gt;

&lt;p&gt;In this section, we will create &lt;code&gt;.vimrc&lt;/code&gt; and all its constituent files.&lt;/p&gt;

&lt;h3&gt;
  
  
  .vimrc
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;.vimrc&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .vimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following to your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Global&lt;/span&gt;
&lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;
&lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;maps&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;
&lt;span class="k"&gt;source&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/.vim/&lt;/span&gt;autoload&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;vim&lt;/span&gt;

&lt;span class="c"&gt;" Plugins&lt;/span&gt;

&lt;span class="c"&gt;" My plugins&lt;/span&gt;
&lt;span class="c"&gt;" This is a plugin I wrote&lt;/span&gt;
&lt;span class="c"&gt;"source ~/.vim/plugin/run_command.vim&lt;/span&gt;

&lt;span class="c"&gt;" Other&lt;/span&gt;
&lt;span class="c"&gt;" I use the following third-party plugin&lt;/span&gt;
&lt;span class="c"&gt;"source ~/.vim/plugin/auto-pairs.vim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commented-out lines show how to include your custom plugins and third-party plugins.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I strongly recommend browsing vim.org for plugins, which has a large database of plugins that do all sorts of great things for you: intellisense-like completion menus, a file explorer, custom color schemes, syntax files, and more. The tutorial &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-vundle-to-manage-vim-plugins-on-a-linux-vps" rel="noopener noreferrer"&gt;How To Use Vundle to Manage Vim Plugins on a Linux VPS&lt;/a&gt; by Justin Ellingwood teaches you how to use the Vundle vim plugin manager to install plugins.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  .vim/autoload.vi
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;autoload.vim&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .vim/autoload.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very bare bones file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Basic indentation for comments (optional)&lt;/span&gt;
autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; html xml &lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;commentstring&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;autoload &lt;span class="nb"&gt;FileType&lt;/span&gt; css &lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;commentstring&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="sr"&gt;/* %s */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  .vim/maps.vim
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;maps.vim&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .vim/maps.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maps are specific to each user. These happen to be useful to me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Miscellaneous&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;O mpO&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;`&lt;span class="k"&gt;p&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;o&lt;/span&gt; mpo&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;`&lt;span class="k"&gt;p&lt;/span&gt;

&lt;span class="c"&gt;" Moving around&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
inoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;A

&lt;span class="c"&gt;" Buffers and windows&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;wu &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;wincmd&lt;/span&gt; &lt;span class="k"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;wd&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;wincmd&lt;/span&gt; &lt;span class="k"&gt;j&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

nnoremap Bd &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;bd&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;" Saving Files&lt;/span&gt;
&lt;span class="c"&gt;"&lt;/span&gt;
nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;so&lt;/span&gt; %&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

nnoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;s &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;
inoremap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;leader&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;s &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;esc&lt;span class="p"&gt;&amp;gt;:&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;cr&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  .vim/set.vim
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;set.vim&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim .vim/set.vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a good collection of Vim settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="nb"&gt;syntax&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;number&lt;/span&gt;

&lt;span class="c"&gt;" Disable swap files&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;noswapfile&lt;/span&gt;

&lt;span class="c"&gt;" Enable spell checking&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;spelllang&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;en_us
autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; text&lt;span class="p"&gt;,&lt;/span&gt; markdown &lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;spell&lt;/span&gt;

&lt;span class="c"&gt;" Enable wildmenu&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;wildmenu&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;wildmode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;longest&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;list&lt;/span&gt;

&lt;span class="c"&gt;" Display cursor position&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;ruler&lt;/span&gt;

&lt;span class="c"&gt;" Highlight current line&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;cursorline&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;expandtab&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;tabstop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;shiftwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;

&lt;span class="c"&gt;"set relativenumber&lt;/span&gt;
&lt;span class="c"&gt;"set foldmethod=indent&lt;/span&gt;
&lt;span class="c"&gt;"set foldnestmax=3&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;splitbelow&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;splitright&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;

&lt;span class="k"&gt;colorscheme&lt;/span&gt; delek
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;background&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;dark&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;wrap&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;linebreak&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;showmatch&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;incsearch&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;nohlsearch&lt;/span&gt;

&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;autoindent&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;smartindent&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; mapleader&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;';'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are some key takeaways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;expandtab&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;tabstop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;shiftwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These settings make Vim use tabs--two spaces in size--whenever possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;"set relativenumber&lt;/span&gt;
&lt;span class="c"&gt;"set foldmethod=indent&lt;/span&gt;
&lt;span class="c"&gt;"set foldnestmax=3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I commented this out because I haven't been writing too much code lately. If you write a lot of code, I recommend trying these settings out. They enable folding for indented blocks of code and show line numbers relative to the cursor position.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Disable swap files&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;noswapfile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those vim &lt;code&gt;.swp&lt;/code&gt; swap files are ignored. This shuts them off.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you use the mouse. I didn't know this one existed until I talked to Claude 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;splitbelow&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;splitright&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, &lt;code&gt;:sp&lt;/code&gt; splits above and &lt;code&gt;:vs&lt;/code&gt; splits right. These settings change the directions to below and left, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="c"&gt;" Highlight current line&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;cursorline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an interesting setting. It shows a horizontal line below the cursor, making it easier to see where you are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Nine -- Updating Your Repository
&lt;/h2&gt;

&lt;p&gt;Congratulations on making it this far. You have successfully built your dotfiles project. The last step is to update your remote repository. &lt;/p&gt;

&lt;p&gt;You're done! Your dotfiles repository is ready to use!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Your Dotfiles Repository
&lt;/h2&gt;

&lt;p&gt;Let's consume our dotfiles repository.  Create a new Codespace and launch a terminal once VS Code finishes loading. Next, change to your home directory and clone the dotfiles repository using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repo in the home directory&lt;/span&gt;
&lt;span class="nb"&gt;cd
&lt;/span&gt;git clone https://github.com/username/dotfiles.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Replace &lt;code&gt;username&lt;/code&gt; above with your GitHub username.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Change to the dotfiles directory and run the installation script using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;dotfiles

&lt;span class="c"&gt;# Run the installation script&lt;/span&gt;
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./install.sh
./install.sh

&lt;span class="c"&gt;# Reload the terminal&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;!$&lt;/code&gt; represents the last argument passed to the last command.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now all your customizations are in place. Don't forget to test everything.&lt;/p&gt;

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

&lt;p&gt;Congratulations on making it through this tutorial! Now, when you create a new Codespace, you have all of your customizations set up and you're ready to start working. Thanks for reading. Now leave, please.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>linux</category>
      <category>devops</category>
      <category>vim</category>
    </item>
    <item>
      <title>Creating Beautiful User Interfaces With Material Design for Bootstrap 4 &amp; 5 (MDB)</title>
      <dc:creator>Boone Cabal</dc:creator>
      <pubDate>Thu, 22 May 2025 22:51:02 +0000</pubDate>
      <link>https://dev.to/boonecabal/creating-beautiful-user-interfaces-with-material-design-for-bootstrap-4-5-mdb-1lch</link>
      <guid>https://dev.to/boonecabal/creating-beautiful-user-interfaces-with-material-design-for-bootstrap-4-5-mdb-1lch</guid>
      <description>&lt;p&gt;Combining multiple front-end technologies can be challenging due to limited documentation. We’ll solve such a problem by creating a small web application that combines Svelte–a small but powerful front-end technology akin to React and Vue–with the elegant Material Design for Bootstrap 4 &amp;amp; 5 (MDB) framework. It will feature a navigation bar with an embedded dropdown menu that facilitates switching between three different content panes, each populated with stylish MDB components, resulting in an aesthetically appealing and responsive User Interface (UI).&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This article is for the intermediate-to-advanced level web developer who’s conversant in CSS and Bootstrap 5. If you’re not well-versed in either, don’t worry, as this article provides links to useful documentation.&lt;/p&gt;

&lt;p&gt;We're going to build our Svelte application using the &lt;a href="https://svelte.dev/repl/hello-world?version=4.2.18" rel="noopener noreferrer"&gt;Svelte REPL sandbox&lt;/a&gt; (or just REPL) at &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;svelte.dev&lt;/a&gt;. I recommend checking out all the great documentation at svelte.dev, like its &lt;a href="https://svelte.dev/examples/hello-world" rel="noopener noreferrer"&gt;Examples section&lt;/a&gt; showcasing Svelte's many features, as well as the cool interactive tutorial at &lt;a href="https://learn.svelte.dev" rel="noopener noreferrer"&gt;learn.svelte.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here are resources to consider looking at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Bootstrap 5

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://getbootstrap.com/docs/5.3/getting-started/introduction/" rel="noopener noreferrer"&gt;Getting Started with Bootstrap&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  MDB

&lt;ul&gt;
&lt;li&gt;  MDBootstrap 5 &lt;a href="https://mdbootstrap.com/docs/standard/getting-started/installation/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  Svelte

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://learn.svelte.dev/tutorial/welcome-to-svelte" rel="noopener noreferrer"&gt;LEARN.SVELTE.DEV&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started" rel="noopener noreferrer"&gt;Getting started with Svelte (MDN Web docs)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  (Bonus) &lt;a href="https://sveltestrap.js.org/?path=/docs/sveltestrap-overview--docs" rel="noopener noreferrer"&gt;Bootstrap 5 Components for Svelte 4+&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step One – Creating a Svelte/MDB Boilerplate in REPL
&lt;/h2&gt;

&lt;p&gt;When you navigate to the Svelte REPL sandbox and click the REPL link, it takes you to a Hello World application with the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;App.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's link Bootstrap 5, FontAwesome, a Google font, and MDB stylesheets using a special &lt;code&gt;&amp;lt;svelte:head&amp;gt;&lt;/code&gt; element and the Popper and MDB JavaScripts. Replace this markup with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

  &lt;span class="c1"&gt;// Component initialization code goes here.&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svelte:head&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Bootstrap CSS --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
    &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"&lt;/span&gt;
    &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
    &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"&lt;/span&gt;
    &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Font Awesome --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
    &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"&lt;/span&gt;
    &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Google Fonts --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
    &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&amp;amp;display=swap"&lt;/span&gt;
    &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- MDB --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
    &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/7.3.2/mdb.min.css"&lt;/span&gt;
    &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/svelte:head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- navbar --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- header --&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container py-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane content --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!--  Bootstrap Bundle with Popper --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"&lt;/span&gt;
    &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"&lt;/span&gt;
    &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- MDB --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/7.3.2/mdb.umd.min.js"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;/* Scripts */&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;When you paste code blocks from this article into REPL, it won’t be formatted with the proper whitespace, so you might want to fold the pasted code block, select it, and then tab it in. I hope they consider adding a “format HTML” button.&lt;/p&gt;

&lt;p&gt;It’s important to understand that the above-linked files might be obsolete when you read this. I recommend replacing the above &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; elements with the markup from the &lt;a href="https://mdbootstrap.com/docs/standard/getting-started/installation/#section-cdn" rel="noopener noreferrer"&gt;MDB installation page&lt;/a&gt;. It provides detailed instructions about how to do this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s wise to save this REPL with a meaningful name like Svelte Boilerplate, fork it, and then rename the forked copy to the name of this project. This is akin to creating a commit.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/2e5e0772dde04577aa01bf0f03e0038a?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two – Adding Navigation Bar and Cards
&lt;/h2&gt;

&lt;p&gt;Now we'll flesh out our application by adding an &lt;a href="https://mdbootstrap.com/docs/standard/navigation/navbar/" rel="noopener noreferrer"&gt;MDB navbar&lt;/a&gt;, and an &lt;a href="https://mdbootstrap.com/docs/standard/components/accordion/#section-with-icons" rel="noopener noreferrer"&gt;accordion&lt;/a&gt; as our content for pane 1–the default pane. We'll start with the navigation bar (navbar).&lt;/p&gt;

&lt;h3&gt;
  
  
  MDB Navigation Bar
&lt;/h3&gt;

&lt;p&gt;Our navbar will have a left-aligned brand logo and a right-aligned dropdown menu. Clicking a menu item switches between panes, and the active pane will be displayed in the dropdown's display text.&lt;/p&gt;

&lt;p&gt;We'll build our navbar over several steps, starting with a static navbar containing dummy menu items. Let's start by replacing our &lt;code&gt;&amp;lt;!-- navbar --&amp;gt;&lt;/code&gt; block with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- navbar --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar navbar-expand-lg navbar-light bg-body-tertiary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container-fluid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-brand"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"navbar_Click"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Branding&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item dropdown pe-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
        &lt;span class="na"&gt;data-mdb-dropdown-init&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link dropdown-toggle"&lt;/span&gt;
        &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;
        &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
        &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Selected Pane&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- nav-link (dropdown button) --&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-menu"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt;
            &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Pane 1"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pane 1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt;
            &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Pane 2"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pane 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt;
            &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Pane 3"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pane 3&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- dropdown-menu --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- container-fluid --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- navbar --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MDB Accordion
&lt;/h3&gt;

&lt;p&gt;Let’s add an MDB accordion as filler content to pane 1. Replace the &lt;code&gt;&amp;lt;!-- pane content --&amp;gt;&lt;/code&gt; block with the following code, copied from the MDB accordion documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"accordionExampleY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-header"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"headingOneY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-mdb-collapse-init&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-button"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;data-mdb-toggle=&lt;/span&gt;&lt;span class="s"&gt;"collapse"&lt;/span&gt;
        &lt;span class="na"&gt;data-mdb-target=&lt;/span&gt;&lt;span class="s"&gt;"#collapseOneY"&lt;/span&gt; &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"collapseOneY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-question-circle fa-sm me-2 opacity-70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;Accordion Item #1
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-header --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"collapseOneY"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-collapse collapse show"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"headingOneY"&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-parent=&lt;/span&gt;&lt;span class="s"&gt;"#accordionExampleY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;This is the first item's accordion body.&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; It is hidden by
        default, until the collapse plugin adds the appropriate classes we use to
        style each element. These classes control the overall appearance and
        the visibility via CSS transitions. You can modify any of this with
        custom CSS or overriding our default variables. It's also worth noting that
        nearly any HTML can go within the &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;.accordion-body&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;, though the
        transition does limit overflow.
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-collapse --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- accordion-item --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-header"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"headingTwoY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-mdb-collapse-init&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-button collapsed"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;data-mdb-toggle=&lt;/span&gt;&lt;span class="s"&gt;"collapse"&lt;/span&gt;
        &lt;span class="na"&gt;data-mdb-target=&lt;/span&gt;&lt;span class="s"&gt;"#collapseTwoY"&lt;/span&gt; &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"collapseTwoY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-question-circle fa-sm me-2 opacity-70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;Accordion Item #2
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-header --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"collapseTwoY"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-collapse collapse"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"headingTwoY"&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-parent=&lt;/span&gt;&lt;span class="s"&gt;"#accordionExampleY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;This is the second item's accordion body.&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; It is hidden by
        default, until the collapse plugin adds the appropriate classes we use to
        style each element. These classes control the overall appearance and
        the visibility via CSS transitions. You can modify any of this with
        custom CSS or overriding our default variables. It's also worth noting that
        nearly any HTML can go within the &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;.accordion-body&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;, though the
        transition does limit overflow.
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-collapse --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- accordion-item --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-header"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"headingThreeY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-mdb-collapse-init&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-button collapsed"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;data-mdb-toggle=&lt;/span&gt;&lt;span class="s"&gt;"collapse"&lt;/span&gt;
        &lt;span class="na"&gt;data-mdb-target=&lt;/span&gt;&lt;span class="s"&gt;"#collapseThreeY"&lt;/span&gt; &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"collapseThreeY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-question-circle fa-sm me-2 opacity-70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;Accordion Item #3
      &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-heading --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"collapseThreeY"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-collapse collapse"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"headingThreeY"&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-parent=&lt;/span&gt;&lt;span class="s"&gt;"#accordionExampleY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"accordion-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;This is the third item's accordion body.&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; It is hidden by
        default, until the collapse plugin adds the appropriate classes we use to
        style each element. These classes control the overall appearance and
        the visibility via CSS transitions. You can modify any of this with
        custom CSS or overriding our default variables. It's also worth noting that
        nearly any HTML can go within the &lt;span class="nt"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;.accordion-body&lt;span class="nt"&gt;&amp;lt;/code&amp;gt;&lt;/span&gt;, though the
        transition does limit overflow.
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- accordion-collapse --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- accordion-item --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- accordion --&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/e4b853c0894645a08e001efc32a9c649?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three – Populating Navbar Dropdown Menu
&lt;/h2&gt;

&lt;p&gt;Now, we'll use some Svelte template code to dynamically populate the navbar’s dropdown menu and synchronize its display text with the name of the active pane.&lt;/p&gt;

&lt;p&gt;First, let's create a &lt;code&gt;ButtonTypes&lt;/code&gt; enumerated type, which represents the currently active pane, and a &lt;code&gt;mode&lt;/code&gt; variable of type &lt;code&gt;ButtonTypes&lt;/code&gt;. Replace your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I use the term “makeshift” because a true enumerated type is only available in TypeScript. Unfortunately, svelte.dev doesn't support TypeScript as of this writing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, let’s dynamically create our dropdown menu items and set the menu's display text to the name of the active pane. Replace the &lt;code&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/code&gt; comment block with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item dropdown pe-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-dropdown-init&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link dropdown-toggle"&lt;/span&gt;
      &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;
      &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
      &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- nav-link (dropdown button) --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-menu"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#each&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
            &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; 
            &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt; 
            &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
            &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/each&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- dropdown-menu --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;ButtonTypes&lt;/code&gt; is an object and not a true enumerated type, we iterate over its properties, assigning each menu item's display text.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/f64f4fab47a64ac88cb5e0ccc0cf7698?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Four – Switching Between Panes
&lt;/h2&gt;

&lt;p&gt;Now we're going to augment our dropdown menu with functionality to switch between panes. For now we’ll create filler content for panes 2 and 3 with &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; elements. (We already have an accordion in pane 1.) Additionally, we’ll add an if statement to our &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element that uses our &lt;code&gt;mode&lt;/code&gt; enum to decide which pane to display.&lt;/p&gt;

&lt;p&gt;First, let’s create a click event-handler function named &lt;code&gt;navbar_Click&lt;/code&gt; and attach it to each menu item. &lt;code&gt;navbar_Click&lt;/code&gt; changes the active pane by assigning a new value to &lt;code&gt;mode&lt;/code&gt;. Replace your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navbar_Click&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`e.target.value = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s attach &lt;code&gt;navbar_Click&lt;/code&gt; to each dropdown menu item &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; as it is created. Replace your &lt;code&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/code&gt; block with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item dropdown pe-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-dropdown-init&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link dropdown-toggle"&lt;/span&gt;
      &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;
      &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
      &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- nav-link (dropdown button) --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-menu"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#each&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; 
          &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;navbar_Click&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; 
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt; 
          &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
          &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/each&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- dropdown-menu --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- nav-item --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let’s add an if statement to &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; that uses &lt;code&gt;mode&lt;/code&gt; to determine which pane to display. Update your &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element with the following if statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container py-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- accordion ... --&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Panel 2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Panel 3&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/if&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 

&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You’ll want to replace the above &lt;code&gt;&amp;lt;!-- accordion ... --&amp;gt;&lt;/code&gt; block with either the accordion markup you used earlier in this article, or, preferably, that found in the MDB accordion documentation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Test the UI and make sure the dropdown menu properly switches between panes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/fa69118f99d6455787cbfde095f42854?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Five – Disabling the Active Panel’s Menu Item
&lt;/h2&gt;

&lt;p&gt;Sometimes it’s useful to disable or hide elements in a UI to prevent invalid actions or give the user hints about how the user interface works. We’ll disable the dropdown menu item representing the active pane, thus helping the user understand which pane is active.&lt;/p&gt;

&lt;p&gt;First, let’s add a &lt;code&gt;disableMenuItem&lt;/code&gt; boolean variable to our &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;. Replace your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;disableMenuItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navbar_Click&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`e.target.value = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's add a &lt;code&gt;disabled&lt;/code&gt; attribute to the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; menu item, assigning it to &lt;code&gt;disableMenuItem&lt;/code&gt;. Replace the &lt;code&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/code&gt; block with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item dropdown pe-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
      &lt;span class="na"&gt;data-mdb-dropdown-init&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link dropdown-toggle"&lt;/span&gt;
      &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;
      &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
      &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- nav-link (dropdown button) --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-menu"&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"navbarDropdownMenuLink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#each&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dropdown-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; 
          &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;navbar_Click&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;disabled=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disableMenuItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; 
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-link"&lt;/span&gt; 
          &lt;span class="na"&gt;data-mdb-ripple-init&lt;/span&gt;
          &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;buttonTypeKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- dropdown-item --&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/each&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- dropdown-menu --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- nav-item dropdown --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Dropdown Menu --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/3b40b889486a4f1d9c8905d0b830064a?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Six – Fleshing Out Panels With MDB Components
&lt;/h2&gt;

&lt;p&gt;Now we'll flesh out our UI by adding MDB components, taken directly from the MDB website documentation–to panes 2 and 3. Let's add a &lt;a href="https://mdbootstrap.com/docs/standard/components/cards/#subsection-grid-cards" rel="noopener noreferrer"&gt;card gallery&lt;/a&gt; to pane 2 and &lt;a href="https://mdbootstrap.com/docs/standard/components/badges/#section-icon-inside" rel="noopener noreferrer"&gt;feature badges&lt;/a&gt; to pane 3. (We’ve already added an MDB accordion to pane 1, so we only need content for panes 2 and 3.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Panel 2 – MDB Cards
&lt;/h3&gt;

&lt;p&gt;Replace your &lt;code&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/code&gt; block with the following card gallery markup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ve added whitespace and comments to the following code.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row row-cols-1 row-cols-md-3 g-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://mdbcdn.b-cdn.net/img/new/standard/city/041.webp"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-img-top"&lt;/span&gt; 
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Hollywood Sign on The Hill"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;h5&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Card title&lt;span class="nt"&gt;&amp;lt;/h5&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          This is a longer card with supporting text below as a natural lead-in to
          additional content. This content is a little bit longer.
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- card-body --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- card --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://mdbcdn.b-cdn.net/img/new/standard/city/042.webp"&lt;/span&gt; 
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-img-top"&lt;/span&gt; 
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Palm Springs Road"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;h5&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Card title&lt;span class="nt"&gt;&amp;lt;/h5&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          This is a longer card with supporting text below as a natural lead-in to
          additional content. This content is a little bit longer.
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- card-body --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- card --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://mdbcdn.b-cdn.net/img/new/standard/city/043.webp"&lt;/span&gt; 
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-img-top"&lt;/span&gt; 
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Los Angeles Skyscrapers"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;h5&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Card title&lt;span class="nt"&gt;&amp;lt;/h5&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This is a longer card with supporting text below as a natural lead-in to additional content.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- card-body --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- card --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://mdbcdn.b-cdn.net/img/new/standard/city/044.webp"&lt;/span&gt; 
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-img-top"&lt;/span&gt; 
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Skyscrapers"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;h5&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Card title&lt;span class="nt"&gt;&amp;lt;/h5&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          This is a longer card with supporting text below as a natural lead-in to
          additional content. This content is a little bit longer.
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- card --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- row --&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Panel 3 – MDB Feature Badges
&lt;/h3&gt;

&lt;p&gt;Replace your &lt;code&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/code&gt; block with the following feature badges markup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row gx-lg-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-6 mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex align-items-start"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-3 badge-primary rounded-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-cloud-upload-alt fa-lg text-primary fa-fw"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-grow-1 ms-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fw-bold mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Tutorials&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            Dozens of free tutorials to help you discover the full potential of MDB.
          &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"google.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-6 mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex align-items-start"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-3 badge-primary rounded-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-database fa-lg text-primary fa-fw"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-grow-1 ms-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fw-bold mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Integrations&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            MDB is integrated with all major technologies and tools.
          &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"google.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-6 mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex align-items-start"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-3 badge-primary rounded-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-stream fa-lg text-primary fa-fw"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-grow-1 ms-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fw-bold mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Backend friendly&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            MDB is designed to be seamlessly integrated and used with the backend.
          &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"google.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-6 mb-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex align-items-start"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-shrink-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-3 badge-primary rounded-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-copy fa-lg text-primary fa-fw"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-grow-1 ms-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fw-bold mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Support and community&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted mb-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            The MDB team and our global community are there to support you.
          &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"google.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- col --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- row--&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another great benefit of MDB is the relative ease with which you can create responsive web pages. Try horizontally resizing the sandbox Result window and notice how the components resize and reposition as breakpoints are crossed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/c6a90dbdc2a74182b52e416a00e2c95b?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning Up Our Code
&lt;/h2&gt;

&lt;p&gt;Now that we’ve finished creating a winsome UI, we’ll clean up and refactor our code. First, we’ll divide our code into multiple files by using &lt;code&gt;&amp;lt;svelte:component&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One – Using &lt;a&gt;svelte:component&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Svelte offers a very useful &lt;code&gt;&amp;lt;svelte:component&amp;gt;&lt;/code&gt; element that lets us pass a component to display using the &lt;code&gt;this&lt;/code&gt; directive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Check out this &lt;a href="https://svelte.dev/examples/svelte-component" rel="noopener noreferrer"&gt;great example of using&lt;/a&gt; svelte:component and &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility#working_with_dom_nodes_using_the_bindthisdom_node_directive" rel="noopener noreferrer"&gt;Working with DOM nodes using the bind:this={dom_node} directive&lt;/a&gt; for more about &lt;code&gt;&amp;lt;svelte:component&amp;gt;&lt;/code&gt; and the &lt;code&gt;this&lt;/code&gt; directive, respectively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, let’s create three new components representing each of our panes, Move your &lt;code&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/code&gt; code block into a new &lt;code&gt;Panel1.svelte&lt;/code&gt;, &lt;code&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/code&gt; into &lt;code&gt;Panel2.svelte&lt;/code&gt;, and &lt;code&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/code&gt; into &lt;code&gt;Panel3.svelte&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, let’s import the new panel components into &lt;code&gt;App.svelte&lt;/code&gt;. Replace your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block with the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;App.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel1&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel1.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel2&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel2.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel3.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;PANEL_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navbar_Click&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`e.target.value = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let’s update &lt;code&gt;App.svelte&lt;/code&gt; to use &lt;code&gt;&amp;lt;svelte:component&amp;gt;&lt;/code&gt; elements to display our new pane components. Replace your &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; with the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;App.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container py-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/if&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/03d6afac95fb4d6d9958f39bcfdba314?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two – Creating Store For &lt;code&gt;mode&lt;/code&gt; Variable
&lt;/h2&gt;

&lt;p&gt;Sometimes it’s more convenient to use some application-wide state (a global) instead of propagating it from a parent component to a child. Stores are the Svelte equivalent of readable and writable global variables. To use a store, simply import &lt;code&gt;writable&lt;/code&gt; from &lt;code&gt;svelte/store&lt;/code&gt;, and then create a store variable using &lt;code&gt;writable&lt;/code&gt;. Furthermore, you must prefix a store variable with &lt;code&gt;$&lt;/code&gt; when using it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is all you need to know about stores for this article. The MDB article &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores" rel="noopener noreferrer"&gt;Working with Svelte stores&lt;/a&gt; provides a thorough explanation of stores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need to move some code around. First, let’s create a &lt;code&gt;stores.js&lt;/code&gt; file that contains &lt;code&gt;ButtonTypes&lt;/code&gt;, imports &lt;code&gt;writable&lt;/code&gt;, and redefines &lt;code&gt;mode&lt;/code&gt; as a writable store. Create &lt;code&gt;stores.js&lt;/code&gt; and add the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;stores.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;import &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writable&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt; from 'svelte/store';

export let ButtonTypes = &lt;span class="si"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PANEL_2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nx"&gt;PANEL_3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Panel 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
&lt;span class="si"&gt;}&lt;/span&gt;;

export const mode = writable(ButtonTypes.PANEL_1);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s update our &lt;code&gt;App.svelte&lt;/code&gt; by importing &lt;code&gt;mode&lt;/code&gt; and &lt;code&gt;ButtonTypes&lt;/code&gt; from &lt;code&gt;stores.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;App.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./stores.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel1&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel1.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel2&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel2.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel3.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;disableMenuItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navbar_Click&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`e.target.value = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in a syntax error. To fix it, type &lt;code&gt;CTRL+f&lt;/code&gt;, and then search-and-replace all instances of &lt;code&gt;mode&lt;/code&gt; with &lt;code&gt;$mode&lt;/code&gt;. However, you &lt;em&gt;do not&lt;/em&gt; want to apply this change to the &lt;code&gt;mode&lt;/code&gt; in the import statement.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/1c2c8189027343dfacb6bbecb85c41e7?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three – Creating a Layout Component
&lt;/h2&gt;

&lt;p&gt;Now we'll learn how to create generic templates using the &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;h3&gt;
  
  
  An Example of Using &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Unlike template processors like Python Flask, Svelte doesn't use template inheritance; instead, it uses composition. Therefore, we don’t inherit from a parent template; instead, any component needing some shared layout will contain a reference to a layout component.&lt;/p&gt;

&lt;p&gt;We'll digress and walk through an example using &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt;. First, let's create a BaseLayout component with some shared structure. It will use &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; (or &lt;code&gt;&amp;lt;slot /&amp;gt;&lt;/code&gt;) elements as placeholders wherein a Page component will inject code.&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;BaseLayout.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"layout"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- footer content ... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This BaseLayout component defines a header, content area, and footer, and an exported &lt;code&gt;title&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now let’s create a Page component that contains BaseLayout component instance and injects code into it.&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;Page.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BaseLayout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./BaseLayout.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home Page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;BaseLayout&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is the home page content.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/BaseLayout&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even the most casual observer will notice how we bind Page's &lt;code&gt;title&lt;/code&gt; variable to Layout's &lt;code&gt;title&lt;/code&gt; property using the &lt;code&gt;{title}&lt;/code&gt; directive, illustrating passing state from a parent (Page) component to a child (BaseLayout).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find a thorough explanation of passing state between parent and child components in the article &lt;a href="https://react.dev/learn/sharing-state-between-components" rel="noopener noreferrer"&gt;Sharing State Between Components&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; in Our Application
&lt;/h3&gt;

&lt;p&gt;Let's use &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt; in our application. First, create a new &lt;code&gt;Layout.svelte&lt;/code&gt; file and move all the code from &lt;code&gt;App.svelte&lt;/code&gt; into it. Replace the &lt;code&gt;&amp;lt;!-- main --&amp;gt;&lt;/code&gt; block with the following code.&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;Layout.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container py-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- main --&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, replace the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element with the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;Layout.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./stores.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Variables &lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;disableMenuItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// DOM event-handlers&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navbar_Click&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`e.target.value = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="nx"&gt;$mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! You refactored a base layout into its own component.&lt;/p&gt;

&lt;p&gt;Finally, let’s update &lt;code&gt;App.svelte&lt;/code&gt;. Import Layout, and use it as an element to inject an if statement into its inner HTML. Replace all your &lt;code&gt;App.svelte&lt;/code&gt; code with the following code:&lt;/p&gt;

&lt;p&gt;(In &lt;code&gt;App.svelte&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./stores.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel1&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel1.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel2&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel2.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Panel3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Panel3.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Layout.svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;Layout&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#if&lt;/span&gt; &lt;span class="nx"&gt;$mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- pane 1 --&amp;gt;&lt;/span&gt;


  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;$mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- pane 2 --&amp;gt;&lt;/span&gt;


  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;:else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;$mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;ButtonTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PANEL_3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svelte:component&lt;/span&gt; &lt;span class="na"&gt;this=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Panel3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- pane 3 --&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/if&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/Layout&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Check out &lt;a href="https://svelte.dev/examples/slot-fallbacks" rel="noopener noreferrer"&gt;slot fallbacks&lt;/a&gt; and &lt;a href="https://svelte.dev/examples/named-slots" rel="noopener noreferrer"&gt;named slots&lt;/a&gt; for great examples of using &lt;code&gt;&amp;lt;slot&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://svelte.dev/repl/e2a156fb62a84b6ca2714d1a82cd5b49?version=4.2.18" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is the REPL for this step.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nested components let you compose more complex components, making it easier to understand and maintain your codebase.&lt;/p&gt;

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

&lt;p&gt;We covered a lot in this article. Now you have the tools to create dainty, pleasurable UIs with MDB and compose nested components. Have fun using Svelte, friend. Now leave, please.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>svelte</category>
    </item>
  </channel>
</rss>
