<?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: Dragoș Străinu</title>
    <description>The latest articles on DEV Community by Dragoș Străinu (@strdr4605).</description>
    <link>https://dev.to/strdr4605</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F161616%2F7b63f9f2-cf3f-48d9-96a7-1b34f12f97d2.jpeg</url>
      <title>DEV Community: Dragoș Străinu</title>
      <link>https://dev.to/strdr4605</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/strdr4605"/>
    <language>en</language>
    <item>
      <title>I don't use git anymore</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:48:52 +0000</pubDate>
      <link>https://dev.to/strdr4605/i-dont-use-git-anymore-1846</link>
      <guid>https://dev.to/strdr4605/i-dont-use-git-anymore-1846</guid>
      <description>&lt;p&gt;You probably opened this article with the thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This guy outsourced all his work to coding agents and is not managing git by himself🤔😅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this is a partial truth; although coding agents do manipulate git by themselves, I still check the git state, commits, branches (so it's not fully outsourced).&lt;/p&gt;

&lt;p&gt;But this is a story about replacing git with a better alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I started using git
&lt;/h2&gt;

&lt;p&gt;I found out about git in the hard way.&lt;/p&gt;

&lt;p&gt;While in the middle of a 4-week hackathon trying to develop &lt;a href="https://strdr4605.com/fracfik/" rel="noopener noreferrer"&gt;Fracfik&lt;/a&gt; in collaboration with my teammates, not knowing about git, and sharing code changes on Messenger by sending files and archives of the project and handling code merging and conflicts manually😭.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff5w2yi1rvt5lxq3zcgye.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff5w2yi1rvt5lxq3zcgye.png" alt="fracfik-version-2" width="644" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was a nightmare to work that way and I thought to myself&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There should be a better way of doing this kind of collaboration over a coding project🤔&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the end of the hackathon a mentor saw how we work, and asked us, "Why don't you use git for the project?" It was too late for that project, but that day I went home and started digging into git and GitHub.&lt;/p&gt;

&lt;p&gt;That day I had the "aha moment", and from then on I used git and GitHub for all my hackathons, university, and personal projects.&lt;/p&gt;

&lt;p&gt;Going back I think version control systems and git should be among the first things that a software engineer needs to learn and understand. This is why I teach students git and GitHub at the beginning of all my courses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The git expert
&lt;/h2&gt;

&lt;p&gt;Over the course of years I got more advanced at using git and went above "git add, commit, push, pull" commands. &lt;em&gt;I know engineers who are stuck at this level even after years in the career&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I became the go-to person when some of my friends or teammates would have to handle some complicated git operations.&lt;/p&gt;

&lt;p&gt;A friend of mine would call me every other week and ask me to help him fix a git problem. &lt;em&gt;Nowadays he doesn't reach out to me anymore as his coding agents solve any git-related problems&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As you can see from &lt;a href="https://strdr4605.com/tags/git" rel="noopener noreferrer"&gt;other articles of mine&lt;/a&gt;, I consider myself a proficient git user who can manipulate commits and branches with ease.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgi6mkqf5h1bi0flzm22r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgi6mkqf5h1bi0flzm22r.gif" alt="iron-man-hologram" width="498" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I &lt;code&gt;rebase&lt;/code&gt; and &lt;code&gt;push --force&lt;/code&gt; multiple times per day&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;I kind of &lt;a href="https://strdr4605.com/no-tits-in-git" rel="noopener noreferrer"&gt;hate &lt;code&gt;git merge&lt;/code&gt;&lt;/a&gt;😅, and promote &lt;a href="https://trunkbaseddevelopment.com/" rel="noopener noreferrer"&gt;Trunk based development&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://strdr4605.com/you-need-to-use-git-worktree" rel="noopener noreferrer"&gt;git worktrees&lt;/a&gt; before it became mainstream, and coding agents picked up on it too.&lt;/p&gt;

&lt;p&gt;I added &lt;a href="https://strdr4605.com/stop-doing-git-checkout-master-branch" rel="noopener noreferrer"&gt;custom aliases&lt;/a&gt; to simplify my workflow.&lt;/p&gt;

&lt;p&gt;And now my &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/.gitconfig" rel="noopener noreferrer"&gt;.gitconfig&lt;/a&gt; has a lot of settings that match my needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with git
&lt;/h2&gt;

&lt;p&gt;I encountered a bottleneck in git when trying to explore the &lt;a href="https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/" rel="noopener noreferrer"&gt;Stacked diffs&lt;/a&gt; concept and trying to do a &lt;a href="https://docs.github.com/en/pull-requests/how-tos/stacked-pull-requests" rel="noopener noreferrer"&gt;Stacked Pull Requests workflow&lt;/a&gt; (even before it was a feature in GitHub).&lt;/p&gt;

&lt;p&gt;I tried several tools (&lt;a href="https://github.com/ezyang/ghstack" rel="noopener noreferrer"&gt;ghstack&lt;/a&gt;, &lt;a href="https://github.com/spacedentist/spr" rel="noopener noreferrer"&gt;spr&lt;/a&gt;) and eventually created my own scripts: &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/bin/gh-pr-create-stacked" rel="noopener noreferrer"&gt;gh-pr-create-stacked&lt;/a&gt;, &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/bin/git-push-stacked" rel="noopener noreferrer"&gt;git-push-stacked&lt;/a&gt;. But in the chase to create a perfect git flow and commit history, it was a nightmare to edit, rebase, fix stacked PRs, and maintain a simple workflow. &lt;em&gt;Even after discovering &lt;code&gt;git commit --fixup&lt;/code&gt; and &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/.gitconfig#L22-L25" rel="noopener noreferrer"&gt;nice git settings&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the solution
&lt;/h2&gt;

&lt;p&gt;In autumn of 2025 I found out about &lt;a href="https://gitbutler.com/" rel="noopener noreferrer"&gt;GitButler&lt;/a&gt;, a tool to simplify the work with git, but at that time it was presented as a Desktop app&lt;sup id="fnref2"&gt;2&lt;/sup&gt; and, being a terminal guy, I skipped it but was still interested and watching tutorials on their YouTube channel.&lt;/p&gt;

&lt;p&gt;One day I saw &lt;a href="https://www.youtube.com/watch?v=dwyMlLYIrPk" rel="noopener noreferrer"&gt;Jujutsu | Ep. 5 Bits and Booze&lt;/a&gt; and was very intrigued by this &lt;a href="https://www.jj-vcs.dev/latest/" rel="noopener noreferrer"&gt;jj-vcs&lt;/a&gt; alternative to git; one that can use git as backend and allows you to collaborate with teammates that are still using git.&lt;/p&gt;

&lt;p&gt;I installed the &lt;code&gt;jj&lt;/code&gt; CLI and ran &lt;code&gt;jj git init&lt;/code&gt; to colocate it in the same repo with a work project.&lt;/p&gt;

&lt;p&gt;And OMG😱, I felt like one of my students when I teach them &lt;code&gt;git rebase -i&lt;/code&gt;. All these commands were new to me, I was afraid to run most of them&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;I added the Neovim integration for Jujutsu and even &lt;a href="https://github.com/NicolasGB/jj.nvim/pull/2" rel="noopener noreferrer"&gt;contributed to it&lt;/a&gt; but while doing this I encountered a conflict that was hard to understand (in jj workflow) so I decided I'd had enough jj for that day and went back to git.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final switch
&lt;/h2&gt;

&lt;p&gt;This year, while building a new project, I decided to challenge myself and not use git&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. And created &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/jj-git-nudge.zsh#L75-L147" rel="noopener noreferrer"&gt;&lt;code&gt;jjask&lt;/code&gt;&lt;/a&gt; headless coding agents helpers to guide me:&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;command &lt;/span&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--model&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JJ_SUGGEST_MODEL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output-format&lt;/span&gt; text &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--append-system-prompt&lt;/span&gt; &lt;span class="s1"&gt;'You are a Jujutsu (jj) expert helping a user accomplish a task in jj. Reply with concrete jj command(s) in a fenced code block, then brief reasoning. Keep it under ~12 lines, no preamble, no closing remarks. Target jj 0.43+ and use CURRENT commands only: prefer `jj new`/`jj edit` (never the deprecated `jj checkout`), `jj bookmark` (not `jj branch`), `jj git fetch`/`jj git push`, `jj describe`/`jj squash`; remote branches are bookmarks like `master@origin`. Do NOT call any tools; answer only from the provided context.'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"I want to: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;question&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Here is my current jj state:

&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ctx&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

What should I do?"&lt;/span&gt; &amp;lt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To match my current setup (with git worktrees) I created &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/bin/jj-clone-jjmain-for-workspaces" rel="noopener noreferrer"&gt;helper scripts&lt;/a&gt; that allow me to create jj workspaces.&lt;/p&gt;

&lt;p&gt;I am still new to &lt;code&gt;jj&lt;/code&gt; and have a lot to learn&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is the part that excites me🤩, a new tool that I have the joy of exploring and becoming good at.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are some &lt;code&gt;jj&lt;/code&gt; features that I really like:&lt;/p&gt;

&lt;h3&gt;
  
  
  No staging area
&lt;/h3&gt;

&lt;p&gt;Unlike &lt;code&gt;git&lt;/code&gt;, in &lt;code&gt;jj&lt;/code&gt; every change is automatically committed into a change and if I need these changes to be in separate commits I can run &lt;code&gt;jj split&lt;/code&gt; with a very nice TUI:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwukdtdiutry8sbztppvb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwukdtdiutry8sbztppvb.png" alt="jj-split" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactor without manual rebasing
&lt;/h3&gt;

&lt;p&gt;When I need to change a previous commit, I don't do &lt;code&gt;git commit --fixup&lt;/code&gt; or &lt;code&gt;git rebase -i&lt;/code&gt;, I just run &lt;code&gt;jj edit -r &amp;lt;change-id&amp;gt;&lt;/code&gt;, do my fixes and then I &lt;code&gt;jj edit -r &amp;lt;top-change-id&amp;gt;&lt;/code&gt; and jj automatically rebases all changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  No need for branches
&lt;/h3&gt;

&lt;p&gt;I consider that branches come and go (created and removed), only commits matter, then why are they almost always required for a normal git flow? With Jujutsu you create branches (bookmarks) at the end of developing when you want to share changes on GitHub. (No more need for temp/test branches).&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling conflicts
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;jj&lt;/code&gt; conflicts are first-class citizens, it records the conflict as a normal conflicted state in commit history instead of forcing you to stop and resolve immediately. You can keep working with conflicted changes and resolve conflicts later whenever you’re ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;jj absorb&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In a stacked PRs scenario you can fix suggestions from multiple PRs in one big change and running &lt;code&gt;jj absorb&lt;/code&gt; will move independent changes to their related descendant PRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;It's still a long way until I may consider myself good at using jj as I am now with git. And in today's era, where coding agents do most of the manipulation with git and jj, it's hard to learn a proper usage (as it's easy to reach out to agents for help). Who knows, maybe one day I will discover that GitButler is better than jj and I will write another article titled &lt;strong&gt;&lt;code&gt;"I don't use jj anymore"&lt;/code&gt;&lt;/strong&gt; or even &lt;strong&gt;&lt;code&gt;"I am going back to git"&lt;/code&gt;&lt;/strong&gt; 😱🤔.&lt;/p&gt;

