<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Santosh Manoharan</title><link>https://santoshmano.com/</link><description>Recent content on Santosh Manoharan</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Santosh Manoharan</copyright><lastBuildDate>Sat, 15 Nov 2025 23:35:34 -0800</lastBuildDate><atom:link href="https://santoshmano.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Debugging Process Hangs on Mac: A Systematic Approach</title><link>https://santoshmano.com/blog/debugging-process-hangs-on-mac/</link><pubDate>Mon, 10 Nov 2025 10:00:00 -0800</pubDate><guid>https://santoshmano.com/blog/debugging-process-hangs-on-mac/</guid><description>&lt;p>I ran into a deadlock recently while testing Claude Code. Running &lt;code>/mcp reconnect playwright&lt;/code> in a project without Playwright configured would show an error, then immediately freeze the entire session. Couldn&amp;rsquo;t type, Escape did nothing - had to &lt;code>kill -9&lt;/code> it.&lt;/p>
&lt;p>This seemed like a good opportunity to practice systematic debugging and document the process. Here&amp;rsquo;s how I tracked down the root cause.&lt;/p>
&lt;h2 id="the-problem">The Problem
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>Command:&lt;/strong> &lt;code>/mcp reconnect playwright&lt;/code>&lt;/li>
&lt;li>&lt;strong>Response:&lt;/strong> &lt;code>✘ Failed to reconnect to playwright&lt;/code> / &lt;code>Error: MCP server &amp;quot;playwright&amp;quot; not found&lt;/code>&lt;/li>
&lt;li>&lt;strong>Result:&lt;/strong> Complete freeze, no recovery possible&lt;/li>
&lt;/ul>
&lt;h2 id="reproducing-the-issue">Reproducing the Issue
&lt;/h2>&lt;p>Before diving into debugging, I needed to confirm this wasn&amp;rsquo;t a one-off fluke. I killed the frozen process and tried again:&lt;/p>
&lt;ol>
&lt;li>Open a fresh Claude session&lt;/li>
&lt;li>Navigate to a project without Playwright configured&lt;/li>
&lt;li>Run &lt;code>/mcp reconnect playwright&lt;/code>&lt;/li>
&lt;li>Wait for error message&lt;/li>
&lt;li>Try to type anything → frozen&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Result:&lt;/strong> 100% reproducible. Same freeze every time.&lt;/p>
&lt;p>This is critical. If you can&amp;rsquo;t reproduce a bug, you&amp;rsquo;re mostly guessing. Reproducibility means:&lt;/p>
&lt;ul>
&lt;li>You can test your hypothesis&lt;/li>
&lt;li>You can verify your fix&lt;/li>
&lt;li>You can provide clear steps in a bug report&lt;/li>
&lt;/ul>
&lt;p>One-off hangs? Document what you saw, but don&amp;rsquo;t spend hours debugging something that might never happen again.&lt;/p>
&lt;h2 id="finding-the-hanging-process">Finding the Hanging Process
&lt;/h2>&lt;p>I had multiple Claude sessions running in tmux panes. First problem: which process was actually stuck?&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ps aux &lt;span class="p">|&lt;/span> grep claude
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This gave me several PIDs. But which one was frozen? I needed to match the PID to the working directory:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">lsof -p &lt;span class="m">12061&lt;/span> -p &lt;span class="m">36125&lt;/span> -p &lt;span class="m">44674&lt;/span> -p &lt;span class="m">48811&lt;/span> &lt;span class="p">|&lt;/span> grep cwd
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Output showed PID 48811 was in the &lt;code>aisystemsprimer&lt;/code> directory - that&amp;rsquo;s where I reproduced the bug. Found it.&lt;/p>
&lt;h2 id="first-attempt-usr2-signal">First Attempt: USR2 Signal
&lt;/h2>&lt;p>My initial instinct was to get a diagnostic report using Node.js&amp;rsquo;s built-in signal handler:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">kill&lt;/span> -USR2 &lt;span class="m">48811&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This killed the process outright instead of generating a report. Makes sense in retrospect - if the event loop is deadlocked, signal handlers can&amp;rsquo;t execute. The process can&amp;rsquo;t respond to anything.&lt;/p>
&lt;h2 id="getting-a-stack-trace">Getting a Stack Trace
&lt;/h2>&lt;p>On macOS, &lt;code>sample&lt;/code> is the right tool for this. It profiles a process without disturbing it:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">sample &lt;span class="m">48811&lt;/span> &lt;span class="m">5&lt;/span> -file ~/stack_trace.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The &lt;code>-file&lt;/code> flag saves output to a file. The &lt;code>5&lt;/code> means sample for 5 seconds.&lt;/p>
&lt;p>The stack trace showed the main thread stuck here:&lt;/p>
&lt;pre tabindex="0">&lt;code>+ 3913 uv__io_poll (in libuv.1.0.0.dylib) + 724
+ 3913 kevent (in libsystem_kernel.dylib) + 8
&lt;/code>&lt;/pre>&lt;p>The event loop was blocked in &lt;code>kevent()&lt;/code>, waiting for I/O that would never arrive. Classic deadlock pattern.&lt;/p>
&lt;h2 id="what-was-it-waiting-for">What Was It Waiting For?
&lt;/h2>&lt;p>Time to check file descriptors:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">lsof -p &lt;span class="m">48811&lt;/span> &lt;span class="p">|&lt;/span> grep PIPE
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Output:&lt;/p>
&lt;pre tabindex="0">&lt;code>node 48811 sandman 13 PIPE 0xac44d11643cbe7d8 16384 -&amp;gt;0x301027970e85d0dd
node 48811 sandman 14 PIPE 0x301027970e85d0dd 16384 -&amp;gt;0xac44d11643cbe7d8
&lt;/code>&lt;/pre>&lt;p>Two open pipes. These are typically used for IPC (inter-process communication) with child processes. But was there a child process?&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ps -o pid,ppid,command &lt;span class="p">|&lt;/span> awk &lt;span class="s1">&amp;#39;$2 == 48811&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Nothing. No child process.&lt;/p>
&lt;p>The pipes were opened for communication with a child that never spawned. The main thread was waiting on I/O that would never arrive because the other end didn&amp;rsquo;t exist.&lt;/p>
&lt;h2 id="checking-debug-logs">Checking Debug Logs
&lt;/h2>&lt;p>Claude Code keeps debug logs in &lt;code>~/.claude/debug/&lt;/code>. I needed to find the log for this session:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">grep -l &lt;span class="s2">&amp;#34;tmp.48811&amp;#34;&lt;/span> ~/.claude/debug/*.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Found: &lt;code>6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">tail -100 ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Last entries:&lt;/p>
&lt;pre tabindex="0">&lt;code>[DEBUG] Getting matching hook commands for SubagentStop with query: undefined
[DEBUG] Found 0 hook matchers in settings
[DEBUG] AutoUpdaterWrapper: Installation type: npm-global
&lt;/code>&lt;/pre>&lt;p>Then I searched for MCP-related activity:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">grep -i &lt;span class="s2">&amp;#34;mcp\|reconnect\|playwright&amp;#34;&lt;/span> ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Zero results. The &lt;code>/mcp reconnect&lt;/code> command was never logged, which means the hang happened before the event loop could process the next iteration.&lt;/p>
&lt;h2 id="comparing-with-a-working-session">Comparing With a Working Session
&lt;/h2>&lt;p>I checked a working session&amp;rsquo;s logs where Playwright MCP was properly configured:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">tail -100 ~/.claude/debug/7928bf05-1443-4731-ba34-50369be48ec9.txt &lt;span class="p">|&lt;/span> grep -i mcp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;pre tabindex="0">&lt;code>[DEBUG] MCP server &amp;#34;playwright&amp;#34;: Successfully connected to stdio server in 637ms
[DEBUG] MCP server &amp;#34;playwright&amp;#34;: Connection established with capabilities: {...}
&lt;/code>&lt;/pre>&lt;p>Clear difference: working sessions complete the entire connection flow.&lt;/p>
&lt;h2 id="root-cause">Root Cause
&lt;/h2>&lt;p>Connecting the evidence:&lt;/p>
&lt;ol>
&lt;li>Error message displays correctly (&amp;ldquo;MCP server not found&amp;rdquo;)&lt;/li>
&lt;li>Despite the error, code attempts to connect anyway&lt;/li>
&lt;li>Opens pipes for IPC with the would-be child process&lt;/li>
&lt;li>Child process spawn fails (silently)&lt;/li>
&lt;li>Main thread blocks on &lt;code>kevent()&lt;/code> waiting for I/O from non-existent child&lt;/li>
&lt;li>No timeout implemented&lt;/li>
&lt;li>&lt;strong>Deadlock&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>The &lt;code>/mcp reconnect&lt;/code> command doesn&amp;rsquo;t validate server existence before attempting connection. It allocates resources (pipes) then blocks indefinitely waiting for a process that never started.&lt;/p>
&lt;h2 id="collecting-evidence">Collecting Evidence
&lt;/h2>&lt;p>I organized everything for the bug report:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mkdir ~/claude_hang_bug_report
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Hanging session log&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cp ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> ~/claude_hang_bug_report/hanging_session_log.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Stack trace&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cp ~/stack_trace.txt ~/claude_hang_bug_report/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Working session for comparison&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cp ~/.claude/debug/7928bf05-1443-4731-ba34-50369be48ec9.txt &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> ~/claude_hang_bug_report/working_session_log.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Full lsof output&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">lsof -p &lt;span class="m">48811&lt;/span> &amp;gt; ~/claude_hang_bug_report/lsof_full.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Process state&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ps -p &lt;span class="m">48811&lt;/span> -o pid,ppid,state,etime,%cpu,%mem,command &amp;gt; &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> ~/claude_hang_bug_report/process_state.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># System info&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">claude --version &amp;gt; ~/claude_hang_bug_report/system_info.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">node --version &amp;gt;&amp;gt; ~/claude_hang_bug_report/system_info.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sw_vers &amp;gt;&amp;gt; ~/claude_hang_bug_report/system_info.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="the-tools">The Tools
&lt;/h2>&lt;p>&lt;strong>&lt;code>ps&lt;/code>&lt;/strong> - Process listing. Shows PIDs, resource usage, process states. Essential for identifying which process is the problem.&lt;/p>
&lt;p>&lt;strong>&lt;code>lsof&lt;/code>&lt;/strong> - List open files. Critical for seeing file descriptors, sockets, pipes. In this case, revealed the open pipes with no corresponding child process.&lt;/p>
&lt;p>&lt;strong>&lt;code>sample&lt;/code>&lt;/strong> - macOS sampling profiler. Non-invasive stack trace collection. Showed exactly where the process was stuck (&lt;code>kevent()&lt;/code> in the event loop).&lt;/p>
&lt;p>&lt;strong>&lt;code>grep&lt;/code>&lt;/strong> - Pattern search through logs. Here, the &lt;em>absence&lt;/em> of &amp;ldquo;mcp&amp;rdquo; in logs was as informative as any error message.&lt;/p>
&lt;p>&lt;strong>Process tree analysis&lt;/strong> - &lt;code>ps -o pid,ppid,command&lt;/code> to check parent-child relationships. The missing child process was key evidence.&lt;/p>
&lt;h2 id="debug-flow">Debug Flow
&lt;/h2>&lt;p>Here&amp;rsquo;s the systematic approach:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
A[Process Hung] --> B{Can Reproduce?}
B -->|No| C[Document What Happened]
C --> D[Monitor for Recurrence]
B -->|Yes| E[Identify PID]
E --> F[Check Working Directory]
F --> G{Correct Process?}
G -->|No| E
G -->|Yes| H[Capture Stack Trace]
H --> I[Analyze File Descriptors]
I --> J[Check Process Tree]
J --> K[Review Debug Logs]
K --> L[Compare with Working Case]
L --> M[Form Hypothesis]
M --> N[Collect Evidence]
N --> O[Write Up Notes]
O --> P[File Bug Report]
style B fill:#fff3e0
style O fill:#e8f5e9
style P fill:#e8f5e9
&lt;/div>
&lt;/div>
&lt;p>Step by step:&lt;/p>
&lt;p>&lt;strong>0. Try to reproduce&lt;/strong> - Before deep investigation, confirm you can trigger the hang consistently&lt;/p>
&lt;ul>
&lt;li>If not reproducible: Document what happened, save any logs, move on&lt;/li>
&lt;li>If reproducible: Proceed with systematic debugging&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>1. Isolate the affected process&lt;/strong> - Use &lt;code>lsof&lt;/code> to verify working directory&lt;/p>
&lt;ul>
&lt;li>Multiple processes running? Match PID to the right directory&lt;/li>
&lt;li>&lt;code>lsof -p PID1 -p PID2 | grep cwd&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. Capture state non-invasively&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>sample PID duration&lt;/code> for stack trace&lt;/li>
&lt;li>&lt;code>lsof -p PID&lt;/code> for file descriptors&lt;/li>
&lt;li>&lt;code>ps -o pid,ppid,command&lt;/code> for process tree&lt;/li>
&lt;li>Don&amp;rsquo;t use &lt;code>kill -USR2&lt;/code> on a hung process - it may kill it instead&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>3. Analyze what you captured&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Stack trace → where it&amp;rsquo;s stuck (&lt;code>kevent&lt;/code>)&lt;/li>
&lt;li>File descriptors → what it&amp;rsquo;s waiting for (pipes)&lt;/li>
&lt;li>Process tree → missing child process&lt;/li>
&lt;li>Logs → when it stopped (before command execution)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>4. Compare with working case&lt;/strong> - Identify where behavior diverges&lt;/p>
&lt;ul>
&lt;li>Run the command in a working scenario&lt;/li>
&lt;li>Note what happens differently&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>5. Form hypothesis&lt;/strong> - Connect evidence to root cause&lt;/p>
&lt;ul>
&lt;li>Event loop blocked waiting for child process that never spawned&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>6. Write up notes&lt;/strong> - Document your findings before losing context&lt;/p>
&lt;ul>
&lt;li>Steps to reproduce&lt;/li>
&lt;li>Evidence collected (stack traces, file descriptors, logs)&lt;/li>
&lt;li>Hypothesis about root cause&lt;/li>
&lt;li>Screenshots or terminal output if helpful&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>7. File bug report&lt;/strong> - Share your investigation with maintainers&lt;/p>
&lt;ul>
&lt;li>Include reproduction steps&lt;/li>
&lt;li>Attach diagnostic data&lt;/li>
&lt;li>Link to your notes or GitHub issue&lt;/li>
&lt;/ul>
&lt;h2 id="key-lessons">Key Lessons
&lt;/h2>&lt;p>&lt;strong>Reproducibility is everything&lt;/strong> - Don&amp;rsquo;t spend hours debugging something you can&amp;rsquo;t reproduce. If it happens once and never again, document it and move on. If you can reproduce it reliably, you can debug it systematically.&lt;/p>
&lt;p>&lt;strong>Write up notes before you forget&lt;/strong> - Context fades fast. After collecting evidence, write down your findings immediately: reproduction steps, stack traces, hypothesis. Future you (or the maintainer reading your bug report) will thank you.&lt;/p>
&lt;p>&lt;strong>Verify assumptions early&lt;/strong> - I initially guessed which process was hanging based on timing. Using &lt;code>lsof&lt;/code> to check the working directory confirmed it immediately.&lt;/p>
&lt;p>&lt;strong>Use non-invasive tools first&lt;/strong> - &lt;code>kill -USR2&lt;/code> killed the process. &lt;code>sample&lt;/code> captured what I needed without disturbing anything.&lt;/p>
&lt;p>&lt;strong>Absence is information&lt;/strong> - No MCP log entries told me the command never executed, which narrowed down where the bug occurred.&lt;/p>
&lt;p>&lt;strong>Compare working vs broken&lt;/strong> - Seeing what &lt;em>should&lt;/em> happen makes it much clearer what went wrong.&lt;/p>
&lt;p>&lt;strong>Stack traces reveal mechanisms&lt;/strong> - Seeing &lt;code>kevent()&lt;/code> immediately suggested an event loop issue, which directed me toward IPC investigation.&lt;/p>
&lt;p>&lt;strong>File descriptors don&amp;rsquo;t lie&lt;/strong> - Open pipes with no child process was definitive proof the spawn failed.&lt;/p>
&lt;p>&lt;strong>Collect before killing&lt;/strong> - Once you kill the process, all evidence disappears. Get stack traces and state snapshots while it&amp;rsquo;s frozen.&lt;/p>
&lt;h2 id="the-github-issue">The GitHub Issue
&lt;/h2>&lt;p>I filed a detailed bug report including:&lt;/p>
&lt;ul>
&lt;li>Exact reproduction steps&lt;/li>
&lt;li>Stack trace showing &lt;code>kevent()&lt;/code> deadlock&lt;/li>
&lt;li>File descriptor analysis (open pipes, no child process)&lt;/li>
&lt;li>Debug log evidence (command never logged)&lt;/li>
&lt;li>Working session comparison for contrast&lt;/li>
&lt;li>Root cause hypothesis with supporting evidence&lt;/li>
&lt;li>All collected diagnostic data as attachments&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Impact:&lt;/strong> High severity - complete session loss, no recovery possible, 100% reproducible&lt;/p>
&lt;p>&lt;strong>Root cause:&lt;/strong> Missing validation check + no timeout in MCP reconnection logic&lt;/p>
&lt;h2 id="quick-reference">Quick Reference
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Tool&lt;/th>
&lt;th>Purpose&lt;/th>
&lt;th>Example&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>ps&lt;/code>&lt;/td>
&lt;td>List processes&lt;/td>
&lt;td>&lt;code>ps aux | grep process_name&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>lsof&lt;/code>&lt;/td>
&lt;td>View open files/descriptors&lt;/td>
&lt;td>&lt;code>lsof -p PID | grep PIPE&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>sample&lt;/code>&lt;/td>
&lt;td>Get stack trace&lt;/td>
&lt;td>&lt;code>sample PID 5 -file trace.txt&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>grep&lt;/code>&lt;/td>
&lt;td>Search logs&lt;/td>
&lt;td>&lt;code>grep -i &amp;quot;error&amp;quot; logfile.txt&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>kill&lt;/code>&lt;/td>
&lt;td>Send signals&lt;/td>
&lt;td>&lt;code>kill -USR2 PID&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;p>What started as a frustrating hang turned into an interesting debugging exercise. The key was systematic evidence collection and understanding what each tool reveals about process state. When you&amp;rsquo;re stuck with a hung process, these macOS tools give you everything you need to figure out why.&lt;/p>
&lt;p>Filed: &lt;a class="link" href="https://github.com/anthropics/claude-code/issues/11385" target="_blank" rel="noopener"
>https://github.com/anthropics/claude-code/issues/11385&lt;/a>&lt;/p></description></item><item><title>Flowchart Symbols and How to Use Them</title><link>https://santoshmano.com/blog/flowchart-symbols-guide/</link><pubDate>Mon, 13 Jan 2025 11:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/flowchart-symbols-guide/</guid><description>&lt;p>I&amp;rsquo;ve drawn many flowcharts over my career. A well-drawn flowchart can explain a complicated workflow in seconds. But you need to know the right symbols.&lt;/p>
&lt;p>Here&amp;rsquo;s a practical guide to flowchart symbols and how to actually use them.&lt;/p>
&lt;h2 id="why-flowcharts-matter">Why Flowcharts Matter
&lt;/h2>&lt;p>Before we get into symbols, here&amp;rsquo;s why flowcharts are still relevant:&lt;/p>
&lt;p>&lt;strong>They force clarity.&lt;/strong> If you can&amp;rsquo;t draw a flowchart of your process, you don&amp;rsquo;t fully understand it.&lt;/p>
&lt;p>&lt;strong>They reveal problems.&lt;/strong> Dead ends, infinite loops, missing error handling - all obvious in a flowchart.&lt;/p>
&lt;p>&lt;strong>They communicate fast.&lt;/strong> A flowchart shows the flow in a way that paragraphs of text never will.&lt;/p>
&lt;p>I&amp;rsquo;ve used flowcharts to:&lt;/p>
&lt;ul>
&lt;li>Understand operating system flows and dig deeper into how things work&lt;/li>
&lt;li>Debug production incidents&lt;/li>
&lt;li>Explain algorithms (especially recursive ones)&lt;/li>
&lt;/ul>
&lt;h2 id="the-essential-symbols">The Essential Symbols
&lt;/h2>&lt;h3 id="1-terminal--terminator">1. Terminal / Terminator
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Rounded rectangle (oval)
&lt;strong>Purpose:&lt;/strong> Start and end points of your flow&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start]) --> End([End])
&lt;/div>
&lt;/div>
&lt;p>Use clear labels: &amp;ldquo;Start&amp;rdquo;, &amp;ldquo;Begin&amp;rdquo;, &amp;ldquo;End&amp;rdquo;, &amp;ldquo;Exit&amp;rdquo;. This tells readers where the flow begins and where it terminates.&lt;/p>
&lt;h3 id="2-process--rectangle">2. Process / Rectangle
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Rectangle
&lt;strong>Purpose:&lt;/strong> An action, operation, or process step&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Process1[Read configuration file]
Process1 --> Process2[Parse JSON]
Process2 --> Process3[Initialize database]
Process3 --> End([End])
&lt;/div>
&lt;/div>
&lt;p>This is your workhorse symbol. Use verbs: &amp;ldquo;Calculate total&amp;rdquo;, &amp;ldquo;Send email&amp;rdquo;, &amp;ldquo;Save to database&amp;rdquo;.&lt;/p>
&lt;h3 id="3-decision--conditional">3. Decision / Conditional
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Diamond
&lt;strong>Purpose:&lt;/strong> A question with Yes/No or True/False outcomes&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Check{File exists?}
Check -->|Yes| Read[Read file]
Check -->|No| Error[Show error]
Read --> End([End])
Error --> End
&lt;/div>
&lt;/div>
&lt;p>Always label the arrows coming out. &amp;ldquo;Yes/No&amp;rdquo;, &amp;ldquo;True/False&amp;rdquo;, or specific conditions like &amp;ldquo;&amp;gt;100&amp;rdquo; and &amp;ldquo;≤100&amp;rdquo;.&lt;/p>
&lt;h3 id="4-data-io">4. Data (I/O)
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Parallelogram
&lt;strong>Purpose:&lt;/strong> Input or output of data&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Input[/Enter username and password/]
Input --> Validate{Valid credentials?}
Validate -->|Yes| Output[/Display dashboard/]
Validate -->|No| Error[/Show error message/]
Output --> End([End])
Error --> End
&lt;/div>
&lt;/div>
&lt;p>Use this for user input, file reads, API responses, or any data coming in or going out.&lt;/p>
&lt;h3 id="5-document">5. Document
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Rectangle with wavy bottom
&lt;strong>Purpose:&lt;/strong> A document or report generated&lt;/p>
&lt;p>In Mermaid, we approximate this with special notation:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Process[Generate monthly report]
Process --> Doc[/Report PDF/]
Doc --> Email[Email to stakeholders]
Email --> End([End])
&lt;/div>
&lt;/div>
&lt;p>Use this when your process creates or reads a specific document.&lt;/p>
&lt;h3 id="6-subroutine--predefined-process">6. Subroutine / Predefined Process
&lt;/h3>&lt;p>&lt;strong>Shape:&lt;/strong> Rectangle with double vertical lines
&lt;strong>Purpose:&lt;/strong> A process defined elsewhere (function call, subprocess)&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Input[/Get user input/]
Input --> Validate[[Validate input]]
Validate --> Process[Process data]
Process --> Save[[Save to database]]
Save --> End([End])
&lt;/div>
&lt;/div>
&lt;p>The double brackets &lt;code>[[...]]&lt;/code> in Mermaid create this style. Use it for reusable processes or functions that are detailed in separate flowcharts.&lt;/p>
&lt;h2 id="real-world-examples">Real-World Examples
&lt;/h2>&lt;h3 id="example-1-user-login-flow">Example 1: User Login Flow
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([User visits login page])
Start --> Input[/Enter email and password/]
Input --> Submit[Click login button]
Submit --> Validate{Credentials valid?}
Validate -->|No| Error[/Display error message/]
Error --> Input
Validate -->|Yes| Check{2FA enabled?}
Check -->|No| Dashboard[/Redirect to dashboard/]
Check -->|Yes| TwoFactor[/Prompt for 2FA code/]
TwoFactor --> EnterCode[/Enter 2FA code/]
EnterCode --> VerifyCode{Code valid?}
VerifyCode -->|No| Error2[/Show error/]
Error2 --> TwoFactor
VerifyCode -->|Yes| Dashboard
Dashboard --> End([End])
&lt;/div>
&lt;/div>
&lt;p>This shows a complete authentication flow with error handling and conditional 2FA.&lt;/p>
&lt;h3 id="example-2-deployment-process">Example 2: Deployment Process
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start deployment])
Start --> Tests[[Run test suite]]
Tests --> TestPass{Tests passed?}
TestPass -->|No| Notify[/Notify team/]
Notify --> End([Deployment failed])
TestPass -->|Yes| Build[Build Docker image]
Build --> Push[Push to registry]
Push --> Deploy[Deploy to staging]
Deploy --> Smoke{Smoke tests passed?}
Smoke -->|No| Rollback[Rollback deployment]
Rollback --> Notify
Smoke -->|Yes| Prod{Deploy to production?}
Prod -->|No| End2([End])
Prod -->|Yes| ProdDeploy[Deploy to production]
ProdDeploy --> Monitor[Monitor metrics]
Monitor --> Success([Deployment complete])
&lt;/div>
&lt;/div>
&lt;p>This shows a typical CI/CD pipeline with testing gates and rollback logic.&lt;/p>
&lt;h3 id="example-3-e-commerce-checkout">Example 3: E-commerce Checkout
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([User clicks checkout])
Start --> Cart{Cart empty?}
Cart -->|Yes| Error[/Show error message/]
Error --> End([Return to shop])
Cart -->|No| Address[/Enter shipping address/]
Address --> Payment[/Enter payment info/]
Payment --> Validate[[Validate payment]]
Validate --> Valid{Payment valid?}
Valid -->|No| Retry{Retry?}
Retry -->|Yes| Payment
Retry -->|No| Cancel([Order cancelled])
Valid -->|Yes| Process[Process order]
Process --> Inventory{Items in stock?}
Inventory -->|No| Backorder[Create backorder]
Inventory -->|Yes| Ship[Create shipping label]
Backorder --> Notify[/Email customer/]
Ship --> Confirm[/Send confirmation email/]
Confirm --> Success([Order complete])
Notify --> Success
&lt;/div>
&lt;/div>
&lt;p>This shows decision points, error handling, and multiple end states.&lt;/p>
&lt;h3 id="example-4-api-request-handler">Example 4: API Request Handler
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Receive API request])
Start --> Auth{Valid auth token?}
Auth -->|No| Unauth[/Return 401 Unauthorized/]
Unauth --> End([End])
Auth -->|Yes| Validate[[Validate request body]]
Validate --> Valid{Schema valid?}
Valid -->|No| BadReq[/Return 400 Bad Request/]
BadReq --> End
Valid -->|Yes| Check{Resource exists?}
Check -->|No| NotFound[/Return 404 Not Found/]
NotFound --> End
Check -->|Yes| Process[Process request]
Process --> Error{Error occurred?}
Error -->|Yes| ServerErr[/Return 500 Server Error/]
ServerErr --> End
Error -->|No| Success[/Return 200 with data/]
Success --> End
&lt;/div>
&lt;/div>
&lt;p>This shows how to document API logic with proper HTTP status codes.&lt;/p>
&lt;h3 id="example-5-recursive-function">Example 5: Recursive Function
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([calculateFactorial n])
Start --> Base{n == 0 or n == 1?}
Base -->|Yes| Return1[Return 1]
Return1 --> End([End])
Base -->|No| Recurse[[calculateFactorial n-1]]
Recurse --> Multiply[Multiply result by n]
Multiply --> Return2[Return result]
Return2 --> End
&lt;/div>
&lt;/div>
&lt;p>Recursion is easier to understand with a flowchart. The &lt;code>[[...]]&lt;/code> notation shows the recursive call.&lt;/p>
&lt;h2 id="tips-for-drawing-better-flowcharts">Tips for Drawing Better Flowcharts
&lt;/h2>&lt;h3 id="1-keep-it-simple">1. Keep It Simple
&lt;/h3>&lt;p>Don&amp;rsquo;t try to fit your entire system into one flowchart. Break complex flows into multiple diagrams.&lt;/p>
&lt;p>&lt;strong>Bad:&lt;/strong> One massive flowchart with 50 boxes
&lt;strong>Good:&lt;/strong> Main flowchart with subroutines, each detailed separately&lt;/p>
&lt;h3 id="2-use-consistent-spacing">2. Use Consistent Spacing
&lt;/h3>&lt;p>Align your boxes. Keep arrows clean. Messy flowcharts are hard to read.&lt;/p>
&lt;h3 id="3-label-everything">3. Label Everything
&lt;/h3>&lt;p>Every decision diamond needs labels on its outputs. Every process box needs a clear action.&lt;/p>
&lt;p>&lt;strong>Bad:&lt;/strong> Diamond with &amp;ldquo;Check&amp;rdquo; and arrows with no labels
&lt;strong>Good:&lt;/strong> Diamond with &amp;ldquo;User age &amp;gt;= 18?&amp;rdquo; and arrows labeled &amp;ldquo;Yes&amp;rdquo; and &amp;ldquo;No&amp;rdquo;&lt;/p>
&lt;h3 id="4-show-error-paths">4. Show Error Paths
&lt;/h3>&lt;p>Don&amp;rsquo;t just show the happy path. Show what happens when things fail.&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> API[Call external API]
API --> Success{API success?}
Success -->|Yes| Process[Process response]
Success -->|No| Retry{Retry &lt; 3?}
Retry -->|Yes| Wait[Wait 1 second]
Wait --> API
Retry -->|No| Error[/Log error and alert/]
Process --> End([End])
Error --> End
&lt;/div>
&lt;/div>
&lt;p>This shows retry logic and error handling - critical for production systems.&lt;/p>
&lt;h3 id="5-avoid-spaghetti">5. Avoid Spaghetti
&lt;/h3>&lt;p>If your flowchart has arrows going everywhere, it&amp;rsquo;s too complex. Simplify your logic or break it into sub-processes.&lt;/p>
&lt;h3 id="6-use-color-sparingly">6. Use Color Sparingly
&lt;/h3>&lt;p>In Mermaid, you can add color for emphasis:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Process[Normal process]
Process --> Critical[Critical security check]
Critical --> End([End])
style Critical fill:#ff6b6b,stroke:#c92a2a,color:#fff
&lt;/div>
&lt;/div>
&lt;p>But don&amp;rsquo;t overdo it. Color should highlight important nodes, not decorate everything.&lt;/p>
&lt;h2 id="common-flowchart-patterns">Common Flowchart Patterns
&lt;/h2>&lt;h3 id="the-retry-loop">The Retry Loop
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Try[Attempt operation]
Try --> Success{Success?}
Success -->|Yes| Done([End])
Success -->|No| Count{Retry count &lt; max?}
Count -->|Yes| Inc[Increment retry count]
Inc --> Try
Count -->|No| Fail([Give up])
&lt;/div>
&lt;/div>
&lt;p>Use this pattern for network calls, database operations, or any unreliable external dependency.&lt;/p>
&lt;h3 id="the-validation-chain">The Validation Chain
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> V1{Check 1 valid?}
V1 -->|No| E1[/Error: Check 1 failed/]
E1 --> End([End])
V1 -->|Yes| V2{Check 2 valid?}
V2 -->|No| E2[/Error: Check 2 failed/]
E2 --> End
V2 -->|Yes| V3{Check 3 valid?}
V3 -->|No| E3[/Error: Check 3 failed/]
E3 --> End
V3 -->|Yes| Success[Process data]
Success --> End
&lt;/div>
&lt;/div>
&lt;p>Use this when you have multiple validation checks that must all pass.&lt;/p>
&lt;h3 id="the-batch-processor">The Batch Processor
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start([Start])
Start --> Get[Get next item]
Get --> More{Items remaining?}
More -->|No| Done([End])
More -->|Yes| Process[Process item]
Process --> Error{Error?}
Error -->|Yes| Log[Log error]
Error -->|No| Get
Log --> Get
&lt;/div>
&lt;/div>
&lt;p>Use this for processing queues, files, or any batch operation.&lt;/p>
&lt;h2 id="creating-flowcharts-with-mermaid">Creating Flowcharts with Mermaid
&lt;/h2>&lt;p>All the diagrams in this article are written in Mermaid syntax. Here&amp;rsquo;s a quick reference:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
A([Start]) --> B[Process]
B --> C{Decision?}
C -->|Yes| D[/Output/]
C -->|No| E[[Subroutine]]
D --> F([End])
E --> F
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Syntax:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>graph TD&lt;/code> - Top to bottom flow (use &lt;code>LR&lt;/code> for left to right)&lt;/li>
&lt;li>&lt;code>([...])&lt;/code> - Rounded rectangle (terminator)&lt;/li>
&lt;li>&lt;code>[...]&lt;/code> - Rectangle (process)&lt;/li>
&lt;li>&lt;code>{...}&lt;/code> - Diamond (decision)&lt;/li>
&lt;li>&lt;code>[/..../]&lt;/code> - Parallelogram (input/output)&lt;/li>
&lt;li>&lt;code>[[...]]&lt;/code> - Subroutine (double border)&lt;/li>
&lt;li>&lt;code>--&amp;gt;&lt;/code> - Arrow&lt;/li>
&lt;li>&lt;code>--&amp;gt;|label|&lt;/code> - Labeled arrow&lt;/li>
&lt;/ul>
&lt;p>You can add these directly to markdown files and they&amp;rsquo;ll render in most modern documentation tools.&lt;/p>
&lt;h2 id="when-not-to-use-flowcharts">When Not to Use Flowcharts
&lt;/h2>&lt;p>Flowcharts aren&amp;rsquo;t always the right tool:&lt;/p>
&lt;p>&lt;strong>Use flowcharts for:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Algorithms and logic&lt;/li>
&lt;li>Process flows with decisions&lt;/li>
&lt;li>Troubleshooting guides&lt;/li>
&lt;li>Deployment procedures&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Don&amp;rsquo;t use flowcharts for:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>System architecture (use block diagrams or component diagrams)&lt;/li>
&lt;li>Data models (use ER diagrams)&lt;/li>
&lt;li>Time-based interactions (use sequence diagrams)&lt;/li>
&lt;li>Class relationships (use class diagrams)&lt;/li>
&lt;/ul>
&lt;h2 id="tools-for-drawing-flowcharts">Tools for Drawing Flowcharts
&lt;/h2>&lt;p>&lt;strong>Mermaid (my preference):&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Write flowcharts in text&lt;/li>
&lt;li>Version control friendly&lt;/li>
&lt;li>Renders in markdown&lt;/li>
&lt;li>Free and open source&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Lucidchart:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Drag-and-drop interface&lt;/li>
&lt;li>Good for non-technical users&lt;/li>
&lt;li>Collaboration features&lt;/li>
&lt;li>Paid (free tier limited)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Draw.io (diagrams.net):&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Free and open source&lt;/li>
&lt;li>Desktop or web-based&lt;/li>
&lt;li>Export to many formats&lt;/li>
&lt;li>More manual than Mermaid&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Graphviz:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Text-based like Mermaid&lt;/li>
&lt;li>Very powerful for complex graphs&lt;/li>
&lt;li>Steeper learning curve&lt;/li>
&lt;li>Great for automated diagram generation&lt;/li>
&lt;/ul>
&lt;h2 id="my-take">My Take
&lt;/h2>&lt;p>I still draw flowcharts regularly. When debugging a production issue, I&amp;rsquo;ll sketch the request flow to find where it&amp;rsquo;s breaking. When designing a new feature, I&amp;rsquo;ll flowchart the logic before writing code.&lt;/p>
&lt;p>The key is keeping them simple. One decision per diamond. One action per box. Clear labels. If your flowchart is too complex to fit on a screen, break it into smaller diagrams.&lt;/p>
&lt;p>And if you&amp;rsquo;re writing documentation, embed flowcharts directly in markdown using Mermaid. Your future self (and your teammates) will thank you.&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://mermaid.js.org/" target="_blank" rel="noopener"
>Mermaid Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://www.iso.org/standard/11955.html" target="_blank" rel="noopener"
>Flowchart Best Practices (ISO 5807)&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://app.diagrams.net/" target="_blank" rel="noopener"
>Draw.io&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://graphviz.org/" target="_blank" rel="noopener"
>Graphviz&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>&lt;strong>Related Posts:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/mermaid-diagram-test/" >Mermaid Diagram Test&lt;/a> - Examples of different Mermaid diagram types&lt;/li>
&lt;/ul></description></item><item><title>OpenGrok: Fast Source Code Browsing for Large Codebases</title><link>https://santoshmano.com/blog/opengrok-local-setup/</link><pubDate>Mon, 13 Jan 2025 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/opengrok-local-setup/</guid><description>&lt;p>A teammate introduced me to OpenGrok years ago when we were working on a large C codebase. ctags and cscope were great for navigating individual files, but sometimes you needed to search across the entire codebase, find all usages of a function, or trace how data structures evolved across different modules.&lt;/p>
&lt;p>That&amp;rsquo;s where OpenGrok came in. It&amp;rsquo;s a fast source code search and cross-reference engine that gives you a web interface to explore code. Think of it as Google for your codebase.&lt;/p>
&lt;h2 id="what-is-opengrok">What Is OpenGrok?
&lt;/h2>&lt;p>OpenGrok is an open-source code search engine originally developed at Sun Microsystems (now maintained by Oracle). It:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Indexes your entire codebase&lt;/strong> using Apache Lucene&lt;/li>
&lt;li>&lt;strong>Integrates with ctags&lt;/strong> for definitions and cross-references&lt;/li>
&lt;li>&lt;strong>Supports version control&lt;/strong> (Git, SVN, Perforce, Mercurial)&lt;/li>
&lt;li>&lt;strong>Provides a web UI&lt;/strong> for searching and browsing&lt;/li>
&lt;li>&lt;strong>Handles large codebases&lt;/strong> - scales well even with thousands of files&lt;/li>
&lt;/ul>
&lt;p>The killer feature: you can search for function definitions, usages, file paths, and even full-text search across your entire source tree in seconds.&lt;/p>
&lt;h2 id="why-use-opengrok-instead-of-grep">Why Use OpenGrok Instead of grep?
&lt;/h2>&lt;p>&lt;code>grep -r&lt;/code> works great for small projects. But when you&amp;rsquo;re dealing with a large codebase:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Speed&lt;/strong>: OpenGrok indexes once, searches instantly. grep re-scans every time.&lt;/li>
&lt;li>&lt;strong>Cross-references&lt;/strong>: OpenGrok uses ctags to show where functions are defined and called.&lt;/li>
&lt;li>&lt;strong>History&lt;/strong>: OpenGrok integrates with version control to show file history and blame.&lt;/li>
&lt;li>&lt;strong>Web UI&lt;/strong>: Share links to code with teammates. No need to SSH and navigate directories.&lt;/li>
&lt;/ul>
&lt;p>We ran OpenGrok on a shared server so the entire team could search the codebase from their browsers. But you can also run it locally for your own projects.&lt;/p>
&lt;h2 id="local-setup-on-macos">Local Setup on macOS
&lt;/h2>&lt;p>Here&amp;rsquo;s how to set up OpenGrok locally. This assumes you have Homebrew installed.&lt;/p>
&lt;h3 id="1-install-prerequisites">1. Install Prerequisites
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install Java (OpenGrok requires Java 11+)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew install openjdk@11
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install Universal Ctags (better than Exuberant Ctags)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew install universal-ctags
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Install Tomcat (servlet container to run OpenGrok)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew install tomcat
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="2-download-opengrok">2. Download OpenGrok
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Download latest OpenGrok release&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ~/Downloads
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">wget https://github.com/oracle/opengrok/releases/download/1.13.3/opengrok-1.13.3.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tar -xzf opengrok-1.13.3.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Move to /usr/local&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo mv opengrok-1.13.3 /usr/local/opengrok
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="3-set-up-directory-structure">3. Set Up Directory Structure
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create OpenGrok data directories&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo mkdir -p /var/opengrok/&lt;span class="o">{&lt;/span>src,data,etc&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set permissions (adjust username as needed)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo chown -R &lt;span class="nv">$USER&lt;/span> /var/opengrok
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="4-configure-opengrok">4. Configure OpenGrok
&lt;/h3>&lt;p>Create a configuration file at &lt;code>/var/opengrok/etc/configuration.xml&lt;/code> (OpenGrok will generate this on first run, but you can customize it):&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Index your source code&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Replace /path/to/your/code with actual path&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">OPENGROK_TOMCAT_BASE&lt;/span>&lt;span class="o">=&lt;/span>/usr/local/opt/tomcat/libexec &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span>java -jar /usr/local/opengrok/lib/opengrok.jar &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -c /usr/local/bin/ctags &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -s /var/opengrok/src &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -d /var/opengrok/data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -H -P -S -G &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -W /var/opengrok/etc/configuration.xml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="5-deploy-to-tomcat">5. Deploy to Tomcat
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Copy OpenGrok web app to Tomcat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo cp /usr/local/opengrok/lib/source.war /usr/local/opt/tomcat/libexec/webapps/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Create context file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cat &amp;gt; /usr/local/opt/tomcat/libexec/conf/Catalina/localhost/source.xml &lt;span class="s">&amp;lt;&amp;lt;EOF
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&amp;lt;Context path=&amp;#34;/source&amp;#34;&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s"> &amp;lt;Parameter name=&amp;#34;CONFIGURATION&amp;#34; value=&amp;#34;/var/opengrok/etc/configuration.xml&amp;#34; override=&amp;#34;false&amp;#34;/&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&amp;lt;/Context&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="6-start-tomcat">6. Start Tomcat
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start Tomcat server&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">catalina start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check it&amp;#39;s running&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tail -f /usr/local/opt/tomcat/libexec/logs/catalina.out
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="7-copy-your-code-and-index">7. Copy Your Code and Index
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Copy or symlink your source code to OpenGrok&amp;#39;s src directory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cp -R /path/to/your/code /var/opengrok/src/myproject
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Or use symlink&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ln -s /path/to/your/code /var/opengrok/src/myproject
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Index the code&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">java -jar /usr/local/opengrok/lib/opengrok.jar &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -c /usr/local/bin/ctags &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -s /var/opengrok/src &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -d /var/opengrok/data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -H -P -S -G &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -W /var/opengrok/etc/configuration.xml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="8-access-opengrok">8. Access OpenGrok
&lt;/h3>&lt;p>Open your browser to:&lt;/p>
&lt;pre tabindex="0">&lt;code>http://localhost:8080/source
&lt;/code>&lt;/pre>&lt;p>You should see the OpenGrok web interface with your indexed code.&lt;/p>
&lt;h2 id="using-opengrok">Using OpenGrok
&lt;/h2>&lt;p>Once it&amp;rsquo;s running, here&amp;rsquo;s what you can do:&lt;/p>
&lt;h3 id="full-text-search">Full Text Search
&lt;/h3>&lt;p>Search for any text across all files. Great for finding error messages, string literals, or comments.&lt;/p>
&lt;h3 id="definition-search">Definition Search
&lt;/h3>&lt;p>Find where a function or variable is defined. OpenGrok uses ctags for this.&lt;/p>
&lt;h3 id="symbol-search">Symbol Search
&lt;/h3>&lt;p>Find all references to a symbol (function calls, variable usage).&lt;/p>
&lt;h3 id="path-search">Path Search
&lt;/h3>&lt;p>Search for files by name or path pattern.&lt;/p>
&lt;h3 id="history-view">History View
&lt;/h3>&lt;p>See git/svn history for any file, with blame annotations.&lt;/p>
&lt;h3 id="cross-reference">Cross-Reference
&lt;/h3>&lt;p>Click on any function or variable to see its definition and all usages.&lt;/p>
&lt;h2 id="indexing-large-codebases">Indexing Large Codebases
&lt;/h2>&lt;p>For large codebases, indexing can take a while. Some tips:&lt;/p>
&lt;p>&lt;strong>Exclude directories you don&amp;rsquo;t need:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">java -jar /usr/local/opengrok/lib/opengrok.jar &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -c /usr/local/bin/ctags &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -s /var/opengrok/src &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -d /var/opengrok/data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -i &lt;span class="s1">&amp;#39;*.o&amp;#39;&lt;/span> -i &lt;span class="s1">&amp;#39;*.a&amp;#39;&lt;/span> -i &lt;span class="s1">&amp;#39;build/*&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -H -P -S -G &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -W /var/opengrok/etc/configuration.xml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Incremental indexing:&lt;/strong>
After the initial index, you can run incremental updates:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">java -jar /usr/local/opengrok/lib/opengrok.jar &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -c /usr/local/bin/ctags &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -s /var/opengrok/src &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -d /var/opengrok/data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -H -P -S -G
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Automate with cron:&lt;/strong>
Set up a cron job to reindex nightly:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Add to crontab&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span> * * * java -jar /usr/local/opengrok/lib/opengrok.jar -c /usr/local/bin/ctags -s /var/opengrok/src -d /var/opengrok/data -H -P -S -G
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="version-control-integration">Version Control Integration
&lt;/h2>&lt;p>OpenGrok can show file history and annotations if your code is in version control.&lt;/p>
&lt;p>&lt;strong>Git:&lt;/strong>
OpenGrok auto-detects Git repositories. Just make sure &lt;code>.git&lt;/code> is present.&lt;/p>
&lt;p>&lt;strong>Perforce:&lt;/strong>
If you&amp;rsquo;re using Perforce, configure P4 environment variables:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">P4PORT&lt;/span>&lt;span class="o">=&lt;/span>perforce:1666
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">P4USER&lt;/span>&lt;span class="o">=&lt;/span>your-username
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">P4CLIENT&lt;/span>&lt;span class="o">=&lt;/span>your-workspace
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>SVN:&lt;/strong>
OpenGrok auto-detects SVN repositories. Make sure &lt;code>.svn&lt;/code> is present.&lt;/p>
&lt;h2 id="command-reference">Command Reference
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start Tomcat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">catalina start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Stop Tomcat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">catalina stop
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Reindex all code&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">java -jar /usr/local/opengrok/lib/opengrok.jar &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -c /usr/local/bin/ctags &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -s /var/opengrok/src &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -d /var/opengrok/data &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -H -P -S -G &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span> -W /var/opengrok/etc/configuration.xml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check Tomcat logs&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tail -f /usr/local/opt/tomcat/libexec/logs/catalina.out
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Check OpenGrok logs&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tail -f /var/opengrok/data/logs/opengrok.log
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="opengrok-vs-modern-alternatives">OpenGrok vs. Modern Alternatives
&lt;/h2>&lt;p>Since I started using OpenGrok, newer tools have emerged:&lt;/p>
&lt;p>&lt;strong>Sourcegraph&lt;/strong> - Cloud-hosted code search with great UI. Free for public repos, paid for private.&lt;/p>
&lt;p>&lt;strong>GitHub Code Search&lt;/strong> - If your code is on GitHub, their built-in search is fast and integrates with PRs/issues.&lt;/p>
&lt;p>&lt;strong>grep.app&lt;/strong> - Web-based regex search across GitHub repos.&lt;/p>
&lt;p>&lt;strong>ripgrep&lt;/strong> - Blazing fast command-line search. No indexing, but searches fast enough for most projects.&lt;/p>
&lt;p>But OpenGrok still has advantages:&lt;/p>
&lt;ul>
&lt;li>Self-hosted (no cloud dependency)&lt;/li>
&lt;li>Works offline&lt;/li>
&lt;li>Handles any version control system&lt;/li>
&lt;li>Free and open source&lt;/li>
&lt;li>Battle-tested on massive codebases&lt;/li>
&lt;/ul>
&lt;h2 id="when-to-use-opengrok">When to Use OpenGrok
&lt;/h2>&lt;p>&lt;strong>Use OpenGrok if:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>You have a large codebase (100k+ lines)&lt;/li>
&lt;li>You want a web UI for code browsing&lt;/li>
&lt;li>You need to share code links with teammates&lt;/li>
&lt;li>You&amp;rsquo;re using Perforce or SVN (less tooling available)&lt;/li>
&lt;li>You want self-hosted search (no cloud)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Stick with simpler tools if:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Your codebase is small (use grep, ripgrep, or editor search)&lt;/li>
&lt;li>Your code is on GitHub (use GitHub&amp;rsquo;s search)&lt;/li>
&lt;li>You prefer command-line only (use ctags + cscope)&lt;/li>
&lt;/ul>
&lt;h2 id="my-take">My Take
&lt;/h2>&lt;p>OpenGrok was invaluable when working on large codebases. When debugging a production issue, I could search for an error message and instantly see every place it appeared in the codebase. When refactoring, I could find all callers of a function across multiple modules.&lt;/p>
&lt;p>For small projects, it&amp;rsquo;s overkill. But for large, complex codebases - especially legacy C/C++ code - OpenGrok is still one of the best tools available.&lt;/p>
&lt;p>If you&amp;rsquo;re working on a big project and find yourself constantly grepping for patterns or losing track of function calls, give OpenGrok a try. The initial setup takes an hour, but you&amp;rsquo;ll save that time back on the first day you use it.&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://github.com/oracle/opengrok" target="_blank" rel="noopener"
>OpenGrok GitHub&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://github.com/oracle/opengrok/wiki" target="_blank" rel="noopener"
>Official Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://github.com/universal-ctags/ctags" target="_blank" rel="noopener"
>Universal Ctags&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>&lt;strong>Related Posts:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/ctags-cscope-screen-my-first-ide/" >ctags, cscope, and Screen: My IDE for 12 Years&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/vim-commands-and-shell-vi-mode/" >Essential Vim Commands and Shell Vi Mode&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Example: Embedding PDFs in Hugo Posts</title><link>https://santoshmano.com/blog/pdf-embedding-example/</link><pubDate>Tue, 05 Nov 2024 10:00:00 -0800</pubDate><guid>https://santoshmano.com/blog/pdf-embedding-example/</guid><description>&lt;p>This is an example post showing different ways to embed PDF files in your Hugo blog posts.&lt;/p>
&lt;h2 id="setup">Setup
&lt;/h2>&lt;p>First, place your PDF file in the &lt;code>static/documents/&lt;/code> directory. For example:&lt;/p>
&lt;ul>
&lt;li>&lt;code>static/documents/resume.pdf&lt;/code>&lt;/li>
&lt;li>&lt;code>static/documents/whitepaper.pdf&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="method-1-simple-iframe-recommended">Method 1: Simple iframe (Recommended)
&lt;/h2>&lt;p>This is the most compatible method that works across all browsers:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">iframe&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/yourfile.pdf&amp;#34;&lt;/span> &lt;span class="na">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;100%&amp;#34;&lt;/span> &lt;span class="na">height&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;600px&amp;#34;&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;border: 1px solid #ccc; border-radius: 4px;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">iframe&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Example with actual file:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">iframe&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/resume.pdf&amp;#34;&lt;/span> &lt;span class="na">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;100%&amp;#34;&lt;/span> &lt;span class="na">height&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;600px&amp;#34;&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;border: 1px solid #ccc; border-radius: 4px;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">iframe&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="method-2-embed-tag">Method 2: Embed tag
&lt;/h2>&lt;p>Another approach using the embed tag:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">embed&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/yourfile.pdf&amp;#34;&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/pdf&amp;#34;&lt;/span> &lt;span class="na">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;100%&amp;#34;&lt;/span> &lt;span class="na">height&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;600px&amp;#34;&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;border: 1px solid #ccc; border-radius: 4px;&amp;#34;&lt;/span> &lt;span class="p">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="method-3-object-tag-with-fallback">Method 3: Object tag with fallback
&lt;/h2>&lt;p>This provides a download link for browsers that can&amp;rsquo;t display PDFs:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">object&lt;/span> &lt;span class="na">data&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/yourfile.pdf&amp;#34;&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/pdf&amp;#34;&lt;/span> &lt;span class="na">width&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;100%&amp;#34;&lt;/span> &lt;span class="na">height&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;600px&amp;#34;&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;border: 1px solid #ccc; border-radius: 4px;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>Your browser doesn&amp;#39;t support PDF viewing. &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">a&lt;/span> &lt;span class="na">href&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/yourfile.pdf&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>Download the PDF&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">a&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> to view it.&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">object&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="responsive-styling">Responsive Styling
&lt;/h2>&lt;p>You can make the PDF viewer responsive with better styling:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">div&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">iframe&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/documents/yourfile.pdf&amp;#34;&lt;/span> &lt;span class="na">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">iframe&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">div&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="live-demo">Live Demo
&lt;/h2>&lt;p>Here&amp;rsquo;s a working example with an actual embedded PDF:&lt;/p>
&lt;iframe src="https://santoshmano.com/documents/sample.pdf" width="100%" height="600px" style="border: 1px solid #ccc; border-radius: 4px;">
&lt;/iframe>
&lt;h2 id="how-to-use">How to Use
&lt;/h2>&lt;ol>
&lt;li>Place your PDF files in &lt;code>static/documents/&lt;/code> directory&lt;/li>
&lt;li>Reference them in your markdown as &lt;code>/documents/filename.pdf&lt;/code>&lt;/li>
&lt;li>Choose one of the methods above and paste the HTML code in your markdown&lt;/li>
&lt;li>Adjust width and height as needed&lt;/li>
&lt;/ol>
&lt;p>That&amp;rsquo;s it! The PDF will be embedded directly in your blog post and visitors can view it without downloading.&lt;/p></description></item><item><title>Using Mermaid Diagrams in Documentation</title><link>https://santoshmano.com/blog/mermaid-diagram-test/</link><pubDate>Fri, 25 Oct 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/mermaid-diagram-test/</guid><description>&lt;h2 id="from-ascii-art-to-mermaid">From ASCII Art to Mermaid
&lt;/h2>&lt;p>For the first 12 years of my career, most of my work was using a terminal and vi editor. Many of the design documents were simple text files, or just direclty documented in code. ASCII art was the to draw diagrams, and it was great. Simple illustrations. At one of the startups I worked at, we maintained all our design diagrams in text files—there was no other option. This wasn&amp;rsquo;t just a preference; it was the reality of working in Unix environments where everything was text-based, version-controlled, and had to work over SSH connections.&lt;/p>
&lt;p>I&amp;rsquo;d spend hours on &lt;a class="link" href="https://asciiflow.com" target="_blank" rel="noopener"
>asciiflow.com&lt;/a>, carefully drawing boxes and arrows with text characters,trying to make them look somewhat professional. The results were functional but fragile—one character misaligned and the whole diagram fell apart. Sharing them in markdown files or design docs worked, but editing them was always a pain.&lt;/p>
&lt;pre tabindex="0">&lt;code>+----------------+ +------------------+
| Browser |-----&amp;gt;| Web Server |
+----------------+ +------------------+
|
v
+-------------+
| Database |
+-------------+
&lt;/code>&lt;/pre>&lt;p>Recently, I discovered Mermaid, and it&amp;rsquo;s changed how I think about diagrams in documentation. Instead of drawing with characters, you write code that describes the diagram. The syntax is clean, the diagrams look professional, and best of all—they&amp;rsquo;re easy to edit and version control. Plus, they automatically adapt to light and dark themes on my blog.&lt;/p>
&lt;p>Here&amp;rsquo;s that same diagram in Mermaid:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph LR
Browser -->|HTTP| WebServer[Web Server]
WebServer --> Database
&lt;/div>
&lt;/div>
&lt;p>Let me show you what&amp;rsquo;s possible with Mermaid.&lt;/p>
&lt;h2 id="system-architecture-example">System Architecture Example
&lt;/h2>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TB
User[User Browser] -->|HTTPS| CDN[Cloudflare CDN]
CDN -->|Cache Miss| Netlify[Netlify Hosting]
Netlify -->|Static Files| Hugo[Hugo Generated Site]
Hugo -->|Markdown| Content[Content Files]
Hugo -->|Templates| Theme[Stack Theme]
Hugo -->|Assets| CSS[SCSS/CSS]
style User fill:#5fb878
style CDN fill:#f9a825
style Netlify fill:#00c7b7
style Hugo fill:#ff4088
&lt;/div>
&lt;/div>
&lt;h2 id="sequence-diagram-example">Sequence Diagram Example
&lt;/h2>&lt;p>Here&amp;rsquo;s how a typical request flows through the system:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">sequenceDiagram
participant User
participant CDN as Cloudflare CDN
participant Host as Netlify
participant Git as GitHub
User->>CDN: Request page
CDN->>CDN: Check cache
alt Cache Hit
CDN->>User: Return cached page
else Cache Miss
CDN->>Host: Request page
Host->>User: Return fresh page
CDN->>CDN: Cache page
end
Note over Git,Host: On git push
Git->>Host: Trigger build
Host->>Host: Run Hugo build
Host->>CDN: Invalidate cache
&lt;/div>
&lt;/div>
&lt;h2 id="flowchart-example">Flowchart Example
&lt;/h2>&lt;p>Decision flow for publishing content:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">flowchart TD
Start([Write Draft]) --> Review{Review Complete?}
Review -->|No| Edit[Make Edits]
Edit --> Review
Review -->|Yes| Diagrams{Add Diagrams?}
Diagrams -->|Yes| Mermaid[Create Mermaid Diagrams]
Mermaid --> Publish
Diagrams -->|No| Publish[Publish Post]
Publish --> Share[Share on Social Media]
Share --> End([Done])
style Start fill:#5fb878
style End fill:#5fb878
style Publish fill:#ff4088
&lt;/div>
&lt;/div>
&lt;h2 id="class-diagram-example">Class Diagram Example
&lt;/h2>&lt;p>For documenting system components:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">classDiagram
class BlogPost {
+String title
+String content
+Date published
+String[] tags
+String category
+render()
+publish()
}
class Diagram {
+String type
+String code
+render()
}
class Theme {
+String name
+loadCSS()
+loadJS()
}
BlogPost "1" --> "0..*" Diagram
BlogPost --> Theme
&lt;/div>
&lt;/div>
&lt;h2 id="git-graph-example">Git Graph Example
&lt;/h2>&lt;p>Visualizing branching and merging:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">gitGraph
commit id: "Initial commit"
commit id: "Add blog structure"
branch feature
checkout feature
commit id: "Add Mermaid support"
commit id: "Create About page"
checkout main
commit id: "Fix search bug"
checkout feature
commit id: "Test diagrams"
checkout main
merge feature
commit id: "Deploy to production"
&lt;/div>
&lt;/div>
&lt;h2 id="state-diagram-example">State Diagram Example
&lt;/h2>&lt;p>Perfect for modeling state machines and workflows:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">stateDiagram-v2
[*] --> Draft
Draft --> Review: Submit for review
Review --> Draft: Request changes
Review --> Approved: Approve
Approved --> Published: Publish
Published --> Archived: Archive
Archived --> [*]
Draft: Draft Post
Review: In Review
Approved: Approved
Published: Published
Archived: Archived
note right of Review
Editors review content
for quality and accuracy
end note
&lt;/div>
&lt;/div>
&lt;h2 id="entity-relationship-diagram">Entity Relationship Diagram
&lt;/h2>&lt;p>For documenting database schemas:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">erDiagram
USER ||--o{ POST : writes
USER ||--o{ COMMENT : makes
POST ||--o{ COMMENT : has
POST }o--o{ TAG : tagged_with
POST }o--|| CATEGORY : belongs_to
USER {
int id PK
string username
string email
datetime created_at
}
POST {
int id PK
int author_id FK
int category_id FK
string title
text content
datetime published_at
}
COMMENT {
int id PK
int user_id FK
int post_id FK
text content
datetime created_at
}
TAG {
int id PK
string name
}
CATEGORY {
int id PK
string name
}
&lt;/div>
&lt;/div>
&lt;h2 id="gantt-chart-example">Gantt Chart Example
&lt;/h2>&lt;p>Great for project planning and timelines:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">gantt
title Blog Migration Project
dateFormat YYYY-MM-DD
section Planning
Research static site generators :done, research, 2025-10-01, 7d
Choose Hugo and theme :done, choose, 2025-10-08, 3d
section Development
Set up Hugo project :done, setup, 2025-10-11, 2d
Migrate existing posts :done, migrate, 2025-10-13, 10d
Custom theme styling :done, styling, 2025-10-23, 5d
Add Mermaid support :active, mermaid, 2025-10-28, 5d
section Testing
Test on multiple devices :testing, 2025-11-02, 3d
Performance optimization :optimize, 2025-11-05, 4d
section Launch
Deploy to production :deploy, 2025-11-09, 1d
Monitor and fix issues :monitor, 2025-11-10, 7d
&lt;/div>
&lt;/div>
&lt;h2 id="wide-gantt-chart-example">Wide Gantt Chart Example
&lt;/h2>&lt;p>With AI-powered development, what used to take years now takes weeks. This 90-day sprint shows how horizontal scrolling helps visualize packed timelines:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">gantt
title AI-Accelerated Product Development Sprint (90 Days)
dateFormat YYYY-MM-DD
section Week 1-2: Discovery
Market Research with AI :done, 2025-01-01, 3d
Competitor Analysis :done, 2025-01-04, 2d
User Interviews :done, 2025-01-06, 3d
Requirements Doc with Claude :done, 2025-01-09, 2d
Technical Feasibility :done, 2025-01-11, 2d
section Week 3-4: Design
System Architecture :done, 2025-01-15, 3d
Database Schema Design :done, 2025-01-18, 2d
API Design :done, 2025-01-20, 2d
UI/UX Mockups :done, 2025-01-22, 3d
Design System Setup :done, 2025-01-25, 2d
Figma to Code :done, 2025-01-27, 2d
section Week 5-6: Backend Core
Project Scaffolding :active, 2025-02-01, 1d
Auth Service :active, 2025-02-02, 3d
User Management API :active, 2025-02-05, 3d
Database Migrations :active, 2025-02-08, 2d
API Gateway :2025-02-10, 2d
Logging &amp; Monitoring :2025-02-12, 2d
section Week 7-8: Frontend Core
React Setup with Vite :2025-02-15, 1d
Component Library :2025-02-16, 3d
Routing &amp; Navigation :2025-02-19, 2d
State Management :2025-02-21, 2d
Form Handling :2025-02-23, 2d
API Integration Layer :2025-02-25, 3d
section Week 9-10: Features Sprint 1
User Dashboard :2025-03-01, 3d
Profile Management :2025-03-04, 2d
Settings Page :2025-03-06, 2d
Search Functionality :2025-03-08, 3d
Notifications System :2025-03-11, 3d
Real-time Updates :2025-03-14, 2d
section Week 11-12: Features Sprint 2
Payment Integration :2025-03-18, 4d
Subscription Management :2025-03-22, 3d
Invoice Generation :2025-03-25, 2d
Analytics Dashboard :2025-03-27, 3d
Reporting Engine :2025-03-30, 3d
Data Export :2025-04-02, 2d
section Week 13-14: Advanced Features
AI Chat Integration :2025-04-05, 4d
File Upload &amp; Storage :2025-04-09, 3d
Image Processing :2025-04-12, 2d
Email Service :2025-04-14, 2d
SMS Notifications :2025-04-16, 2d
Webhook System :2025-04-18, 3d
section Week 15-16: Admin &amp; Security
Admin Dashboard :2025-04-22, 4d
User Management Panel :2025-04-26, 3d
Role-Based Access Control :2025-04-29, 3d
Security Audit :2025-05-02, 2d
GDPR Compliance :2025-05-04, 2d
Rate Limiting :2025-05-06, 2d
section Week 17-18: Testing
Unit Test Coverage :2025-05-10, 4d
Integration Tests :2025-05-14, 3d
E2E Tests with Playwright :2025-05-17, 3d
Performance Testing :2025-05-20, 2d
Security Testing :2025-05-22, 2d
Load Testing :2025-05-24, 2d
section Week 19-20: Polish &amp; Optimization
UI Polish :2025-05-28, 3d
Performance Optimization :2025-05-31, 3d
Bundle Size Reduction :2025-06-03, 2d
SEO Optimization :2025-06-05, 2d
Accessibility Audit :2025-06-07, 2d
Mobile Responsiveness :2025-06-09, 2d
section Week 21-22: Deployment
CI/CD Pipeline Setup :2025-06-13, 2d
Staging Deployment :2025-06-15, 2d
QA Testing :2025-06-17, 3d
Bug Fixes :2025-06-20, 3d
Production Deployment :2025-06-23, 2d
Monitoring Setup :2025-06-25, 2d
section Week 23-24: Launch
Beta User Onboarding :2025-06-29, 3d
Feedback Collection :2025-07-02, 3d
Quick Iterations :2025-07-05, 3d
Marketing Site :2025-07-08, 3d
Documentation :2025-07-11, 3d
Public Launch :2025-07-14, 1d
Post-Launch Support :2025-07-15, 7d
&lt;/div>
&lt;/div>
&lt;h2 id="pie-chart-example">Pie Chart Example
&lt;/h2>&lt;p>Useful for showing proportions and distributions:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">pie title Technology Stack Distribution
"Hugo (Go)" : 30
"JavaScript" : 25
"SCSS/CSS" : 20
"Markdown" : 15
"HTML Templates" : 10
&lt;/div>
&lt;/div>
&lt;h2 id="quadrant-chart-example">Quadrant Chart Example
&lt;/h2>&lt;p>For categorizing items across two dimensions:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">quadrantChart
title Blog Post Priority Matrix
x-axis Low Traffic --> High Traffic
y-axis Low Effort --> High Effort
quadrant-1 Plan Carefully
quadrant-2 Do First
quadrant-3 Maybe Later
quadrant-4 Quick Wins
"tmux tutorial": [0.8, 0.3]
"Vim shortcuts": [0.6, 0.2]
"System design series": [0.4, 0.9]
"Git tips": [0.7, 0.15]
"Mermaid diagrams": [0.3, 0.25]
"Career advice": [0.5, 0.7]
&lt;/div>
&lt;/div>
&lt;h2 id="how-to-use-mermaid">How to Use Mermaid
&lt;/h2>&lt;p>To add any of these diagrams to your markdown files, just use standard code blocks with &lt;code>mermaid&lt;/code> as the language:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="s">```mermaid
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&lt;/span>graph TD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[Start] --&amp;gt; B[Process]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C[End]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">```&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The diagrams automatically adjust to match your site&amp;rsquo;s theme—light or dark mode—which is something ASCII diagrams could never do.&lt;/p>
&lt;h2 id="why-i-switched">Why I Switched
&lt;/h2>&lt;p>Here&amp;rsquo;s what I appreciate about Mermaid over ASCII diagrams:&lt;/p>
&lt;p>&lt;strong>Version control friendly:&lt;/strong> Changing a diagram is as simple as editing a line of text. With ASCII art, any structural change meant redrawing half the diagram.&lt;/p>
&lt;p>&lt;strong>Consistent styling:&lt;/strong> All diagrams look professional and match each other. No more aligning boxes by hand or counting spaces.&lt;/p>
&lt;p>&lt;strong>Easy to edit:&lt;/strong> Want to add a new node? Just add a line. Want to change a relationship? Update the arrow. In ASCII, this meant shifting entire sections around.&lt;/p>
&lt;p>&lt;strong>Portable:&lt;/strong> The same Mermaid code works in GitHub, GitLab, Notion, and countless other tools. ASCII diagrams looked different everywhere depending on font rendering.&lt;/p>
&lt;p>&lt;strong>Maintainable:&lt;/strong> I can actually come back to a diagram six months later and understand how to update it. ASCII diagrams were write-only code.&lt;/p>
&lt;p>For quick sketches, I still use a whiteboard or pen and paper. But for anything that goes into documentation, Mermaid has completely replaced my ASCII diagram workflow.&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;p>If you want to try Mermaid:&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://mermaid.js.org/" target="_blank" rel="noopener"
>Mermaid Documentation&lt;/a> - Complete reference for all diagram types&lt;/li>
&lt;li>&lt;a class="link" href="https://mermaid.live/" target="_blank" rel="noopener"
>Mermaid Live Editor&lt;/a> - Interactive playground to test diagrams&lt;/li>
&lt;li>&lt;a class="link" href="https://mermaid.js.org/intro/syntax-reference.html" target="_blank" rel="noopener"
>Syntax Guide&lt;/a> - Quick syntax reference&lt;/li>
&lt;/ul>
&lt;p>The learning curve is minimal—if you can write markdown, you can write Mermaid diagrams.&lt;/p></description></item><item><title>Understanding Compound Interest</title><link>https://santoshmano.com/blog/compound-interest/</link><pubDate>Tue, 15 Oct 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/compound-interest/</guid><description>&lt;img src="https://santoshmano.com/images/plant-tree-compound-interest.jpg" alt="Featured image of post Understanding Compound Interest" />&lt;p>I remember opening my first PPF account in India and seeing &amp;ldquo;7.1% interest compounded annually.&amp;rdquo; I thought, &amp;ldquo;okay, 7.1% per year, simple enough.&amp;rdquo; But then I opened a money market fund in the US that said &amp;ldquo;4.5% compounded daily,&amp;rdquo; and suddenly I had questions. Why does compounding frequency matter? Is daily compounding really better than annual?&lt;/p>
&lt;p>Let me break this down with real examples.&lt;/p>
&lt;h2 id="what-is-compound-interest">What Is Compound Interest?
&lt;/h2>&lt;p>Think of compound interest as &amp;ldquo;interest on interest&amp;rdquo; - your money makes money, and then that new money also makes money.&lt;/p>
&lt;p>Here&amp;rsquo;s a simple example with $100 at 10% interest per year:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph LR
A["Year 0&lt;br/>$100"] --> B["Year 1&lt;br/>$110&lt;br/>(earned $10)"]
B --> C["Year 2&lt;br/>$121&lt;br/>(earned $11)"]
C --> D["Year 3&lt;br/>$133.10&lt;br/>(earned $12.10)"]
style A fill:#5fb878
style D fill:#5fb878
&lt;/div>
&lt;/div>
&lt;p>Notice how you earn more each year? That&amp;rsquo;s the snowball effect.&lt;/p>
&lt;h2 id="the-formula">The Formula
&lt;/h2>&lt;p>The compound interest formula is:&lt;/p>
&lt;p>$$A = P\left(1 + \frac{r}{n}\right)^{nt}$$&lt;/p>
&lt;p>Where:&lt;/p>
&lt;ul>
&lt;li>$A$ = final amount&lt;/li>
&lt;li>$P$ = principal (initial investment)&lt;/li>
&lt;li>$r$ = annual interest rate (as decimal, so 5% = 0.05)&lt;/li>
&lt;li>$n$ = number of times interest compounds per year&lt;/li>
&lt;li>$t$ = number of years&lt;/li>
&lt;/ul>
&lt;h2 id="how-we-get-this-formula">How We Get This Formula
&lt;/h2>&lt;p>Let&amp;rsquo;s derive it step by step. Say you start with amount $P$ and interest rate $r$ per year.&lt;/p>
&lt;p>&lt;strong>After Year 1:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>You earn interest: $P \times r$&lt;/li>
&lt;li>New amount: $P + P \times r = P(1 + r)$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>After Year 2:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>You now earn interest on $P(1 + r)$&lt;/li>
&lt;li>New amount: $P(1 + r) \times (1 + r) = P(1 + r)^2$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>After Year 3:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>New amount: $P(1 + r)^3$&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>After $t$ years:&lt;/strong>&lt;/p>
&lt;p>$$A = P(1 + r)^t$$&lt;/p>
&lt;p>That&amp;rsquo;s the basic formula for annual compounding!&lt;/p>
&lt;p>&lt;strong>What about compounding more frequently?&lt;/strong>&lt;/p>
&lt;p>If interest compounds $n$ times per year:&lt;/p>
&lt;ul>
&lt;li>Each period gives you $\frac{r}{n}$ interest&lt;/li>
&lt;li>In $t$ years, there are $n \times t$ periods&lt;/li>
&lt;li>So we get:&lt;/li>
&lt;/ul>
&lt;p>$$A = P\left(1 + \frac{r}{n}\right)^{nt}$$&lt;/p>
&lt;h2 id="compounding-frequencies-compared">Compounding Frequencies Compared
&lt;/h2>&lt;p>Let&amp;rsquo;s invest &lt;strong>$10,000 at 6% annual interest for 10 years&lt;/strong> and see how different compounding frequencies affect the outcome:&lt;/p>
&lt;h3 id="the-math">The Math
&lt;/h3>&lt;p>&lt;strong>Annually ($n=1$):&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000\left(1 + \frac{0.06}{1}\right)^{1 \times 10} = 10{,}000(1.06)^{10} = 17{,}908.48$$&lt;/p>
&lt;p>&lt;strong>Quarterly ($n=4$):&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000\left(1 + \frac{0.06}{4}\right)^{4 \times 10} = 10{,}000(1.015)^{40} = 18{,}140.18$$&lt;/p>
&lt;p>&lt;strong>Monthly ($n=12$):&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000\left(1 + \frac{0.06}{12}\right)^{12 \times 10} = 10{,}000(1.005)^{120} = 18{,}194.25$$&lt;/p>
&lt;p>&lt;strong>Daily ($n=365$):&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000\left(1 + \frac{0.06}{365}\right)^{365 \times 10} = 10{,}000(1.000164)^{3650} = 18{,}220.51$$&lt;/p>
&lt;h3 id="visual-comparison">Visual Comparison
&lt;/h3>&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Start["Initial Investment&lt;br/>$10,000&lt;br/>6% annual rate&lt;br/>10 years"] --> Annual["Annually&lt;br/>$17,908.48&lt;br/>+$7,908"]
Start --> Quarterly["Quarterly&lt;br/>$18,140.18&lt;br/>+$8,140"]
Start --> Monthly["Monthly&lt;br/>$18,194.25&lt;br/>+$8,194"]
Start --> Daily["Daily&lt;br/>$18,220.51&lt;br/>+$8,221"]
style Start fill:#5fb878
style Daily fill:#ff4088
&lt;/div>
&lt;/div>
&lt;h3 id="does-frequency-matter">Does Frequency Matter?
&lt;/h3>&lt;p>&lt;strong>Yes, but not dramatically.&lt;/strong> Here&amp;rsquo;s the difference:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Frequency&lt;/th>
&lt;th>Final Amount&lt;/th>
&lt;th>Gain vs Annual&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Annually&lt;/td>
&lt;td>$17,908.48&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Quarterly&lt;/td>
&lt;td>$18,140.18&lt;/td>
&lt;td>+$231.70&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Monthly&lt;/td>
&lt;td>$18,194.25&lt;/td>
&lt;td>+$285.77&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Daily&lt;/td>
&lt;td>$18,220.51&lt;/td>
&lt;td>+$312.03&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Daily compounding gives you &lt;strong>$312 more&lt;/strong> than annual compounding over 10 years. Not huge, but free money is free money.&lt;/p>
&lt;p>&lt;strong>The rule:&lt;/strong> More frequent compounding is always better, but the difference gets smaller as you compound more often. Going from annual to monthly matters more than going from monthly to daily.&lt;/p>
&lt;h2 id="real-world-examples">Real-World Examples
&lt;/h2>&lt;h3 id="example-1-fidelity-money-market-fund-usa">Example 1: Fidelity Money Market Fund (USA)
&lt;/h3>&lt;p>You invest &lt;strong>$10,000&lt;/strong> in a money market fund with &lt;strong>4.5% annual yield&lt;/strong>, compounded &lt;strong>daily&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>How it works:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Dividends paid daily&lt;/li>
&lt;li>Automatically reinvested (buy more shares)&lt;/li>
&lt;li>This is n = 365&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>After 1 year:&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000\left(1 + \frac{0.045}{365}\right)^{365 \times 1} = 10{,}000(1.000123)^{365} \approx 10{,}460$$&lt;/p>
&lt;p>You earned &lt;strong>$460&lt;/strong> instead of just $450 (simple interest) thanks to daily compounding.&lt;/p>
&lt;p>&lt;strong>After 10 years:&lt;/strong>&lt;/p>
&lt;p>$$A = 10{,}000(1.000123)^{3650} \approx 15{,}657$$&lt;/p>
&lt;h3 id="example-2-ppf---public-provident-fund-india">Example 2: PPF - Public Provident Fund (India)
&lt;/h3>&lt;p>You invest &lt;strong>₹1,50,000 per year&lt;/strong> (maximum allowed) for &lt;strong>15 years&lt;/strong> at &lt;strong>7.1% annual interest&lt;/strong>, compounded &lt;strong>annually&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>How it works:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Interest compounds once per year&lt;/li>
&lt;li>Calculated on lowest balance between 5th and end of month&lt;/li>
&lt;li>This is n = 1&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Strategy:&lt;/strong> Invest on April 1st each year to maximize interest.&lt;/p>
&lt;p>&lt;strong>Calculation:&lt;/strong>&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph TD
Y1["Year 1&lt;br/>Invest: ₹1,50,000&lt;br/>Balance: ₹1,60,650"] --> Y2["Year 2&lt;br/>Invest: ₹1,50,000&lt;br/>Balance: ₹3,32,556"]
Y2 --> Y3["Year 3&lt;br/>Invest: ₹1,50,000&lt;br/>Balance: ₹5,14,045"]
Y3 --> Y15["...&lt;br/>Year 15&lt;br/>Invest: ₹1,50,000&lt;br/>Balance: ₹40,68,209"]
style Y1 fill:#5fb878
style Y15 fill:#ff4088
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Final result after 15 years:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Total invested: &lt;strong>₹22,50,000&lt;/strong>&lt;/li>
&lt;li>Final amount: &lt;strong>₹40,68,209&lt;/strong>&lt;/li>
&lt;li>Interest earned: &lt;strong>₹18,18,209&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Your money almost doubled! And it&amp;rsquo;s completely &lt;strong>tax-free&lt;/strong> (EEE status).&lt;/p>
&lt;h3 id="comparison-money-market-vs-ppf">Comparison: Money Market vs PPF
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Feature&lt;/th>
&lt;th>Fidelity Money Market&lt;/th>
&lt;th>Indian PPF&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Compounding&lt;/td>
&lt;td>Daily (365×/year)&lt;/td>
&lt;td>Annually (1×/year)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Rate&lt;/td>
&lt;td>~4.5%&lt;/td>
&lt;td>7.1%&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Liquidity&lt;/td>
&lt;td>Withdraw anytime&lt;/td>
&lt;td>Locked 15 years&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Taxation&lt;/td>
&lt;td>Taxable income&lt;/td>
&lt;td>Tax-free (EEE)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Best for&lt;/td>
&lt;td>Emergency fund, liquidity&lt;/td>
&lt;td>Long-term, tax savings&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="the-power-of-time">The Power of Time
&lt;/h2>&lt;p>Here&amp;rsquo;s the real magic of compound interest - &lt;strong>time matters more than frequency&lt;/strong>.&lt;/p>
&lt;p>Let&amp;rsquo;s compare two scenarios with $10,000 at 6%:&lt;/p>
&lt;p>&lt;strong>Scenario A:&lt;/strong> Daily compounding, 10 years = &lt;strong>$18,220.51&lt;/strong>
&lt;strong>Scenario B:&lt;/strong> Annual compounding, 20 years = &lt;strong>$32,071.35&lt;/strong>&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph LR
A["10 years&lt;br/>daily compounding&lt;br/>$18,220"]
B["20 years&lt;br/>annual compounding&lt;br/>$32,071"]
A -.->|"10 more years"| C["20 years&lt;br/>daily compounding&lt;br/>$33,201"]
style B fill:#5fb878
style C fill:#ff4088
&lt;/div>
&lt;/div>
&lt;p>&lt;strong>Key insight:&lt;/strong> An extra 10 years beats better compounding frequency. Time is your most powerful tool.&lt;/p>
&lt;h2 id="where-can-you-get-compound-interest">Where Can You Get Compound Interest?
&lt;/h2>&lt;h3 id="united-states">United States
&lt;/h3>&lt;p>&lt;strong>Daily Compounding:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Money market funds (Fidelity, Vanguard, Schwab)&lt;/li>
&lt;li>High-yield savings accounts (Marcus, Ally Bank)&lt;/li>
&lt;li>CDs (Certificates of Deposit)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Monthly/Quarterly:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Most bonds (if you reinvest interest)&lt;/li>
&lt;li>Dividend-paying stocks (DRIP programs)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Through Reinvestment:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>401(k) - All gains compound tax-deferred&lt;/li>
&lt;li>IRA (Traditional and Roth)&lt;/li>
&lt;li>Index funds / ETFs with dividend reinvestment&lt;/li>
&lt;/ul>
&lt;h3 id="india">India
&lt;/h3>&lt;p>&lt;strong>Annual Compounding:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>PPF (Public Provident Fund) - 7.1%, tax-free&lt;/li>
&lt;li>EPF (Employee Provident Fund) - 8.15%&lt;/li>
&lt;li>Sukanya Samriddhi Yojana - 8.2%&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Quarterly Compounding:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Fixed Deposits (banks)&lt;/li>
&lt;li>Recurring Deposits&lt;/li>
&lt;li>National Savings Certificate (NSC)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Through Market Growth:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Mutual funds with dividend reinvestment&lt;/li>
&lt;li>SIP (Systematic Investment Plan)&lt;/li>
&lt;li>NPS (National Pension System)&lt;/li>
&lt;/ul>
&lt;h2 id="practical-examples-how-your-money-grows">Practical Examples: How Your Money Grows
&lt;/h2>&lt;p>Let&amp;rsquo;s look at real numbers. Here&amp;rsquo;s what happens when you invest &lt;strong>$10,000&lt;/strong> at different rates over various time periods (assumes annual compounding for simplicity):&lt;/p>
&lt;h3 id="conservative-rate-5---high-yield-savings-cds">Conservative Rate (5% - High-Yield Savings, CDs)
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Years&lt;/th>
&lt;th>Amount&lt;/th>
&lt;th>Total Gain&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>$10,500&lt;/td>
&lt;td>$500&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>$11,576&lt;/td>
&lt;td>$1,576&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>$12,763&lt;/td>
&lt;td>$2,763&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10&lt;/td>
&lt;td>$16,289&lt;/td>
&lt;td>$6,289&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20&lt;/td>
&lt;td>$26,533&lt;/td>
&lt;td>$16,533&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>30&lt;/td>
&lt;td>$43,219&lt;/td>
&lt;td>$33,219&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Takeaway:&lt;/strong> Even at 5%, your money more than doubles in 15 years and quadruples in 30.&lt;/p>
&lt;h3 id="moderate-rate-8---typical-stock-market-long-term-average">Moderate Rate (8% - Typical Stock Market Long-Term Average)
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Years&lt;/th>
&lt;th>Amount&lt;/th>
&lt;th>Total Gain&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>$10,800&lt;/td>
&lt;td>$800&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>$12,597&lt;/td>
&lt;td>$2,597&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>$14,693&lt;/td>
&lt;td>$4,693&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10&lt;/td>
&lt;td>$21,589&lt;/td>
&lt;td>$11,589&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20&lt;/td>
&lt;td>$46,610&lt;/td>
&lt;td>$36,610&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>30&lt;/td>
&lt;td>$100,627&lt;/td>
&lt;td>$90,627&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Takeaway:&lt;/strong> At 8%, your money doubles roughly every 9 years. After 30 years, that $10,000 becomes over $100,000.&lt;/p>
&lt;h3 id="aggressive-rate-10---high-growth-stocks-index-funds">Aggressive Rate (10% - High-Growth Stocks, Index Funds)
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Years&lt;/th>
&lt;th>Amount&lt;/th>
&lt;th>Total Gain&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>$11,000&lt;/td>
&lt;td>$1,000&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>$13,310&lt;/td>
&lt;td>$3,310&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>$16,105&lt;/td>
&lt;td>$6,105&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10&lt;/td>
&lt;td>$25,937&lt;/td>
&lt;td>$15,937&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20&lt;/td>
&lt;td>$67,275&lt;/td>
&lt;td>$57,275&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>30&lt;/td>
&lt;td>$174,494&lt;/td>
&lt;td>$164,494&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Takeaway:&lt;/strong> At 10%, money doubles approximately every 7 years. After 30 years, $10,000 grows to over $174,000.&lt;/p>
&lt;h3 id="monthly-contribution-example">Monthly Contribution Example
&lt;/h3>&lt;p>What if instead of a one-time $10,000, you invest &lt;strong>$500/month&lt;/strong> ($6,000/year) at 8% annual return?&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Years&lt;/th>
&lt;th>Amount&lt;/th>
&lt;th>Your Contributions&lt;/th>
&lt;th>Earnings&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>$6,244&lt;/td>
&lt;td>$6,000&lt;/td>
&lt;td>$244&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>$19,780&lt;/td>
&lt;td>$18,000&lt;/td>
&lt;td>$1,780&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>$36,738&lt;/td>
&lt;td>$30,000&lt;/td>
&lt;td>$6,738&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10&lt;/td>
&lt;td>$91,473&lt;/td>
&lt;td>$60,000&lt;/td>
&lt;td>$31,473&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20&lt;/td>
&lt;td>$294,510&lt;/td>
&lt;td>$120,000&lt;/td>
&lt;td>$174,510&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>30&lt;/td>
&lt;td>$745,180&lt;/td>
&lt;td>$180,000&lt;/td>
&lt;td>$565,180&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Takeaway:&lt;/strong> Regular contributions combined with compound interest is incredibly powerful. After 30 years, you&amp;rsquo;d have contributed $180,000 but end up with $745,000 - more than 4x your contributions!&lt;/p>
&lt;h3 id="the-rule-of-72">The Rule of 72
&lt;/h3>&lt;p>Quick mental math: To estimate how long it takes to double your money, divide 72 by the interest rate:&lt;/p>
&lt;ul>
&lt;li>At 6%: 72 ÷ 6 = 12 years to double&lt;/li>
&lt;li>At 8%: 72 ÷ 8 = 9 years to double&lt;/li>
&lt;li>At 10%: 72 ÷ 10 = 7.2 years to double&lt;/li>
&lt;/ul>
&lt;p>This is why time and rate both matter so much.&lt;/p>
&lt;h2 id="the-bottom-line">The Bottom Line
&lt;/h2>&lt;p>&lt;strong>Three key takeaways:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Compound interest is powerful&lt;/strong> - Your money makes money, which makes more money&lt;/li>
&lt;li>&lt;strong>Frequency helps, but not dramatically&lt;/strong> - Daily vs annual might add 1-2% over time&lt;/li>
&lt;li>&lt;strong>Time matters most&lt;/strong> - 20 years of annual compounding beats 10 years of daily compounding&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>What to do:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Start early (even small amounts)&lt;/li>
&lt;li>Reinvest your earnings (dividends, interest)&lt;/li>
&lt;li>Be patient - compounding needs time to work its magic&lt;/li>
&lt;li>Don&amp;rsquo;t obsess over compounding frequency - focus on getting started&lt;/li>
&lt;/ul>
&lt;p>Remember: &lt;img src="https://santoshmano.com/images/plant-tree-compound-interest.jpg"
loading="lazy"
alt="The best time to plant a tree was 20 years ago. The next best time is now."
>&lt;/p>
&lt;p>&lt;em>Thanks to Preeti Agarwal for painting this rock for me. This image has been digitally enhanced.&lt;/em>&lt;/p></description></item><item><title>KaTeX Math Notation Reference</title><link>https://santoshmano.com/blog/katex-math-notation-reference/</link><pubDate>Tue, 01 Oct 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/katex-math-notation-reference/</guid><description>&lt;p>If you need to write mathematical notation in markdown files, KaTeX is the way to go. It&amp;rsquo;s fast, renders beautifully, and uses familiar LaTeX syntax.&lt;/p>
&lt;h2 id="what-is-katex">What is KaTeX?
&lt;/h2>&lt;p>KaTeX is a math typesetting library that renders LaTeX math notation on the web. It&amp;rsquo;s faster than MathJax and produces crisp, readable formulas. If you&amp;rsquo;ve ever used LaTeX in academic papers, you already know the syntax.&lt;/p>
&lt;p>KaTeX works in many contexts: Hugo sites, GitHub markdown, Jekyll, documentation sites, and more.&lt;/p>
&lt;h2 id="setting-up-katex">Setting Up KaTeX
&lt;/h2>&lt;p>Setup varies by platform:&lt;/p>
&lt;p>&lt;strong>Hugo (with Stack theme or similar):&lt;/strong>
Many Hugo themes support KaTeX out of the box. If yours doesn&amp;rsquo;t, add this to &lt;code>layouts/partials/head/custom.html&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">link&lt;/span> &lt;span class="na">rel&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;stylesheet&amp;#34;&lt;/span> &lt;span class="na">href&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">defer&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">defer&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">onload&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;renderMathInElement(document.body);&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>GitHub Markdown:&lt;/strong>
GitHub renders KaTeX automatically. Just use the syntax below - no setup needed.&lt;/p>
&lt;p>&lt;strong>Other platforms:&lt;/strong>
Most static site generators and documentation tools support KaTeX through plugins or themes. Check your platform&amp;rsquo;s documentation.&lt;/p>
&lt;p>Once set up, the syntax below works everywhere.&lt;/p>
&lt;h2 id="basic-syntax">Basic Syntax
&lt;/h2>&lt;h3 id="inline-math">Inline Math
&lt;/h3>&lt;p>Use single dollar signs for inline math:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">The quadratic formula is $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Renders as: The quadratic formula is $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.&lt;/p>
&lt;h3 id="display-math-block">Display Math (Block)
&lt;/h3>&lt;p>Use double dollar signs for centered, display-style equations:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">E = mc^2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Renders as:&lt;/p>
&lt;p>$$
E = mc^2
$$&lt;/p>
&lt;h2 id="common-examples">Common Examples
&lt;/h2>&lt;h3 id="fractions">Fractions
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\frac{a}{b} \quad \frac{1}{2} \quad \frac{\pi}{4}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\frac{a}{b} \quad \frac{1}{2} \quad \frac{\pi}{4}
$$&lt;/p>
&lt;h3 id="exponents-and-subscripts">Exponents and Subscripts
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">x^2 \quad y^{10} \quad a_1 \quad b_{n+1}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
x^2 \quad y^{10} \quad a_1 \quad b_{n+1}
$$&lt;/p>
&lt;h3 id="square-roots">Square Roots
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\sqrt{2} \quad \sqrt{x^2 + y^2} \quad \sqrt[3]{8}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\sqrt{2} \quad \sqrt{x^2 + y^2} \quad \sqrt[3]{8}
$$&lt;/p>
&lt;h3 id="greek-letters">Greek Letters
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\alpha, \beta, \gamma, \delta, \epsilon, \theta, \pi, \sigma, \omega
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\alpha, \beta, \gamma, \delta, \epsilon, \theta, \pi, \sigma, \omega
$$&lt;/p>
&lt;h3 id="summation-and-products">Summation and Products
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\prod_{i=1}^{n} i = n!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\prod_{i=1}^{n} i = n!
$$&lt;/p>
&lt;h3 id="integrals">Integrals
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\int_0^1 x^2 \, dx = \frac{1}{3}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\int_0^1 x^2 , dx = \frac{1}{3}
$$&lt;/p>
&lt;h3 id="limits">Limits
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\lim_{x \to \infty} \frac{1}{x} = 0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\lim_{x \to \infty} \frac{1}{x} = 0
$$&lt;/p>
&lt;h3 id="matrices">Matrices
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\begin{bmatrix}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">a &lt;span class="err">&amp;amp;&lt;/span> b \\
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">c &lt;span class="err">&amp;amp;&lt;/span> d
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\end{bmatrix}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\begin{bmatrix}
a &amp;amp; b \
c &amp;amp; d
\end{bmatrix}
$$&lt;/p>
&lt;h3 id="systems-of-equations">Systems of Equations
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\begin{cases}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">x + y = 5 \\
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2x - y = 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\end{cases}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\begin{cases}
x + y = 5 \
2x - y = 1
\end{cases}
$$&lt;/p>
&lt;h2 id="real-world-example-compound-interest">Real-World Example: Compound Interest
&lt;/h2>&lt;p>Here&amp;rsquo;s a practical formula you might actually use:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">A = P\left(1 + \frac{r}{n}\right)^{nt}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Where:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> $A$ = final amount
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> $P$ = principal (initial investment)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> $r$ = annual interest rate (decimal)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> $n$ = compounding frequency per year
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> $t$ = time in years
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Renders as:&lt;/p>
&lt;p>$$
A = P\left(1 + \frac{r}{n}\right)^{nt}
$$&lt;/p>
&lt;p>Where:&lt;/p>
&lt;ul>
&lt;li>$A$ = final amount&lt;/li>
&lt;li>$P$ = principal (initial investment)&lt;/li>
&lt;li>$r$ = annual interest rate (decimal)&lt;/li>
&lt;li>$n$ = compounding frequency per year&lt;/li>
&lt;li>$t$ = time in years&lt;/li>
&lt;/ul>
&lt;h2 id="quick-reference">Quick Reference
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>What You Want&lt;/th>
&lt;th>LaTeX Syntax&lt;/th>
&lt;th>Result&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Fraction&lt;/td>
&lt;td>&lt;code>\frac{a}{b}&lt;/code>&lt;/td>
&lt;td>$\frac{a}{b}$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Exponent&lt;/td>
&lt;td>&lt;code>x^2&lt;/code>&lt;/td>
&lt;td>$x^2$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Subscript&lt;/td>
&lt;td>&lt;code>x_1&lt;/code>&lt;/td>
&lt;td>$x_1$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Square root&lt;/td>
&lt;td>&lt;code>\sqrt{x}&lt;/code>&lt;/td>
&lt;td>$\sqrt{x}$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Summation&lt;/td>
&lt;td>&lt;code>\sum_{i=1}^{n}&lt;/code>&lt;/td>
&lt;td>$\sum_{i=1}^{n}$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Integral&lt;/td>
&lt;td>&lt;code>\int_a^b&lt;/code>&lt;/td>
&lt;td>$\int_a^b$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Limit&lt;/td>
&lt;td>&lt;code>\lim_{x \to \infty}&lt;/code>&lt;/td>
&lt;td>$\lim_{x \to \infty}$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Pi&lt;/td>
&lt;td>&lt;code>\pi&lt;/code>&lt;/td>
&lt;td>$\pi$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Infinity&lt;/td>
&lt;td>&lt;code>\infty&lt;/code>&lt;/td>
&lt;td>$\infty$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Less/Greater&lt;/td>
&lt;td>&lt;code>\leq&lt;/code> &lt;code>\geq&lt;/code>&lt;/td>
&lt;td>$\leq$ $\geq$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Not equal&lt;/td>
&lt;td>&lt;code>\neq&lt;/code>&lt;/td>
&lt;td>$\neq$&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Approximately&lt;/td>
&lt;td>&lt;code>\approx&lt;/code>&lt;/td>
&lt;td>$\approx$&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="common-operators">Common Operators
&lt;/h2>&lt;ul>
&lt;li>Multiplication: &lt;code>\times&lt;/code> → $\times$&lt;/li>
&lt;li>Division: &lt;code>\div&lt;/code> → $\div$&lt;/li>
&lt;li>Plus/minus: &lt;code>\pm&lt;/code> → $\pm$&lt;/li>
&lt;li>Dot product: &lt;code>\cdot&lt;/code> → $\cdot$&lt;/li>
&lt;/ul>
&lt;h2 id="spacing">Spacing
&lt;/h2>&lt;p>Use these for better spacing:&lt;/p>
&lt;ul>
&lt;li>&lt;code>\,&lt;/code> — small space&lt;/li>
&lt;li>&lt;code>\quad&lt;/code> — medium space&lt;/li>
&lt;li>&lt;code>\qquad&lt;/code> — large space&lt;/li>
&lt;/ul>
&lt;p>Example: &lt;code>$a \, b \quad c \qquad d$&lt;/code> renders as $a , b \quad c \qquad d$&lt;/p>
&lt;h2 id="tips">Tips
&lt;/h2>&lt;p>&lt;strong>Escaping special characters:&lt;/strong> If you need to show actual dollar signs in text, escape them: &lt;code>\$100&lt;/code>&lt;/p>
&lt;p>&lt;strong>Alignment:&lt;/strong> Use &lt;code>&amp;amp;&lt;/code> for alignment in multi-line equations with &lt;code>aligned&lt;/code> environment:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\begin{aligned}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">f(x) &lt;span class="err">&amp;amp;&lt;/span>= x^2 + 2x + 1 \\
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">&amp;amp;&lt;/span>= (x + 1)^2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">\end{aligned}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>$$
\begin{aligned}
f(x) &amp;amp;= x^2 + 2x + 1 \
&amp;amp;= (x + 1)^2
\end{aligned}
$$&lt;/p>
&lt;p>&lt;strong>Curly braces:&lt;/strong> Use &lt;code>\{&lt;/code> and &lt;code>\}&lt;/code> for literal braces: ${1, 2, 3}$&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://katex.org/docs/supported.html" target="_blank" rel="noopener"
>KaTeX Supported Functions&lt;/a> - Complete reference&lt;/li>
&lt;li>&lt;a class="link" href="http://detexify.kirelabs.org/classify.html" target="_blank" rel="noopener"
>Detexify&lt;/a> - Draw a symbol to find its LaTeX command&lt;/li>
&lt;li>&lt;a class="link" href="https://www.cmor-faculty.rice.edu/~heinken/latex/symbols.pdf" target="_blank" rel="noopener"
>LaTeX Math Symbols&lt;/a> - Comprehensive PDF&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>That&amp;rsquo;s all you need to add beautiful math notation to your posts. The syntax might look intimidating at first, but you&amp;rsquo;ll quickly remember the common patterns.&lt;/p></description></item><item><title>Essential Vim Commands and Shell Vi Mode</title><link>https://santoshmano.com/blog/vim-commands-and-shell-vi-mode/</link><pubDate>Fri, 20 Sep 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/vim-commands-and-shell-vi-mode/</guid><description>&lt;h1 id="essential-vim-commands-and-shell-vi-mode">Essential Vim Commands and Shell Vi Mode
&lt;/h1>&lt;p>A practical guide to the most commonly used vim commands and shell vi mode. This covers the 20% of commands you&amp;rsquo;ll use 80% of the time.&lt;/p>
&lt;h2 id="setting-up-vi-mode-in-shell">Setting Up Vi Mode in Shell
&lt;/h2>&lt;h3 id="zsh">Zsh
&lt;/h3>&lt;p>Add to &lt;code>~/.zshrc&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enable vi mode&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bindkey -v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Reduce delay when switching modes&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">KEYTIMEOUT&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="bash">Bash
&lt;/h3>&lt;p>Add to &lt;code>~/.bashrc&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Enable vi mode&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -o vi
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="apply-and-test">Apply and Test
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Reload configuration&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> ~/.zshrc &lt;span class="c1"># for zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> ~/.bashrc &lt;span class="c1"># for bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Test it:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Type some text&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Press ESC (enter command mode)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Press k (navigate history)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. Press i (back to insert mode)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="shell-vi-mode---essential-commands">Shell Vi Mode - Essential Commands
&lt;/h2>&lt;h3 id="the-basics">The Basics
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>ESC&lt;/code>&lt;/td>
&lt;td>Enter command mode&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>i&lt;/code>&lt;/td>
&lt;td>Enter insert mode&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>a&lt;/code>&lt;/td>
&lt;td>Insert after cursor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>A&lt;/code>&lt;/td>
&lt;td>Insert at end of line&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="navigation">Navigation
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>h, j, k, l&lt;/code>&lt;/td>
&lt;td>Left, down, up, right&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>w&lt;/code>&lt;/td>
&lt;td>Next word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>b&lt;/code>&lt;/td>
&lt;td>Previous word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>0&lt;/code>&lt;/td>
&lt;td>Start of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>$&lt;/code>&lt;/td>
&lt;td>End of line&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="editing">Editing
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>x&lt;/code>&lt;/td>
&lt;td>Delete character&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>dd&lt;/code>&lt;/td>
&lt;td>Delete line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>D&lt;/code>&lt;/td>
&lt;td>Delete to end of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>cc&lt;/code>&lt;/td>
&lt;td>Delete line and insert&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>u&lt;/code>&lt;/td>
&lt;td>Undo&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="history--search">History &amp;amp; Search
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>k&lt;/code> / &lt;code>j&lt;/code>&lt;/td>
&lt;td>Previous / next in history&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>/text&lt;/code>&lt;/td>
&lt;td>Search history forward&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>n&lt;/code>&lt;/td>
&lt;td>Next search result&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="essential-vim-commands">Essential Vim Commands
&lt;/h2>&lt;h3 id="opening-files">Opening Files
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">vim filename.txt &lt;span class="c1"># Open file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">vim +42 filename.txt &lt;span class="c1"># Open at line 42&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="the-two-modes-you-need">The Two Modes You Need
&lt;/h3>&lt;pre tabindex="0">&lt;code>ESC - Normal mode (navigate and command)
i - Insert mode (type text)
&lt;/code>&lt;/pre>&lt;h3 id="saving-and-quitting">Saving and Quitting
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>:w&lt;/code>&lt;/td>
&lt;td>Save&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:q&lt;/code>&lt;/td>
&lt;td>Quit&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:wq&lt;/code> or &lt;code>ZZ&lt;/code>&lt;/td>
&lt;td>Save and quit&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:q!&lt;/code>&lt;/td>
&lt;td>Quit without saving&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="navigation-1">Navigation
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>h, j, k, l&lt;/code>&lt;/td>
&lt;td>Left, down, up, right&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>w&lt;/code>&lt;/td>
&lt;td>Next word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>b&lt;/code>&lt;/td>
&lt;td>Previous word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>0&lt;/code>&lt;/td>
&lt;td>Beginning of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>$&lt;/code>&lt;/td>
&lt;td>End of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>gg&lt;/code>&lt;/td>
&lt;td>First line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>G&lt;/code>&lt;/td>
&lt;td>Last line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:42&lt;/code>&lt;/td>
&lt;td>Go to line 42&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Ctrl-d&lt;/code> / &lt;code>Ctrl-u&lt;/code>&lt;/td>
&lt;td>Scroll down/up&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="editing-1">Editing
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>i&lt;/code>&lt;/td>
&lt;td>Insert before cursor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>a&lt;/code>&lt;/td>
&lt;td>Insert after cursor&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>I&lt;/code>&lt;/td>
&lt;td>Insert at line start&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>A&lt;/code>&lt;/td>
&lt;td>Insert at line end&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>o&lt;/code>&lt;/td>
&lt;td>Open line below&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>O&lt;/code>&lt;/td>
&lt;td>Open line above&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>x&lt;/code>&lt;/td>
&lt;td>Delete character&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>dd&lt;/code>&lt;/td>
&lt;td>Delete line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>D&lt;/code>&lt;/td>
&lt;td>Delete to end of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>cc&lt;/code>&lt;/td>
&lt;td>Change entire line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>J&lt;/code>&lt;/td>
&lt;td>Join line with next&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>u&lt;/code>&lt;/td>
&lt;td>Undo&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>Ctrl-r&lt;/code>&lt;/td>
&lt;td>Redo&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>.&lt;/code>&lt;/td>
&lt;td>Repeat last command&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="copy-cut-paste">Copy, Cut, Paste
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>yy&lt;/code>&lt;/td>
&lt;td>Copy line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>yw&lt;/code>&lt;/td>
&lt;td>Copy word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>y$&lt;/code>&lt;/td>
&lt;td>Copy to end of line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>dd&lt;/code>&lt;/td>
&lt;td>Cut line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>dw&lt;/code>&lt;/td>
&lt;td>Cut word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>p&lt;/code>&lt;/td>
&lt;td>Paste after&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>P&lt;/code>&lt;/td>
&lt;td>Paste before&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="search">Search
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>/pattern&lt;/code>&lt;/td>
&lt;td>Search forward&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>?pattern&lt;/code>&lt;/td>
&lt;td>Search backward&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>n&lt;/code>&lt;/td>
&lt;td>Next result&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N&lt;/code>&lt;/td>
&lt;td>Previous result&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>*&lt;/code>&lt;/td>
&lt;td>Search word under cursor&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="replace">Replace
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>:s/old/new/&lt;/code>&lt;/td>
&lt;td>Replace first in line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:s/old/new/g&lt;/code>&lt;/td>
&lt;td>Replace all in line&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:%s/old/new/g&lt;/code>&lt;/td>
&lt;td>Replace all in file&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>:%s/old/new/gc&lt;/code>&lt;/td>
&lt;td>Replace with confirmation&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="visual-mode-selection">Visual Mode (Selection)
&lt;/h3>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Command&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>v&lt;/code>&lt;/td>
&lt;td>Visual character mode&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>V&lt;/code>&lt;/td>
&lt;td>Visual line mode&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>y&lt;/code>&lt;/td>
&lt;td>Copy selection&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>d&lt;/code>&lt;/td>
&lt;td>Delete selection&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="quick-reference-card">Quick Reference Card
&lt;/h2>&lt;p>&lt;strong>Most Common Workflow:&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code>1. Open file: vim file.txt
2. Navigate: h,j,k,l or arrow keys
3. Start editing: i (insert) or a (append)
4. Type your text
5. Exit insert: ESC
6. Save and quit: :wq
&lt;/code>&lt;/pre>&lt;p>&lt;strong>Essential Shortcuts:&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code># Navigation
gg - Top of file
G - Bottom of file
0 - Start of line
$ - End of line
w / b - Next/previous word
# Editing
dd - Delete line
yy - Copy line
p - Paste
u - Undo
. - Repeat
# Search
/text - Find &amp;#39;text&amp;#39;
n - Next result
# Save/Quit
:w - Save
:q - Quit
:wq - Save and quit
:q! - Quit without saving
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="vim-configuration">Vim Configuration
&lt;/h2>&lt;h3 id="permanent-settings-vimrc">Permanent Settings (.vimrc)
&lt;/h3>&lt;p>Create &lt;code>~/.vimrc&lt;/code> with basics:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-vim" data-lang="vim">&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;#34; Essentials&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">number&lt;/span> &lt;span class="c">&amp;#34; Line numbers&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">cursorline&lt;/span> &lt;span class="c">&amp;#34; Highlight current line&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">hlsearch&lt;/span> &lt;span class="c">&amp;#34; Highlight search results&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">incsearch&lt;/span> &lt;span class="c">&amp;#34; Search as you type&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">ignorecase&lt;/span> &lt;span class="c">&amp;#34; Case insensitive search&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">smartcase&lt;/span> &lt;span class="c">&amp;#34; Case sensitive if uppercase used&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;#34; Indentation&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">tabstop&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="m">4&lt;/span> &lt;span class="c">&amp;#34; Tab width&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">shiftwidth&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="m">4&lt;/span> &lt;span class="c">&amp;#34; Indent width&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">expandtab&lt;/span> &lt;span class="c">&amp;#34; Spaces instead of tabs&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">autoindent&lt;/span> &lt;span class="c">&amp;#34; Auto indent&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;#34; Usability&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">showcmd&lt;/span> &lt;span class="c">&amp;#34; Show command&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">wildmenu&lt;/span> &lt;span class="c">&amp;#34; Command completion&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">set&lt;/span> &lt;span class="nx">showmatch&lt;/span> &lt;span class="c">&amp;#34; Show matching brackets&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="runtime-settings">Runtime Settings
&lt;/h3>&lt;p>Apply these settings within vim for the current session:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-vim" data-lang="vim">&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nx">se&lt;/span> &lt;span class="nx">ic&lt;/span> &lt;span class="c">&amp;#34; ignore case for search&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nx">se&lt;/span> &lt;span class="nx">noai&lt;/span> &lt;span class="c">&amp;#34; turn off auto indent&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nx">se&lt;/span> &lt;span class="nx">hlsearch&lt;/span> &lt;span class="c">&amp;#34; highlight search matches&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="k">highlight&lt;/span> &lt;span class="nx">Comment&lt;/span> &lt;span class="nx">ctermfg&lt;/span>&lt;span class="p">=&lt;/span>&lt;span class="nx">blue&lt;/span> &lt;span class="c">&amp;#34; change color of commented text&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nx">se&lt;/span> &lt;span class="k">syntax&lt;/span> &lt;span class="c">&amp;#34; enable syntax highlighting&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>These are shortcuts for &lt;code>:set&lt;/code>. Add them to &lt;code>.vimrc&lt;/code> to make permanent (without the colon).&lt;/p>
&lt;hr>
&lt;h2 id="tips-for-daily-use">Tips for Daily Use
&lt;/h2>&lt;h3 id="1-learn-the-movement-keys-first">1. Learn the Movement Keys First
&lt;/h3>&lt;p>Before anything else, get comfortable with &lt;code>h, j, k, l&lt;/code> and &lt;code>w, b&lt;/code>. Your hands never leave home row.&lt;/p>
&lt;h3 id="2-use--dot-command">2. Use . (Dot) Command
&lt;/h3>&lt;p>The dot command repeats your last change. Super powerful:&lt;/p>
&lt;pre tabindex="0">&lt;code>cw new&amp;lt;ESC&amp;gt; - Change word to &amp;#34;new&amp;#34;
w - Move to next word
. - Repeat the change
&lt;/code>&lt;/pre>&lt;h3 id="3-shell-vi-mode-tricks">3. Shell Vi Mode Tricks
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># After typing a long command:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ESC - Enter &lt;span class="nb">command&lt;/span> mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">0&lt;/span> - Jump to start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">w w w - Move forward &lt;span class="m">3&lt;/span> words
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">i - Insert and edit
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="4-dont-overthink-it">4. Don&amp;rsquo;t Overthink It
&lt;/h3>&lt;p>Start with these basics. Add more as you need them. You don&amp;rsquo;t need to master everything at once.&lt;/p>
&lt;hr>
&lt;h2 id="common-mistakes">Common Mistakes
&lt;/h2>&lt;p>&lt;strong>Stuck in Insert Mode?&lt;/strong> Press &lt;code>ESC&lt;/code>&lt;/p>
&lt;p>&lt;strong>Can&amp;rsquo;t Exit Vim?&lt;/strong> Type &lt;code>:q!&lt;/code> and press Enter&lt;/p>
&lt;p>&lt;strong>Commands Not Working?&lt;/strong> Make sure you&amp;rsquo;re in normal mode (press &lt;code>ESC&lt;/code>)&lt;/p>
&lt;p>&lt;strong>Slow Mode Switching?&lt;/strong> Add &lt;code>export KEYTIMEOUT=1&lt;/code> to your shell config&lt;/p>
&lt;hr>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>Run &lt;code>vimtutor&lt;/code> in your terminal - 30 minute interactive tutorial&lt;/li>
&lt;li>&lt;a class="link" href="https://www.vim.org/docs.php" target="_blank" rel="noopener"
>Vim Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://www.openvim.com/" target="_blank" rel="noopener"
>OpenVim Tutorial&lt;/a> - Interactive in browser&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="practice-exercise">Practice Exercise
&lt;/h2>&lt;p>Try this workflow:&lt;/p>
&lt;ol>
&lt;li>Enable vi mode: &lt;code>bindkey -v&lt;/code> (zsh) or &lt;code>set -o vi&lt;/code> (bash)&lt;/li>
&lt;li>Type: &lt;code>ls -la /usr/local/bin&lt;/code>&lt;/li>
&lt;li>Press &lt;code>ESC&lt;/code>&lt;/li>
&lt;li>Press &lt;code>0&lt;/code> (go to start)&lt;/li>
&lt;li>Press &lt;code>w&lt;/code> three times (skip &amp;ldquo;ls -la&amp;rdquo;)&lt;/li>
&lt;li>Press &lt;code>cw&lt;/code> (change word)&lt;/li>
&lt;li>Type a new path&lt;/li>
&lt;li>Press &lt;code>Enter&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>The key is practice. Use it daily and it becomes second nature.&lt;/strong>&lt;/p>
&lt;hr>
&lt;p>&lt;em>Remember: You only need to know 20% of vim to be 80% effective. Start here, expand later.&lt;/em>&lt;/p>
&lt;h2 id="related-posts">Related Posts
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/ctags-cscope-screen-my-first-ide/" >ctags, cscope, and Screen: My IDE for 12 Years&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/unix-screen-utility/" >Using GNU Screen on Unix&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/tmux-mac-tutorial/" >How I Use tmux on Mac&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>How I Use tmux on Mac</title><link>https://santoshmano.com/blog/tmux-mac-tutorial/</link><pubDate>Thu, 05 Sep 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/tmux-mac-tutorial/</guid><description>&lt;p>I started using tmux about a year ago and honestly can&amp;rsquo;t imagine going back. If you spend a lot of time in the terminal like I do, tmux is a game-changer.&lt;/p>
&lt;h2 id="why-i-use-tmux">Why I Use tmux
&lt;/h2>&lt;p>I used to have like 10 terminal windows open, constantly switching between them. SSH sessions would die when my laptop went to sleep. I&amp;rsquo;d lose my carefully arranged split panes when I closed a terminal by accident.&lt;/p>
&lt;p>tmux solved all of that. Now I have persistent sessions that survive disconnects, I can split my terminal however I want, and everything stays exactly how I left it.&lt;/p>
&lt;h2 id="getting-started">Getting Started
&lt;/h2>&lt;p>Install it with Homebrew:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">brew install tmux
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>That&amp;rsquo;s it. Run &lt;code>tmux&lt;/code> and you&amp;rsquo;re in.&lt;/p>
&lt;h2 id="the-basics-what-i-actually-use-daily">The Basics (What I Actually Use Daily)
&lt;/h2>&lt;p>tmux uses a &amp;ldquo;prefix key&amp;rdquo; for commands - by default it&amp;rsquo;s &lt;code>Ctrl-b&lt;/code>. You press that first, release, then press the command key.&lt;/p>
&lt;h3 id="sessions---the-killer-feature">Sessions - The Killer Feature
&lt;/h3>&lt;p>This is why tmux is worth it:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start a named session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux new -s myproject
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Detach (close terminal, session keeps running)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b d
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Come back later, everything&amp;#39;s still there&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux attach -t myproject
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># List all your sessions&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux ls
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>I have persistent sessions for different projects. My work session, my personal projects session, experiments session. They&amp;rsquo;re always running, I just attach/detach as needed.&lt;/p>
&lt;h3 id="window-management">Window Management
&lt;/h3>&lt;p>Think of these like browser tabs:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># New window&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b c
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Next/previous window&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b n / Ctrl-b p
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Jump to window 0-9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b 0-9
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Rename window (I do this for every window)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b ,
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>I typically have 3-4 windows per session: one for code, one for servers, one for git operations, one for random commands.&lt;/p>
&lt;p>&lt;strong>Note on split screens:&lt;/strong> I use iTerm&amp;rsquo;s built-in split panes instead of tmux panes. iTerm handles splits well, and it&amp;rsquo;s one less thing to manage in tmux.&lt;/p>
&lt;h2 id="my-tmuxconf">My ~/.tmux.conf
&lt;/h2>&lt;p>I spent way too long tweaking this, but here&amp;rsquo;s what actually matters:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Mouse support&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g mouse on
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start window numbering at 1 (easier to reach than 0)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g base-index &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># More scrollback history&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g history-limit &lt;span class="m">10000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Better colors&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g default-terminal &lt;span class="s2">&amp;#34;screen-256color&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Reload config quickly&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">bind&lt;/span> r source-file ~/.tmux.conf &lt;span class="se">\;&lt;/span> display &lt;span class="s2">&amp;#34;Config reloaded!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Don&amp;#39;t auto-rename my carefully named windows&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">set-option -g allow-rename off
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Simple status bar&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g status-style &lt;span class="nv">bg&lt;/span>&lt;span class="o">=&lt;/span>black,fg&lt;span class="o">=&lt;/span>white
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g status-left &lt;span class="s1">&amp;#39;#[fg=green]#S &amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">set&lt;/span> -g status-right &lt;span class="s1">&amp;#39;#[fg=cyan]%d %b %R&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Put that in &lt;code>~/.tmux.conf&lt;/code> and reload with &lt;code>Ctrl-b :&lt;/code> then &lt;code>source-file ~/.tmux.conf&lt;/code>.&lt;/p>
&lt;h2 id="my-actual-workflow">My Actual Workflow
&lt;/h2>&lt;p>&lt;strong>Starting my day:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Attach to my main work session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux attach -t work
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Everything&amp;rsquo;s exactly where I left it yesterday. Editor still open, servers still running, git still on the right branch.&lt;/p>
&lt;p>&lt;strong>Working on a side project:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Detach from work&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Ctrl-b d
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Start or attach to project session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux attach -t sideproject
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Context switch in 2 seconds.&lt;/p>
&lt;p>&lt;strong>SSH-ing to a server:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ssh myserver
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux attach
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>My remote session persists even if my connection drops. I can pick up right where I left off.&lt;/p>
&lt;h2 id="what-took-me-a-while-to-learn">What Took Me a While to Learn
&lt;/h2>&lt;p>&lt;strong>Copy mode:&lt;/strong> &lt;code>Ctrl-b [&lt;/code> lets you scroll back and copy text. Use arrow keys to navigate, Space to start selection, Enter to copy, then &lt;code>Ctrl-b ]&lt;/code> to paste. Took me forever to figure this out.&lt;/p>
&lt;p>&lt;strong>Detaching vs Closing:&lt;/strong> &lt;code>Ctrl-b d&lt;/code> detaches (session keeps running). &lt;code>exit&lt;/code> in all windows actually closes the session. I used to confuse these.&lt;/p>
&lt;p>&lt;strong>Command mode:&lt;/strong> &lt;code>Ctrl-b :&lt;/code> opens a command prompt. You can type any tmux command here. I use it for killing sessions: &lt;code>:kill-session -t oldproject&lt;/code>&lt;/p>
&lt;p>&lt;strong>Session groups (viewing different windows simultaneously):&lt;/strong> This took me forever to figure out. When you attach to the same session from multiple terminals using &lt;code>tmux attach&lt;/code>, all terminals mirror each other - they show the same window. Not what you want.&lt;/p>
&lt;p>If you want independent views of different windows within the same session, use session groups:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Terminal 1: Create the main session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux new -s work
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Terminal 2: Create a new session grouped with &amp;#39;work&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux new -t work -s work-view2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Terminal 3: Another grouped session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux new -t work -s work-view3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Or use the short form (tmux auto-generates unique names)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux new -t work
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>What this does:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>All sessions share the same windows (0, 1, 2, 3, etc.)&lt;/li>
&lt;li>Each terminal can view a different window independently&lt;/li>
&lt;li>Changes in one terminal (creating/closing windows) appear in all&lt;/li>
&lt;li>But each terminal can switch windows independently!&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Verify it&amp;rsquo;s working:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">tmux ls
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># You&amp;#39;ll see something like:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># work: 5 windows (created Mon Nov 11 10:00:00 2025)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># work-view2: 5 windows (created Mon Nov 11 10:01:00 2025) (group work)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># work-view3: 5 windows (created Mon Nov 11 10:02:00 2025) (group work)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The &lt;code>(group work)&lt;/code> indicates they share the same windows.&lt;/p>
&lt;p>&lt;strong>What NOT to do:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ❌ This causes mirroring (all terminals show the same window)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tmux attach -t work &lt;span class="c1"># Don&amp;#39;t use this in multiple terminals&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Bonus alias&lt;/strong> (add to &lt;code>~/.zshrc&lt;/code> or &lt;code>~/.bashrc&lt;/code>):&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">alias&lt;/span> tmux-join&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;tmux new-session -t&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Usage:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># tmux-join work&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This was a game-changer for me - I can have my code editor in one terminal window, logs in another, and tests in a third, all from the same tmux session but viewing different windows at the same time.&lt;/p>
&lt;h2 id="quick-reference-what-i-look-up-every-time">Quick Reference (What I Look Up Every Time)
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>What I Want&lt;/th>
&lt;th>Key&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Detach from session&lt;/td>
&lt;td>&lt;code>Ctrl-b d&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>New window&lt;/td>
&lt;td>&lt;code>Ctrl-b c&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Next/prev window&lt;/td>
&lt;td>&lt;code>Ctrl-b n/p&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Copy mode (scroll)&lt;/td>
&lt;td>&lt;code>Ctrl-b [&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>List all commands&lt;/td>
&lt;td>&lt;code>Ctrl-b ?&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="is-it-worth-learning">Is It Worth Learning?
&lt;/h2>&lt;p>If you live in the terminal: absolutely yes.&lt;/p>
&lt;p>The learning curve is real - for the first few days I kept closing tmux by accident and getting confused. But once it clicks, you&amp;rsquo;ll wonder how you worked without it.&lt;/p>
&lt;p>Start simple: just use sessions and detach/attach. That alone is worth it. Then gradually add windows and panes as you get comfortable.&lt;/p>
&lt;p>For me, tmux means I can close my laptop, open it somewhere else, and continue exactly where I left off. That&amp;rsquo;s powerful.&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://tmuxcheatsheet.com/" target="_blank" rel="noopener"
>tmux cheat sheet&lt;/a> - I still reference this&lt;/li>
&lt;li>Official docs: &lt;a class="link" href="https://github.com/tmux/tmux/wiki" target="_blank" rel="noopener"
>https://github.com/tmux/tmux/wiki&lt;/a>&lt;/li>
&lt;li>Book: &amp;ldquo;tmux 2&amp;rdquo; by Brian Hogan - actually worth reading&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>That&amp;rsquo;s my tmux setup. Not fancy, but works great for me. If you have questions or want to share your setup, find me on &lt;a class="link" href="https://x.com/santoshmano" target="_blank" rel="noopener"
>X&lt;/a>.&lt;/p></description></item><item><title>Writing in Markdown: A Simple Guide</title><link>https://santoshmano.com/blog/markdown-basics-guide/</link><pubDate>Thu, 15 Aug 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/markdown-basics-guide/</guid><description>&lt;p>I write every post on this blog in Markdown. It&amp;rsquo;s simple, clean, and lets me focus on writing without fussing over formatting buttons or HTML tags.&lt;/p>
&lt;p>If you&amp;rsquo;ve never used Markdown before, it might look weird at first - you&amp;rsquo;re literally typing asterisks and hash marks into a text file. But after about 10 minutes, it becomes second nature. And once you get it, you&amp;rsquo;ll find yourself wishing every text box supported Markdown.&lt;/p>
&lt;h2 id="what-is-markdown">What is Markdown?
&lt;/h2>&lt;p>Markdown is a way to write formatted text using plain text. Instead of clicking &amp;ldquo;Bold&amp;rdquo; or selecting &amp;ldquo;Heading 1&amp;rdquo; from a dropdown, you just type &lt;code>**bold**&lt;/code> or &lt;code># Heading 1&lt;/code>. When your Markdown file gets processed (by Hugo, Jekyll, GitHub, etc.), it converts these markers into proper HTML.&lt;/p>
&lt;p>The beauty? You can write Markdown in any text editor - VS Code, Sublime, even Notepad. No special software needed.&lt;/p>
&lt;h2 id="basic-formatting">Basic Formatting
&lt;/h2>&lt;h3 id="headings">Headings
&lt;/h3>&lt;p>Use hash marks for headings. More hashes = smaller heading.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="gh"># Heading 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gh">&lt;/span>&lt;span class="gu">## Heading 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">### Heading 3
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">#### Heading 4
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="emphasis">Emphasis
&lt;/h3>&lt;p>&lt;strong>Bold&lt;/strong> text with double asterisks or underscores:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">**This is bold**
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gs">__This is also bold__&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;em>Italic&lt;/em> text with single asterisks or underscores:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">*This is italic*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">_This is also italic_&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;em>&lt;strong>Bold and italic&lt;/strong>&lt;/em> together:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">***Bold and italic***
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="lists">Lists
&lt;/h3>&lt;p>Unordered lists with dashes, asterisks, or plus signs:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> Item one
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> Item two
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> Item three
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ordered lists with numbers:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">1.&lt;/span> First item
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">2.&lt;/span> Second item
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">3.&lt;/span> Third item
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Nested lists? Just indent:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> Main item
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">-&lt;/span> Sub item
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">-&lt;/span> Another sub item
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> Another main item
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="links-and-images">Links and Images
&lt;/h3>&lt;p>Links use brackets and parentheses:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">[&lt;span class="nt">Link text&lt;/span>](&lt;span class="na">https://example.com&lt;/span>)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[&lt;span class="nt">Link with title&lt;/span>](&lt;span class="na">https://example.com &amp;#34;Hover text&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Images are just like links with an exclamation mark in front:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">![&lt;span class="nt">Alt text&lt;/span>](&lt;span class="na">/path/to/image.jpg&lt;/span>)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">![&lt;span class="nt">Image with title&lt;/span>](&lt;span class="na">/path/to/image.jpg &amp;#34;Image title&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="code">Code
&lt;/h3>&lt;p>Inline code uses backticks:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">Use the &lt;span class="sb">`hugo server`&lt;/span> command to start the dev server.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Code blocks use triple backticks with optional language:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="s">```python
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&lt;/span>&lt;span class="k">def&lt;/span> &lt;span class="nf">hello&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hello, world!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">```&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="blockquotes">Blockquotes
&lt;/h3>&lt;p>Use the greater-than symbol:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">This is a blockquote.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">It can span multiple lines.
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="horizontal-rules">Horizontal Rules
&lt;/h3>&lt;p>Three or more dashes, asterisks, or underscores:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">---
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="tables">Tables
&lt;/h2>&lt;p>Tables use pipes and dashes:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">| Column 1 | Column 2 | Column 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">|----------|----------|----------|
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| Data 1 | Data 2 | Data 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| Data 4 | Data 5 | Data 6 |
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Which renders as:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Column 1&lt;/th>
&lt;th>Column 2&lt;/th>
&lt;th>Column 3&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Data 1&lt;/td>
&lt;td>Data 2&lt;/td>
&lt;td>Data 3&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Data 4&lt;/td>
&lt;td>Data 5&lt;/td>
&lt;td>Data 6&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Align columns with colons:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">| Left | Center | Right |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">|:-----|:------:|------:|
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| L1 | C1 | R1 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| L2 | C2 | R2 |
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="what-i-actually-use">What I Actually Use
&lt;/h2>&lt;p>I don&amp;rsquo;t use all of Markdown&amp;rsquo;s features in every post. Here&amp;rsquo;s what I use most:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Headings&lt;/strong> - Structure every article with &lt;code>##&lt;/code> and &lt;code>###&lt;/code>&lt;/li>
&lt;li>&lt;strong>Bold and italic&lt;/strong> - Emphasis where it matters&lt;/li>
&lt;li>&lt;strong>Code blocks&lt;/strong> - Command examples and code snippets&lt;/li>
&lt;li>&lt;strong>Lists&lt;/strong> - Breaking down steps or options&lt;/li>
&lt;li>&lt;strong>Links&lt;/strong> - Connecting to related articles or references&lt;/li>
&lt;/ol>
&lt;p>I rarely use blockquotes or tables unless the content really calls for it.&lt;/p>
&lt;h2 id="hugo-specific-features">Hugo-Specific Features
&lt;/h2>&lt;p>Since this blog runs on Hugo, I also use:&lt;/p>
&lt;h3 id="front-matter">Front Matter
&lt;/h3>&lt;p>Every post starts with YAML front matter:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Your Post Title&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">date&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ld">2025-01-14T10:00:00&lt;/span>&lt;span class="m">-08&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">draft&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">tags&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;tag1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;tag2&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">categories&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;category&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">description&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Short description for SEO and previews&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="mermaid-diagrams">Mermaid Diagrams
&lt;/h3>&lt;p>For diagrams, I use Mermaid with standard markdown code blocks. This is a feature I added to the blog more recently - you can create flowcharts, sequence diagrams, and more right in your Markdown files.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="s">```mermaid
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">&lt;/span>graph LR
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> A[Write Markdown] --&amp;gt; B[Run Hugo]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> B --&amp;gt; C[Get HTML]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s">```&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Which renders as:&lt;/p>
&lt;div class="mermaid-wrapper">
&lt;div class="mermaid">graph LR
A[Write Markdown] --> B[Run Hugo]
B --> C[Get HTML]
&lt;/div>
&lt;/div>
&lt;p>I wrote a whole post about &lt;a class="link" href="https://santoshmano.com/blog/mermaid-diagram-test/" >using Mermaid diagrams in Hugo&lt;/a> if you want to see more examples and learn how to add it to your own Hugo site.&lt;/p>
&lt;h2 id="tips-for-writing">Tips for Writing
&lt;/h2>&lt;p>&lt;strong>Use a Markdown-aware editor&lt;/strong> - VS Code, Typora, or iA Writer all have live preview. You can see formatting as you type.&lt;/p>
&lt;p>&lt;strong>Keep it simple&lt;/strong> - Don&amp;rsquo;t overthink formatting. Focus on writing. Add formatting after.&lt;/p>
&lt;p>&lt;strong>Preview before publishing&lt;/strong> - Run &lt;code>hugo server -D&lt;/code> locally to see how your post looks before publishing.&lt;/p>
&lt;p>&lt;strong>Learn as you go&lt;/strong> - Start with headings, bold, and code blocks. Add more formatting techniques as you need them.&lt;/p>
&lt;h2 id="common-mistakes">Common Mistakes
&lt;/h2>&lt;p>&lt;strong>Extra spaces in lists&lt;/strong> - Markdown is picky about indentation. Use consistent spacing.&lt;/p>
&lt;p>&lt;strong>Forgetting the blank line&lt;/strong> - Always put a blank line before and after code blocks, lists, and headings. Makes Markdown parsers happy.&lt;/p>
&lt;p>&lt;strong>Not escaping special characters&lt;/strong> - If you need a literal asterisk or underscore, escape it with a backslash: &lt;code>\*&lt;/code> or &lt;code>\_&lt;/code>.&lt;/p>
&lt;h2 id="thats-it">That&amp;rsquo;s It
&lt;/h2>&lt;p>Markdown isn&amp;rsquo;t complicated. It&amp;rsquo;s just a few symbols that make sense once you use them a few times. Write a couple of posts and you&amp;rsquo;ll have it down.&lt;/p>
&lt;p>The reason I like Markdown is that my content is just text files. No proprietary formats, no databases, no vendor lock-in. Just &lt;code>.md&lt;/code> files I can open in any editor, now or 10 years from now.&lt;/p>
&lt;p>That&amp;rsquo;s powerful.&lt;/p></description></item><item><title>Using GNU Screen on Unix</title><link>https://santoshmano.com/blog/unix-screen-utility/</link><pubDate>Sat, 10 Aug 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/unix-screen-utility/</guid><description>&lt;p>Back in the day, I used GNU Screen religiously when working on HP-UX. I&amp;rsquo;d SSH into a server, kick off a kernel build that would take hours, start a screen session, and ride my bike home. The next morning, I could reconnect and see if the build succeeded or failed overnight.&lt;/p>
&lt;p>Screen is a terminal multiplexer - it lets you create multiple terminal windows within one session. The killer feature? Sessions persist even when you disconnect.&lt;/p>
&lt;h2 id="why-screen-was-essential">Why Screen Was Essential
&lt;/h2>&lt;p>When you&amp;rsquo;re working on remote servers, Screen solves a real problem. Network drops, laptop going to sleep, accidentally closing your terminal - none of that kills your running processes. You just reconnect and everything&amp;rsquo;s still there.&lt;/p>
&lt;p>I used it for years for long-running kernel builds, deployment scripts, and SSH sessions to production servers.&lt;/p>
&lt;h2 id="why-i-switched-to-tmux">Why I Switched to tmux
&lt;/h2>&lt;p>Eventually I moved from Screen to tmux. The core functionality is the same, but tmux has better defaults, easier configuration, and more active development. If you&amp;rsquo;re starting fresh today, &lt;a class="link" href="https://santoshmano.com/blog/tmux-mac-tutorial/" >I&amp;rsquo;d recommend tmux&lt;/a> instead.&lt;/p>
&lt;p>That said, Screen still works great and you&amp;rsquo;ll find it on almost any Unix system.&lt;/p>
&lt;h2 id="essential-commands">Essential Commands
&lt;/h2>&lt;h3 id="session-management">Session Management
&lt;/h3>&lt;ul>
&lt;li>&lt;code>screen -S&lt;/code> — create new sessions&lt;/li>
&lt;li>&lt;code>screen -x&lt;/code> — attach to existing session&lt;/li>
&lt;li>&lt;code>screen -d -r&lt;/code> — reattach with forced detachment if needed&lt;/li>
&lt;li>&lt;code>screen -d&lt;/code> — detach from terminal&lt;/li>
&lt;li>&lt;code>screen -list&lt;/code> — display status&lt;/li>
&lt;li>&lt;code>screen -dr owner/sessionid.name&lt;/code> — connect to another user&amp;rsquo;s session (root access required)&lt;/li>
&lt;/ul>
&lt;h3 id="within-screen">Within Screen
&lt;/h3>&lt;ul>
&lt;li>&lt;code>^a c&lt;/code> — create new window&lt;/li>
&lt;li>&lt;code>^a d&lt;/code> — detach from session&lt;/li>
&lt;li>&lt;code>^a spacebar&lt;/code> — navigate to next window&lt;/li>
&lt;li>&lt;code>^a backspace&lt;/code> or &lt;code>^a del&lt;/code> — navigate to previous window&lt;/li>
&lt;li>&lt;code>^a 2&lt;/code> — jump to window 2&lt;/li>
&lt;li>&lt;code>^a w&lt;/code> — list windows&lt;/li>
&lt;li>&lt;code>^a ^a&lt;/code> — toggle between windows&lt;/li>
&lt;li>&lt;code>^a SHIFT-a&lt;/code> — rename window&lt;/li>
&lt;/ul>
&lt;p>(^ represents Control key)&lt;/p>
&lt;h2 id="configuration">Configuration
&lt;/h2>&lt;h3 id="scrollback-buffer">Scrollback Buffer
&lt;/h3>&lt;p>By default, Screen has limited scrollback. To increase it, set this within a running session:&lt;/p>
&lt;pre tabindex="0">&lt;code>:scrollback 10000
&lt;/code>&lt;/pre>&lt;p>Or add it to your &lt;code>~/.screenrc&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">scrollback &lt;span class="m">10000&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="status-line-screenrc">Status Line (.screenrc)
&lt;/h3>&lt;p>Here&amp;rsquo;s a useful status line configuration that shows window list, system info, and timestamp:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">caption always &lt;span class="s2">&amp;#34;%{= kw}%-w%{= BW}%n %t%{-}%+w %-= @%H - %LD %d %LM - %c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This displays:&lt;/p>
&lt;ul>
&lt;li>Window list with current window highlighted&lt;/li>
&lt;li>Hostname&lt;/li>
&lt;li>Date and time&lt;/li>
&lt;li>Updates automatically&lt;/li>
&lt;/ul>
&lt;h2 id="getting-started">Getting Started
&lt;/h2>&lt;p>Screen comes pre-installed on most Unix systems. Just type &lt;code>screen&lt;/code> to start a session.&lt;/p>
&lt;p>The keybindings take some getting used to, but they become muscle memory fast. You can customize everything in a &lt;code>~/.screenrc&lt;/code> file.&lt;/p>
&lt;h2 id="historical-note">Historical Note
&lt;/h2>&lt;p>This article is from 2010 when I was actively using Screen. I&amp;rsquo;ve since switched to tmux, but Screen still works great if you prefer it or need to work on systems where it&amp;rsquo;s already installed.&lt;/p>
&lt;h2 id="related-posts">Related Posts
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/ctags-cscope-screen-my-first-ide/" >ctags, cscope, and Screen: My IDE for 12 Years&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/tmux-mac-tutorial/" >How I Use tmux on Mac&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://santoshmano.com/blog/vim-commands-and-shell-vi-mode/" >Essential Vim Commands&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>How I Set Up This Site with Hugo, Netlify, and Cloudflare</title><link>https://santoshmano.com/blog/deploying-hugo-netlify-cloudflare/</link><pubDate>Fri, 05 Jul 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/deploying-hugo-netlify-cloudflare/</guid><description>&lt;p>I recently rebuilt my personal site from scratch, and I wanted to share what I learned along the way. My requirements were simple: something fast, easy to maintain, and with automated deployments. I didn&amp;rsquo;t want to deal with databases, server maintenance, or complex CMS systems.&lt;/p>
&lt;p>After some research, I went with Hugo paired with the Stack theme, deployed through Netlify, with Cloudflare handling DNS and CDN. The setup turned out to be surprisingly straightforward, and the result is exactly what I wanted.&lt;/p>
&lt;h2 id="why-i-chose-this-setup">Why I Chose This Setup
&lt;/h2>&lt;p>I picked &lt;strong>Hugo&lt;/strong> because it&amp;rsquo;s incredibly fast and generates pure static HTML. No server-side processing, no security vulnerabilities to worry about. The &lt;strong>Stack theme&lt;/strong> caught my eye immediately – clean, card-based design that just works.&lt;/p>
&lt;p>For hosting, &lt;strong>Netlify&lt;/strong> was a no-brainer. Their free tier is generous, and the git-based deployment workflow is elegant: I write locally, push to GitHub, and Netlify automatically builds and deploys everything.&lt;/p>
&lt;p>&lt;strong>Cloudflare&lt;/strong> was already managing my domain, so I kept it there for DNS and their global CDN. The combination means visitors anywhere in the world get fast load times.&lt;/p>
&lt;p>The entire workflow: &lt;strong>write locally → push to GitHub → Netlify auto-deploys → Cloudflare serves it globally.&lt;/strong>&lt;/p>
&lt;hr>
&lt;h2 id="setting-up-locally">Setting Up Locally
&lt;/h2>&lt;p>I&amp;rsquo;m on a Mac, so I used Homebrew to install everything I needed:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">brew install hugo go git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>After installation, I verified everything was working:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hugo version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">go version
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Then I created the site structure and set it up as a Hugo module:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mkdir santoshmano &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> santoshmano
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo new site .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo mod init github.com/santoshmano/santoshmano.com
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="configuring-the-stack-theme">Configuring the Stack Theme
&lt;/h3>&lt;p>I created a &lt;code>hugo.toml&lt;/code> configuration file with these settings:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">baseURL&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;https://santoshmano.com/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">title&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;Santosh Manoharan&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">languageCode&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;en-us&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">paginate&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">10&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">enableRobotsTXT&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">module&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[[&lt;/span>&lt;span class="nx">module&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">imports&lt;/span>&lt;span class="p">]]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">path&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;github.com/CaiJimmy/hugo-theme-stack/v3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">params&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">enableSearch&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">showReadingTime&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">showCodeCopyButtons&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">mainSections&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;blog&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">colorScheme&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">toggle&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">default&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;auto&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">taxonomies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">tag&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;tags&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">category&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;categories&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">markup&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="nx">markup&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">goldmark&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">renderer&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">unsafe&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="nx">markup&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">highlight&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">noClasses&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">false&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">lineNos&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>To preview locally, I ran:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hugo server -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This starts a development server at &lt;code>http://localhost:1313&lt;/code> with live reload, which made testing changes incredibly fast. When I was ready to build for production, I used:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hugo --minify
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="pushing-to-github">Pushing to GitHub
&lt;/h2>&lt;p>I initialized a git repository and pushed everything to GitHub:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git init
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git add .
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git commit -m &lt;span class="s2">&amp;#34;Initial Hugo setup with Stack theme&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git branch -M main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git remote add origin https://github.com/santoshmano/santoshmano.com.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git push -u origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="deploying-to-netlify">Deploying to Netlify
&lt;/h2>&lt;p>I logged into &lt;a class="link" href="https://app.netlify.com" target="_blank" rel="noopener"
>Netlify&lt;/a> and connected my GitHub repository. The setup was straightforward:&lt;/p>
&lt;ol>
&lt;li>Clicked &lt;strong>&amp;ldquo;Add new site&amp;rdquo;&lt;/strong> → &lt;strong>&amp;ldquo;Import from GitHub&amp;rdquo;&lt;/strong>&lt;/li>
&lt;li>Selected my repository&lt;/li>
&lt;li>Configured the build settings:
&lt;ul>
&lt;li>&lt;strong>Build command:&lt;/strong> &lt;code>hugo --minify&lt;/code>&lt;/li>
&lt;li>&lt;strong>Publish directory:&lt;/strong> &lt;code>public&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Added an environment variable:
&lt;ul>
&lt;li>&lt;strong>Key:&lt;/strong> &lt;code>HUGO_VERSION&lt;/code>&lt;/li>
&lt;li>&lt;strong>Value:&lt;/strong> &lt;code>0.139.0&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Hit &lt;strong>&amp;ldquo;Deploy site&amp;rdquo;&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>Within minutes, my site was live at a Netlify subdomain.&lt;/p>
&lt;h3 id="adding-netlifytoml">Adding netlify.toml
&lt;/h3>&lt;p>For better control over the build process, I added a &lt;code>netlify.toml&lt;/code> file to my project root:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">build&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">command&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;hugo --minify&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">publish&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;public&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">build&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">environment&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">HUGO_VERSION&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.139.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">HUGO_ENV&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">HUGO_ENABLEGITINFO&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;true&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">context&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">production&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">environment&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">HUGO_ENV&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">context&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">deploy-preview&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">environment&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">HUGO_VERSION&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;0.139.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="connecting-my-custom-domain-with-cloudflare">Connecting My Custom Domain with Cloudflare
&lt;/h2>&lt;p>Since my domain was already registered with Cloudflare, I kept it there for DNS management instead of switching to Netlify&amp;rsquo;s DNS.&lt;/p>
&lt;h3 id="dns-configuration">DNS Configuration
&lt;/h3>&lt;p>In Cloudflare&amp;rsquo;s DNS settings, I added two CNAME records:&lt;/p>
&lt;p>&lt;strong>For the root domain (santoshmano.com):&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code>Type: CNAME
Name: @
Content: santoshmano.netlify.app
Proxy status: Proxied (🟠 orange cloud ON)
TTL: Auto
&lt;/code>&lt;/pre>&lt;p>&lt;strong>For the www subdomain:&lt;/strong>&lt;/p>
&lt;pre tabindex="0">&lt;code>Type: CNAME
Name: www
Content: santoshmano.netlify.app
Proxy status: Proxied (🟠 orange cloud ON)
TTL: Auto
&lt;/code>&lt;/pre>&lt;hr>
&lt;h2 id="ssltls-configuration">SSL/TLS Configuration
&lt;/h2>&lt;p>In Cloudflare&amp;rsquo;s SSL/TLS settings, I set the encryption mode to &lt;strong>Full&lt;/strong>. This ensures proper end-to-end encryption between Cloudflare and Netlify.&lt;/p>
&lt;hr>
&lt;h2 id="adding-the-domain-in-netlify">Adding the Domain in Netlify
&lt;/h2>&lt;p>Back in Netlify, I added my custom domain:&lt;/p>
&lt;ol>
&lt;li>Went to &lt;strong>Site settings&lt;/strong> → &lt;strong>Domain management&lt;/strong>&lt;/li>
&lt;li>Clicked &lt;strong>&amp;ldquo;Add a domain&amp;rdquo;&lt;/strong>&lt;/li>
&lt;li>Entered &lt;code>santoshmano.com&lt;/code> and verified it&lt;/li>
&lt;li>Repeated the process for &lt;code>www.santoshmano.com&lt;/code>&lt;/li>
&lt;li>Set &lt;code>santoshmano.com&lt;/code> as the primary domain&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="setting-up-https">Setting Up HTTPS
&lt;/h2>&lt;p>In Netlify&amp;rsquo;s HTTPS section, I clicked &lt;strong>&amp;ldquo;Verify DNS configuration&amp;rdquo;&lt;/strong> and then &lt;strong>&amp;ldquo;Provision certificate&amp;rdquo;&lt;/strong>. Netlify automatically issued a Let&amp;rsquo;s Encrypt SSL certificate, which took about 5-10 minutes.&lt;/p>
&lt;hr>
&lt;h2 id="testing-everything">Testing Everything
&lt;/h2>&lt;p>After waiting for DNS propagation (around 15 minutes in my case), I tested:&lt;/p>
&lt;ul>
&lt;li>✅ &lt;code>https://santoshmano.com&lt;/code> → loaded perfectly&lt;/li>
&lt;li>✅ &lt;code>https://www.santoshmano.com&lt;/code> → redirected to the main domain&lt;/li>
&lt;li>✅ &lt;code>https://santoshmano.netlify.app&lt;/code> → also worked&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="issues-i-ran-into">Issues I Ran Into
&lt;/h2>&lt;p>A few hiccups along the way that might save you some time:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Certificate provisioning took longer than expected&lt;/strong> - I had to wait about 15 minutes and click &amp;ldquo;Verify DNS&amp;rdquo; a couple of times before it went through. Patience is key.&lt;/li>
&lt;li>&lt;strong>Initially forgot to set SSL mode to &amp;ldquo;Full&amp;rdquo; in Cloudflare&lt;/strong> - This caused redirect loops. Once I fixed the SSL/TLS setting, everything worked smoothly.&lt;/li>
&lt;li>&lt;strong>The Hugo version matters&lt;/strong> - Netlify was using an older Hugo version by default, which broke the Stack theme. Setting &lt;code>HUGO_VERSION&lt;/code> in the environment variables fixed it.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="how-it-all-fits-together">How It All Fits Together
&lt;/h2>&lt;p>The architecture is elegantly simple:&lt;/p>
&lt;pre tabindex="0">&lt;code>My Mac (write posts in Markdown)
|
| git push
v
GitHub (stores the code)
|
| triggers webhook
v
Netlify (builds with Hugo, deploys)
|
| serves content to
v
Cloudflare (DNS, CDN, SSL)
|
| delivers to
v
Visitors (fast HTTPS everywhere)
&lt;/code>&lt;/pre>&lt;p>Every time I push to GitHub, Netlify automatically rebuilds and deploys the site. Cloudflare&amp;rsquo;s CDN ensures fast load times globally.&lt;/p>
&lt;hr>
&lt;h2 id="reflections">Reflections
&lt;/h2>&lt;p>This setup has been running smoothly for months now. The git-based workflow feels natural, and I love that I can write in Markdown without worrying about databases or server maintenance.&lt;/p>
&lt;p>The Stack theme has been great out of the box, though I did add some custom styling in &lt;code>assets/scss/custom.scss&lt;/code> to tweak the dark mode colors and accent color to my liking.&lt;/p>
&lt;p>If you&amp;rsquo;re considering building a personal site or blog, I&amp;rsquo;d highly recommend this stack. It&amp;rsquo;s fast, secure, free (for most personal use cases), and requires minimal maintenance.&lt;/p>
&lt;hr>
&lt;h2 id="useful-links">Useful Links
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="https://gohugo.io/documentation/" target="_blank" rel="noopener"
>Hugo Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://stack.jimmycai.com/" target="_blank" rel="noopener"
>Stack Theme Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://docs.netlify.com/" target="_blank" rel="noopener"
>Netlify Documentation&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://developers.cloudflare.com/dns/" target="_blank" rel="noopener"
>Cloudflare DNS Documentation&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Hello World</title><link>https://santoshmano.com/blog/hello-world/</link><pubDate>Mon, 01 Jul 2024 10:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/hello-world/</guid><description/></item><item><title>Couch to Goggins 4x4x48 Challenge</title><link>https://santoshmano.com/blog/couch-to-goggins-4x4x48-challenge/</link><pubDate>Thu, 11 Mar 2021 05:02:44 +0000</pubDate><guid>https://santoshmano.com/blog/couch-to-goggins-4x4x48-challenge/</guid><description>&lt;p>A type 1 diabetic&amp;rsquo;s notes on learning to balance food, insulin, exercise &amp;amp; mind&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*FcbjNzQbVAuYkJcxdtizcg.png"
loading="lazy"
alt="Goggins Challenge Banner"
>
&lt;em>Image credit: &lt;a class="link" href="https://www.gogginschallenge.com/" target="_blank" rel="noopener"
>https://www.gogginschallenge.com/&lt;/a>&lt;/em>&lt;/p>
&lt;p>I came across David Goggins via some podcasts. I immediately liked his straight talk, his approach to challenging situations, and all his physical achievements. I am someone who draws inspiration and learns from people I know personally, but of late I started to read books on people and listen to podcasts. And after coming across Goggins, I was quick to follow him. I have been in a slump for a while now due to many factors, and have been struggling to get back into a rhythm. But then who doesn&amp;rsquo;t. Goggins had a challenge coming up and I decided to use it to kickstart myself.&lt;/p>
&lt;p>The &lt;a class="link" href="https://www.gogginschallenge.com" target="_blank" rel="noopener"
>challenge&lt;/a> was to run 4 miles every 4 hours, for a total duration of 48 hours. If one could not run, the suggestion was to do an equivalent workout for 45–60 minutes at the same time. That would be 12 repetitions of ~1hr workouts with a 3 hrs break.&lt;/p>
&lt;p>I have Type 1 diabetes and a bad right knee, both for over 15 years. I had a complex surgery after a motorcycle accident and then went on to tear my constructed ligament again while playing soccer. Now with no ACL, my knee easily swells up during intense workouts when I don&amp;rsquo;t plan and work up towards it. In the last few years, I have also been struggling with yo-yo weight reaching obesity numbers a few times, and currently at 212 lbs.&lt;/p>
&lt;p>I was lucky to come across a few great people (references at the end) who managed their health so well. I learned a lot from them on, nutrition, metabolism, exercise, habits, and how to manage my diabetes improving my HBA1C from an average of 7.5 for over a decade to 4.8. Had also lost over 30lbs once. But with the current slump, I had gotten back to bad health. I was not fit or fat-adapted but I was confident that I could do this challenge because of the things I had learned and practiced in the past.&lt;/p>
&lt;p>I planned a few things out in my head on the day of the challenge:&lt;/p>
&lt;ul>
&lt;li>Ride my bike instead of a run as it is easier with my current weight &amp;amp; knee.&lt;/li>
&lt;li>Ride a fixed route, as I can focus on my health instead of route challenges.&lt;/li>
&lt;li>Stock a few things I can eat and drink, and stock glucose tablets.&lt;/li>
&lt;li>Keep a few ice packs in the freezer, fix my bikes, and continuous glucose monitors.&lt;/li>
&lt;/ul>
&lt;p>The rest I thought I will figure out along the way.&lt;/p>
&lt;p>As you are reading through this you may feel that I look organized and ready for the challenge, but in reality, I was having butterflies the whole day. I was afraid I may sleep through one of the workouts, injure my knee, or maybe just not do it. But I knew that if I start, I will not give up, even if I make mistakes or perform poorly, I will keep trying, something I learned from my Dad. My wife shared a hilarious prep suggestion from Goggins which &lt;a class="link" href="https://lexfridman.com/" target="_blank" rel="noopener"
>Lex Fridman&lt;/a>/&lt;a class="link" href="https://www.hubermanlab.com/" target="_blank" rel="noopener"
>Andrew Huberman&lt;/a> mentioned in their podcast on how to prepare for this challenge — take an SIU pill with a can of hard. What the heck is SIU? you may ask, and in Goggins own style —&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Suck It Up&amp;rdquo; and &amp;ldquo;Stay Hard&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>Disclaimer:&lt;/strong> &lt;em>Health, Diet, Nutrition are sometimes religious topics for many. We and our circumstances are different and we need to personalize it for ourselves. Some of you need experts/doctor&amp;rsquo;s advice or you may be putting yourself at risk, please be safe first. The key thing I want anyone new looking at this is that you can learn about your health and learn from data and observations to make corrections and adapt along the way. You can achieve things while having chronic or other conditions with a little bit of learning and staying hard.&lt;/em>&lt;/p>
&lt;h2 id="summary">Summary
&lt;/h2>&lt;p>Below is the visualization summary of the data I noted down about my ride, food, insulin during the challenge:&lt;/p>
&lt;ul>
&lt;li>March 5 &amp;amp; 6 was hard with constant lows, numerous corrections, varying glucose levels even though it was mostly in range.&lt;/li>
&lt;li>March 7 was great, as I had learned the patterns and adjusted food/insulin accordingly and the body was also adapting. The blood sugars were far more flat, and hardly needed any corrections, and insulin consumption dropped.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/2560/1*e_8-8q1OW-F9YfVxNfsv2A.png"
loading="lazy"
alt="Day 1"
>
&lt;em>Day 1&lt;/em>&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/2560/1*YRjwJNyWZcEZ7DfygGSPdw.png"
loading="lazy"
alt="Day 2"
>
&lt;em>Day 2&lt;/em>&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/2560/1*NEl2hSWLmoS6d-EWGAY_JQ.png"
loading="lazy"
alt="Day 3"
>
&lt;em>Day 3&lt;/em>&lt;/p>
&lt;h2 id="ride-notes">Ride Notes
&lt;/h2>&lt;ul>
&lt;li>Decided to ride indoors at 8 pm, 12 am &amp;amp; 4 am, on my new unused stationary bike, and outdoors at 8 am, 12 pm &amp;amp; 4 pm, on an old creaking hybrid, in a fixed known route that I had done several times before.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*423RTc88vkP3zrPAO4biZg.png"
loading="lazy"
alt="Ride Schedule"
>&lt;/p>
&lt;ul>
&lt;li>Waking up on time and ready to go sharp at the 4th hour was the key to this challenge, so setup up alarms on 3 different devices and left one in the living room in case I fell asleep in my bedroom.&lt;/li>
&lt;li>I ended up riding close to 79 miles (indoor not accurate) for a total of around 13 hrs. This pales in comparison to what some of my inspirational friends achieve in just 1 ride/day, but it was a big deal for me for where i am at. Did not care much about the total miles, but was really happy to have gone through with doing all the 12 rides on time and for at least 12 hours.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Wf6Jd2pCVifRCeHpwNiaWQ.png"
loading="lazy"
alt="Ride Stats"
>&lt;/p>
&lt;ul>
&lt;li>I had initially planned to do 12 miles every repetition for my indoor rides. But when I started indoors it was a rude shock, even though I rode at 11–13 mph the total distance was only 6 miles. I know the cheap meters are not very accurate with the readings, but I thought speed and distance were directly proportional to some extent. Nevermind. So I quickly reduced my goal using by half. In the second leg indoors, with lack of sleep and knee pains, I halved my goal again to 3 miles. But I was glad to have stuck to 60 minutes of staying awake and fighting it out on the bike.&lt;/li>
&lt;li>My outdoor ride was great initially but then it took longer and longer every ride. It was primarily because of the low sugars, felt the lack of energy. The second day was far better after the electrolytes and the food timing. Riding out with my son was surprisingly fast, what usually takes us 90–100 minutes took at 88 minutes together.&lt;/li>
&lt;li>It was inspiring seeing David Goggins show up on his live feed before every ride, was hesitant on asking him a question directly, next time.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*v4-zEo2NiKCYqFzN9aaYVw.png"
loading="lazy"
alt="Goggins Live Feed"
>&lt;/p>
&lt;ul>
&lt;li>My knees and thighs hurt like hell during the night of the second day, and I was constantly stopping and icing my knees during Ride 7–10. But the worst was my butt :) when indoors I used a pillow and outdoor rode on my thigh many a time. Need to train well to avoid this next time.&lt;/li>
&lt;li>It was a mental battle, a few things played on in my head constantly — maybe I can miss this workout, 1 mile is good enough now, 45 minutes is good enough, I can stop at 58 minutes, and so on. But even though I stopped a few times in between, I slowly rode on and made sure I went through the 60 minutes.&lt;/li>
&lt;li>Riding out was easier in a lot of ways, as there was no other alternative than to finish my loop, mind is fresher being out, and there are rest times when going downhill, or traffic stops, but indoors on a stationary bike was tougher on the mind and the legs.&lt;/li>
&lt;/ul>
&lt;h2 id="food-and-glucose-notes">Food and Glucose Notes
&lt;/h2>&lt;ul>
&lt;li>The first two days were crazy with constant corrections with glucose tablets and also made mistakes of taking more insulin. This is what happens to me when the body is not fit and/or fat-adapted. It is a constant battle with highs and lows because it is just not easy to balance insulin-exercise-food in realtime when on a high carb diet and doing tough workouts. That said you do need some amount of carbs, when doing some extreme aerobic workouts, this was not that extreme but because I was not fit and used to the rigor, my body behaved as though it was.&lt;/li>
&lt;li>The total calories consumed from start to finish was ~4500 calories over a 48 hr period, and it turned out to be a 50–30–20 Fat-Protein-Carb split, it was not planned, just it turned out this way based on my past learnings and habits.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Os7jegspkUZ1uaOo8Rr-pA.png"
loading="lazy"
alt="Nutrition Breakdown"
>&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*zIvMeNnVw6rvK93yljvrtw.png"
loading="lazy"
alt="Food Log"
>&lt;/p>
&lt;ul>
&lt;li>Observed something interesting repeatedly, ate carbs like banana/orange before the bike ride so that I don&amp;rsquo;t go low. It usually takes me ~30 minutes to start seeing the rise in my sugar. But this time it did not work that way, during my ride I kept going low, it looked as though my body functions were just focused on supporting my ride, and food did not metabolize like usual. As soon as I came back home and sat down after the ride, my BG started to rise sharply. It could also be because of my lack of fitness my body was in a state of shock the whole day. I remember reading about this before, need to investigate this more.&lt;/li>
&lt;li>There was hardly any knee pain on the third day, thanks partly to the electrolytes, missed taking it the previous two days, added extra Magnesium for the muscle soreness. It helped with the general tiredness too. (I have been on and off taking measured electrolytes for the past 4 years, especially when on a low carb diet, so I could easily see how it made me feel different). Protein shakes also worked great in giving energy during the ride and helping me stay level on my blood glucose. Need to make these two fixed during any such endeavors in the future.&lt;/li>
&lt;/ul>
&lt;p>I felt good as I was reaching home from the last ride. Was happy that I went through with this and completed it. In reality, it was a struggle on the first 2 days physically and mentally. I was able to do it easily because of my wife being there all the while, handing me the sugar tablets and ice packs during the ride, cooking me nice omelets, waking up along with me during my rides most of the time, and nudging me on gently. One night my son kept an alarm on his watch and woke me up. My daughter provided great comic relief by holding onto me whenever I left home and being the drama queen and crying and asking me not to go, but when I am at home she is busy lost in her own world. My son joined me for the last ride which was special. My wife set up a surprise party with the kids, balloons, a cake, and a rock for my desk. The helmet in this photo is gifted by a friend of mine who is an inspiring biker that I look upto.&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*OnifWpV7q6h_CYIacgnTOg.png"
loading="lazy"
alt="Celebration Photo"
>&lt;/p>
&lt;p>Few people I would like to thanks, I got first introduced to learning how to manage my diabetes via &lt;a class="link" href="https://samiinkinen.medium.com/" target="_blank" rel="noopener"
>Sami Inkinen&lt;/a> of &lt;a class="link" href="https://www.virtahealth.com" target="_blank" rel="noopener"
>VirtaHealth&lt;/a> who pointed me in the right direction of some amazing people who work so hard on learning and managing their health, all my friends at &lt;a class="link" href="https://www.facebook.com/Type1Grit/" target="_blank" rel="noopener"
>TypeoneGrit&lt;/a> and the decades of learned wisdom of &lt;a class="link" href="https://www.youtube.com/c/DrRichardKBernstein/videos" target="_blank" rel="noopener"
>Dr. Bernstein&lt;/a> who wrote the diabetes bible, &lt;a class="link" href="https://www.amazon.com/Dr-Bernsteins-Diabetes-Solution-Achieving/dp/0316182699" target="_blank" rel="noopener"
>The Diabetes Solution&lt;/a>. The fitness, diet, and habit-building techniques I learned at &lt;a class="link" href="https://www.ketogains.com/" target="_blank" rel="noopener"
>Ketogains&lt;/a>. I will write a different post mentioning all the wonderful things I have learned for these folks.&lt;/p>
&lt;h2 id="key-takeaways">Key Takeaways
&lt;/h2>&lt;ul>
&lt;li>Learning how proteins, fats, and carbs metabolize is the key. And then creating a predictable menu for such days and rehearsing it during practice would be ideal.&lt;/li>
&lt;li>Being fit and fat-adapted, and eating high protein foods does a world of good for me while doing activities like this and in general.&lt;/li>
&lt;li>Glucose tablets/liquid is compulsory for a diabetic to carry when doing anything physical like this, they could save your life. I just carry tablets.&lt;/li>
&lt;li>Ice therapy is amazing for injuries, inflammation. I need to invest in a better ice pack for my knees. Low carb also reduces inflammation, I have done controlled experiments to observe this for my knee and gum aches.&lt;/li>
&lt;li>I always drop my Basal insulin prior to such activities. I drop it around 30–80%, how much depends on many factors. If I don&amp;rsquo;t do this I will be battling lows all through, and when low they energy also goes low.&lt;/li>
&lt;li>Electrolytes work like magic, I tend to forget it sometimes.&lt;/li>
&lt;li>Our body is an amazing machine, adapts super fast, and learns to meet the moment, and with the latest devices like a CGM, and our current understanding of nutrition and metabolism, we can pretty much do anything being a T1D, with a little bit of learning, planning, and practice.&lt;/li>
&lt;li>The SIU pill worked wonders when I was questioning myself. The mind is everything, learning to train our minds to suck it up sometimes and fight off the inner voice or past bad habits is something that can be learned and practiced.&lt;/li>
&lt;li>I usually do things like this alone, but among all the bike rides the most I enjoyed was the one with my kid. There is something about doing physical feats with someone else for the mind and body, I definitely perform better, I compete with my 8-year-old :)&lt;/li>
&lt;li>This time I just got off the couch and did it, lucky to have not injured my knee. I plan to do this again when I am fit and fat-adapted and note the difference it makes then.&lt;/li>
&lt;/ul>
&lt;p>I dropped 3lbs in 48 hrs, which is mostly water weight, but the best part of it is I got a kick in my butt, a shock to my system, a restart of my healthy eating and exercising, and a bit of confidence back in myself. This is the way! The rock that my wife painted for me will be a reminder of what I could do on a weekend, no matter what shape in life I am in. Looking forward to doing this again next year and hope you will join me!&lt;/p>
&lt;hr>
&lt;p>&lt;em>Would love to hear your feedback: &lt;a class="link" href="mailto:santosh.mano@gmail.com" >santosh.mano@gmail.com&lt;/a>&lt;/em>&lt;/p>
&lt;p>&lt;em>Originally published on &lt;a class="link" href="https://medium.com/@santoshmano/couch-to-goggins-4x4x48-challenge-59deb50d071a" target="_blank" rel="noopener"
>Medium&lt;/a> on March 11, 2021.&lt;/em>&lt;/p></description></item><item><title>Exercise and Sugars</title><link>https://santoshmano.com/blog/exercise-and-sugars/</link><pubDate>Fri, 27 Jan 2017 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/exercise-and-sugars/</guid><description>&lt;img src="https://santoshmano.com/images/posts/exercise-bg-chart.jpg" alt="Featured image of post Exercise and Sugars" />&lt;p>Personal observations about how different exercise types affect blood glucose (BG) levels in diabetes management.&lt;/p>
&lt;h2 id="morning-context">Morning Context
&lt;/h2>&lt;p>I started with elevated blood sugar due to &amp;ldquo;Dawn Phenomenon and some unwise overeating of protein the previous night.&amp;rdquo; After breakfast and a 2-unit insulin correction, exercise began at 11 AM.&lt;/p>
&lt;h2 id="aerobic-exercise-phase">Aerobic Exercise Phase
&lt;/h2>&lt;p>One hour of walking at 140 HR (approximately 400 calories, 2.5 miles with incline) caused rapid BG decline to 55 mg/dL. The aerobic exercise (and the effect of my earlier correction insulin) got my BG down to 55.&lt;/p>
&lt;p>&lt;img src="https://santoshmano.com/images/posts/exercise-bg-chart.jpg"
loading="lazy"
alt="Blood Glucose Chart"
>&lt;/p>
&lt;h2 id="correction--anaerobic-exercise">Correction &amp;amp; Anaerobic Exercise
&lt;/h2>&lt;p>Consuming 12g carbs (3 glucose tablets) followed by shoulder weight training raised glucose to 123 mg/dL. I observed that &amp;ldquo;intense weight lifting&amp;rdquo; caused the elevation, contrasting with previous experiences where similar situations resulted in 65-80 mg/dL.&lt;/p>
&lt;h2 id="secondary-aerobic-phase">Secondary Aerobic Phase
&lt;/h2>&lt;p>Returning to cycling for 25 minutes (100 calories) reversed the trend, dropping BG to 85 mg/dL. Within 5 minutes of resuming aerobic activity, &amp;ldquo;my BG rise stopped and it started to drop down.&amp;rdquo;&lt;/p>
&lt;h2 id="conclusion">Conclusion
&lt;/h2>&lt;p>This represents &amp;ldquo;my conclusive 4th experiment&amp;rdquo; demonstrating: &lt;strong>how my BG goes down with Aerobic exercises and goes up with few Anaerobic exercises like lifting heavy weights.&lt;/strong>&lt;/p>
&lt;p>The pattern is clear:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Aerobic exercise&lt;/strong> (walking, cycling) → Blood glucose decreases&lt;/li>
&lt;li>&lt;strong>Anaerobic exercise&lt;/strong> (heavy weight lifting) → Blood glucose increases&lt;/li>
&lt;/ul></description></item><item><title>Endurance Exercises</title><link>https://santoshmano.com/blog/endurance-exercises/</link><pubDate>Mon, 09 Jan 2017 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/endurance-exercises/</guid><description>&lt;p>Five muscular endurance exercises sourced from Healthline to build strength and stamina.&lt;/p>
&lt;h2 id="1-plank">1. Plank
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/plank.jpg"
loading="lazy"
alt="Plank Exercise"
>&lt;/p>
&lt;ul>
&lt;li>Start prone with forearms supporting upper body&lt;/li>
&lt;li>Tighten and clench your lower back and shoulders to elevate your hips&lt;/li>
&lt;li>&lt;strong>Hold:&lt;/strong> 30-45 seconds per set&lt;/li>
&lt;li>&lt;strong>Sets:&lt;/strong> 5&lt;/li>
&lt;/ul>
&lt;h2 id="2-body-weight-squats">2. Body Weight Squats
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/squats.jpg"
loading="lazy"
alt="Squat Exercise"
>&lt;/p>
&lt;ul>
&lt;li>Stand with feet wider than shoulder-width&lt;/li>
&lt;li>Drop to 90-degree knee angle&lt;/li>
&lt;li>Drive your body weight through your heels and push yourself back upright&lt;/li>
&lt;li>&lt;strong>Reps:&lt;/strong> 25 repetitions&lt;/li>
&lt;li>&lt;strong>Sets:&lt;/strong> 5&lt;/li>
&lt;/ul>
&lt;h2 id="3-walking-lunges">3. Walking Lunges
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/lunges.jpg"
loading="lazy"
alt="Lunge Exercise"
>&lt;/p>
&lt;ul>
&lt;li>Stand with feet shoulder-width apart&lt;/li>
&lt;li>Step forward, drop hips until back leg touches ground&lt;/li>
&lt;li>&lt;strong>Reps:&lt;/strong> 30 lunges (15 per leg)&lt;/li>
&lt;li>&lt;strong>Sets:&lt;/strong> 5&lt;/li>
&lt;/ul>
&lt;h2 id="4-pushups">4. Pushups
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/pushups.jpg"
loading="lazy"
alt="Pushup Exercise"
>&lt;/p>
&lt;ul>
&lt;li>Start prone, push off ground into plank&lt;/li>
&lt;li>Lower yourself back downwards, letting your chest touch the ground&lt;/li>
&lt;li>&lt;strong>Reps:&lt;/strong> 15 repetitions&lt;/li>
&lt;li>&lt;strong>Sets:&lt;/strong> 5&lt;/li>
&lt;/ul>
&lt;h2 id="5-situps">5. Situps
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/situps.jpg"
loading="lazy"
alt="Situp Exercise"
>&lt;/p>
&lt;ul>
&lt;li>Lay supine with bent knees, feet flat&lt;/li>
&lt;li>Clench your stomach muscles to bring your torso up so that it&amp;rsquo;s flush&lt;/li>
&lt;li>&lt;strong>Reps:&lt;/strong> 25 repetitions&lt;/li>
&lt;li>&lt;strong>Sets:&lt;/strong> 5&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Source:&lt;/strong> &lt;a class="link" href="http://www.healthline.com/health/fitness-exercise/muscular-endurance-exercises" target="_blank" rel="noopener"
>Healthline - Muscular Endurance Exercises&lt;/a>&lt;/p></description></item><item><title>Grit Reading Material</title><link>https://santoshmano.com/blog/grit-reading-material/</link><pubDate>Sat, 24 Dec 2016 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/grit-reading-material/</guid><description>&lt;p>A compilation of learning resources focused on diabetes management and fitness.&lt;/p>
&lt;h2 id="dr-bernsteins-books">Dr. Bernstein&amp;rsquo;s Books
&lt;/h2>&lt;p>&lt;img src="https://santoshmano.com/images/posts/bernstein-book1.jpg"
loading="lazy"
alt="Dr. Bernsteins Diabetes Solution"
>
&lt;img src="https://santoshmano.com/images/posts/bernstein-book2.jpg"
loading="lazy"
alt="Dr. Bernsteins Book"
>&lt;/p>
&lt;h2 id="key-resources">Key Resources
&lt;/h2>&lt;h3 id="books--audiobooks">Books &amp;amp; Audiobooks
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Diabetes Solution&lt;/strong> - Available on &lt;a class="link" href="https://www.audible.com" target="_blank" rel="noopener"
>Audible&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="video-resources">Video Resources
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Dr. Bernstein&amp;rsquo;s Diabetes University&lt;/strong> - Comprehensive video playlist covering diabetes management&lt;/li>
&lt;li>&lt;strong>Dr. Dikeman&amp;rsquo;s Presentation&lt;/strong> - Low Carb USA conference talk&lt;/li>
&lt;/ul>
&lt;h3 id="online-collections">Online Collections
&lt;/h3>&lt;ul>
&lt;li>&lt;strong>Pinterest Boards&lt;/strong> - &lt;a class="link" href="https://www.pinterest.com/typeonegrit/boards/" target="_blank" rel="noopener"
>TypeOneGrit Boards&lt;/a>&lt;/li>
&lt;li>&lt;strong>Google Photos&lt;/strong> - Collection of quotes and excerpts&lt;/li>
&lt;li>&lt;strong>Grit Recipes&lt;/strong> - Recipe collection for diabetes management&lt;/li>
&lt;/ul>
&lt;h2 id="about-these-resources">About These Resources
&lt;/h2>&lt;p>This curated bibliography provides evidence-based approaches to managing type 1 diabetes through dietary and exercise interventions. The materials emphasize practical strategies for blood glucose control and long-term health outcomes.&lt;/p></description></item><item><title>Standard Input and Output Redirection</title><link>https://santoshmano.com/blog/standard-input-output-redirection/</link><pubDate>Thu, 21 Mar 2013 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/standard-input-output-redirection/</guid><description>&lt;p>This post explains how the shell and Unix commands handle input/output streams and how to redirect them.&lt;/p>
&lt;h2 id="overview">Overview
&lt;/h2>&lt;p>&amp;ldquo;The shell and many UNIX commands take their input from standard input (stdin), write output to standard output (stdout), and write error output to standard error (stderr).&amp;rdquo;&lt;/p>
&lt;p>By default, stdin connects to the keyboard while stdout and stderr display on the terminal screen. File redirection uses metacharacters to specify alternative destinations.&lt;/p>
&lt;h2 id="c-shell-family">C Shell Family
&lt;/h2>&lt;p>Key redirection operators:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Character&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&lt;/code>&lt;/td>
&lt;td>Redirect standard output&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&amp;amp;&lt;/code>&lt;/td>
&lt;td>Redirect stdout and stderr&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>!&lt;/code>&lt;/td>
&lt;td>Redirect stdout; overwrite existing file&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&amp;amp;!&lt;/code>&lt;/td>
&lt;td>Redirect stdout/stderr; force overwrite&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>|&lt;/td>
&lt;td>Pipe stdout to another command&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&amp;gt;&lt;/code>&lt;/td>
&lt;td>Append to stdout&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&amp;gt;&amp;amp;&lt;/code>&lt;/td>
&lt;td>Append stdout and stderr&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Example commands:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>who &amp;gt; names&lt;/code> — save output to file&lt;/li>
&lt;li>&lt;code>(pwd; ls -l) &amp;gt; out&lt;/code> — redirect multiple commands&lt;/li>
&lt;li>&lt;code>who &amp;gt;&amp;amp; /dev/null&lt;/code> — suppress all output&lt;/li>
&lt;/ul>
&lt;h2 id="bourne-shell-family">Bourne Shell Family
&lt;/h2>&lt;p>Uses numeric file descriptors (0=stdin, 1=stdout, 2=stderr):&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Character&lt;/th>
&lt;th>Action&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&lt;/code>&lt;/td>
&lt;td>Redirect stdout&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>2&amp;gt;&lt;/code>&lt;/td>
&lt;td>Redirect stderr&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>2&amp;gt;&amp;amp;1&lt;/code>&lt;/td>
&lt;td>Redirect stderr to stdout&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>&amp;gt;&amp;gt;&lt;/code>&lt;/td>
&lt;td>Append stdout&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>2&amp;gt;&amp;amp;1|&lt;/code>&lt;/td>
&lt;td>Pipe both streams&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Example commands:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>who &amp;gt; names&lt;/code> — redirect output&lt;/li>
&lt;li>&lt;code>who 2&amp;gt; /dev/null&lt;/code> — suppress errors only&lt;/li>
&lt;li>&lt;code>cat file &amp;gt; out 2&amp;gt; error&lt;/code> — separate output and error files&lt;/li>
&lt;/ul>
&lt;h2 id="source">Source
&lt;/h2>&lt;p>Reference material adapted from &lt;a class="link" href="http://www.mathinfo.u-picardie.fr/" target="_blank" rel="noopener"
>Math/CS at University of Picardie&lt;/a>&lt;/p></description></item><item><title>Bit Twiddling Hacks</title><link>https://santoshmano.com/blog/bit-twiddling-hacks/</link><pubDate>Mon, 07 Feb 2011 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/bit-twiddling-hacks/</guid><description>&lt;p>An excellent resource on bit manipulation techniques and low-level bitwise operations.&lt;/p>
&lt;h2 id="resource">Resource
&lt;/h2>&lt;p>Check out &lt;a class="link" href="http://graphics.stanford.edu/~seander/bithacks.html#OperationCounting" target="_blank" rel="noopener"
>Bit Twiddling Hacks&lt;/a> by Sean Eron Anderson at Stanford&amp;rsquo;s graphics lab.&lt;/p>
&lt;p>This comprehensive guide covers various bitwise operations and optimizations, including:&lt;/p>
&lt;ul>
&lt;li>Counting set bits&lt;/li>
&lt;li>Determining if integers have opposite signs&lt;/li>
&lt;li>Computing absolute values without branching&lt;/li>
&lt;li>Swapping values without temporary variables&lt;/li>
&lt;li>Finding minimum/maximum without branching&lt;/li>
&lt;li>And many more clever bit manipulation techniques&lt;/li>
&lt;/ul>
&lt;p>These techniques are particularly useful for performance-critical code and understanding low-level programming concepts.&lt;/p></description></item><item><title>Algorithmic Efficiency - Various Orders and Examples</title><link>https://santoshmano.com/blog/algorithmic-efficiency/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/algorithmic-efficiency/</guid><description>&lt;p>This post discusses various algorithmic time complexities and their practical examples.&lt;/p>
&lt;h2 id="o1---constant-time">O(1) - Constant Time
&lt;/h2>&lt;p>An algorithm that runs the same no matter what the input exemplifies constant time complexity, returning identical results regardless of input size.&lt;/p>
&lt;h2 id="olog-n---logarithmic-time">O(log n) - Logarithmic Time
&lt;/h2>&lt;p>Binary search trees and binary search algorithms demonstrate logarithmic efficiency. A balanced binary search tree requires traversing one node per layer, with only log(n) total layers. Binary search divides an ordered array repeatedly, requiring at most log(n) divisions.&lt;/p>
&lt;h2 id="on---linear-time">O(n) - Linear Time
&lt;/h2>&lt;p>Linear search algorithms checking each element sequentially represent linear time complexity. Linked list access operations also exhibit O(n) behavior due to lack of random access support.&lt;/p>
&lt;h2 id="on-log-n---linearithmic-time">O(n log n) - Linearithmic Time
&lt;/h2>&lt;p>Merge sort exemplifies this efficiency class. The algorithm &amp;ldquo;breaks up an array into two halves, sorts those two halves by recursively calling itself on them, and then merging the result back&amp;rdquo; yielding O(n log n) overall complexity.&lt;/p>
&lt;h2 id="on---quadratic-time">O(n²) - Quadratic Time
&lt;/h2>&lt;p>Selection sort and comparable algorithms operate within polynomial time, representing reasonable but less efficient solutions.&lt;/p>
&lt;h2 id="o2ⁿ---exponential-time">O(2ⁿ) - Exponential Time
&lt;/h2>&lt;p>Exponential algorithms address difficult problems like factoring large binary numbers. Trial-and-error approaches require &amp;ldquo;twice as many tests&amp;rdquo; per additional digit, demonstrating impractical scalability.&lt;/p>
&lt;p>&lt;strong>Source:&lt;/strong> cprogramming.com&lt;/p></description></item><item><title>IBM Instant Capacity Products</title><link>https://santoshmano.com/blog/ibm-instant-capacity/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/ibm-instant-capacity/</guid><description>&lt;p>IBM offers several Capacity on Demand (CoD) solutions designed to help organizations activate processors and memory without disrupting operations.&lt;/p>
&lt;h2 id="ibms-product-offerings">IBM&amp;rsquo;s Product Offerings
&lt;/h2>&lt;h3 id="1-capacity-upgrade-on-demand-permanent">1. Capacity Upgrade on Demand (Permanent)
&lt;/h3>&lt;p>Enables dynamic activation of processors and memory in single processor or 1GB memory increments. Users receive encrypted activation codes via the internet with no hardware shipping required.&lt;/p>
&lt;h3 id="2-trial-capacity-on-demand">2. Trial Capacity on Demand
&lt;/h3>&lt;p>Provides 30-day trial periods for evaluating additional capacity.&lt;/p>
&lt;h3 id="3-onoff-capacity-on-demand-manual">3. On/Off Capacity on Demand (Manual)
&lt;/h3>&lt;p>Allows short-term activation similar to Ticap offerings.&lt;/p>
&lt;h3 id="4-utility-capacity-on-demand-automatic">4. Utility Capacity on Demand (Automatic)
&lt;/h3>&lt;p>Automatically manages processor allocation from shared pools, measured in processor-minute increments for unpredictable workload spikes.&lt;/p>
&lt;h3 id="5-capacity-backup">5. Capacity BackUp
&lt;/h3>&lt;p>Designed for disaster recovery with &amp;ldquo;a minimum set of active processors&amp;rdquo; and numerous inactive processors available for emergency activation. Includes complimentary activation days.&lt;/p>
&lt;h2 id="key-features">Key Features
&lt;/h2>&lt;p>Capacity on Demand allows you to easily activate processors and memory without disruption to your operations, paying for increased capacity as needs grow.&lt;/p>
&lt;p>Both prepay and post-pay options are available for most solutions.&lt;/p>
&lt;h2 id="note">Note
&lt;/h2>&lt;p>Finding IBM&amp;rsquo;s GICAP equivalent to HP&amp;rsquo;s offering in this category proved difficult.&lt;/p></description></item><item><title>Linux RPM Commands</title><link>https://santoshmano.com/blog/linux-rpm-commands/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/linux-rpm-commands/</guid><description>&lt;p>This post provides a quick reference guide for common RPM (Red Hat Package Manager) commands used in Linux systems.&lt;/p>
&lt;h2 id="basic-package-operations">Basic Package Operations
&lt;/h2>&lt;p>&lt;strong>List installed packages:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -qa
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Install a package:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -ivh foo-1.0-2.i386.rpm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Test installation (without actually installing):&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -ivh --test pkgname
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Remove a package:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -e foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Upgrade a package:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -Uvh foo-1.0-2.i386.rpm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Freshen a package (upgrade only if previous version exists):&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -Fvh pkgname
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="query-and-information-commands">Query and Information Commands
&lt;/h2>&lt;p>&lt;strong>Query a package:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -q foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Display package information:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -qi foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>List files in a package:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -ql foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Find which package a file belongs to:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -qf filename
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Display file list and package information:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm -qfl pkgname
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="package-verification">Package Verification
&lt;/h2>&lt;p>&lt;strong>Check RPM signature:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">rpm --checksig foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="operation-reference-table">Operation Reference Table
&lt;/h2>&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Operation&lt;/th>
&lt;th>Short Option&lt;/th>
&lt;th>Long Option&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Upgrade/install&lt;/td>
&lt;td>-U&lt;/td>
&lt;td>&amp;ndash;upgrade&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Install&lt;/td>
&lt;td>-I&lt;/td>
&lt;td>&amp;ndash;install&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Remove&lt;/td>
&lt;td>-e&lt;/td>
&lt;td>&amp;ndash;erase&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Query&lt;/td>
&lt;td>-q&lt;/td>
&lt;td>&amp;ndash;query&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Verify&lt;/td>
&lt;td>-V&lt;/td>
&lt;td>&amp;ndash;verify&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Check signature&lt;/td>
&lt;td>-K&lt;/td>
&lt;td>&amp;ndash;checksig&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Freshen&lt;/td>
&lt;td>-F&lt;/td>
&lt;td>&amp;ndash;freshen&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Initialize database&lt;/td>
&lt;td>—&lt;/td>
&lt;td>&amp;ndash;initdb&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Rebuild database&lt;/td>
&lt;td>—&lt;/td>
&lt;td>&amp;ndash;rebuilddb&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Source:&lt;/strong> &lt;a class="link" href="http://docs.fedoraproject.org/drafts/rpm-guide-en/ch02s03.html" target="_blank" rel="noopener"
>Fedora RPM Guide&lt;/a>&lt;/p></description></item><item><title>Sort Benchmark</title><link>https://santoshmano.com/blog/sort-benchmark/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/sort-benchmark/</guid><description>&lt;p>Check out comprehensive sorting algorithm benchmarks at &lt;a class="link" href="http://sortbenchmark.org/" target="_blank" rel="noopener"
>sortbenchmark.org&lt;/a>.&lt;/p>
&lt;p>This site provides detailed performance comparisons and benchmarks for various sorting algorithms across different data sets and conditions.&lt;/p></description></item><item><title>Steps to Create a Filesystem on HPUX</title><link>https://santoshmano.com/blog/hpux-filesystem-creation/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/hpux-filesystem-creation/</guid><description>&lt;p>A comprehensive guide to creating filesystems on HP-UX systems using Logical Volume Manager (LVM).&lt;/p>
&lt;h2 id="check-list-of-disks-available">Check List of Disks Available
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ioscan -funC disk&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Class I H/W Path Driver S/W State H/W Type &lt;span class="nv">Description&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">=======================================================================&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">disk &lt;span class="m">3&lt;/span> 0/0/0/2/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAS3367NC
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c0t6d0 /dev/dsk/c0t6d0s2 /dev/rdsk/c0t6d0 /dev/rdsk/c0t6d0s2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c0t6d0s1 /dev/dsk/c0t6d0s3 /dev/rdsk/c0t6d0s1 /dev/rdsk/c0t6d0s3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">disk &lt;span class="m">0&lt;/span> 0/0/0/2/1.2.0 sdisk CLAIMED DEVICE HP DVD-ROM &lt;span class="m">305&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c1t2d0 /dev/rdsk/c1t2d0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">disk &lt;span class="m">4&lt;/span> 0/0/0/3/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAP3367NC
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c2t6d0 /dev/dsk/c2t6d0s2 /dev/rdsk/c2t6d0 /dev/rdsk/c2t6d0s2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c2t6d0s1 /dev/dsk/c2t6d0s3 /dev/rdsk/c2t6d0s1 /dev/rdsk/c2t6d0s3
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="check-disks-already-in-use">Check Disks Already in Use
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># strings /etc/lvmtab&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/dsk/c0t6d0s2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="create-filesystem-using-free-disk">Create Filesystem Using Free Disk
&lt;/h2>&lt;h3 id="step-1-create-physical-volume">Step 1: Create Physical Volume
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># pvcreate -f /dev/rdsk/c2t6d0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Physical volume &lt;span class="s2">&amp;#34;/dev/rdsk/c2t6d0&amp;#34;&lt;/span> has been successfully created.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="step-2-create-volume-group-directory-and-device-node">Step 2: Create Volume Group Directory and Device Node
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># mkdir /dev/vg01&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># mknod /dev/vg01/group c 64 0x010000&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="step-3-create-volume-group">Step 3: Create Volume Group
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># vgcreate /dev/vg01 /dev/dsk/c2t6d0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Increased the number of physical extents per physical volume to 8683.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Volume group &lt;span class="s2">&amp;#34;/dev/vg01&amp;#34;&lt;/span> has been successfully created.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Volume Group configuration &lt;span class="k">for&lt;/span> /dev/vg01 has been saved in /etc/lvmconf/vg01.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="step-4-create-logical-volume">Step 4: Create Logical Volume
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># lvcreate -L 20000 -n depot /dev/vg01&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Logical volume &lt;span class="s2">&amp;#34;/dev/vg01/depot&amp;#34;&lt;/span> has been successfully created with character device &lt;span class="s2">&amp;#34;/dev/vg01/rdepot&amp;#34;&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Logical volume &lt;span class="s2">&amp;#34;/dev/vg01/depot&amp;#34;&lt;/span> has been successfully extended.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Volume Group configuration &lt;span class="k">for&lt;/span> /dev/vg01 has been saved in /etc/lvmconf/vg01.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="step-5-create-filesystem">Step 5: Create Filesystem
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># mkfs -F vxfs /dev/vg01/rdepot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">version &lt;span class="m">6&lt;/span> layout
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">20480000&lt;/span> sectors, &lt;span class="m">20480000&lt;/span> blocks of size 1024, log size &lt;span class="m">16384&lt;/span> blocks
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">largefiles supported
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="step-6-create-mount-point-and-mount-filesystem">Step 6: Create Mount Point and Mount Filesystem
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># mkdir /depot&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># mount /dev/vg01/depot /depot&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="configure-automatic-mounting-on-reboot">Configure Automatic Mounting on Reboot
&lt;/h2>&lt;p>Edit &lt;code>/etc/fstab&lt;/code> to add the new filesystem:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># System /etc/fstab file. Static information about the file systems&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># See fstab(4) and sam(1M) for further details on configuring devices.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol3 / vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol1 /stand vxfs tranflush &lt;span class="m">0&lt;/span> &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol4 /tmp vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol5 /home vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol6 /opt vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol7 /usr vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg00/lvol8 /var vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/dev/vg01/depot /depot vxfs delaylog &lt;span class="m">0&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>The filesystem will now mount automatically on system reboot.&lt;/p></description></item><item><title>Sun's Instant Capacity Offerings</title><link>https://santoshmano.com/blog/sun-instant-capacity/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/sun-instant-capacity/</guid><description>&lt;p>Sun Microsystems offers Capacity on Demand (COD) solutions for enterprise infrastructure management.&lt;/p>
&lt;h2 id="resources">Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;a class="link" href="http://www.sun.com/datacenter/cod/COD_BuyersGuide.pdf" target="_blank" rel="noopener"
>COD Buyers Guide PDF&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="http://www.sun.com/datacenter/cod/SUN_COD_datasheet.pdf" target="_blank" rel="noopener"
>SUN COD Datasheet PDF&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>These documents provide comprehensive information about Sun&amp;rsquo;s capacity planning and on-demand resource allocation offerings.&lt;/p></description></item><item><title>The Invaluable Find Command</title><link>https://santoshmano.com/blog/invaluable-find-command/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/invaluable-find-command/</guid><description>&lt;p>A powerful command-line technique for searching file contents across a directory structure:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">find . -name &lt;span class="s2">&amp;#34;*&amp;#34;&lt;/span> -exec grep string &lt;span class="o">{}&lt;/span> &lt;span class="se">\;&lt;/span> -print
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>This command searches the current directory and all subdirectories for files containing a specified string pattern. The &lt;code>find&lt;/code> command locates files, while &lt;code>grep&lt;/code> searches within each file for the specified string.&lt;/p></description></item><item><title>The Linux Documentation Project</title><link>https://santoshmano.com/blog/linux-documentation-project/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/linux-documentation-project/</guid><description>&lt;p>Pretty neat documentation at &lt;a class="link" href="http://tldp.org/" target="_blank" rel="noopener"
>tldp.org&lt;/a>&lt;/p>
&lt;h2 id="key-resources">Key Resources
&lt;/h2>&lt;ul>
&lt;li>&lt;strong>The Linux Kernel&lt;/strong> - Documentation covering core kernel topics&lt;/li>
&lt;li>&lt;strong>The Linux Programmer&amp;rsquo;s Guide&lt;/strong> - Features comprehensive coverage of inter-process communication (IPC) mechanisms&lt;/li>
&lt;/ul>
&lt;p>The Linux Documentation Project provides comprehensive reference materials for Linux developers and system administrators.&lt;/p></description></item><item><title>Virtualization for Dummies</title><link>https://santoshmano.com/blog/virtualization-for-dummies/</link><pubDate>Sat, 04 Sep 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/virtualization-for-dummies/</guid><description>&lt;p>A foundational educational document about virtualization technology is available from Sun and AMD.&lt;/p>
&lt;p>&amp;ldquo;Virtualization for Dummies&amp;rdquo; is a beginner-friendly guide that explains core virtualization concepts, perfect for those getting started with virtualization technologies.&lt;/p>
&lt;p>This collaborative resource from Sun and AMD provides accessible explanations of fundamental virtualization principles and practices.&lt;/p></description></item><item><title>C Traps and Pitfalls</title><link>https://santoshmano.com/blog/c-traps-and-pitfalls/</link><pubDate>Sun, 15 Aug 2010 00:00:00 -0700</pubDate><guid>https://santoshmano.com/blog/c-traps-and-pitfalls/</guid><description>&lt;p>&lt;a class="link" href="http://literateprogramming.com/ctraps.pdf" target="_blank" rel="noopener"
>Click here&lt;/a> to jump to a nice writeup on C&amp;rsquo;s traps and pitfalls.&lt;/p>
&lt;p>This comprehensive resource explores common mistakes and tricky aspects developers encounter when working with C, covering situations where the language&amp;rsquo;s design can lead to unexpected behavior or code errors.&lt;/p></description></item><item><title>Archives</title><link>https://santoshmano.com/archives/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://santoshmano.com/archives/</guid><description/></item><item><title>Search</title><link>https://santoshmano.com/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://santoshmano.com/search/</guid><description>&lt;div class="search-container">
&lt;input type="text" id="search-input" placeholder="Search posts, tags, categories..." autofocus style="width: 100%; padding: 1rem; font-size: 1.1rem; border: 2px solid #5fb878; border-radius: 8px; background: var(--card-background); color: var(--card-text-color-main); margin-bottom: 2rem;">
&lt;div id="search-results">&lt;/div>
&lt;/div>
&lt;script src="https://cdn.jsdelivr.net/npm/fuse.js@6.6.2">&lt;/script>
&lt;script>
let searchData = [];
let fuse = null;
// Load search index
fetch('/index.json')
.then(response => response.json())
.then(data => {
searchData = data;
// Configure Fuse.js
const options = {
keys: [
{ name: 'title', weight: 0.4 },
{ name: 'content', weight: 0.3 },
{ name: 'tags', weight: 0.2 },
{ name: 'categories', weight: 0.1 }
],
threshold: 0.3,
includeScore: true,
minMatchCharLength: 2
};
fuse = new Fuse(searchData, options);
// Check for query parameter (supports both 'q' and 'keyword')
const urlParams = new URLSearchParams(window.location.search);
const query = urlParams.get('q') || urlParams.get('keyword');
if (query) {
document.getElementById('search-input').value = query;
performSearch(query);
}
})
.catch(err => console.error('Failed to load search index:', err));
// Search input handler
const searchInput = document.getElementById('search-input');
const searchResults = document.getElementById('search-results');
searchInput.addEventListener('input', (e) => {
const query = e.target.value;
if (query.length &lt; 2) {
searchResults.innerHTML = '';
return;
}
performSearch(query);
});
function performSearch(query) {
if (!fuse) return;
const results = fuse.search(query);
if (results.length === 0) {
searchResults.innerHTML = '&lt;p style="text-align: center; color: rgba(255, 255, 255, 0.6); padding: 2rem;">No results found&lt;/p>';
return;
}
let html = '&lt;div style="display: flex; flex-direction: column; gap: 1.5rem;">';
results.slice(0, 20).forEach(result => {
const item = result.item;
html += `
&lt;article style="padding: 1.5rem; background: var(--card-background); border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.1);">
&lt;h3 style="margin: 0 0 0.5rem 0;">&lt;a href="${item.permalink}" style="color: #5fb878; text-decoration: none;">${item.title}&lt;/a>&lt;/h3>
&lt;div style="display: flex; gap: 1rem; margin-bottom: 0.75rem; font-size: 0.9rem; color: rgba(255, 255, 255, 0.6);">
&lt;span>${item.date}&lt;/span>
${item.categories &amp;&amp; item.categories.length > 0 ?
`&lt;span style="background: #5fb878; color: #000; padding: 2px 8px; border-radius: 4px;">${item.categories[0]}&lt;/span>` : ''}
&lt;/div>
&lt;p style="color: rgba(255, 255, 255, 0.8); line-height: 1.6; margin: 0.75rem 0;">${truncate(item.summary || item.content, 200)}&lt;/p>
&lt;div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem;">
${item.tags ? item.tags.map(tag => `&lt;span style="background: rgba(95, 184, 120, 0.2); color: #5fb878; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">${tag}&lt;/span>`).join('') : ''}
&lt;/div>
&lt;/article>
`;
});
html += '&lt;/div>';
searchResults.innerHTML = html;
}
function truncate(str, length) {
if (!str) return '';
if (str.length &lt;= length) return str;
return str.substring(0, length) + '...';
}
// Add keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
searchInput.blur();
}
});
// Add Enter key support
searchInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
const query = searchInput.value;
if (query.length >= 2) {
performSearch(query);
}
}
});
&lt;/script>
&lt;script>
// Add Enter key support to sidebar search widget
document.addEventListener('DOMContentLoaded', () => {
// Find the sidebar search input
const sidebarSearch = document.querySelector('aside.right-sidebar input[type="text"]');
if (sidebarSearch) {
sidebarSearch.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
const query = sidebarSearch.value.trim();
if (query) {
window.location.href = `/search/?keyword=${encodeURIComponent(query)}`;
}
}
});
}
});
&lt;/script></description></item></channel></rss>