<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><atom:link href="https://iamsang.com" rel="self" type="application/rss+xml"/><title>I am Sang</title><link>https://iamsang.com</link><description>I'm a software engineer from South Korea and currently live in Berlin. I write articles and draw comics in Korean and English.</description><generator>clj-rss</generator><image><url>https://iamsang.com/logo.png</url><title>I am Sang</title><link>https://iamsang.com</link></image><item><title>How I use MacBook without a mouse</title><link>https://iamsang.com/en/2022/08/03/no-mouse</link><pubDate>Wed, 03 Aug 2022 22:30:00 +0200</pubDate><description>&lt;p&gt;I used to use one of the most expensive mice on the market, &lt;a href='https://www.cnet.com/reviews/logitech-mx-revolution-review/'&gt;Logitech MX Revolution&lt;/a&gt;. It was a mouse on which I could map around ten buttons. I enjoyed using it.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/1200px-Logitech_MX_Revolution_a.png" alt="Logitech MX Revolution" width="400px" /&gt;&lt;/p&gt;&lt;p&gt;I found it from a Stack Overflow thread discussing the best mouse for developers. It was the second most popular answer; the most popular answer was "No mouse is the best mouse."&lt;/p&gt;&lt;p&gt;As usual, the thread was deleted, being flagged as off-topic.&lt;/p&gt;&lt;p&gt;I moved from the second-best mouse to the best mouse after I started using a Mac, and I rarely use trackpad when I work.&lt;/p&gt;&lt;h3 id="why-no-mouse"&gt;Why no mouse?&lt;/h3&gt;&lt;p&gt;I barely move my hands when I use my laptop, and I've never had wrist pain since ditching the mouse. It's more productive and healthier.&lt;/p&gt;&lt;p&gt;I use these applications, tools, and tricks to avoid using the mouse.&lt;/p&gt;&lt;h3 id="chrome"&gt;Chrome&lt;/h3&gt;&lt;h4 id="vimium"&gt;Vimium&lt;/h4&gt;&lt;p&gt;&lt;a href='https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=en'&gt;Vimium&lt;/a&gt; is a Chrome extension that enables you to navigate using keyboard shortcuts.&lt;/p&gt;&lt;p&gt;If you're not a vim user, you can learn some key mappings with it.&lt;/p&gt;&lt;h4 id="switching-focus-from-the-address-bar-to-the-page"&gt;Switching focus from the address bar to the page&lt;/h4&gt;&lt;p&gt;With Vimium, you can avoid using the mouse when the focus is inside a page, but you usually have to click the page to switch focus from the address bar to the page.&lt;/p&gt;&lt;p&gt;To avoid using the mouse, type in &lt;code&gt;javascript:&lt;/code&gt; in the address bar and press Enter.&lt;/p&gt;&lt;p&gt;If you think &lt;code&gt;javascript:&lt;/code&gt; is too long, you can add a shortcut by following the instructions on &lt;a href='https://stackoverflow.com/a/30567119/524588'&gt;this page&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="vimac"&gt;Vimac&lt;/h3&gt;&lt;p&gt;&lt;a href='https://vimacapp.com/'&gt;Vimac&lt;/a&gt; is an open-source project that works similarly to Vimium.&lt;/p&gt;&lt;p&gt;It's a bit slow and flaky but useful.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/vimac.png" alt="vimac usage screenshot" /&gt;&lt;/p&gt;&lt;h3 id="shortcat"&gt;Shortcat&lt;/h3&gt;&lt;p&gt;&lt;a href='https://shortcat.app/'&gt;Shortcat&lt;/a&gt; is similar to Vimac, but behaves slightly differently. I stopped using Shortcat after I started using Vimac.&lt;/p&gt;&lt;h3 id="bettertouchtool-paid"&gt;BetterTouchTool (Paid)&lt;/h3&gt;&lt;p&gt;&lt;a href='https://folivora.ai/'&gt;BetterTouchTool (BTT)&lt;/a&gt; is a tool that allows you to customize various input devices.&lt;/p&gt;&lt;p&gt;With BTT, I open applications and run shell scripts and AppleScripts using keyboard shortcuts. A MacBook feels broken to me without it.&lt;/p&gt;&lt;p&gt;You can find more use cases in this Reddit post: &lt;iframe id="reddit-embed" src="https://www.redditmedia.com/r/MacOS/comments/nke8g6/bettertouchtool_is_one_of_the_most_worthit/?ref_source=embed&amp;amp;ref=share&amp;amp;embed=true&amp;amp;showmedia=false" sandbox="allow-scripts allow-same-origin allow-popups" style="border: none;" height="162" width="640" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;h3 id="alfred-paid-for-advanced-features"&gt;Alfred (Paid for advanced features)&lt;/h3&gt;&lt;p&gt;&lt;a href='https://www.alfredapp.com/'&gt;Alfred&lt;/a&gt; is an application launcher and productivity tool.&lt;/p&gt;&lt;p&gt;I use it to launch applications, search things, and run shell commands.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/alfred.png" alt="alfred usage screenshot" /&gt;&lt;/p&gt;&lt;h3 id="vim"&gt;Vim&lt;/h3&gt;&lt;p&gt;Using Vim, you can avoid using the mouse while writing or coding.&lt;/p&gt;&lt;p&gt;Vim is not an easy application since it requires lots of time investment, but it's worth it if you plan to use your laptop for a long time.&lt;/p&gt;&lt;p&gt;If you haven’t started using Vim due to its steep learning curve, trying Vim plugins in your editor or IDE can be a good start.&lt;/p&gt;&lt;p&gt;Once you get used to Vim key mappings, you'll be surprised by how many applications support them.&lt;/p&gt;&lt;p&gt;If you're already using Vim and want to go to the next level, my previous article &lt;a href='https://iamsang.com/en/2022/04/13/vimrc/'&gt;Learnings after 500 commits to my vimrc&lt;/a&gt; might be interesting to you.&lt;/p&gt;&lt;h3 id="iterm2-shell-and-command-line-tools"&gt;iTerm2, shell, and command line tools&lt;/h3&gt;&lt;p&gt;Once you get used to shell scripts and command line tools, you can ditch many applications that require you to use the mouse.&lt;/p&gt;&lt;p&gt;For example, you can replace Postman with &lt;a href='https://httpie.io/'&gt;Httpie&lt;/a&gt;, and SourceTree with &lt;a href='https://jonas.github.io/tig/'&gt;tig&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="hammerspoon"&gt;Hammerspoon&lt;/h3&gt;&lt;p&gt;&lt;a href='https://www.hammerspoon.org/'&gt;Hammerspoon&lt;/a&gt; is an application that allows users to customize and automate their Mac using the Lua programming language.&lt;/p&gt;&lt;p&gt;I use Hammerspoon mainly for these purposes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Automatically arranging windows&lt;/li&gt;&lt;li&gt;Opening an application with a keyboard shortcut, specifically the last-used window of that application&lt;/li&gt;&lt;li&gt;Toggling Do Not Disturb, Wi-Fi, and Bluetooth based on certain conditions&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Hammerspoon isn't always stable, and the documentation is often unclear, but it provides powerful features that can't be easily replaced.&lt;/p&gt;&lt;p&gt;You can find my Hammerspoon configuration in &lt;a href='https://github.com/Sangdol/hammerspoon-config'&gt;this GitHub repository&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="applescripts"&gt;AppleScripts&lt;/h3&gt;&lt;p&gt;I don't like AppleScripts and never learned to write them properly, but it sometimes helps to automate things. The scripts I'll introduce here are written by someone else, and I tweaked them when needed.&lt;/p&gt;&lt;p&gt;I trigger these scripts with keyboard shortcuts using BetterTouchTool.&lt;/p&gt;&lt;h4 id="un-minimize-windows"&gt;Un-minimize windows&lt;/h4&gt;&lt;p&gt;Un-minimizing a window takes a few steps, and there's no built-in keyboard shortcut.&lt;/p&gt;&lt;p&gt;I use this script to un-minimize the lastly minimized window of the currently focused application (&lt;a href='https://gist.github.com/Sangdol/bff520b39778e268aef45a7f592596aa'&gt;gist&lt;/a&gt;).&lt;/p&gt;&lt;h3 id="jxa-javascript-for-automation"&gt;JXA (JavaScript for Automation)&lt;/h3&gt;&lt;p&gt;&lt;a href='https://developer.apple.com/library/archive/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html'&gt;JXA&lt;/a&gt; is a JavaScript-based alternative to AppleScript. Apple introduced it long ago, but the documentation is horrible, so writing a decent script isn't easy.&lt;/p&gt;&lt;p&gt;Thankfully, a JavaScript library, &lt;a href='https://github.com/sindresorhus/run-jxa'&gt;run-jxa&lt;/a&gt;, allows you to run JXA from a node application.&lt;/p&gt;&lt;h4 id="reminders-jxa"&gt;Reminders JXA&lt;/h4&gt;&lt;p&gt;&lt;a href='https://github.com/Sangdol/reminders-jxa'&gt;Reminders JXA&lt;/a&gt; is a script that I wrote to use with Alfred. It doesn't have many features, but it does one thing well.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/alfred-reminders-jxa.png" alt="Alfred Reminder JXA usage screenshot" /&gt;&lt;/p&gt;&lt;p&gt;I used to use &lt;a href='https://github.com/surrealroad/alfred-reminders'&gt;an Alfred Reminders Workflow&lt;/a&gt; to add new items to Reminders, but it was too laggy, so I decided to write my own Workflow.&lt;/p&gt;</description></item><item><title>Learnings after 500 commits to my vimrc</title><link>https://iamsang.com/en/2022/04/13/vimrc</link><pubDate>Wed, 13 Apr 2022 21:55:00 +0200</pubDate><description>&lt;p&gt;Last winter, on a Saturday, I decided to tweak &lt;a href='https://github.com/Sangdol/vimrc/'&gt;my vimrc&lt;/a&gt;. I'd been putting it off for a long time since I felt spending time on improving and cleaning up vimrc was too luxurious; it'd be fun, but it wouldn't pay back the invested time.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/vimrc.png" alt="vimrc comic" /&gt;&lt;/p&gt;&lt;p&gt;This time I determined to do myself a favor and enjoy spending a day or two working on my vimrc.&lt;/p&gt;&lt;p&gt;I ended up spending more than three months and making around 500 commits to my vimrc, and I still work on it from time to time &amp;ndash; I didn't intend it, but coincidentally it's precisely 500 commits when I try to publish this article.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/500-commits-2.png" alt="500 commits" /&gt;&lt;/p&gt;&lt;p&gt;I've learned more than I'd learned in the past ten years during this time.&lt;/p&gt;&lt;p&gt;It was a fun and frustrating journey. I want to share what I've learned along the way and how happy I am now.&lt;/p&gt;&lt;h3 id="table-of-contents"&gt;Table of Contents&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='#what-i-have-done'&gt;What I have done&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='#books'&gt;Books&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#vimrcs'&gt;vimrcs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#vimscript'&gt;vimscript&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#how-to-troubleshoot-vim-and-plugins'&gt;How to troubleshoot vim and plugins&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='#showing-error-messages-with-message'&gt;Showing error messages with &lt;code&gt;:message&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#binary-search-to-find-a-problematic-plugin-or-code'&gt;Binary search to find a problematic plugin or code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#git-bisect-to-find-a-problematic-commit'&gt;&lt;code&gt;git bisect&lt;/code&gt; to find a problematic commit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#reading-plugin-documentation'&gt;Reading plugin documentation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#advanced-customizing-plugin-code'&gt;(Advanced) customizing plugin code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#searching-for-help'&gt;Searching for help&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#improved-productivity'&gt;Improved Productivity&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='#using-vim-as-a-file-manager-with-fzf-and-nvim-tree'&gt;Using vim as a File Manager with &lt;code&gt;fzf&lt;/code&gt; and &lt;code&gt;nvim-tree&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#nvim-terminal-as-tmux'&gt;nvim terminal as &lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#git'&gt;Git&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#coding'&gt;Coding&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href='#reflection'&gt;Reflection&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="what-i-have-done"&gt;What I have done&lt;/h3&gt;&lt;p&gt;I started by deleting unused plugins and configurations, and then I looked for plugins to fix and improve a few things that were bothering me.&lt;/p&gt;&lt;p&gt;Once I got started working on it, I couldn't stop. Learning how things work and improving my daily workflows with the new knowledge was too fun and exciting.&lt;/p&gt;&lt;h4 id="books"&gt;Books&lt;/h4&gt;&lt;p&gt;To better understand vim help pages and plugin documents, I started checking out books.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://www.oreilly.com/library/view/learning-the-vi/9781492078791/'&gt;Learning the vi and Vim Editors, 8th Edition&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href='https://learning.oreilly.com/library/view/practical-vim-2nd/9781680501629/'&gt;Practical Vim, 2nd Edition&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href='https://learning.oreilly.com/library/view/modern-vim/9781680506006/'&gt;Modern Vim&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;&lt;a href='https://learning.oreilly.com/library/view/mastering-vim/9781789341096/'&gt;Mastering Vim&lt;/a&gt;, and&lt;/li&gt;&lt;li&gt;&lt;a href='https://learning.oreilly.com/library/view/the-viml-primer/9781680500585/'&gt;The VimL Primer&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Especially, &lt;i&gt;Learning the vi and Vim Editors&lt;/i&gt; was good to brush up on my vim skills, and &lt;i&gt;The VimL Primer&lt;/i&gt; was helpful to learn vimscript.&lt;/p&gt;&lt;p&gt;I could access all the books freely thanks to the &lt;a href='https://www.oreilly.com/'&gt;O'Reilly membership&lt;/a&gt; that &lt;a href='https://jobs.zalando.com/de/'&gt;my employer&lt;/a&gt; provides me.&lt;/p&gt;&lt;p&gt;I checked out chapters that interested me instead of reading cover to cover. Reading books with the membership feels like listening to music with a music streaming service instead of having to buy CDs.&lt;/p&gt;&lt;h4 id="vimrcs"&gt;vimrcs&lt;/h4&gt;&lt;p&gt;I read a few awesome guys' vimrc, such as&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://github.com/junegunn/dotfiles/blob/master/vimrc'&gt;Junegunn&lt;/a&gt;, who wrote &lt;a href='https://github.com/junegunn/vim-plug'&gt;Plug&lt;/a&gt; and &lt;a href='https://github.com/junegunn/fzf.vim'&gt;fzf&lt;/a&gt;, and&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/wookayin/dotfiles/'&gt;wookayin&lt;/a&gt;, who wrote &lt;a href='https://github.com/wookayin/gpustat'&gt;gpustat&lt;/a&gt; and happens to be my former co-worker.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I learned many things from the books and vimrcs, but I still often had to read help pages and Stack Overflow threads to achieve what I wanted.&lt;/p&gt;&lt;h4 id="vimscript"&gt;vimscript&lt;/h4&gt;&lt;p&gt;I learned that Vimscript is not that hard once you're good with vim.&lt;/p&gt;&lt;p&gt;When I learn a new programming language, I start writing tests with it. This method is called Test-Driven Learning.&lt;/p&gt;&lt;p&gt;Writing test code is an excellent way to learn a programming language because&lt;/p&gt;&lt;ol&gt;&lt;li&gt;You learn the testing framework of a language in the early stage.&lt;/li&gt;&lt;li&gt;You learn by writing working code.&lt;/li&gt;&lt;li&gt;You have working documentation.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;a href='https://github.com/junegunn/vader.vim'&gt;Vader&lt;/a&gt; is a vimscript testing framework that is written by Junegunn. This is my Test-Driven Learning project using Vader: &lt;a href='https://github.com/Sangdol/vimscript-test-driven-learning'&gt;Github project&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I wrote a vim plugin &lt;a href='https://github.com/Sangdol/mintabline.vim/'&gt;Mintabline&lt;/a&gt; to solve a problem that Neovim doesn't show the tabline properly for terminal buffers.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/mintablinev2.png" alt="mintabline screenshot" /&gt;&lt;/p&gt;&lt;p&gt;I feel powerful after learning vimscript.&lt;/p&gt;&lt;h3 id="how-to-troubleshoot-vim-and-plugins"&gt;How to troubleshoot vim and plugins&lt;/h3&gt;&lt;p&gt;I used to spend hours and days to find out the reason for a vim issue, but now It usually takes no more than 30 minutes using the methods that I'll introduce soon.&lt;/p&gt;&lt;p&gt;Knowing how to fix issues is the key to utilizing vim to its full power &amp;ndash; which is valid for any other technology.&lt;/p&gt;&lt;p&gt;I used to keep my plugin list lean to avoid randomly happening errors and slowness; I often didn't know where I should start to troubleshoot a problem.&lt;/p&gt;&lt;p&gt;I've tried tens of plugins for the past few months and faced loads of issues; it sometimes took a few weeks to resolve.&lt;/p&gt;&lt;p&gt;Vim plugins are powerful since they can control vim without having to reside in a sandbox or container, but this makes it harder to debug an issue.&lt;/p&gt;&lt;h4 id="showing-error-messages-with-message"&gt;Showing error messages with &lt;code&gt;:message&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;When you face an issue, the first thing you should do is to read error messages carefully, but an error message could quickly disappear when you do some actions in vim. In this case, you can use the &lt;code&gt;:message&lt;/code&gt; command to bring the message back.&lt;/p&gt;&lt;p&gt;However, it's impossible to easily copy the message or have the result window open while troubleshooting. You can load messages into a buffer using this function to tackle this problem (&lt;a href='https://vim.fandom.com/wiki/Append_output_of_an_external_command'&gt;source wiki&lt;/a&gt;).&lt;/p&gt;&lt;pre&gt;&lt;code class="vim"&gt;function! TabMessage&amp;#40;cmd&amp;#41;
  redir =&amp;gt; message
  silent execute a:cmd
  redir END
  if empty&amp;#40;message&amp;#41;
    echoerr &amp;quot;no output&amp;quot;
  else
    tabnew
    setlocal buftype=nofile bufhidden=wipe noswapfile nobuflisted nomodified
    silent put=message
  endif