&lt;p&gt;If you are interested in trying jj or GitButler I strongly suggest giving it a try, but before that, it's worth becoming comfortable with git's lower-level tools, so in rare cases when your company's agents subscription is cancelled/unpaid or APIs time out, you could rebase/bisect/cherry-pick without needing a coding agent.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Who says that &lt;code&gt;--force&lt;/code&gt; is dangerous and forbidden, does not know git.  &amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Nowadays GitButler has a CLI, so who knows, maybe one day I will switch to &lt;code&gt;but&lt;/code&gt;&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Especially because I was in the middle of a WIP feature that I did not want to lose 😅&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;I even mapped the &lt;code&gt;git&lt;/code&gt; command to a &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/jj-git-nudge.zsh#L32-L71" rel="noopener noreferrer"&gt;helper function&lt;/a&gt; that no longer allowed me to run &lt;code&gt;git&lt;/code&gt;😄, but it had a recursion bug that ended up spawning multiple headless claude instances so I had to abandon this idea.&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>git</category>
      <category>jj</category>
    </item>
    <item>
      <title>Dynamic Tmux Window Naming with Claude Code</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:48:49 +0000</pubDate>
      <link>https://dev.to/strdr4605/dynamic-tmux-window-naming-with-claude-code-cd4</link>
      <guid>https://dev.to/strdr4605/dynamic-tmux-window-naming-with-claude-code-cd4</guid>
      <description>&lt;p&gt;When working with Claude Code in tmux, I wanted a way to automatically update my window names based on what I'm currently working on. Instead of manually renaming windows or having generic names, I set up Claude Code to dynamically update the window name as I switch between tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;The goal was to have Claude Code automatically rename the tmux window with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;claude-&lt;/code&gt; prefix to identify Claude Code sessions&lt;/li&gt;
&lt;li&gt;2-3 dash-separated words describing the current task&lt;/li&gt;
&lt;li&gt;Updates only when the topic changes significantly (new task, after &lt;code&gt;/clear&lt;/code&gt;, progress milestones)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;claude-code&lt;/code&gt; - default/idle state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-fix-auth&lt;/code&gt; - fixing authentication issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-explore-api&lt;/code&gt; - exploring API code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;claude-blog-post&lt;/code&gt; - writing blog posts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Custom Instructions
&lt;/h2&gt;

&lt;p&gt;First, I created a custom instructions file that Claude Code reads on startup:&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; ~/.claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;~/.claude/instructions.md&lt;/code&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;# Tmux Window Management&lt;/span&gt;

When running inside a tmux session, automatically manage the window name:
&lt;span class="p"&gt;
-&lt;/span&gt; Always use "claude-" prefix followed by 2-3 words separated by dashes
&lt;span class="p"&gt;-&lt;/span&gt; Update the window name ONLY when the topic changes significantly:
&lt;span class="p"&gt;  -&lt;/span&gt; After &lt;span class="sb"&gt;`/clear`&lt;/span&gt; command is used
&lt;span class="p"&gt;  -&lt;/span&gt; When starting a new task or issue
&lt;span class="p"&gt;  -&lt;/span&gt; When making significant progress on a task
&lt;span class="p"&gt;  -&lt;/span&gt; When switching between different work contexts
&lt;span class="p"&gt;-&lt;/span&gt; Use the command: &lt;span class="sb"&gt;`tmux rename-window "name-here"`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Do it silently without announcing the rename to the user
&lt;span class="p"&gt;-&lt;/span&gt; Keep names concise and descriptive of the current work

Initial name: "claude-code"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Auto-Approve Tmux Commands
&lt;/h2&gt;

&lt;p&gt;Claude Code has a permission system that prompts for approval before running bash commands. To make the window renaming seamless, I needed to auto-approve &lt;code&gt;tmux rename-window&lt;/code&gt; commands using a PreToolUse hook.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;~/.claude/approve-tmux.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Read the hook input from stdin
&lt;/span&gt;    &lt;span class="n"&gt;hook_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;# Check if this is a Bash tool use
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hook_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hook_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parameters&lt;/span&gt;&lt;span class="sh"&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Auto-approve tmux rename-window commands
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tmux rename-window&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hookSpecificOutput&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hookEventName&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PreToolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;permissionDecision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;allow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;permissionDecisionReason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tmux rename-window auto-approved&lt;/span&gt;&lt;span class="sh"&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="c1"&gt;# For all other commands, no decision (normal flow)
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it executable:&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 ~/.claude/approve-tmux.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Configure the Hook
&lt;/h2&gt;

&lt;p&gt;Update &lt;code&gt;~/.claude/settings.json&lt;/code&gt; to add the PreToolUse hook:&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;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://json.schemastore.org/claude-code-settings.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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;"PreToolUse"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.claude/approve-tmux.py"&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;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="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;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;Once configured, Claude Code will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the instructions on startup and understand its role in managing tmux window names&lt;/li&gt;
&lt;li&gt;Monitor task changes during the session&lt;/li&gt;
&lt;li&gt;When a significant topic change occurs, run &lt;code&gt;tmux rename-window&lt;/code&gt; with an appropriate name&lt;/li&gt;
&lt;li&gt;The PreToolUse hook intercepts the bash command and auto-approves it&lt;/li&gt;
&lt;li&gt;The window name updates seamlessly without any user prompts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;Now my tmux status bar always shows what Claude Code is currently helping me with. It's especially useful when running multiple tmux sessions - I can quickly identify which window has Claude Code and what it's working on.&lt;/p&gt;

&lt;p&gt;The window names update naturally as I work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start debugging → &lt;code&gt;claude-debug-api&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Switch to writing tests → &lt;code&gt;claude-write-tests&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Explore codebase → &lt;code&gt;claude-explore-auth&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Back to idle → &lt;code&gt;claude-code&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This small automation makes tmux window management effortless and gives me better context awareness across my terminal sessions.&lt;/p&gt;

</description>
      <category>tmux</category>
      <category>claude</category>
      <category>automation</category>
      <category>tools</category>
    </item>
    <item>
      <title>Clean Paste in Neovim: Paste Text Without Newlines and Leading Whitespace</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:48:13 +0000</pubDate>
      <link>https://dev.to/strdr4605/clean-paste-in-neovim-paste-text-without-newlines-and-leading-whitespace-dp9</link>
      <guid>https://dev.to/strdr4605/clean-paste-in-neovim-paste-text-without-newlines-and-leading-whitespace-dp9</guid>
      <description>&lt;p&gt;When I work on a web project, I find myself copy-pasting HTML tags or Components from one place to another.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 1: Copy html tag to another parent  --&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;"1"&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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 2: Copy component to another parent --&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;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Component&lt;/span&gt;
    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Copy me to div#2"&lt;/span&gt;
    &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;"Here is the description"&lt;/span&gt;
  &lt;span class="nt"&gt;/&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;id=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 3: component as prop --&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;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Component&lt;/span&gt;
    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Move me to Container header"&lt;/span&gt;
    &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;"Here is the description"&lt;/span&gt;
  &lt;span class="nt"&gt;/&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;Container&lt;/span&gt; &lt;span class="na"&gt;header=&lt;/span&gt;&lt;span class="s"&gt;{}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 4: Return component --&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;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Component&lt;/span&gt;
    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Move me to Container header"&lt;/span&gt;
    &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;"Here is the description"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

return ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the first use case, I can put the cursor inside&lt;br&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;div class="copy-paste"&amp;gt;&lt;/code&gt; and do &lt;code&gt;yat&lt;/code&gt; or &lt;code&gt;vaty&lt;/code&gt; (yank around tag) to copy the HTML tag, then move inside &lt;code&gt;&amp;lt;div id="2"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; and paste.&lt;/p&gt;

&lt;p&gt;But for the other use cases, this does not work because&lt;br&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;Component /&amp;gt;&lt;/code&gt; is self-closing and Neovim can't select with &lt;code&gt;t&lt;/code&gt; (tag).&lt;/p&gt;

&lt;p&gt;So most often I just use &lt;code&gt;SHIFT+V&lt;/code&gt; to enter in visual mode on the whole line, move N lines below, select the HTML tag or Component, then use &lt;code&gt;y&lt;/code&gt; to copy the selection.&lt;/p&gt;

&lt;p&gt;Now because of &lt;code&gt;SHIFT+V&lt;/code&gt;, the yanked text includes newlines and leading whitespace, and when I paste I get this result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 1: Copy html tag to another parent  --&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;"1"&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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I created a keymap to paste the text without newlines and leading whitespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Map yp to paste yanked line without newlines and without leading whitespace&lt;/span&gt;
&lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keymap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"n"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"yp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;-- Get content from register 0 (most recent yank)&lt;/span&gt;
  &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;yanked_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getreg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;-- Remove trailing newline if present&lt;/span&gt;
  &lt;span class="n"&gt;yanked_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yanked_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sr"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sr"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;-- Remove leading whitespace&lt;/span&gt;
  &lt;span class="n"&gt;yanked_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yanked_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;"^%s+"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sr"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;-- Store in register p&lt;/span&gt;
  &lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setreg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"p"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yanked_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;-- Paste from register p&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'"pp'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;expr&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change the keymap to &lt;code&gt;cp&lt;/code&gt; (clean paste) or &lt;code&gt;&amp;lt;leader&amp;gt;p&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The result when using this keymap is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 1: Copy html tag to another parent  --&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;"1"&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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And next, I just let my formatter do the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 1: Copy html tag to another parent  --&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;"1"&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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"2"&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;"copy-paste"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Copy me to div#2&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Here is another child element&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also works for other use cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 4: Return component --&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;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Component&lt;/span&gt;
    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Move me to Container header"&lt;/span&gt;
    &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;"Here is the description"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

return (&lt;span class="nt"&gt;&amp;lt;Component&lt;/span&gt;
    &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"copy-paste"&lt;/span&gt;
    &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Move me to Container header"&lt;/span&gt;
    &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;"Here is the description"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;);

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpk0nqv395r2yzvazsnsg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpk0nqv395r2yzvazsnsg.gif" alt="neovim-clean-paste" width="640" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vim</category>
    </item>
    <item>
      <title>How to set up Lexical editor in React Native</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:48:10 +0000</pubDate>
      <link>https://dev.to/strdr4605/how-to-set-up-lexical-editor-in-react-native-doo</link>
      <guid>https://dev.to/strdr4605/how-to-set-up-lexical-editor-in-react-native-doo</guid>
      <description>&lt;p&gt;So you have a web app that uses Lexical editor and now you want to build the same editor on React Native, or maybe you just want to build a rich text editor in React Native using Lexical.&lt;br&gt;
But unfortunately lexical does not &lt;a href="https://github.com/facebook/lexical/discussions/2410" rel="noopener noreferrer"&gt;support React Native&lt;/a&gt; at the moment.&lt;/p&gt;

&lt;p&gt;So the idea that comes to mind is to try Lexical editor in a react-native-webview. There are similar solutions like &lt;a href="https://github.com/imnapo/react-native-cn-quill" rel="noopener noreferrer"&gt;react-native-cn-quill&lt;/a&gt; and &lt;a href="https://github.com/wxik/react-native-rich-editor" rel="noopener noreferrer"&gt;react-native-rich-editor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But as &lt;a href="https://docs.expo.dev/guides/editing-richtext/#custom-webview-based-editor" rel="noopener noreferrer"&gt;expo docs&lt;/a&gt; say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you need more configurability, you can build a similar library with an existing web-only editor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So let's implement a lexical editor in an Expo app.&lt;br&gt;&lt;br&gt;
(This is a demo project but you can follow the steps to add the editor to an existing React Native app)&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the expo app
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-expo-app &lt;span class="nt"&gt;-t&lt;/span&gt; expo-template-blank-typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now let's install &lt;code&gt;react-native-webview&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;npm i react-native-webview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And make some changes in &lt;code&gt;App.tsx&lt;/code&gt;, to display the WebView with &lt;a href="https://playground.lexical.dev/" rel="noopener noreferrer"&gt;https://playground.lexical.dev/&lt;/a&gt; (for now).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./App.tsx&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;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&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="s2"&gt;react-native&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;WebView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;80%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Lexical Webview&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://playground.lexical.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;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;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#e0e0e0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should have this result:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o68hb6a00givi52wq3b.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o68hb6a00givi52wq3b.png" alt="expo-webview-init" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add lexical editor
&lt;/h2&gt;

&lt;p&gt;Other implementations for a rich text editor in react-native give us a predefined editor. However, we want to create our custom lexical editor with custom nodes and logic. So the only option is to create the editor from scratch.&lt;br&gt;&lt;br&gt;
How? By creating a new app inside the project using &lt;a href="https://docs.npmjs.com/cli/v7/using-npm/workspaces" rel="noopener noreferrer"&gt;npm workspaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We add a workspace to &lt;code&gt;package.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="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;"react-native-lexical"&lt;/span&gt;&lt;span class="err"&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.0"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/expo/AppEntry.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;!code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"lexical-editor"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;!code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;!code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"expo start --android"&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;blockquote&gt;
&lt;p&gt;We can name it how we want &lt;code&gt;post-editor&lt;/code&gt;, &lt;code&gt;page-editor&lt;/code&gt;. Also we can have multiple editors if needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Create web app as npm workspace
&lt;/h3&gt;

&lt;p&gt;For this, we will use &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;vite&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest lexical-editor &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt; react-ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's do a cleanup and some changes in lexical-editor app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lexical-editor
├── README.md
├── index.html
├── package.json
├── src
│&amp;nbsp;&amp;nbsp; ├── App.tsx
│&amp;nbsp;&amp;nbsp; ├── index.css
│&amp;nbsp;&amp;nbsp; ├── main.tsx
│&amp;nbsp;&amp;nbsp; └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important to not enable zoom in the WebView, add this to &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt;
  &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt;
  &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1, maximum-scale=0.99, user-scalable=0"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run the web app:&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;# in the root of expo app, we run script from lexical-editor workspace&lt;/span&gt;
npm &lt;span class="nt"&gt;--workspace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lexical-editor run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can see this in the browser:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fykcnpcjdd4ljmf9hg48r.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fykcnpcjdd4ljmf9hg48r.png" alt="lexical-vite-init" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, now how can we put this into &lt;code&gt;react-native-webview&lt;/code&gt;?!&lt;/p&gt;

&lt;h3&gt;
  
  
  Build a web app for react-native-webview
&lt;/h3&gt;

&lt;p&gt;For this, we need some vite plugins that will build the app into a single file that we will import into react-native-webview.&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="nt"&gt;-w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lexical-editor i &lt;span class="nt"&gt;-D&lt;/span&gt; vite-plugin-singlefile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and let's change the &lt;code&gt;vite.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .lexical-editor/vite.config.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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="s2"&gt;vite&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;viteSingleFile&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="s2"&gt;vite-plugin-singlefile&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;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://vitejs.dev/config/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;include&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="s2"&gt;src/**&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;buildDelay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;viteSingleFile&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite-plugin-html-string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nf"&gt;closeBundle&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;bundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&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;escaped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bundle&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;js&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`export default &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;escaped&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist/htmlString.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;js&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This config watches for changes and builds the app into a single &lt;code&gt;index.html&lt;/code&gt; file that we next write into a file named &lt;code&gt;htmlString.ts&lt;/code&gt; so we can import it into react-native.&lt;/p&gt;

&lt;p&gt;Now we can run:&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="nt"&gt;-w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lexical-editor run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And vite will build the web editor on every change.&lt;/p&gt;

&lt;p&gt;Also, we need to build the app on install:&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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc &amp;amp;&amp;amp; vite build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prepare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build -- --no-watch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;!code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only now we can import the output of the web app into react-native-webview:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&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="s2"&gt;react-native&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;WebView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&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;htmlString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./lexical-editor/dist/htmlString&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Lexical Webview&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;originWhitelist&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://playground.lexical.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code --]&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;View&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;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqstuahjxu94g84361ahw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqstuahjxu94g84361ahw.png" alt="lexical-vite-webview" width="800" height="1731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a basic lexical editor
&lt;/h2&gt;

