DEV Community

Cover image for Neovim changed my perspective
Jonny
Jonny

Posted on

Neovim changed my perspective

How deep down do I want to explore? A thought I ponder, neck-deep in a project trying to use Web Components instead of React.

Is it worth it? I think while attempting to create a game engine with the Canvas API and vanilla JavaScript. (I quickly ditched that idea and started using Phaser)

Should I build my own hot reload? I wonder while exploring the WebSocket API because I decided to potentially not use Vite.

But you get the point - a common dilemma I encounter is how far back I want to learn about a certain topic. But the thing is - all these "rabbit hole" experiences I've encountered have proven to be, time and time again, some of the most valuable experiences I face. I have never regretted my time exploring these technologies, even if I didn't end up using them. Having a deeper understanding of the tools I use every day allows me to make better implementation decisions in my job, for my personal projects, and even when brainstorming my next project.

Let's rewind...

"...neck-deep in a project trying to use Web Components instead of React..."

I ended up choosing to stick with Web Components. Although I could have built my idea much more quickly using a framework like React, a little bit of research is what sold it for me. It was as simple as figuring out how I could make my own version of React's state variable within a Web Component. That sparked my interest in how this magic behind closed doors with React occurs. This is obviously just the tip of the iceberg, and I want to learn more.

For those interested - and as you probably could have guessed:

// React state variable
import React, { useState } from 'react';

function Counter() {
  // Initialize the state variable 'count' with a default value of 0
  const [count, setCount] = useState(0);

  // Function to increment the count
  const incrementCount = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>You clicked the button {count} times.</p>
      <button onClick={incrementCount}>Click me</button>
    </div>
  );
}

export default Counter;

Enter fullscreen mode Exit fullscreen mode
// WebComponent
class CounterComponent extends HTMLElement {
  constructor() {
    super(); // Always call super() first in the constructor.
    this.count = 0; // Initialize the state.

    // Create a shadow root to encapsulate styles and markup.
    this.shadow = this.attachShadow({ mode: 'open' });

    // Initial render of the component.
    this.render();
  }

  // Method to increment the count.
  incrementCount() {
    this.count++;
    this.render(); // Re-render the component with the new count.
  }

  // Method to render the component.
  render() {
    this.shadow.innerHTML = `
      <style>
        /* Styles specific to this component */
        div {
          padding: 10px;
          background-color: #f0f0f0;
          border-radius: 5px;
          display: inline-block;
        }
        button {
          margin-top: 10px;
        }
      </style>
      <div>
        <p>You clicked the button ${this.count} times.</p>
        <button>Click me</button>
      </div>
    `;

    // Attach the click event listener to the button.
    this.shadow.querySelector('button').onclick = () => this.incrementCount();
  }
}

// Define the new element.
customElements.define('counter-component', CounterComponent);
Enter fullscreen mode Exit fullscreen mode

This leads me to discover the Shadow DOM. My first thought was, is it like the Virtual DOM? To answer that question... sort of, but not really... I will quickly highlight some of their similarities before going over what makes them different.

How are they similar?

  • they both aim to optimize DOM interactions giving a smoother user experience
  • the both perform DOM manipulation for dynamic content updates

How are they different?

  • Shadow DOM is native to the browser, while the Virtual DOM is a concept in JavaScript frameworks like React
  • Virtual DOM uses a diffing algorithm to update the DOM efficiently
  • Shadow DOM's main goal is encapsulation and isolation within the DOM

These are just a few examples of gathering a deeper understanding of the tools we use everyday from a tiny bit of research.

A common consensus throughout the dev community is that a lot of us newbies (including myself) are learning things backwards. Yes, I went through a Computer Science degree and learned the fundamentals and theory; however, it felt like that wasn't enough to prepare me for the shields of frameworks and libraries I would be using and what they are actually doing behind the scenes.

I view some of these frameworks as "shields" as I find I often get too comfortable using these tools without understanding what is going on under the hood...

But wait, how does any of this tie into Neovim?

All these thoughts I've shared, I would have them on occasion - but ever since I switched to Linux and Neovim, my curiosity has been through the roof. Switching over to Neovim and Linux was a not so fun weekend of configuration and spending half a day getting my work's local dev environment running on my new OS (which no one has tested development on). But I now have a deeper understanding of the tools I use, and have a text editor configured to be the most optimal for the way I want to use it.

Yeah, thinking back logically, I would have done it differently. But diving headfirst like that has truly sparked drive, curiosity, confidence, and confirmation that I have in fact chosen the right field. I feel grateful to be in it. If you're on the verge of deciding to try Vim? I say absolutely go for it, just be cautious you may lose some efficiency at the start. But in my experience, it does not take long at all to surpass that of moving with the mouse. If you're on the verge of trying Neovim? Do it. These things aren't as easy to set up as VSCode or Sublime - but they are what resparked my passion for development.

Understanding one of the tools I use everyday (my text editor) has led to a chain reaction of curiosity into almost every tool I use for development, and that excites me.