endfunction

command! -nargs=+ -complete=command TabMessage call TabMessage&amp;#40;&amp;lt;q-args&amp;gt;&amp;#41;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once you have the code in your vimrc you can open a buffer with messages like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="vim"&gt;:TabMessage message
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or simply&lt;pre&gt;&lt;code class="vim"&gt;:TabMessage mes
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;You can use this function not only for messages but also for any other commands. For example, you will get a buffer list in a new buffer when you run this:&lt;/p&gt;&lt;pre&gt;&lt;code class="vim"&gt;:TabMessage ls
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="binary-search-to-find-a-problematic-plugin-or-code"&gt;Binary search to find a problematic plugin or code&lt;/h4&gt;&lt;p&gt;You can try a manual binary search when it's not possible to find the root cause by just reading error messages, which is usually the case.&lt;/p&gt;&lt;p&gt;With this approach, you can search for problematic code by commenting out plugins, functions, or options &amp;ndash; half of the code at a time to make it efficient.&lt;/p&gt;&lt;p&gt;To make this task even easier, I've modularized my vimrc (&lt;a href='https://github.com/Sangdol/vimrc/blob/master/vimrc'&gt;code link&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/vimrc-diagram.png" alt="vimrc diagram" /&gt;&lt;/p&gt;&lt;p&gt;I can quickly turn on and off a specific module with this structure.&lt;/p&gt;&lt;p&gt;These would be steps to debug:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Disable modules or code by deleting or commenting out.&lt;/li&gt;&lt;li&gt;Run vim (in a separate terminal or window).&lt;/li&gt;&lt;li&gt;See if it's fixed.&lt;/li&gt;&lt;li&gt;Go to Step 1 if it's not fixed.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This approach can be applied to any issue when there's no clue.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/binary-search-in-practice-en.png" alt="binary search in practice comic" /&gt;&lt;/p&gt;&lt;h4 id="git-bisect-to-find-a-problematic-commit"&gt;&lt;code&gt;git bisect&lt;/code&gt; to find a problematic commit&lt;/h4&gt;&lt;p&gt;&lt;code&gt;git bisect&lt;/code&gt; is another way to perform a binary search to pinpoint the cause of an issue.&lt;/p&gt;&lt;p&gt;It works like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="sh"&gt;# Start git bisect
$ git bisect start

# Tell Git that the current commit is bad
$ git bisect bad

# Say, 100 commits ago it was good
$ git bisect good HEAD&amp;#126;100

# Git starts bisecting.
# Run vim and see if the current commit is good
# and tell Git.
$ git bisect good

# Run this until git pinpoints
# the problematic commit.
$ git bisect bad

# Finish git bisect:
$ git bisect reset
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It takes only 7 trials for 100 commits (&lt;code&gt;math.log&amp;#40;100, 2&amp;#41; ≈ 6.65&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;I prefer this approach to the previous one since it requires less manual work, although I have to check out &lt;a href='https://iamsang.com/blog/2014/03/02/git-bisect/'&gt;my Korean blog post about &lt;code&gt;git bisect&lt;/code&gt;&lt;/a&gt; whenever I run it to recall the commands for each step.&lt;/p&gt;&lt;h4 id="reading-plugin-documentation"&gt;Reading plugin documentation&lt;/h4&gt;&lt;p&gt;Surprisingly, reading documentation often works. You can first check out the vim help document of the plugin and see if it has relevant information.&lt;/p&gt;&lt;p&gt;If the plugin doesn't have a help document, visit the GitHub page of the plugin and see if there are any related issues.&lt;/p&gt;&lt;p&gt;To quickly open the GitHub page of a Plug line in vimrc, I use a function and command similar to this:&lt;/p&gt;&lt;pre&gt;&lt;code class="vim"&gt;function! s:open&amp;#95;plug&amp;#95;gh&amp;#40;&amp;#41;
  let line = getline&amp;#40;'.'&amp;#41;
  let line = trim&amp;#40;line&amp;#41;
  let plug&amp;#95;regex = '\vPlug &amp;#91;''&amp;quot;&amp;#93;&amp;#40;.{-}&amp;#41;&amp;#91;''&amp;quot;&amp;#93;.&amp;#42;'
  let path = substitute&amp;#40;line, plug&amp;#95;regex, '\1', ''&amp;#41;
  let url = 'https://github.com/' .. path
  exec &amp;quot;!open '&amp;quot;..url..&amp;quot;'&amp;quot;
endfunction

nnoremap &amp;lt;Leader&amp;gt;op :call &amp;lt;SID&amp;gt;open&amp;#95;plug&amp;#95;gh&amp;#40;&amp;#41;&amp;lt;CR&amp;gt;&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, if you run the function on the line below, vim will open the GitHub page of &lt;code&gt;fzf.vim&lt;/code&gt; in the browser.&lt;pre&gt;&lt;code class="vim"&gt;Plug 'junegunn/fzf.vim'
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h4 id="advanced-customizing-plugin-code"&gt;(Advanced) customizing plugin code&lt;/h4&gt;&lt;p&gt;If you can't find any meaningful information from the documentation, you can check out the plugin's code. A vim package manager downloads plugin files into your machine, so it's easy to explore the files.&lt;/p&gt;&lt;p&gt;I have a mapping to find installed plugin files quickly with &lt;code&gt;fzf&lt;/code&gt; since I do it often.&lt;/p&gt;&lt;pre&gt;&lt;code class="vim"&gt;nnoremap &amp;lt;leader&amp;gt;fpl :FZF &amp;#126;/.vim/plugged&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can try fixing the issue directly in the downloaded files and see if it's fixed by reloading plugins or rerunning vim.&lt;/p&gt;&lt;p&gt;Sometimes I had to fix issues only for my environment. For example, the &lt;a href='https://github.com/moll/vim-bbye'&gt;vim-bbye&lt;/a&gt; plugin and the &lt;a href='https://github.com/Asheq/close-buffers.vim'&gt;close-buffer&lt;/a&gt; plugin conflict, but I wanted to use both. I just &lt;a href='https://github.com/Sangdol/vim-bbye'&gt;forked vim-bbye&lt;/a&gt; and deleted the conflicting code.&lt;/p&gt;&lt;h4 id="searching-for-help"&gt;Searching for help&lt;/h4&gt;&lt;p&gt;Lastly, you can look for help in a few places.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;GitHub&lt;/li&gt;&lt;li&gt;Discord&lt;/li&gt;&lt;li&gt;Gitter&lt;/li&gt;&lt;li&gt;Stack Overflow&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I once struggled with an issue with &lt;a href='https://github.com/Olical/conjure'&gt;Conjure&lt;/a&gt;. I thought asking and waiting for an answer would take too long, but it turned out that it was a quicker way to solve the issue.&lt;/p&gt;&lt;p&gt;Looking for a Discord community is another way. I use &lt;a href='https://github.com/scalameta/coc-metals'&gt;coc-metals&lt;/a&gt; for Scala and was able to get help from &lt;a href='https://discord.gg/mZkhURPznE'&gt;the Discord server&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There are fantastic plugin maintainers out there.&lt;/p&gt;&lt;p&gt;Stack Overflow can be helpful as well. Once I even found out the answer to my issue while writing a question.&lt;/p&gt;&lt;h3 id="improved-productivity"&gt;Improved Productivity&lt;/h3&gt;&lt;p&gt;I once made a joke saying that I'll reach a break-even point for the time investment that I made if I write code until 80. That's an exaggeration, but it'll take a long time if I only calculate the saved seconds to recover the time investment.&lt;/p&gt;&lt;p&gt;But, &lt;a href='https://www.johndcook.com/blog/2015/12/22/automate-to-save-mental-energy-not-time/'&gt;we automate not to save time but to save mental energy&lt;/a&gt;; I can try more things with the same time and energy, which reduces problem-solving time.&lt;/p&gt;&lt;p&gt;And, I'm going to write code until after 80 anyway.&lt;/p&gt;&lt;h4 id="using-vim-as-a-file-manager-with-fzf-and-nvim-tree"&gt;Using vim as a File Manager with &lt;code&gt;fzf&lt;/code&gt; and &lt;code&gt;nvim-tree&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;I've tried file managers like &lt;a href='https://github.com/ranger/ranger'&gt;ranger&lt;/a&gt; and &lt;a href='https://github.com/gokcehan/lf'&gt;lf&lt;/a&gt;, but I did not use them due to a few issues.&lt;/p&gt;&lt;p&gt;After I started using vim as a file manager with &lt;a href='https://github.com/junegunn/fzf.vim'&gt;fzf&lt;/a&gt; and &lt;a href='https://github.com/kyazdani42/nvim-tree.lua'&gt;nvim-tree&lt;/a&gt;, I realized that this is the file manager that I've been looking for. I can move around and search for tens of projects easily.&lt;/p&gt;&lt;p&gt;&lt;iframe id="reddit-embed" src="https://www.redditmedia.com/r/neovim/comments/ph7l41/such_a_powerful_tool/?ref_source=embed&amp;amp;ref=share&amp;amp;embed=true" sandbox="allow-scripts allow-same-origin allow-popups" style="border: none;" height="413" width="640" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;h4 id="nvim-terminal-as-tmux"&gt;nvim terminal as &lt;code&gt;tmux&lt;/code&gt;&lt;/h4&gt;&lt;p&gt;I haven't been using &lt;code&gt;tmux&lt;/code&gt; or &lt;code&gt;screen&lt;/code&gt; since they have conflicting keyboard shortcuts with command-line keyboard shortcuts.&lt;/p&gt;&lt;p&gt;When I needed to split a window and open a new session, I could do it with iTerm2 shortcuts. This approach has downsides, but worked okay for me.&lt;/p&gt;&lt;p&gt;With nvim, you can use terminals with customized mappings. Also, it's much easier to search, move around, and copy terminal outputs within nvim terminals.&lt;/p&gt;&lt;h4 id="git"&gt;Git&lt;/h4&gt;&lt;p&gt;I've been using &lt;a href='https://github.com/jonas/tig'&gt;tig&lt;/a&gt; and the command-line git client with lots of shell aliases and functions.&lt;/p&gt;&lt;p&gt;I'm now using &lt;a href='https://github.com/tpope/vim-fugitive'&gt;vim-fugitive&lt;/a&gt; with &lt;a href='https://github.com/tpope/vim-rhubarb'&gt;vim-rhubarb&lt;/a&gt;, &lt;a href='https://github.com/rhysd/git-messenger.vim'&gt;git-messenger&lt;/a&gt;, &lt;a href='https://github.com/junegunn/gv.vim'&gt;gv&lt;/a&gt;, fzf (again), and &lt;a href='https://github.com/mhinz/vim-signify'&gt;vim-signify&lt;/a&gt;. It took a long time to set things up and get used to them, but now the old ways feel ancient.&lt;/p&gt;&lt;h4 id="coding"&gt;Coding&lt;/h4&gt;&lt;p&gt;These are plugins that I use to write code.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href='https://github.com/neoclide/coc.nvim'&gt;coc&lt;/a&gt; for language servers&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/scalameta/coc-metals'&gt;coc-metals&lt;/a&gt; for Scala&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/josa42/coc-lua'&gt;coc-lua&lt;/a&gt; for Lua&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/Olical/conjure'&gt;conjure&lt;/a&gt; for Clojure&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/numirias/semshi'&gt;semshi&lt;/a&gt; for Python&lt;/li&gt;&lt;li&gt;&lt;a href='https://github.com/nvim-treesitter/nvim-treesitter'&gt;tree-sitter&lt;/a&gt; for code highlights&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I didn't have many chances to write a large amount of code using vim after I set up these, but they are at least helpful in writing scripts and navigating codebases.&lt;/p&gt;&lt;p&gt;It wasn't always easy to set things up. I spent weeks learning, customizing, and troubleshooting when I started using &lt;code&gt;coc-metals&lt;/code&gt; and &lt;code&gt;conjure&lt;/code&gt;. I faced a Lua version issue when I tried using &lt;code&gt;coc-lua&lt;/code&gt;. Nothing was free but they were worth it.&lt;/p&gt;&lt;p&gt;I've put the plugins for coding in a separate vimrc module (&lt;a href='https://github.com/Sangdol/vimrc/blob/master/vim/rc/devplugins.vim'&gt;devplugins.vim&lt;/a&gt;) so that I can exclude them in the server environment.&lt;/p&gt;&lt;h3 id="reflection"&gt;Reflection&lt;/h3&gt;&lt;p&gt;The most successful people do not have the most productive development environment.&lt;/p&gt;&lt;p&gt;Once I started working on this, I didn't want to do anything else. Sometimes I was obsessed with minor improvements that wouldn't affect my productivity. Still, I think I'm far from mastering vim, and there are tons of things that I can try to tweak my productivity.&lt;/p&gt;&lt;p&gt;I learned a lot even from the effort that didn't work out, but it's essential to know the cost I spend on improving productivity &amp;ndash; if I want to be genuinely productive.&lt;/p&gt;&lt;p&gt;&lt;img src="https://iamsang.com/img/vimrc-40.png" alt="40 years" /&gt;&lt;/p&gt;</description></item><item><title>(Comic) TCP people, UDP people</title><link>https://iamsang.com/en/2022/04/12/tcp-udp</link><pubDate>Tue, 12 Apr 2022 22:53:00 +0200</pubDate><description>&lt;p&gt;&lt;img src="https://iamsang.com/img/tcp-udp-en.png" alt="(Comic) TCP people, UDP people" /&gt;&lt;/p&gt;</description></item><item><title>(Comic) Legacy Code</title><link>https://iamsang.com/en/2021/12/05/legacy-code</link><pubDate>Sun, 05 Dec 2021 17:20:06 +0100</pubDate><description>&lt;p&gt;&lt;img src="https://iamsang.com/img/git-blame-en.png" alt="(Comic) Legacy Code" /&gt;&lt;/p&gt;</description></item></channel></rss>