&lt;p&gt;Following &lt;a href="https://lexical.dev/docs/getting-started/react" rel="noopener noreferrer"&gt;https://lexical.dev/docs/getting-started/react&lt;/a&gt;&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="nt"&gt;-w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lexical-editor &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; lexical @lexical/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can create a basic lexical editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lexical-editor/src/Editor.tsx&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;LexicalComposer&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="s2"&gt;@lexical/react/LexicalComposer&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PlainTextPlugin&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="s2"&gt;@lexical/react/LexicalPlainTextPlugin&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ContentEditable&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="s2"&gt;@lexical/react/LexicalContentEditable&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HistoryPlugin&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="s2"&gt;@lexical/react/LexicalHistoryPlugin&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;LexicalErrorBoundary&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@lexical/react/LexicalErrorBoundary&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Editor.css&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;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Editor&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;initialConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyEditor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;onError&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LexicalComposer&lt;/span&gt; &lt;span class="na"&gt;initialConfig&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;initialConfig&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editor-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PlainTextPlugin&lt;/span&gt;
          &lt;span class="na"&gt;contentEditable&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ContentEditable&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editor-input"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editor-placeholder"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Enter some text...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LexicalErrorBoundary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HistoryPlugin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LexicalComposer&lt;/span&gt;&lt;span class="p"&gt;&amp;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;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw0w2x4o8aqkm49afskls.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw0w2x4o8aqkm49afskls.gif" alt="basic-lexical-editor" width="560" height="1212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Message from WebView to React Native
&lt;/h2&gt;

&lt;p&gt;Let's add the &lt;code&gt;OnChangePlugin&lt;/code&gt; and post a message to react-native:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;$getRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EditorState&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="s2"&gt;lexical&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&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;LexicalComposer&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="s2"&gt;@lexical/react/LexicalComposer&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PlainTextPlugin&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="s2"&gt;@lexical/react/LexicalPlainTextPlugin&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ContentEditable&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="s2"&gt;@lexical/react/LexicalContentEditable&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HistoryPlugin&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="s2"&gt;@lexical/react/LexicalHistoryPlugin&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OnChangePlugin&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="s2"&gt;@lexical/react/LexicalOnChangePlugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LexicalErrorBoundary&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@lexical/react/LexicalErrorBoundary&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Editor.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="nx"&gt;onError&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;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&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;// [!code ++]&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plainText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$getRoot&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getTextContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LEXICAL_EDITOR_STATE_CHANGE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="nx"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;serializedEditorState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toJSON&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNativeWebView&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LexicalComposer&lt;/span&gt; &lt;span class="na"&gt;initialConfig&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;initialConfig&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"editor-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
// ...
          ErrorBoundary=&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LexicalErrorBoundary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        /&amp;gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HistoryPlugin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OnChangePlugin&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; // [!code ++]
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LexicalComposer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now we can receive this message on the react-native side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&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="s2"&gt;react-native&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;WebView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code --]&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebViewMessageEvent&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="s2"&gt;react-native-webview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;htmlString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./lexical-editor/dist/htmlString&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;onMessage&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;WebViewMessageEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;80%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Lexical Webview&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;originWhitelist&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&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;When we type something in the WebView editor we receive:&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LEXICAL_EDITOR_STATE_CHANGE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payload"&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;"plainText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"serializedEditorState"&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;"root"&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;"children"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"children"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"normal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"style"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&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="mi"&gt;1&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;span class="nl"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ltr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"indent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"paragraph"&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="mi"&gt;1&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;span class="nl"&gt;"direction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ltr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"indent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"root"&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="mi"&gt;1&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;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;We can do a switch on &lt;code&gt;message.type&lt;/code&gt; and handle any messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onMessage&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;WebViewMessageEvent&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LEXICAL_EDITOR_STATE_CHANGE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;// Do something with the editor state&lt;/span&gt;
      &lt;span class="c1"&gt;// like saving it to a database&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&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="s2"&gt;Unknown message type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&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;h2&gt;
  
  
  Command from React Native to Webview
&lt;/h2&gt;

&lt;p&gt;Let's say, we want to initialize the editor state when it is mounted.&lt;/p&gt;

&lt;p&gt;We listen for &lt;code&gt;LEXICAL_EDITOR_READY&lt;/code&gt; message and post a message to webview using WebView ref.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&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;useRef&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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;webviewRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;WebView&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&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;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onMessage&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;WebViewMessageEvent&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="c1"&gt;// Do something with the editor state&lt;/span&gt;
        &lt;span class="c1"&gt;// like saving it to a database&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LEXICAL_EDITOR_READY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commandMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INIT_SERIALIZED_EDITOR_STATE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
            &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;detail&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="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;format&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="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;normal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;style&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;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Initial text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ltr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;format&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;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;indent&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="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paragraph&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ltr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;format&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;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;indent&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="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
              &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
 &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="nx"&gt;webviewRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commandMessage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
      &lt;span class="nl"&gt;default&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="s2"&gt;Unknown message type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;80%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Lexical Webview&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;webviewRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
          &lt;span class="na"&gt;originWhitelist&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to handle this in Lexical editor. We can create a custom plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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="s2"&gt;react&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useLexicalComposerContext&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="s2"&gt;@lexical/react/LexicalComposerContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EditorStateInitPlugin&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useLexicalComposerContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LEXICAL_EDITOR_READY&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNativeWebView&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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;useEffect&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;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&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;data&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INIT_SERIALIZED_EDITOR_STATE&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="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEditorState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseEditorState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FromReactNativeToLexical&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="p"&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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;listener&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&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;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;listener&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;editor&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And use it in our &lt;code&gt;Editor.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;$getRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EditorState&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="s2"&gt;lexical&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code --]&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;$getRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LexicalEditor&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="s2"&gt;lexical&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&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;LexicalComposer&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="s2"&gt;@lexical/react/LexicalComposer&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PlainTextPlugin&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="s2"&gt;@lexical/react/LexicalPlainTextPlugin&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ContentEditable&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="s2"&gt;@lexical/react/LexicalContentEditable&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HistoryPlugin&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="s2"&gt;@lexical/react/LexicalHistoryPlugin&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OnChangePlugin&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="s2"&gt;@lexical/react/LexicalOnChangePlugin&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;LexicalErrorBoundary&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@lexical/react/LexicalErrorBoundary&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EditorStateInitPlugin&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="s2"&gt;./plugins/EditorStateInitPlugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Editor.css&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code --]&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EditorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="nx"&gt;_latestEditor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LexicalEditor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;// [!code ++]&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&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;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FromReactNativeToLexical&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;// [!code ++]&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;// [!code ++]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
    &lt;span class="nx"&gt;editorState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&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;plainText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$getRoot&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getTextContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

          &lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LexicalErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HistoryPlugin&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;EditorStateInitPlugin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// [!code ++]&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OnChangePlugin&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;LexicalComposer&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;Let's see it in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vh5orxmydqsvgvg24nh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8vh5orxmydqsvgvg24nh.gif" alt="lexical-initial-state" width="600" height="1298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Now you can add the desired nodes and plugins into editor. Also, add new messages and commands for communication between React Native and Lexical editor in WebView.&lt;/p&gt;

&lt;p&gt;For the full code example, you can check the playground project on GitHub, &lt;a href="https://github.com/Planable/react-native-lexical" rel="noopener noreferrer"&gt;react-native-lexical&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>reactnative</category>
    </item>
    <item>
      <title>Typescript errors into vim quickfix</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:46:12 +0000</pubDate>
      <link>https://dev.to/strdr4605/typescript-errors-into-vim-quickfix-1ief</link>
      <guid>https://dev.to/strdr4605/typescript-errors-into-vim-quickfix-1ief</guid>
      <description>&lt;p&gt;You may use LSP and &lt;code&gt;lua vim.diagnostic.setloclist()&lt;/code&gt; to show Typescript errors for a specific buffer. But sometimes you could have errors across the whole project.&lt;br&gt;
You can run &lt;code&gt;tsc&lt;/code&gt; in the terminal and manually search for files with errors. But we can do better.&lt;/p&gt;

&lt;p&gt;Vim has the &lt;code&gt;:make&lt;/code&gt; command which executes the program that is set into &lt;code&gt;makeprg&lt;/code&gt;. By default, it's &lt;code&gt;make&lt;/code&gt; but we can change it to any terminal program/command.&lt;br&gt;
The output of &lt;code&gt;makeprg&lt;/code&gt; is then populated into quickfix.&lt;/p&gt;
&lt;h2&gt;
  
  
  Update 🖊️
&lt;/h2&gt;