Let me know what your experiences are with Neovim/Vim motions if you have tried them out after using mouse and keyboard for a long time.

Shout out (not that he needs it) to the Primeagen. All those "Vim btw" jokes wore me down to the point of where I decided to try it.

He has a great video found here that goes through setting up an environment from scratch for Neovim.

Ps. If feel free to share additional information, I am all ears and open to correction :)

Top comments (11)

Collapse
 
hendrikras profile image
Hendrik Ras

Haven't tried neoVim. But will give it a try. For me the power of vim is recording macro's. Whenever I have to do a repetitive edit like converting csv to json. I switch to vim. But the lack of plugins keep me from using it as my day to day editor. Perhaps neoVim will change that.

Collapse
 
jdtoombs profile image
Jonny

Neovim has a great plugin ecosystem!

Collapse
 
pengeszikra profile image
Peter Vivo

Hi which Neovim variant are you using. I also started to work with Neovim: LazyVim, which is quite enoug good build. I can select on my workplace to choose VDI enviroment: linux or windows. My favorite was MacOS so I jump to the linux. I get some experience the vim, and now I use nvim is second editor. Already I work much faster with VS Code. But nvim / vim is close to terminal and fare better for cross repo using.

Collapse
 
jdtoombs profile image
Jonny

Hey! I'm using a custom config with Packer as my plugin manager. I have heard good things about LazyVim!

I also like how nvim is part of the terminal, makes it very quick and easy for navigating through directories and editing files. Not having to open an additional external application is nice :)

Collapse
 
marco_43 profile image
Marco

Hey Jonny, I like your article. I was discovering Vim and Neovim not long ago, too. It was a very thriving experience, but I switched back to VS Code / Jetbrains with Vim Movement activated (but today, I also switched back to "classic" editor behavior with mouse and keyboard). For me I have learned, that using the mouse not always cost time, but give me some space to do small thinking-tasks, like "hmm... where will i put my component? *click *click, maybe here? *click..." But I understand the point for speed when you do bare coding stuff.

I have a question on your web component journey: I have a similar project to, where I would use web components as "plugins". The biggest pain point is the interface between parent and child components. Not simple attributes like strings or numbers, but complex objects, which I will pass down to the child web component. (or functions for callbacks for example). The only way I discovered so far are CustomEvents, but it feels a bit monkey patched.. Do you have any ideas about that?

Collapse
 
jdtoombs profile image
Jonny • Edited

Hey Marco, sounds like you've got a good balance of what works for you :)

You may have already tried this but I directly set the properties on instances of my child component.

For example:

// Parent Component
const child = document.querySelector('child');

child.yourProperty = { key: 'value' };
Enter fullscreen mode Exit fullscreen mode

And of course we would need the getters, and setters for yourProperty

class Child extends HTMLElement {
  constructor() {
    super();
    this._yourProperty = {};
  }

  get yourProperty() {
    return this._yourProperty;
  }

  set yourProperty(val) {
    this._yourProperty = val;
    // must trigger re-render to reflect this change
    this.onPropertyChanged();
  }

  onPropertyChange() {
    this.render();
  }

  render() {
    this.textContent = `${JSON.stringify(this._yourProperty)}`
  }
}
customElements.define('child', Child);
Enter fullscreen mode Exit fullscreen mode

Hopefully this is of some help!

Collapse
 
marco_43 profile image
Marco

hmm, I thought I had tried that, but I will give this way another shot. Thanks for the example :-)

Collapse
 
efpage profile image
Eckehard • Edited

Regarding your experience with ShadowDom you might find that the whole system of HTML/CSS/JS has some conceptual issues. One of them is the lack of local definitions, that apply only to a specific context. ShadowDom is kind of a workaround, but not a real solution. Svelte solves this better allowing CSS rules to be local to the module, but we hope in the future we will see more flexible scoping in CSS.

HTML in JS solutions are not very popular these days, but one advantage is the fine grained scoping you get with JS. Your button example could be much more compact using a HTML in JS approach (look here or here for more information):

let out, count = 0
let txt = () => `You clicked the button ${count} times.`

begin(div("", "padding: 10px; background-color: #f0f0f0; border-radius: 5px; display: inline-block;"+_box))
{
  out = p(txt());
  button("Click me", "margin-top: 10px;").onclick = () => {
    count++
    out.textContent = txt()
  }
}
end()
Enter fullscreen mode Exit fullscreen mode

A running example is here

It will depend much on your task which approach serves best, but it is not necessary the one that "everybody" uses!

Collapse
 
jdtoombs profile image
Jonny

Thanks for this, haven't seen this before! Going to try it out :)

Collapse
 
zeddnyx profile image
Zeddnyx

I use nvim since first learn programming lol, and here my custom config for webdev especially nextjs, ts etc Znvim

Collapse
 
jdtoombs profile image
Jonny

Ooo I will take a look :) - thanks for sharing!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.