&lt;p&gt;After discussion on reddit someone suggested a better approach.&lt;br&gt;
The error is already parced in &lt;a href="https://github.com/neovim/neovim/blob/master/runtime/compiler/tsc.vim" rel="noopener noreferrer"&gt;&lt;code&gt;compiler tsc&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
I just change &lt;code&gt;makeprg=npx\ tsc&lt;/code&gt; instead of &lt;code&gt;makeprg=tsc&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="k"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;cmd &lt;span class="p"&gt;[[&lt;/span&gt;
  augroup strdr4605
    autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; typescript&lt;span class="p"&gt;,&lt;/span&gt;typescriptreact &lt;span class="k"&gt;compiler&lt;/span&gt; tsc &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;makeprg&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;npx\ tsc
  augroup END
&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Initial post
&lt;/h2&gt;

&lt;p&gt;Let's create an auto command that will set makeprg to &lt;code&gt;tsc&lt;/code&gt; if we are in a typescript project:&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;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;cmd &lt;span class="p"&gt;[[&lt;/span&gt;
  augroup strdr4605
    autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; typescript&lt;span class="p"&gt;,&lt;/span&gt;typescriptreact &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;makeprg&lt;/span&gt;&lt;span class="p"&gt;=.&lt;/span&gt;&lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;/tsc
  augroup END
&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or with lua API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;local augroup &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;api&lt;span class="p"&gt;.&lt;/span&gt;nvim_create_augroup&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"strdr4605"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; clear &lt;span class="p"&gt;=&lt;/span&gt; true &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;api&lt;span class="p"&gt;.&lt;/span&gt;nvim_create_autocmd&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"FileType"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  pattern &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"typescript,typescriptreact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  group &lt;span class="p"&gt;=&lt;/span&gt; augroup&lt;span class="p"&gt;,&lt;/span&gt;
  command &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"compiler tsc | setlocal makeprg=npx\\ tsc"&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;Run &lt;code&gt;:make&lt;/code&gt; and see the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;:!./node_modules/.bin/tsc  2&amp;gt;&amp;amp;1| &lt;span class="nb"&gt;tee&lt;/span&gt; /var/folders/3w/m_v388s15pq9rpgswbt131w00000gn/T/nvim.strdr4605/708JAY/2
components/Date.tsx&lt;span class="o"&gt;(&lt;/span&gt;6,28&lt;span class="o"&gt;)&lt;/span&gt;: error TS2339: Property &lt;span class="s1"&gt;'toISOString'&lt;/span&gt; does not exist on &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'number'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;(&lt;/span&gt;1 of 1&lt;span class="o"&gt;)&lt;/span&gt;: components/Date.tsx&lt;span class="o"&gt;(&lt;/span&gt;6,28&lt;span class="o"&gt;)&lt;/span&gt;: error TS2339: Property &lt;span class="s1"&gt;'toISOString'&lt;/span&gt; does not exist on &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'number'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Press ENTER or &lt;span class="nb"&gt;type command &lt;/span&gt;to &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and open the quickfix, &lt;code&gt;:copen&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;components/Date.tsx&lt;span class="o"&gt;(&lt;/span&gt;6,28&lt;span class="o"&gt;)&lt;/span&gt;: error TS2339: Property &lt;span class="s1"&gt;'toISOString'&lt;/span&gt; does not exist on &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'number'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When trying to navigate to any file from quickfix, I see this error: &lt;code&gt;Buffer not found&lt;/code&gt;. &lt;br&gt;
Why? Because the &lt;code&gt;tsc&lt;/code&gt; compiler outputs in a format that is not clear for vim quickfix.&lt;/p&gt;

&lt;p&gt;The problem is in parenthesis around the file line and column: &lt;code&gt;components/Date.tsx(6,28):&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But we can change this by piping the &lt;code&gt;tsc&lt;/code&gt; output to &lt;code&gt;sed&lt;/code&gt; command and replacing &lt;code&gt;(6,28)&lt;/code&gt; with &lt;code&gt;:6:28:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the output if we run it in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ./node_modules/.bin/tsc | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/(\(.*\),\(.*\)):/:\1:\2:/'&lt;/span&gt;                                                                                 130 ↵

components/Date.tsx:6:28: error TS2339: Property &lt;span class="s1"&gt;'toISOString'&lt;/span&gt; does not exist on &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'number'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But to make it work in vim, we need to escape some chars.&lt;br&gt;
The final result is:&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;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;cmd &lt;span class="p"&gt;[[&lt;/span&gt;
  augroup strdr4605
    autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; typescript&lt;span class="p"&gt;,&lt;/span&gt;typescriptreact &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;makeprg&lt;/span&gt;&lt;span class="p"&gt;=.&lt;/span&gt;&lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="sr"&gt;/tsc\ \\\|\ sed\ 's/&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="p"&gt;)):&lt;/span&gt;&lt;span class="sr"&gt;/:\\1:\\2:/&lt;/span&gt;'
  augroup END
&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when running &lt;code&gt;:make&lt;/code&gt; the quickfix list is populated correctly and vim navigates to the first file in the list.&lt;br&gt;
I can fix Typescript errors one by one, by navigating with &lt;code&gt;:cnext&lt;/code&gt; or using &lt;a href="https://github.com/tpope/vim-unimpaired" rel="noopener noreferrer"&gt;vim-unimpaired&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vim</category>
    </item>
    <item>
      <title>How I keep my iPhone battery at optimal level</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:46:11 +0000</pubDate>
      <link>https://dev.to/strdr4605/how-i-keep-my-iphone-battery-at-optimal-level-4mkm</link>
      <guid>https://dev.to/strdr4605/how-i-keep-my-iphone-battery-at-optimal-level-4mkm</guid>
      <description>&lt;p&gt;I am not a heavy user of mobile phones. I don't rush for the latest model and when I buy a phone I hope it to last for at least 4-5 years.&lt;/p&gt;

&lt;p&gt;Till recently I owned an iPhone 7 for about 4 years. &lt;br&gt;
And I could own it a bit more, but the battery maximum capacity went down to 65% over years. It could last a maximum of 3 hours of active usage, and never a full day.&lt;/p&gt;

&lt;p&gt;The battery died so fast because of incorrect usage of it. In special because the phone was used by my brother in the first year to play games all day.&lt;/p&gt;

&lt;p&gt;After I bought a new iPhone 13 mini, I decided to charge the phone smarter to prolong the battery life. &lt;/p&gt;

&lt;p&gt;Batteries in smartphones don't like being fully charged or discharged.&lt;/p&gt;

&lt;p&gt;But how I could remember when to change it and when to stop changing?&lt;/p&gt;

&lt;p&gt;iPhone shortcuts are here to help with this. They can do a ton of stuff. &lt;br&gt;
But for this specific use case, I use shortcuts automation.&lt;/p&gt;

&lt;p&gt;I can add automation when the battery reaches a specific level, like below 35% or above 70%.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwi7w454oj71y7tfztkz3.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwi7w454oj71y7tfztkz3.jpeg" alt="iphone-battery-shortcut1" width="800" height="1626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to show a notification and disabled "Ask before Running".&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q8nnsagn5x4c9j8gqas.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q8nnsagn5x4c9j8gqas.jpeg" alt="iphone-battery-shortcut2" width="800" height="1604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now each time the phone battery drops under 35% I get a notification on my smartwatch and plug the phone to change.&lt;br&gt;
And then the phone was changed to 70% I get another notification and remove the phone from changing.&lt;/p&gt;

&lt;p&gt;Probably this technic is not a drastic improvement over &lt;em&gt;"change it at night to 100%"&lt;/em&gt;. &lt;br&gt;
But the feeling of prolonging the life of my phone brings joy.&lt;br&gt;
Let's see in 5-6 years what will be the battery health 😅.&lt;/p&gt;

</description>
      <category>hacks</category>
      <category>shortcuts</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Git: temporary change commit author</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:42:22 +0000</pubDate>
      <link>https://dev.to/strdr4605/git-temporary-change-commit-author-19nl</link>
      <guid>https://dev.to/strdr4605/git-temporary-change-commit-author-19nl</guid>
      <description>&lt;p&gt;It may happen that sometimes you need to temporarily do commits with another author's name and email.&lt;br&gt;
You can do this with this 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="nv"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Other Name"&lt;/span&gt; &lt;span class="nv"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Other Email"&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; Test &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"Other Name &amp;lt;adriana.sanduta@isa.utm.md&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But you may want to do it multiple times, so you can create a &lt;strong&gt;shell&lt;/strong&gt; function:&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;# Add me to shell config file. ~/.zshrc or ~/.bashrc&lt;/span&gt;
&lt;span class="c"&gt;# Git with author&lt;/span&gt;
git_w_a&lt;span class="o"&gt;(){&lt;/span&gt;
  &lt;span class="nv"&gt;COMMITTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Other Name"&lt;/span&gt;
  &lt;span class="nv"&gt;COMMITTER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"other_email@example.com"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"
    Running:
    GIT_COMMITTER_NAME=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_NAME&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; GIT_COMMITTER_EMAIL=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_EMAIL&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; git &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt; --author &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_NAME&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
  "&lt;/span&gt;
  &lt;span class="nv"&gt;GIT_COMMITTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;GIT_COMMITTER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  git &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--author&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_NAME&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;$COMMITTER_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Test"&lt;/span&gt; &lt;span class="c"&gt;# Commit with default user name and email&lt;/span&gt;
git_w_a commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Test"&lt;/span&gt; &lt;span class="c"&gt;# Commit with other user name and email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Don't forget to change the &lt;code&gt;COMMITTER_NAME&lt;/code&gt; and &lt;code&gt;COMMITTER_EMAIL&lt;/code&gt; &lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>git</category>
      <category>zsh</category>
      <category>tools</category>
    </item>
    <item>
      <title>No tits in git</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:41:17 +0000</pubDate>
      <link>https://dev.to/strdr4605/no-tits-in-git-1kl0</link>
      <guid>https://dev.to/strdr4605/no-tits-in-git-1kl0</guid>
      <description>&lt;p&gt;I don't know about you but my first git experience was with Github.&lt;br&gt;
The power of git is allowing development as a team, where every team member can make a branch and then create a Pull Request.&lt;br&gt;
My &lt;a href="https://firstpr.me/#strdr4605" rel="noopener noreferrer"&gt;first PR&lt;/a&gt; was an experience.&lt;br&gt;
After submitting it, my teammate merged it and the git history looked like this:&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="k"&gt;*&lt;/span&gt;   8d662a2 Merge pull request &lt;span class="c"&gt;#1 from strdr4605/new-colors&lt;/span&gt;
|&lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="k"&gt;*&lt;/span&gt; cbf20e1 Setting better colors &lt;span class="k"&gt;for &lt;/span&gt;rectangles
|/
&lt;span class="k"&gt;*&lt;/span&gt; 40446a6 fixed readme typo
&lt;span class="k"&gt;*&lt;/span&gt; b894618 add readme to lab2, modified cases methods &lt;span class="k"&gt;in &lt;/span&gt;bussiness logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When doing a default merge, git will create a merge commit with info about the branch that was merged history will show the path to commits.&lt;br&gt;
I call it a &lt;strong&gt;"tit"&lt;/strong&gt; and I now will explain why you should not have &lt;strong&gt;tits&lt;/strong&gt; in git!&lt;/p&gt;

&lt;p&gt;Let's say my teammate was doing something on local master, his master branch was at &lt;code&gt;40446a6&lt;/code&gt; then he committed some changes.&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="k"&gt;*&lt;/span&gt; 5963243 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add circles
| &lt;span class="k"&gt;*&lt;/span&gt;   8d662a2 &lt;span class="o"&gt;(&lt;/span&gt;origin/master, origin/HEAD&lt;span class="o"&gt;)&lt;/span&gt; Merge pull request &lt;span class="c"&gt;#1 from strdr4605/new-colors&lt;/span&gt;
| |&lt;span class="se"&gt;\&lt;/span&gt;
|/ /
| &lt;span class="k"&gt;*&lt;/span&gt; cbf20e1 Setting better colors &lt;span class="k"&gt;for &lt;/span&gt;rectangles
|/
&lt;span class="k"&gt;*&lt;/span&gt; 40446a6 fixed readme typo
&lt;span class="k"&gt;*&lt;/span&gt; b894618 add readme to lab2, modified cases methods &lt;span class="k"&gt;in &lt;/span&gt;bussiness logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when he tries to push to remote git will alert that he should first do a &lt;code&gt;git pull&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;git pull&lt;/code&gt; internally is doing 2 things, &lt;code&gt;git fetch&lt;/code&gt; to get updates from &lt;strong&gt;origin/master&lt;/strong&gt; and &lt;code&gt;git merge&lt;/code&gt;.&lt;br&gt;
And the git history looks like this:&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="k"&gt;*&lt;/span&gt;   c3633b4 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; Merge branch &lt;span class="s1"&gt;'master'&lt;/span&gt; of https://github.com/sspatari/OR_Labs
|&lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="k"&gt;*&lt;/span&gt;   8d662a2 &lt;span class="o"&gt;(&lt;/span&gt;origin/master, origin/HEAD&lt;span class="o"&gt;)&lt;/span&gt; Merge pull request &lt;span class="c"&gt;#1 from strdr4605/new-colors&lt;/span&gt;
| |&lt;span class="se"&gt;\&lt;/span&gt;
| | &lt;span class="k"&gt;*&lt;/span&gt; cbf20e1 Setting better colors &lt;span class="k"&gt;for &lt;/span&gt;rectangles
| |/
&lt;span class="k"&gt;*&lt;/span&gt; | c27aac2 add circles
|/
&lt;span class="k"&gt;*&lt;/span&gt; 40446a6 fixed readme typo
&lt;span class="k"&gt;*&lt;/span&gt; b894618 add readme to lab2, modified cases methods &lt;span class="k"&gt;in &lt;/span&gt;bussiness logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see! A new indentation and a bigger &lt;strong&gt;tit&lt;/strong&gt;. Now it's harder to understand the git history.&lt;br&gt;
And it can get worse, and in one moment when you need to debug something and use git history, you see over 9000 tits, small, big, enormous, gigantic.&lt;/p&gt;

&lt;p&gt;I asked a friend of mine whats this:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42l6wsthrwjelmz7gk1d.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F42l6wsthrwjelmz7gk1d.png" alt="Git carpet" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And he told me that it's a photo of my grandma's carpet 😂.&lt;/p&gt;

&lt;p&gt;But actually, it's a git history from a development team of my friend. Here is a zoom out:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff132xzc171zdi0bduvdy.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff132xzc171zdi0bduvdy.jpg" alt="Gigantic git tits" width="799" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may say &lt;em&gt;"I don't look at git history, I don't even use the command line, I only click the magic button on my IDE when I want to push my changes and everything is ok"&lt;/em&gt;.&lt;br&gt;
Sure, it's ok until the moment when things become complicated.&lt;br&gt;
Maybe you need to get some changes from another branch, or maybe you need only one commit from your teammate's branch.&lt;br&gt;
You may have some conflicts when merging/rebasing a wrong branch using your magic IDE.&lt;br&gt;
Maybe you need to find a bug that was introduced some time ago and the only way to understand where approximately it was is by looking at git history.&lt;br&gt;
You may spend hours, days trying to navigate in a dimension full of &lt;strong&gt;tits&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The main causes of git &lt;strong&gt;tits&lt;/strong&gt; are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No desire to learn git a bit&lt;/li&gt;
&lt;li&gt;Using magic IDE buttons&lt;/li&gt;
&lt;li&gt;Using &lt;strong&gt;"Merge pull request"&lt;/strong&gt; option button in Github PRs&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;git rebase&lt;/code&gt; always!&lt;/p&gt;

&lt;p&gt;Here is a version of the git history above if it was done using &lt;code&gt;git rebase&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="k"&gt;*&lt;/span&gt; 461db4e add circles
&lt;span class="k"&gt;*&lt;/span&gt; ad0041c Setting better colors &lt;span class="k"&gt;for &lt;/span&gt;rectangles
&lt;span class="k"&gt;*&lt;/span&gt; 40446a6 fixed readme typo
&lt;span class="k"&gt;*&lt;/span&gt; b894618 add readme to lab2, modified cases methods &lt;span class="k"&gt;in &lt;/span&gt;bussiness logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 Now it's cleaner what is happening in the project.&lt;br&gt;
If rebasing on every feature or bug fix, the git history will look like a straight line with some branches on top.&lt;br&gt;
It will be easier to understand the status of the project and what git operations should be done.&lt;br&gt;
Easier to get some changes from other branches, or to find a bug that from past commits.&lt;/p&gt;

&lt;p&gt;You may think, &lt;a href="https://news.ycombinator.com/item?id=26582912" rel="noopener noreferrer"&gt;rebasing is lying about the project history&lt;/a&gt; and it's true.&lt;br&gt;
When rebasing you reapply the commits and now they have different hashes and committing dates/authors.&lt;br&gt;
You will lose info about the branch name that was merged, or when these changes were initially committed.&lt;br&gt;
If this is more important for you then yeah git &lt;strong&gt;tits&lt;/strong&gt; is the way to go.&lt;br&gt;
But I think about git history, not like some timeline of the project development where changes happened and I need all details,&lt;br&gt;
but more like a version history of the project where every commit is a new version.&lt;br&gt;
Then I don't care about dates, hashes, authors. I only know that this version of the project (commit 2) comes after another version (commit 1).&lt;/p&gt;

&lt;p&gt;So, how to eliminate git &lt;strong&gt;tits&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;git rebase&lt;/code&gt; instead of &lt;code&gt;git merge&lt;/code&gt; (or use &lt;code&gt;git merge --ff-only&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;git pull -r&lt;/code&gt; (will do &lt;code&gt;git fetch&lt;/code&gt; and &lt;code&gt;git rebase&lt;/code&gt;) when getting updates from remote&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Rebase and merge&lt;/strong&gt; option button in Github when merging PRs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only case where we can not escape from git &lt;strong&gt;tit&lt;/strong&gt; is doing a rebase with a lot of commits (20+) and you have to resolve conflicts at every other commit.&lt;br&gt;
This can be a pain, especially when in the process of rebasing you did a mistake and the only way to revert it is to rebase again.&lt;br&gt;
In this case &lt;code&gt;git merge&lt;/code&gt; will let you solve all the conflicts in one take.&lt;/p&gt;

&lt;p&gt;I hope you understood my idea and from now on instead of confusing git &lt;strong&gt;tits&lt;/strong&gt; and spaghetti, your project git history will look more like a beautiful palm tree.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let me know if there are other use cases when git &lt;strong&gt;tits&lt;/strong&gt; are inevitable&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may also check &lt;a href="https://strdr4605.com/how-i-use-git" rel="noopener noreferrer"&gt;how I use git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>My Keyboard as a Status Board for Coding Agents</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:32:24 +0000</pubDate>
      <link>https://dev.to/strdr4605/my-keyboard-as-a-status-board-for-coding-agents-p11</link>
      <guid>https://dev.to/strdr4605/my-keyboard-as-a-status-board-for-coding-agents-p11</guid>
      <description>&lt;p&gt;Over time, my hardware setup changed many times: a single laptop, then a laptop with a big monitor, then a second monitor, then a third monitor. Then I went back to just the laptop, added a mechanical keyboard, and later bought a better one.&lt;/p&gt;

&lt;p&gt;And somehow, in April of 2022, I ended up buying the Planck EZ Glow: &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxq9zfvu9r2bes0fyo0h.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxq9zfvu9r2bes0fyo0h.png" alt="Planck EZ" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first 40% programmable keyboard, with multiple layers, macros, RGB LEDs, and even a built-in buzzer for playing music.&lt;/p&gt;

&lt;p&gt;For the past three years, I used it with a single 32-inch monitor and a closed laptop. It was a nice setup, and I got used to switching layers and typing with ease.&lt;/p&gt;

&lt;p&gt;Then, in the process of switching jobs, I moved the Planck EZ keyboard into a box and kind of forgot about it. I went back to my roots: working from one spot to another with a 14-inch MacBook Pro. The move to fully prompting coding agents in the terminal helped too, because I no longer needed to see chunks of code on a big screen.&lt;/p&gt;

&lt;p&gt;Keyboard stayed in the box for almost a year. I missed it from time to time, but carrying it in my backpack only to use it as an external keyboard for my 14-inch machine was not worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;Not long ago, I switched my terminal multiplexer from &lt;a href="https://tmux.app/" rel="noopener noreferrer"&gt;tmux&lt;/a&gt; to &lt;a href="https://herdr.dev/" rel="noopener noreferrer"&gt;herdr&lt;/a&gt;. I made the change because I got lost with several coding agents running in multiple sessions and tabs in tmux. Herdr, with its panel for running agents and a 90% similarity with my tmux setup, made me switch.&lt;/p&gt;

&lt;p&gt;One day I saw the video &lt;a href="https://www.youtube.com/watch?v=o7X7qOwYBzE" rel="noopener noreferrer"&gt;Herdr + Creator Micro 2: Codex Micro for Nerds&lt;/a&gt; and thought to myself🤔: nice idea. I have a programmable keyboard in my closet. Why create a similar setup with Planck EZ and herdr?&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The first step was to create a separate layer on the keyboard. Switching to that "agentic" layer makes each key fire a custom keyboard event, which I map to my needs.&lt;br&gt;&lt;br&gt;
I use the Hyper chord&lt;sup id="fnref1"&gt;1&lt;/sup&gt; plus a letter, a symbol, or a number.&lt;br&gt;&lt;br&gt;
This way, I am sure that my keyboard events do not conflict with the events of other apps on my macOS.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;Hyper+A&lt;/code&gt; = Ctrl + Alt + Shift + Cmd + A.&lt;/p&gt;

&lt;p&gt;Next, I created a script called &lt;code&gt;planck-agent&lt;/code&gt; that does several things, based on the arguments it receives. To trigger this script, I tested &lt;a href="https://github.com/asmvik/skhd" rel="noopener noreferrer"&gt;skhd&lt;/a&gt; and &lt;a href="https://www.raycast.com/" rel="noopener noreferrer"&gt;Raycast&lt;/a&gt;, which are hotkey daemons for macOS.&lt;/p&gt;

&lt;p&gt;Now &lt;code&gt;planck-agent&lt;/code&gt; does the following, based on my config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;focus my terminal and make herdr focus the specific agent&lt;/li&gt;
&lt;li&gt;run scripts&lt;/li&gt;
&lt;li&gt;write macros&lt;/li&gt;
&lt;li&gt;submit prompts&lt;/li&gt;
&lt;li&gt;control herdr panes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agent statuses and feedback
&lt;/h2&gt;

&lt;p&gt;This is where this setup shines. Using the &lt;a href="https://www.zsa.io/keymapp" rel="noopener noreferrer"&gt;Keymapp API&lt;/a&gt; and the &lt;a href="https://github.com/zsa/kontroll" rel="noopener noreferrer"&gt;Kontroll CLI&lt;/a&gt;, I can give instructions to the Planck EZ Glow keyboard to color any key based on my needs.&lt;/p&gt;

&lt;p&gt;I divided the keyboard layout into two sections. The first row is dedicated to coding agents (12 maximum), and the next two rows are for custom instructions and scripts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;planck-agent&lt;/code&gt; listens to the statuses of the herdr agents and changes the keyboard colors accordingly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orange working&lt;/li&gt;
&lt;li&gt;Blue done (unseen)&lt;/li&gt;
&lt;li&gt;Green idle&lt;/li&gt;
&lt;li&gt;Red blocked&lt;/li&gt;
&lt;li&gt;Purple stale (idle for 10 minutes since it was last focused)&lt;/li&gt;
&lt;li&gt;Dark empty.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is how the architecture looks in the end:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxz7o1nadfpr0f9asixsp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxz7o1nadfpr0f9asixsp.png" alt="planck-agent-architecture" width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because I have two rows (24 keys) free to use for myself, I mapped some of them to macros, often used prompts, and scripts that I may need when working with this new setup.&lt;/p&gt;

&lt;p&gt;My top instructions at the time of writing this blog post:&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;when finishing work on something&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;N&lt;/code&gt; (Next) - &lt;code&gt;"prompt": "Is something missing, or are we done with this task? What's next?"&lt;/code&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;after entering a long prompt, but I do not want the agents to change anything yet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;;&lt;/code&gt; (Pause) - &lt;code&gt;"macro": "Plan first. Do not make changes yet — list 2-3 options and trade-offs."&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;code&gt;S&lt;/code&gt; - &lt;code&gt;"prompt": "Summarize the current state in one line."&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;code&gt;/&lt;/code&gt; - &lt;code&gt;"prompt": "/compact"&lt;/code&gt; (too lazy to type😅)&lt;/p&gt;

&lt;p&gt;Here is my initial config (I have probably already changed it):&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfat5goxqmofytznnnlj.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfat5goxqmofytznnnlj.png" alt="planck-agent-legend" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo time
&lt;/h2&gt;

&lt;p&gt;To truly understand how this all works, you need to see it in action.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;After I finished v1 of &lt;code&gt;planck-agent&lt;/code&gt;, I wanted to show some workflow demos. I planned to film the keyboard interaction and record the screen.&lt;br&gt;&lt;br&gt;
My first idea was to build a demo herdr workspace with agents and custom prompts. Then I would press start, screen recording and iPhone video, and later I would edit the footage into several demos.  &lt;/p&gt;

&lt;p&gt;While I asked my coding agent to create this demo setup and described my plan, the agent did something that completely surprised me🤯🤩.&lt;br&gt;&lt;br&gt;
The agent took the recording part as a task for itself and started to explore how to get a raw video stream and screen frames.&lt;br&gt;&lt;br&gt;
The agent found the iPhone camera stream (the phone is connected to the same iCloud) as a source, tested it, and inspected frames to locate the keyboard and scale the view to focus on it.  &lt;/p&gt;

&lt;p&gt;Then, after some trials and errors (with frame rates and the timing between the two sources), the agent aligned everything and combined it all into MOV and GIF files.&lt;br&gt;&lt;br&gt;
It even mapped keys on my keyboard to start and stop the recording.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk9b79cjvc2bx4sit1xya.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk9b79cjvc2bx4sit1xya.gif" alt="michael-shocked-happy" width="489" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is a document that the coding agent created while it explored how it did it: &lt;a href="https://github.com/strdr4605/.dotfiles/blob/master/planck-agent/demo/RECORDING.md" rel="noopener noreferrer"&gt;/RECORDING.md&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sorry for the low quality. My agent did it😅.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy19k3nl5n7ivbd8piful.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy19k3nl5n7ivbd8piful.gif" alt="planck-agent-1" width="580" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The focus keys jump between the agents. The jj key opens the log and the status panes beside the focused agent. The macro key types a prompt into the input box without sending it, and the approve key sends it. The nLED row shows the state of every agent, and the spacebar shows the worst state of all of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8nhk38qvfbtgjwnrtkj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8nhk38qvfbtgjwnrtkj.gif" alt="planck-agent-2" width="560" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new agent appears when herdr detects it, and its key lights up. The flag key paints a finished agent blue, so a seen agent is not forgotten. A stale agent turns purple after ten minutes of silence.&lt;/p&gt;

&lt;p&gt;Now, with this setup (a laptop and the agentic keyboard on the side), I feel as if I am in a main control room, using a colored panel.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nycy9jbk0ujd0hc7kwr.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2nycy9jbk0ujd0hc7kwr.jpg" alt="nuclear-power-plant-control-room" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have a programmable RGB keyboard, I highly suggest that you play with it. Maybe you can create a similar setup.&lt;/p&gt;

&lt;p&gt;The full setup is available at &lt;a href="https://github.com/strdr4605/.dotfiles/tree/master/planck-agent" rel="noopener noreferrer"&gt;strdr4605/.dotfiles/planck-agent/&lt;/a&gt;. You can point your coding agent at it and let it create something similar for your case.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Hyper = Ctrl + Alt + Shift + Cmd, all at once.  &amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>tools</category>
      <category>automation</category>
      <category>agents</category>
    </item>
    <item>
      <title>MacOS: notify when the terminal command is finished</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Fri, 21 Apr 2023 09:04:17 +0000</pubDate>
      <link>https://dev.to/strdr4605/macos-notify-when-the-terminal-command-is-finished-4ji6</link>
      <guid>https://dev.to/strdr4605/macos-notify-when-the-terminal-command-is-finished-4ji6</guid>
      <description>&lt;p&gt;After reading &lt;a href="https://evanhahn.com/a-decade-of-dotfiles/" rel="noopener noreferrer"&gt;A decade of dotfiles&lt;/a&gt; I wanted to create a similar bash function to &lt;code&gt;boop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And here it is:&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;# ~/.zshrc&lt;/span&gt;
&lt;span class="c"&gt;# ...rest of zshrc&lt;/span&gt;
,notify &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;last_exit_status&lt;/span&gt;&lt;span class="o"&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$last_exit_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'0'&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;osascript &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"display notification &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Done&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; with title &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Good&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; sound name &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Fonk&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;else
    &lt;/span&gt;osascript &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"display notification &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Exit code: &lt;/span&gt;&lt;span class="nv"&gt;$last_exit_status&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; with title &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Bad&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; sound name &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Ping&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;
  &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$last_exit_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It uses &lt;a href="https://ss64.com/osx/osascript.html" rel="noopener noreferrer"&gt;osascript&lt;/a&gt; to execute the AppleScripts that pushes the notification.&lt;br&gt;&lt;br&gt;
According to &lt;a href="https://stackoverflow.com/questions/67406491/osascript-how-to-pass-in-a-variable/67413043#67413043" rel="noopener noreferrer"&gt;stackoverflow&lt;/a&gt; &lt;br&gt;
this is not the best way to pass bash variable to osascript, &lt;br&gt;
but I did not understand how to do it for my use case and as I use &lt;code&gt;last_exit_status&lt;/code&gt; there should be no problem.&lt;/p&gt;

&lt;p&gt;usage:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;I prefix the function name with a comma to faster search for it when doing &lt;code&gt;;,&amp;lt;Tab&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can test it with &lt;code&gt;(exit 0);,notify&lt;/code&gt; and &lt;code&gt;(exit 1);,notify&lt;/code&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F788bzpg33bq4171i756i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F788bzpg33bq4171i756i.png" alt="notify good" width="722" height="148"&gt;&lt;/a&gt;&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdl66j5r9qhawyj9vqbkb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdl66j5r9qhawyj9vqbkb.png" alt="notify bad" width="732" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>macos</category>
      <category>bash</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Stop doing git checkout master branch</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Tue, 14 Mar 2023 13:19:58 +0000</pubDate>
      <link>https://dev.to/strdr4605/stop-doing-git-checkout-master-branch-55bi</link>
      <guid>https://dev.to/strdr4605/stop-doing-git-checkout-master-branch-55bi</guid>
      <description>&lt;p&gt;I see a common workflow when starting to work on new task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout master
git pull &lt;span class="c"&gt;# or git pull -r&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feat/4605-new-task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I do things a bit differently. The main difference is that I don't care about the local &lt;code&gt;master&lt;/code&gt; branch because the source of truth is always remote &lt;code&gt;origin/master&lt;/code&gt;. &lt;br&gt;
I don't do commits on &lt;code&gt;master&lt;/code&gt; branch, because all changes to the project are done through Pull Requests. So why should I keep the local &lt;code&gt;master&lt;/code&gt; in sync with &lt;code&gt;origin/master&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;The first thing I do is fetch the remote master branch to get the latest commits.&lt;/p&gt;

&lt;p&gt;I have an alias in my &lt;code&gt;.gitconfig&lt;/code&gt; file:&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="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  fetch-and-clean-branches &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!git fetch -p &amp;amp;&amp;amp; git branch -vv | grep ': gone]'|  grep -v "&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;" | awk '{ print &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;; }' | xargs git branch -D"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://morgan.cugerone.com/blog/quick-tip-how-to-locally-delete-all-remotely-merged-git-branches/" rel="noopener noreferrer"&gt;How to locally delete all remotely merged git branches&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Running &lt;code&gt;git fetch-and-clean-branches&lt;/code&gt;, will fetch new updates on remote branches and will remove local branches that are not relevant anymore.&lt;/p&gt;

&lt;p&gt;Next, I create a new branch based on &lt;code&gt;origin/master&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;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feat/4605-new-task origin/master &lt;span class="c"&gt;# --no-track&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also created an alias for this 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="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  fetch-and-clean-branches &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!git fetch -p &amp;amp;&amp;amp; git branch -vv | grep ': gone]'|  grep -v "&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;" | awk '{ print &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;; }' | xargs git branch -D"&lt;/span&gt;
  start &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!git fetch-and-clean-branches &amp;amp;&amp;amp; git checkout -b &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; --no-track origin/master #"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I can use it as: &lt;code&gt;git start feat/4605-new-task&lt;/code&gt;. &lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Related: &lt;a href="https:strdr4605.com/how-i-use-git" rel="noopener noreferrer"&gt;How I use Git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>How to gradually add an eslint rule</title>
      <dc:creator>Dragoș Străinu</dc:creator>
      <pubDate>Wed, 18 May 2022 09:51:38 +0000</pubDate>
      <link>https://dev.to/strdr4605/how-to-gradually-add-an-eslint-rule-1ced</link>
      <guid>https://dev.to/strdr4605/how-to-gradually-add-an-eslint-rule-1ced</guid>
      <description>&lt;p&gt;As your javascript project grows and new engineers are joining the team, you may try to add new eslint plugins and rules to make the code base more rigid.&lt;/p&gt;

&lt;p&gt;The problem is that often these new eslint rules may require changes in all project files, and as your project is big enough, you may have a situation when eslint rules require changes in &lt;a href="https://strdr4605.com/how-i-found-a-bug-in-2000-files" rel="noopener noreferrer"&gt;2000+ files&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What if you could gradually enforce an eslint rule, without breaking the CI of your project.&lt;/p&gt;

&lt;p&gt;We can do this using &lt;a href="https://github.com/okonet/lint-staged" rel="noopener noreferrer"&gt;lint-staged&lt;/a&gt;, &lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;husky&lt;/a&gt;, and some changes in the &lt;code&gt;.eslintrc.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;I hope you are already using &lt;code&gt;lint-staged&lt;/code&gt; with &lt;code&gt;husky&lt;/code&gt;. If not, please set up it.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;.lintstagedrc.js&lt;/code&gt; file may look something like this:&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="c1"&gt;// .lintstagedrc.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&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;*.{js,jsx,ts,tsx}&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prettier --write&lt;/span&gt;&lt;span class="dl"&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;eslint --quiet --fix&lt;/span&gt;&lt;span class="dl"&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;*.css&lt;/span&gt;&lt;span class="dl"&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;stylelint --fix&lt;/span&gt;&lt;span class="dl"&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;*.md&lt;/span&gt;&lt;span class="dl"&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;prettier --write&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may also have a script in your &lt;code&gt;package.json&lt;/code&gt; file, that you run in CI to make sure eslint rules are followed:&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"eslint:run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint --ext=.js,.jsx,.ts,.tsx --quiet ."&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;Now let's say you want to enforce the removal of all console logs using the eslint rule &lt;code&gt;no-console&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;.eslintrc.js&lt;/code&gt; file, set the rule to warning:&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="c1"&gt;// .eslintrc.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;rules&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;no-console&lt;/span&gt;&lt;span class="dl"&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;warn&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now running &lt;code&gt;npm run eslint:run&lt;/code&gt; will just show a bunch of warnings but will pass the check.&lt;br&gt;
Next, you need to create a new eslintrc file that will be used only by &lt;code&gt;lint-staged&lt;/code&gt;. Let's name it &lt;code&gt;eslintrc-staged.js&lt;/code&gt;. &lt;br&gt;
There you need to extend the default eslint config and override the rule to error.&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="c1"&gt;// .eslintrc-staged.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./.eslintrc.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;rules&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;no-console&lt;/span&gt;&lt;span class="dl"&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;error&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last change needs to be done in &lt;code&gt;.lintstagedrc.js&lt;/code&gt; to tell lint-staged to use another config file when running eslint.&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&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;*.{js,jsx,ts,tsx}&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prettier --write&lt;/span&gt;&lt;span class="dl"&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;eslint -c eslintrc-staged.js --no-eslintrc --quiet --fix&lt;/span&gt;&lt;span class="dl"&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;*.css&lt;/span&gt;&lt;span class="dl"&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;stylelint --fix&lt;/span&gt;&lt;span class="dl"&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;*.md&lt;/span&gt;&lt;span class="dl"&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;prettier --write&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when doing changes to the project, eslint will throw errors only to the files that were changed before the commit.&lt;/p&gt;

</description>
      <category>development</category>
      <category>eslint</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
