[{"title":"Debugging Process Hangs on Mac: A Systematic Approach","date":"2025-11-10","permalink":"https://santoshmano.com/blog/debugging-process-hangs-on-mac/","summary":"I ran into a deadlock recently while testing Claude Code. Running /mcp reconnect playwright in a project without Playwright configured would show an error, then immediately freeze the entire session. Couldn\u0026rsquo;t type, Escape did nothing - had to kill -9 it.\nThis seemed like a good opportunity to practice systematic debugging and document the process. Here\u0026rsquo;s how I tracked down the root cause.\nThe Problem Command: /mcp reconnect playwright Response: ✘ Failed to reconnect to playwright / Error: MCP server \u0026quot;playwright\u0026quot; not found Result: Complete freeze, no recovery possible Reproducing the Issue Before diving into debugging, I needed to confirm this wasn\u0026rsquo;t a one-off fluke. I killed the frozen process and tried again:\n","content":"I ran into a deadlock recently while testing Claude Code. Running /mcp reconnect playwright in a project without Playwright configured would show an error, then immediately freeze the entire session. Couldn\u0026rsquo;t type, Escape did nothing - had to kill -9 it.\nThis seemed like a good opportunity to practice systematic debugging and document the process. Here\u0026rsquo;s how I tracked down the root cause.\nThe Problem Command: /mcp reconnect playwright Response: ✘ Failed to reconnect to playwright / Error: MCP server \u0026quot;playwright\u0026quot; not found Result: Complete freeze, no recovery possible Reproducing the Issue Before diving into debugging, I needed to confirm this wasn\u0026rsquo;t a one-off fluke. I killed the frozen process and tried again:\nOpen a fresh Claude session Navigate to a project without Playwright configured Run /mcp reconnect playwright Wait for error message Try to type anything → frozen Result: 100% reproducible. Same freeze every time.\nThis is critical. If you can\u0026rsquo;t reproduce a bug, you\u0026rsquo;re mostly guessing. Reproducibility means:\nYou can test your hypothesis You can verify your fix You can provide clear steps in a bug report One-off hangs? Document what you saw, but don\u0026rsquo;t spend hours debugging something that might never happen again.\nFinding the Hanging Process I had multiple Claude sessions running in tmux panes. First problem: which process was actually stuck?\n1 ps aux | grep claude This gave me several PIDs. But which one was frozen? I needed to match the PID to the working directory:\n1 lsof -p 12061 -p 36125 -p 44674 -p 48811 | grep cwd Output showed PID 48811 was in the aisystemsprimer directory - that\u0026rsquo;s where I reproduced the bug. Found it.\nFirst Attempt: USR2 Signal My initial instinct was to get a diagnostic report using Node.js\u0026rsquo;s built-in signal handler:\n1 kill -USR2 48811 This killed the process outright instead of generating a report. Makes sense in retrospect - if the event loop is deadlocked, signal handlers can\u0026rsquo;t execute. The process can\u0026rsquo;t respond to anything.\nGetting a Stack Trace On macOS, sample is the right tool for this. It profiles a process without disturbing it:\n1 sample 48811 5 -file ~/stack_trace.txt The -file flag saves output to a file. The 5 means sample for 5 seconds.\nThe stack trace showed the main thread stuck here:\n+ 3913 uv__io_poll (in libuv.1.0.0.dylib) + 724 + 3913 kevent (in libsystem_kernel.dylib) + 8 The event loop was blocked in kevent(), waiting for I/O that would never arrive. Classic deadlock pattern.\nWhat Was It Waiting For? Time to check file descriptors:\n1 lsof -p 48811 | grep PIPE Output:\nnode 48811 sandman 13 PIPE 0xac44d11643cbe7d8 16384 -\u0026gt;0x301027970e85d0dd node 48811 sandman 14 PIPE 0x301027970e85d0dd 16384 -\u0026gt;0xac44d11643cbe7d8 Two open pipes. These are typically used for IPC (inter-process communication) with child processes. But was there a child process?\n1 ps -o pid,ppid,command | awk \u0026#39;$2 == 48811\u0026#39; Nothing. No child process.\nThe 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\u0026rsquo;t exist.\nChecking Debug Logs Claude Code keeps debug logs in ~/.claude/debug/. I needed to find the log for this session:\n1 grep -l \u0026#34;tmp.48811\u0026#34; ~/.claude/debug/*.txt Found: 6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt\n1 tail -100 ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt Last entries:\n[DEBUG] Getting matching hook commands for SubagentStop with query: undefined [DEBUG] Found 0 hook matchers in settings [DEBUG] AutoUpdaterWrapper: Installation type: npm-global Then I searched for MCP-related activity:\n1 grep -i \u0026#34;mcp\\|reconnect\\|playwright\u0026#34; ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt Zero results. The /mcp reconnect command was never logged, which means the hang happened before the event loop could process the next iteration.\nComparing With a Working Session I checked a working session\u0026rsquo;s logs where Playwright MCP was properly configured:\n1 tail -100 ~/.claude/debug/7928bf05-1443-4731-ba34-50369be48ec9.txt | grep -i mcp [DEBUG] MCP server \u0026#34;playwright\u0026#34;: Successfully connected to stdio server in 637ms [DEBUG] MCP server \u0026#34;playwright\u0026#34;: Connection established with capabilities: {...} Clear difference: working sessions complete the entire connection flow.\nRoot Cause Connecting the evidence:\nError message displays correctly (\u0026ldquo;MCP server not found\u0026rdquo;) Despite the error, code attempts to connect anyway Opens pipes for IPC with the would-be child process Child process spawn fails (silently) Main thread blocks on kevent() waiting for I/O from non-existent child No timeout implemented Deadlock The /mcp reconnect command doesn\u0026rsquo;t validate server existence before attempting connection. It allocates resources (pipes) then blocks indefinitely waiting for a process that never started.\nCollecting Evidence I organized everything for the bug report:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 mkdir ~/claude_hang_bug_report # Hanging session log cp ~/.claude/debug/6c752d67-d15d-4ae1-b12b-723ab852f4eb.txt \\ ~/claude_hang_bug_report/hanging_session_log.txt # Stack trace cp ~/stack_trace.txt ~/claude_hang_bug_report/ # Working session for comparison cp ~/.claude/debug/7928bf05-1443-4731-ba34-50369be48ec9.txt \\ ~/claude_hang_bug_report/working_session_log.txt # Full lsof output lsof -p 48811 \u0026gt; ~/claude_hang_bug_report/lsof_full.txt # Process state ps -p 48811 -o pid,ppid,state,etime,%cpu,%mem,command \u0026gt; \\ ~/claude_hang_bug_report/process_state.txt # System info claude --version \u0026gt; ~/claude_hang_bug_report/system_info.txt node --version \u0026gt;\u0026gt; ~/claude_hang_bug_report/system_info.txt sw_vers \u0026gt;\u0026gt; ~/claude_hang_bug_report/system_info.txt The Tools ps - Process listing. Shows PIDs, resource usage, process states. Essential for identifying which process is the problem.\nlsof - List open files. Critical for seeing file descriptors, sockets, pipes. In this case, revealed the open pipes with no corresponding child process.\nsample - macOS sampling profiler. Non-invasive stack trace collection. Showed exactly where the process was stuck (kevent() in the event loop).\ngrep - Pattern search through logs. Here, the absence of \u0026ldquo;mcp\u0026rdquo; in logs was as informative as any error message.\nProcess tree analysis - ps -o pid,ppid,command to check parent-child relationships. The missing child process was key evidence.\nDebug Flow Here\u0026rsquo;s the systematic approach:\ngraph TD A[Process Hung] --\u003e B{Can Reproduce?} B --\u003e|No| C[Document What Happened] C --\u003e D[Monitor for Recurrence] B --\u003e|Yes| E[Identify PID] E --\u003e F[Check Working Directory] F --\u003e G{Correct Process?} G --\u003e|No| E G --\u003e|Yes| H[Capture Stack Trace] H --\u003e I[Analyze File Descriptors] I --\u003e J[Check Process Tree] J --\u003e K[Review Debug Logs] K --\u003e L[Compare with Working Case] L --\u003e M[Form Hypothesis] M --\u003e N[Collect Evidence] N --\u003e O[Write Up Notes] O --\u003e P[File Bug Report] style B fill:#fff3e0 style O fill:#e8f5e9 style P fill:#e8f5e9 Step by step:\n0. Try to reproduce - Before deep investigation, confirm you can trigger the hang consistently\nIf not reproducible: Document what happened, save any logs, move on If reproducible: Proceed with systematic debugging 1. Isolate the affected process - Use lsof to verify working directory\nMultiple processes running? Match PID to the right directory lsof -p PID1 -p PID2 | grep cwd 2. Capture state non-invasively\nsample PID duration for stack trace lsof -p PID for file descriptors ps -o pid,ppid,command for process tree Don\u0026rsquo;t use kill -USR2 on a hung process - it may kill it instead 3. Analyze what you captured\nStack trace → where it\u0026rsquo;s stuck (kevent) File descriptors → what it\u0026rsquo;s waiting for (pipes) Process tree → missing child process Logs → when it stopped (before command execution) 4. Compare with working case - Identify where behavior diverges\nRun the command in a working scenario Note what happens differently 5. Form hypothesis - Connect evidence to root cause\nEvent loop blocked waiting for child process that never spawned 6. Write up notes - Document your findings before losing context\nSteps to reproduce Evidence collected (stack traces, file descriptors, logs) Hypothesis about root cause Screenshots or terminal output if helpful 7. File bug report - Share your investigation with maintainers\nInclude reproduction steps Attach diagnostic data Link to your notes or GitHub issue Key Lessons Reproducibility is everything - Don\u0026rsquo;t spend hours debugging something you can\u0026rsquo;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.\nWrite up notes before you forget - 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.\nVerify assumptions early - I initially guessed which process was hanging based on timing. Using lsof to check the working directory confirmed it immediately.\nUse non-invasive tools first - kill -USR2 killed the process. sample captured what I needed without disturbing anything.\nAbsence is information - No MCP log entries told me the command never executed, which narrowed down where the bug occurred.\nCompare working vs broken - Seeing what should happen makes it much clearer what went wrong.\nStack traces reveal mechanisms - Seeing kevent() immediately suggested an event loop issue, which directed me toward IPC investigation.\nFile descriptors don\u0026rsquo;t lie - Open pipes with no child process was definitive proof the spawn failed.\nCollect before killing - Once you kill the process, all evidence disappears. Get stack traces and state snapshots while it\u0026rsquo;s frozen.\nThe GitHub Issue I filed a detailed bug report including:\nExact reproduction steps Stack trace showing kevent() deadlock File descriptor analysis (open pipes, no child process) Debug log evidence (command never logged) Working session comparison for contrast Root cause hypothesis with supporting evidence All collected diagnostic data as attachments Impact: High severity - complete session loss, no recovery possible, 100% reproducible\nRoot cause: Missing validation check + no timeout in MCP reconnection logic\nQuick Reference Tool Purpose Example ps List processes ps aux | grep process_name lsof View open files/descriptors lsof -p PID | grep PIPE sample Get stack trace sample PID 5 -file trace.txt grep Search logs grep -i \u0026quot;error\u0026quot; logfile.txt kill Send signals kill -USR2 PID 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\u0026rsquo;re stuck with a hung process, these macOS tools give you everything you need to figure out why.\nFiled: https://github.com/anthropics/claude-code/issues/11385\n","tags":["debugging","macos","unix","troubleshooting"],"categories":["Engineering"]},{"title":"Flowchart Symbols and How to Use Them","date":"2025-01-13","permalink":"https://santoshmano.com/blog/flowchart-symbols-guide/","summary":"I\u0026rsquo;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.\nHere\u0026rsquo;s a practical guide to flowchart symbols and how to actually use them.\nWhy Flowcharts Matter Before we get into symbols, here\u0026rsquo;s why flowcharts are still relevant:\nThey force clarity. If you can\u0026rsquo;t draw a flowchart of your process, you don\u0026rsquo;t fully understand it.\nThey reveal problems. Dead ends, infinite loops, missing error handling - all obvious in a flowchart.\n","content":"I\u0026rsquo;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.\nHere\u0026rsquo;s a practical guide to flowchart symbols and how to actually use them.\nWhy Flowcharts Matter Before we get into symbols, here\u0026rsquo;s why flowcharts are still relevant:\nThey force clarity. If you can\u0026rsquo;t draw a flowchart of your process, you don\u0026rsquo;t fully understand it.\nThey reveal problems. Dead ends, infinite loops, missing error handling - all obvious in a flowchart.\nThey communicate fast. A flowchart shows the flow in a way that paragraphs of text never will.\nI\u0026rsquo;ve used flowcharts to:\nUnderstand operating system flows and dig deeper into how things work Debug production incidents Explain algorithms (especially recursive ones) The Essential Symbols 1. Terminal / Terminator Shape: Rounded rectangle (oval) Purpose: Start and end points of your flow\ngraph TD Start([Start]) --\u003e End([End]) Use clear labels: \u0026ldquo;Start\u0026rdquo;, \u0026ldquo;Begin\u0026rdquo;, \u0026ldquo;End\u0026rdquo;, \u0026ldquo;Exit\u0026rdquo;. This tells readers where the flow begins and where it terminates.\n2. Process / Rectangle Shape: Rectangle Purpose: An action, operation, or process step\ngraph TD Start([Start]) Start --\u003e Process1[Read configuration file] Process1 --\u003e Process2[Parse JSON] Process2 --\u003e Process3[Initialize database] Process3 --\u003e End([End]) This is your workhorse symbol. Use verbs: \u0026ldquo;Calculate total\u0026rdquo;, \u0026ldquo;Send email\u0026rdquo;, \u0026ldquo;Save to database\u0026rdquo;.\n3. Decision / Conditional Shape: Diamond Purpose: A question with Yes/No or True/False outcomes\ngraph TD Start([Start]) Start --\u003e Check{File exists?} Check --\u003e|Yes| Read[Read file] Check --\u003e|No| Error[Show error] Read --\u003e End([End]) Error --\u003e End Always label the arrows coming out. \u0026ldquo;Yes/No\u0026rdquo;, \u0026ldquo;True/False\u0026rdquo;, or specific conditions like \u0026ldquo;\u0026gt;100\u0026rdquo; and \u0026ldquo;≤100\u0026rdquo;.\n4. Data (I/O) Shape: Parallelogram Purpose: Input or output of data\ngraph TD Start([Start]) Start --\u003e Input[/Enter username and password/] Input --\u003e Validate{Valid credentials?} Validate --\u003e|Yes| Output[/Display dashboard/] Validate --\u003e|No| Error[/Show error message/] Output --\u003e End([End]) Error --\u003e End Use this for user input, file reads, API responses, or any data coming in or going out.\n5. Document Shape: Rectangle with wavy bottom Purpose: A document or report generated\nIn Mermaid, we approximate this with special notation:\ngraph TD Start([Start]) Start --\u003e Process[Generate monthly report] Process --\u003e Doc[/Report PDF/] Doc --\u003e Email[Email to stakeholders] Email --\u003e End([End]) Use this when your process creates or reads a specific document.\n6. Subroutine / Predefined Process Shape: Rectangle with double vertical lines Purpose: A process defined elsewhere (function call, subprocess)\ngraph TD Start([Start]) Start --\u003e Input[/Get user input/] Input --\u003e Validate[[Validate input]] Validate --\u003e Process[Process data] Process --\u003e Save[[Save to database]] Save --\u003e End([End]) The double brackets [[...]] in Mermaid create this style. Use it for reusable processes or functions that are detailed in separate flowcharts.\nReal-World Examples Example 1: User Login Flow graph TD Start([User visits login page]) Start --\u003e Input[/Enter email and password/] Input --\u003e Submit[Click login button] Submit --\u003e Validate{Credentials valid?} Validate --\u003e|No| Error[/Display error message/] Error --\u003e Input Validate --\u003e|Yes| Check{2FA enabled?} Check --\u003e|No| Dashboard[/Redirect to dashboard/] Check --\u003e|Yes| TwoFactor[/Prompt for 2FA code/] TwoFactor --\u003e EnterCode[/Enter 2FA code/] EnterCode --\u003e VerifyCode{Code valid?} VerifyCode --\u003e|No| Error2[/Show error/] Error2 --\u003e TwoFactor VerifyCode --\u003e|Yes| Dashboard Dashboard --\u003e End([End]) This shows a complete authentication flow with error handling and conditional 2FA.\nExample 2: Deployment Process graph TD Start([Start deployment]) Start --\u003e Tests[[Run test suite]] Tests --\u003e TestPass{Tests passed?} TestPass --\u003e|No| Notify[/Notify team/] Notify --\u003e End([Deployment failed]) TestPass --\u003e|Yes| Build[Build Docker image] Build --\u003e Push[Push to registry] Push --\u003e Deploy[Deploy to staging] Deploy --\u003e Smoke{Smoke tests passed?} Smoke --\u003e|No| Rollback[Rollback deployment] Rollback --\u003e Notify Smoke --\u003e|Yes| Prod{Deploy to production?} Prod --\u003e|No| End2([End]) Prod --\u003e|Yes| ProdDeploy[Deploy to production] ProdDeploy --\u003e Monitor[Monitor metrics] Monitor --\u003e Success([Deployment complete]) This shows a typical CI/CD pipeline with testing gates and rollback logic.\nExample 3: E-commerce Checkout graph TD Start([User clicks checkout]) Start --\u003e Cart{Cart empty?} Cart --\u003e|Yes| Error[/Show error message/] Error --\u003e End([Return to shop]) Cart --\u003e|No| Address[/Enter shipping address/] Address --\u003e Payment[/Enter payment info/] Payment --\u003e Validate[[Validate payment]] Validate --\u003e Valid{Payment valid?} Valid --\u003e|No| Retry{Retry?} Retry --\u003e|Yes| Payment Retry --\u003e|No| Cancel([Order cancelled]) Valid --\u003e|Yes| Process[Process order] Process --\u003e Inventory{Items in stock?} Inventory --\u003e|No| Backorder[Create backorder] Inventory --\u003e|Yes| Ship[Create shipping label] Backorder --\u003e Notify[/Email customer/] Ship --\u003e Confirm[/Send confirmation email/] Confirm --\u003e Success([Order complete]) Notify --\u003e Success This shows decision points, error handling, and multiple end states.\nExample 4: API Request Handler graph TD Start([Receive API request]) Start --\u003e Auth{Valid auth token?} Auth --\u003e|No| Unauth[/Return 401 Unauthorized/] Unauth --\u003e End([End]) Auth --\u003e|Yes| Validate[[Validate request body]] Validate --\u003e Valid{Schema valid?} Valid --\u003e|No| BadReq[/Return 400 Bad Request/] BadReq --\u003e End Valid --\u003e|Yes| Check{Resource exists?} Check --\u003e|No| NotFound[/Return 404 Not Found/] NotFound --\u003e End Check --\u003e|Yes| Process[Process request] Process --\u003e Error{Error occurred?} Error --\u003e|Yes| ServerErr[/Return 500 Server Error/] ServerErr --\u003e End Error --\u003e|No| Success[/Return 200 with data/] Success --\u003e End This shows how to document API logic with proper HTTP status codes.\nExample 5: Recursive Function graph TD Start([calculateFactorial n]) Start --\u003e Base{n == 0 or n == 1?} Base --\u003e|Yes| Return1[Return 1] Return1 --\u003e End([End]) Base --\u003e|No| Recurse[[calculateFactorial n-1]] Recurse --\u003e Multiply[Multiply result by n] Multiply --\u003e Return2[Return result] Return2 --\u003e End Recursion is easier to understand with a flowchart. The [[...]] notation shows the recursive call.\nTips for Drawing Better Flowcharts 1. Keep It Simple Don\u0026rsquo;t try to fit your entire system into one flowchart. Break complex flows into multiple diagrams.\nBad: One massive flowchart with 50 boxes Good: Main flowchart with subroutines, each detailed separately\n2. Use Consistent Spacing Align your boxes. Keep arrows clean. Messy flowcharts are hard to read.\n3. Label Everything Every decision diamond needs labels on its outputs. Every process box needs a clear action.\nBad: Diamond with \u0026ldquo;Check\u0026rdquo; and arrows with no labels Good: Diamond with \u0026ldquo;User age \u0026gt;= 18?\u0026rdquo; and arrows labeled \u0026ldquo;Yes\u0026rdquo; and \u0026ldquo;No\u0026rdquo;\n4. Show Error Paths Don\u0026rsquo;t just show the happy path. Show what happens when things fail.\ngraph TD Start([Start]) Start --\u003e API[Call external API] API --\u003e Success{API success?} Success --\u003e|Yes| Process[Process response] Success --\u003e|No| Retry{Retry \u003c 3?} Retry --\u003e|Yes| Wait[Wait 1 second] Wait --\u003e API Retry --\u003e|No| Error[/Log error and alert/] Process --\u003e End([End]) Error --\u003e End This shows retry logic and error handling - critical for production systems.\n5. Avoid Spaghetti If your flowchart has arrows going everywhere, it\u0026rsquo;s too complex. Simplify your logic or break it into sub-processes.\n6. Use Color Sparingly In Mermaid, you can add color for emphasis:\ngraph TD Start([Start]) Start --\u003e Process[Normal process] Process --\u003e Critical[Critical security check] Critical --\u003e End([End]) style Critical fill:#ff6b6b,stroke:#c92a2a,color:#fff But don\u0026rsquo;t overdo it. Color should highlight important nodes, not decorate everything.\nCommon Flowchart Patterns The Retry Loop graph TD Start([Start]) Start --\u003e Try[Attempt operation] Try --\u003e Success{Success?} Success --\u003e|Yes| Done([End]) Success --\u003e|No| Count{Retry count \u003c max?} Count --\u003e|Yes| Inc[Increment retry count] Inc --\u003e Try Count --\u003e|No| Fail([Give up]) Use this pattern for network calls, database operations, or any unreliable external dependency.\nThe Validation Chain graph TD Start([Start]) Start --\u003e V1{Check 1 valid?} V1 --\u003e|No| E1[/Error: Check 1 failed/] E1 --\u003e End([End]) V1 --\u003e|Yes| V2{Check 2 valid?} V2 --\u003e|No| E2[/Error: Check 2 failed/] E2 --\u003e End V2 --\u003e|Yes| V3{Check 3 valid?} V3 --\u003e|No| E3[/Error: Check 3 failed/] E3 --\u003e End V3 --\u003e|Yes| Success[Process data] Success --\u003e End Use this when you have multiple validation checks that must all pass.\nThe Batch Processor graph TD Start([Start]) Start --\u003e Get[Get next item] Get --\u003e More{Items remaining?} More --\u003e|No| Done([End]) More --\u003e|Yes| Process[Process item] Process --\u003e Error{Error?} Error --\u003e|Yes| Log[Log error] Error --\u003e|No| Get Log --\u003e Get Use this for processing queues, files, or any batch operation.\nCreating Flowcharts with Mermaid All the diagrams in this article are written in Mermaid syntax. Here\u0026rsquo;s a quick reference:\ngraph TD A([Start]) --\u003e B[Process] B --\u003e C{Decision?} C --\u003e|Yes| D[/Output/] C --\u003e|No| E[[Subroutine]] D --\u003e F([End]) E --\u003e F Syntax:\ngraph TD - Top to bottom flow (use LR for left to right) ([...]) - Rounded rectangle (terminator) [...] - Rectangle (process) {...} - Diamond (decision) [/..../] - Parallelogram (input/output) [[...]] - Subroutine (double border) --\u0026gt; - Arrow --\u0026gt;|label| - Labeled arrow You can add these directly to markdown files and they\u0026rsquo;ll render in most modern documentation tools.\nWhen Not to Use Flowcharts Flowcharts aren\u0026rsquo;t always the right tool:\nUse flowcharts for:\nAlgorithms and logic Process flows with decisions Troubleshooting guides Deployment procedures Don\u0026rsquo;t use flowcharts for:\nSystem architecture (use block diagrams or component diagrams) Data models (use ER diagrams) Time-based interactions (use sequence diagrams) Class relationships (use class diagrams) Tools for Drawing Flowcharts Mermaid (my preference):\nWrite flowcharts in text Version control friendly Renders in markdown Free and open source Lucidchart:\nDrag-and-drop interface Good for non-technical users Collaboration features Paid (free tier limited) Draw.io (diagrams.net):\nFree and open source Desktop or web-based Export to many formats More manual than Mermaid Graphviz:\nText-based like Mermaid Very powerful for complex graphs Steeper learning curve Great for automated diagram generation My Take I still draw flowcharts regularly. When debugging a production issue, I\u0026rsquo;ll sketch the request flow to find where it\u0026rsquo;s breaking. When designing a new feature, I\u0026rsquo;ll flowchart the logic before writing code.\nThe 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.\nAnd if you\u0026rsquo;re writing documentation, embed flowcharts directly in markdown using Mermaid. Your future self (and your teammates) will thank you.\nResources Mermaid Documentation Flowchart Best Practices (ISO 5807) Draw.io Graphviz Related Posts:\nMermaid Diagram Test - Examples of different Mermaid diagram types ","tags":["flowcharts","diagrams","documentation","process","mermaid","visualization"],"categories":["Engineering","Reference"]},{"title":"OpenGrok: Fast Source Code Browsing for Large Codebases","date":"2025-01-13","permalink":"https://santoshmano.com/blog/opengrok-local-setup/","summary":"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.\nThat\u0026rsquo;s where OpenGrok came in. It\u0026rsquo;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.\n","content":"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.\nThat\u0026rsquo;s where OpenGrok came in. It\u0026rsquo;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.\nWhat Is OpenGrok? OpenGrok is an open-source code search engine originally developed at Sun Microsystems (now maintained by Oracle). It:\nIndexes your entire codebase using Apache Lucene Integrates with ctags for definitions and cross-references Supports version control (Git, SVN, Perforce, Mercurial) Provides a web UI for searching and browsing Handles large codebases - scales well even with thousands of files The killer feature: you can search for function definitions, usages, file paths, and even full-text search across your entire source tree in seconds.\nWhy Use OpenGrok Instead of grep? grep -r works great for small projects. But when you\u0026rsquo;re dealing with a large codebase:\nSpeed: OpenGrok indexes once, searches instantly. grep re-scans every time. Cross-references: OpenGrok uses ctags to show where functions are defined and called. History: OpenGrok integrates with version control to show file history and blame. Web UI: Share links to code with teammates. No need to SSH and navigate directories. 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.\nLocal Setup on macOS Here\u0026rsquo;s how to set up OpenGrok locally. This assumes you have Homebrew installed.\n1. Install Prerequisites 1 2 3 4 5 6 7 8 # Install Java (OpenGrok requires Java 11+) brew install openjdk@11 # Install Universal Ctags (better than Exuberant Ctags) brew install universal-ctags # Install Tomcat (servlet container to run OpenGrok) brew install tomcat 2. Download OpenGrok 1 2 3 4 5 6 7 # Download latest OpenGrok release cd ~/Downloads wget https://github.com/oracle/opengrok/releases/download/1.13.3/opengrok-1.13.3.tar.gz tar -xzf opengrok-1.13.3.tar.gz # Move to /usr/local sudo mv opengrok-1.13.3 /usr/local/opengrok 3. Set Up Directory Structure 1 2 3 4 5 # Create OpenGrok data directories sudo mkdir -p /var/opengrok/{src,data,etc} # Set permissions (adjust username as needed) sudo chown -R $USER /var/opengrok 4. Configure OpenGrok Create a configuration file at /var/opengrok/etc/configuration.xml (OpenGrok will generate this on first run, but you can customize it):\n1 2 3 4 5 6 7 8 9 # Index your source code # Replace /path/to/your/code with actual path OPENGROK_TOMCAT_BASE=/usr/local/opt/tomcat/libexec \\ 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 \\ -W /var/opengrok/etc/configuration.xml 5. Deploy to Tomcat 1 2 3 4 5 6 7 8 9 10 # Copy OpenGrok web app to Tomcat sudo cp /usr/local/opengrok/lib/source.war /usr/local/opt/tomcat/libexec/webapps/ # Create context file cat \u0026gt; /usr/local/opt/tomcat/libexec/conf/Catalina/localhost/source.xml \u0026lt;\u0026lt;EOF \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;Context path=\u0026#34;/source\u0026#34;\u0026gt; \u0026lt;Parameter name=\u0026#34;CONFIGURATION\u0026#34; value=\u0026#34;/var/opengrok/etc/configuration.xml\u0026#34; override=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;/Context\u0026gt; EOF 6. Start Tomcat 1 2 3 4 5 # Start Tomcat server catalina start # Check it\u0026#39;s running tail -f /usr/local/opt/tomcat/libexec/logs/catalina.out 7. Copy Your Code and Index 1 2 3 4 5 6 7 8 9 10 11 12 13 # Copy or symlink your source code to OpenGrok\u0026#39;s src directory cp -R /path/to/your/code /var/opengrok/src/myproject # Or use symlink ln -s /path/to/your/code /var/opengrok/src/myproject # Index the code 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 \\ -W /var/opengrok/etc/configuration.xml 8. Access OpenGrok Open your browser to:\nhttp://localhost:8080/source You should see the OpenGrok web interface with your indexed code.\nUsing OpenGrok Once it\u0026rsquo;s running, here\u0026rsquo;s what you can do:\nFull Text Search Search for any text across all files. Great for finding error messages, string literals, or comments.\nDefinition Search Find where a function or variable is defined. OpenGrok uses ctags for this.\nSymbol Search Find all references to a symbol (function calls, variable usage).\nPath Search Search for files by name or path pattern.\nHistory View See git/svn history for any file, with blame annotations.\nCross-Reference Click on any function or variable to see its definition and all usages.\nIndexing Large Codebases For large codebases, indexing can take a while. Some tips:\nExclude directories you don\u0026rsquo;t need:\n1 2 3 4 5 6 7 java -jar /usr/local/opengrok/lib/opengrok.jar \\ -c /usr/local/bin/ctags \\ -s /var/opengrok/src \\ -d /var/opengrok/data \\ -i \u0026#39;*.o\u0026#39; -i \u0026#39;*.a\u0026#39; -i \u0026#39;build/*\u0026#39; \\ -H -P -S -G \\ -W /var/opengrok/etc/configuration.xml Incremental indexing: After the initial index, you can run incremental updates:\n1 2 3 4 5 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 Automate with cron: Set up a cron job to reindex nightly:\n1 2 # Add to crontab 0 2 * * * 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 Version Control Integration OpenGrok can show file history and annotations if your code is in version control.\nGit: OpenGrok auto-detects Git repositories. Just make sure .git is present.\nPerforce: If you\u0026rsquo;re using Perforce, configure P4 environment variables:\n1 2 3 export P4PORT=perforce:1666 export P4USER=your-username export P4CLIENT=your-workspace SVN: OpenGrok auto-detects SVN repositories. Make sure .svn is present.\nCommand Reference 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # Start Tomcat catalina start # Stop Tomcat catalina stop # Reindex all code 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 \\ -W /var/opengrok/etc/configuration.xml # Check Tomcat logs tail -f /usr/local/opt/tomcat/libexec/logs/catalina.out # Check OpenGrok logs tail -f /var/opengrok/data/logs/opengrok.log OpenGrok vs. Modern Alternatives Since I started using OpenGrok, newer tools have emerged:\nSourcegraph - Cloud-hosted code search with great UI. Free for public repos, paid for private.\nGitHub Code Search - If your code is on GitHub, their built-in search is fast and integrates with PRs/issues.\ngrep.app - Web-based regex search across GitHub repos.\nripgrep - Blazing fast command-line search. No indexing, but searches fast enough for most projects.\nBut OpenGrok still has advantages:\nSelf-hosted (no cloud dependency) Works offline Handles any version control system Free and open source Battle-tested on massive codebases When to Use OpenGrok Use OpenGrok if:\nYou have a large codebase (100k+ lines) You want a web UI for code browsing You need to share code links with teammates You\u0026rsquo;re using Perforce or SVN (less tooling available) You want self-hosted search (no cloud) Stick with simpler tools if:\nYour codebase is small (use grep, ripgrep, or editor search) Your code is on GitHub (use GitHub\u0026rsquo;s search) You prefer command-line only (use ctags + cscope) My Take 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.\nFor small projects, it\u0026rsquo;s overkill. But for large, complex codebases - especially legacy C/C++ code - OpenGrok is still one of the best tools available.\nIf you\u0026rsquo;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\u0026rsquo;ll save that time back on the first day you use it.\nResources OpenGrok GitHub Official Documentation Universal Ctags Related Posts:\nctags, cscope, and Screen: My IDE for 12 Years Essential Vim Commands and Shell Vi Mode ","tags":["opengrok","code-search","ctags","java","tomcat","code-navigation","productivity"],"categories":["Engineering"]},{"title":"Example: Embedding PDFs in Hugo Posts","date":"2024-11-05","permalink":"https://santoshmano.com/blog/pdf-embedding-example/","summary":"This is an example post showing different ways to embed PDF files in your Hugo blog posts.\nSetup First, place your PDF file in the static/documents/ directory. For example:\nstatic/documents/resume.pdf static/documents/whitepaper.pdf Method 1: Simple iframe (Recommended) This is the most compatible method that works across all browsers:\n1 2 \u0026lt;iframe src=\u0026#34;/documents/yourfile.pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34;\u0026gt; \u0026lt;/iframe\u0026gt; Example with actual file:\n1 2 \u0026lt;iframe src=\u0026#34;/documents/resume.pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34;\u0026gt; \u0026lt;/iframe\u0026gt; Method 2: Embed tag Another approach using the embed tag:\n","content":"This is an example post showing different ways to embed PDF files in your Hugo blog posts.\nSetup First, place your PDF file in the static/documents/ directory. For example:\nstatic/documents/resume.pdf static/documents/whitepaper.pdf Method 1: Simple iframe (Recommended) This is the most compatible method that works across all browsers:\n1 2 \u0026lt;iframe src=\u0026#34;/documents/yourfile.pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34;\u0026gt; \u0026lt;/iframe\u0026gt; Example with actual file:\n1 2 \u0026lt;iframe src=\u0026#34;/documents/resume.pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34;\u0026gt; \u0026lt;/iframe\u0026gt; Method 2: Embed tag Another approach using the embed tag:\n1 \u0026lt;embed src=\u0026#34;/documents/yourfile.pdf\u0026#34; type=\u0026#34;application/pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34; /\u0026gt; Method 3: Object tag with fallback This provides a download link for browsers that can\u0026rsquo;t display PDFs:\n1 2 3 \u0026lt;object data=\u0026#34;/documents/yourfile.pdf\u0026#34; type=\u0026#34;application/pdf\u0026#34; width=\u0026#34;100%\u0026#34; height=\u0026#34;600px\u0026#34; style=\u0026#34;border: 1px solid #ccc; border-radius: 4px;\u0026#34;\u0026gt; \u0026lt;p\u0026gt;Your browser doesn\u0026#39;t support PDF viewing. \u0026lt;a href=\u0026#34;/documents/yourfile.pdf\u0026#34;\u0026gt;Download the PDF\u0026lt;/a\u0026gt; to view it.\u0026lt;/p\u0026gt; \u0026lt;/object\u0026gt; Responsive Styling You can make the PDF viewer responsive with better styling:\n1 2 3 4 \u0026lt;div style=\u0026#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\u0026#34;\u0026gt; \u0026lt;iframe src=\u0026#34;/documents/yourfile.pdf\u0026#34; style=\u0026#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;\u0026#34;\u0026gt; \u0026lt;/iframe\u0026gt; \u0026lt;/div\u0026gt; Live Demo Here\u0026rsquo;s a working example with an actual embedded PDF:\nHow to Use Place your PDF files in static/documents/ directory Reference them in your markdown as /documents/filename.pdf Choose one of the methods above and paste the HTML code in your markdown Adjust width and height as needed That\u0026rsquo;s it! The PDF will be embedded directly in your blog post and visitors can view it without downloading.\n","tags":["hugo","pdf","tutorial"],"categories":["Engineering"]},{"title":"Using Mermaid Diagrams in Documentation","date":"2024-10-25","permalink":"https://santoshmano.com/blog/mermaid-diagram-test/","summary":"From ASCII Art to Mermaid 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\u0026rsquo;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.\n","content":"From ASCII Art to Mermaid 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\u0026rsquo;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.\nI\u0026rsquo;d spend hours on asciiflow.com, 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.\n+----------------+ +------------------+ | Browser |-----\u0026gt;| Web Server | +----------------+ +------------------+ | v +-------------+ | Database | +-------------+ Recently, I discovered Mermaid, and it\u0026rsquo;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\u0026rsquo;re easy to edit and version control. Plus, they automatically adapt to light and dark themes on my blog.\nHere\u0026rsquo;s that same diagram in Mermaid:\ngraph LR Browser --\u003e|HTTP| WebServer[Web Server] WebServer --\u003e Database Let me show you what\u0026rsquo;s possible with Mermaid.\nSystem Architecture Example graph TB User[User Browser] --\u003e|HTTPS| CDN[Cloudflare CDN] CDN --\u003e|Cache Miss| Netlify[Netlify Hosting] Netlify --\u003e|Static Files| Hugo[Hugo Generated Site] Hugo --\u003e|Markdown| Content[Content Files] Hugo --\u003e|Templates| Theme[Stack Theme] Hugo --\u003e|Assets| CSS[SCSS/CSS] style User fill:#5fb878 style CDN fill:#f9a825 style Netlify fill:#00c7b7 style Hugo fill:#ff4088 Sequence Diagram Example Here\u0026rsquo;s how a typical request flows through the system:\nsequenceDiagram participant User participant CDN as Cloudflare CDN participant Host as Netlify participant Git as GitHub User-\u003e\u003eCDN: Request page CDN-\u003e\u003eCDN: Check cache alt Cache Hit CDN-\u003e\u003eUser: Return cached page else Cache Miss CDN-\u003e\u003eHost: Request page Host-\u003e\u003eUser: Return fresh page CDN-\u003e\u003eCDN: Cache page end Note over Git,Host: On git push Git-\u003e\u003eHost: Trigger build Host-\u003e\u003eHost: Run Hugo build Host-\u003e\u003eCDN: Invalidate cache Flowchart Example Decision flow for publishing content:\nflowchart TD Start([Write Draft]) --\u003e Review{Review Complete?} Review --\u003e|No| Edit[Make Edits] Edit --\u003e Review Review --\u003e|Yes| Diagrams{Add Diagrams?} Diagrams --\u003e|Yes| Mermaid[Create Mermaid Diagrams] Mermaid --\u003e Publish Diagrams --\u003e|No| Publish[Publish Post] Publish --\u003e Share[Share on Social Media] Share --\u003e End([Done]) style Start fill:#5fb878 style End fill:#5fb878 style Publish fill:#ff4088 Class Diagram Example For documenting system components:\nclassDiagram 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\" --\u003e \"0..*\" Diagram BlogPost --\u003e Theme Git Graph Example Visualizing branching and merging:\ngitGraph 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\" State Diagram Example Perfect for modeling state machines and workflows:\nstateDiagram-v2 [*] --\u003e Draft Draft --\u003e Review: Submit for review Review --\u003e Draft: Request changes Review --\u003e Approved: Approve Approved --\u003e Published: Publish Published --\u003e Archived: Archive Archived --\u003e [*] 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 Entity Relationship Diagram For documenting database schemas:\nerDiagram 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 } Gantt Chart Example Great for project planning and timelines:\ngantt 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 Wide Gantt Chart Example With AI-powered development, what used to take years now takes weeks. This 90-day sprint shows how horizontal scrolling helps visualize packed timelines:\ngantt 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 \u0026 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 \u0026 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 \u0026 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 \u0026 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 \u0026 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 Pie Chart Example Useful for showing proportions and distributions:\npie title Technology Stack Distribution \"Hugo (Go)\" : 30 \"JavaScript\" : 25 \"SCSS/CSS\" : 20 \"Markdown\" : 15 \"HTML Templates\" : 10 Quadrant Chart Example For categorizing items across two dimensions:\nquadrantChart title Blog Post Priority Matrix x-axis Low Traffic --\u003e High Traffic y-axis Low Effort --\u003e 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] How to Use Mermaid To add any of these diagrams to your markdown files, just use standard code blocks with mermaid as the language:\n1 2 3 4 5 ```mermaid graph TD A[Start] --\u0026gt; B[Process] B --\u0026gt; C[End] ``` The diagrams automatically adjust to match your site\u0026rsquo;s theme—light or dark mode—which is something ASCII diagrams could never do.\nWhy I Switched Here\u0026rsquo;s what I appreciate about Mermaid over ASCII diagrams:\nVersion control friendly: Changing a diagram is as simple as editing a line of text. With ASCII art, any structural change meant redrawing half the diagram.\nConsistent styling: All diagrams look professional and match each other. No more aligning boxes by hand or counting spaces.\nEasy to edit: 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.\nPortable: The same Mermaid code works in GitHub, GitLab, Notion, and countless other tools. ASCII diagrams looked different everywhere depending on font rendering.\nMaintainable: I can actually come back to a diagram six months later and understand how to update it. ASCII diagrams were write-only code.\nFor 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.\nResources If you want to try Mermaid:\nMermaid Documentation - Complete reference for all diagram types Mermaid Live Editor - Interactive playground to test diagrams Syntax Guide - Quick syntax reference The learning curve is minimal—if you can write markdown, you can write Mermaid diagrams.\n","tags":["Documentation","Diagrams","Tools"],"categories":["Engineering"]},{"title":"Understanding Compound Interest","date":"2024-10-15","permalink":"https://santoshmano.com/blog/compound-interest/","summary":"I remember opening my first PPF account in India and seeing \u0026ldquo;7.1% interest compounded annually.\u0026rdquo; I thought, \u0026ldquo;okay, 7.1% per year, simple enough.\u0026rdquo; But then I opened a money market fund in the US that said \u0026ldquo;4.5% compounded daily,\u0026rdquo; and suddenly I had questions. Why does compounding frequency matter? Is daily compounding really better than annual?\nLet me break this down with real examples.\nWhat Is Compound Interest? Think of compound interest as \u0026ldquo;interest on interest\u0026rdquo; - your money makes money, and then that new money also makes money.\n","content":"I remember opening my first PPF account in India and seeing \u0026ldquo;7.1% interest compounded annually.\u0026rdquo; I thought, \u0026ldquo;okay, 7.1% per year, simple enough.\u0026rdquo; But then I opened a money market fund in the US that said \u0026ldquo;4.5% compounded daily,\u0026rdquo; and suddenly I had questions. Why does compounding frequency matter? Is daily compounding really better than annual?\nLet me break this down with real examples.\nWhat Is Compound Interest? Think of compound interest as \u0026ldquo;interest on interest\u0026rdquo; - your money makes money, and then that new money also makes money.\nHere\u0026rsquo;s a simple example with $100 at 10% interest per year:\ngraph LR A[\"Year 0$100\"] --\u003e B[\"Year 1$110(earned $10)\"] B --\u003e C[\"Year 2$121(earned $11)\"] C --\u003e D[\"Year 3$133.10(earned $12.10)\"] style A fill:#5fb878 style D fill:#5fb878 Notice how you earn more each year? That\u0026rsquo;s the snowball effect.\nThe Formula The compound interest formula is:\n$$A = P\\left(1 + \\frac{r}{n}\\right)^{nt}$$\nWhere:\n$A$ = final amount $P$ = principal (initial investment) $r$ = annual interest rate (as decimal, so 5% = 0.05) $n$ = number of times interest compounds per year $t$ = number of years How We Get This Formula Let\u0026rsquo;s derive it step by step. Say you start with amount $P$ and interest rate $r$ per year.\nAfter Year 1:\nYou earn interest: $P \\times r$ New amount: $P + P \\times r = P(1 + r)$ After Year 2:\nYou now earn interest on $P(1 + r)$ New amount: $P(1 + r) \\times (1 + r) = P(1 + r)^2$ After Year 3:\nNew amount: $P(1 + r)^3$ After $t$ years:\n$$A = P(1 + r)^t$$\nThat\u0026rsquo;s the basic formula for annual compounding!\nWhat about compounding more frequently?\nIf interest compounds $n$ times per year:\nEach period gives you $\\frac{r}{n}$ interest In $t$ years, there are $n \\times t$ periods So we get: $$A = P\\left(1 + \\frac{r}{n}\\right)^{nt}$$\nCompounding Frequencies Compared Let\u0026rsquo;s invest $10,000 at 6% annual interest for 10 years and see how different compounding frequencies affect the outcome:\nThe Math Annually ($n=1$):\n$$A = 10{,}000\\left(1 + \\frac{0.06}{1}\\right)^{1 \\times 10} = 10{,}000(1.06)^{10} = 17{,}908.48$$\nQuarterly ($n=4$):\n$$A = 10{,}000\\left(1 + \\frac{0.06}{4}\\right)^{4 \\times 10} = 10{,}000(1.015)^{40} = 18{,}140.18$$\nMonthly ($n=12$):\n$$A = 10{,}000\\left(1 + \\frac{0.06}{12}\\right)^{12 \\times 10} = 10{,}000(1.005)^{120} = 18{,}194.25$$\nDaily ($n=365$):\n$$A = 10{,}000\\left(1 + \\frac{0.06}{365}\\right)^{365 \\times 10} = 10{,}000(1.000164)^{3650} = 18{,}220.51$$\nVisual Comparison graph TD Start[\"Initial Investment$10,0006% annual rate10 years\"] --\u003e Annual[\"Annually$17,908.48+$7,908\"] Start --\u003e Quarterly[\"Quarterly$18,140.18+$8,140\"] Start --\u003e Monthly[\"Monthly$18,194.25+$8,194\"] Start --\u003e Daily[\"Daily$18,220.51+$8,221\"] style Start fill:#5fb878 style Daily fill:#ff4088 Does Frequency Matter? Yes, but not dramatically. Here\u0026rsquo;s the difference:\nFrequency Final Amount Gain vs Annual Annually $17,908.48 - Quarterly $18,140.18 +$231.70 Monthly $18,194.25 +$285.77 Daily $18,220.51 +$312.03 Daily compounding gives you $312 more than annual compounding over 10 years. Not huge, but free money is free money.\nThe rule: 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.\nReal-World Examples Example 1: Fidelity Money Market Fund (USA) You invest $10,000 in a money market fund with 4.5% annual yield, compounded daily.\nHow it works:\nDividends paid daily Automatically reinvested (buy more shares) This is n = 365 After 1 year:\n$$A = 10{,}000\\left(1 + \\frac{0.045}{365}\\right)^{365 \\times 1} = 10{,}000(1.000123)^{365} \\approx 10{,}460$$\nYou earned $460 instead of just $450 (simple interest) thanks to daily compounding.\nAfter 10 years:\n$$A = 10{,}000(1.000123)^{3650} \\approx 15{,}657$$\nExample 2: PPF - Public Provident Fund (India) You invest ₹1,50,000 per year (maximum allowed) for 15 years at 7.1% annual interest, compounded annually.\nHow it works:\nInterest compounds once per year Calculated on lowest balance between 5th and end of month This is n = 1 Strategy: Invest on April 1st each year to maximize interest.\nCalculation:\ngraph TD Y1[\"Year 1Invest: ₹1,50,000Balance: ₹1,60,650\"] --\u003e Y2[\"Year 2Invest: ₹1,50,000Balance: ₹3,32,556\"] Y2 --\u003e Y3[\"Year 3Invest: ₹1,50,000Balance: ₹5,14,045\"] Y3 --\u003e Y15[\"...Year 15Invest: ₹1,50,000Balance: ₹40,68,209\"] style Y1 fill:#5fb878 style Y15 fill:#ff4088 Final result after 15 years:\nTotal invested: ₹22,50,000 Final amount: ₹40,68,209 Interest earned: ₹18,18,209 Your money almost doubled! And it\u0026rsquo;s completely tax-free (EEE status).\nComparison: Money Market vs PPF Feature Fidelity Money Market Indian PPF Compounding Daily (365×/year) Annually (1×/year) Rate ~4.5% 7.1% Liquidity Withdraw anytime Locked 15 years Taxation Taxable income Tax-free (EEE) Best for Emergency fund, liquidity Long-term, tax savings The Power of Time Here\u0026rsquo;s the real magic of compound interest - time matters more than frequency.\nLet\u0026rsquo;s compare two scenarios with $10,000 at 6%:\nScenario A: Daily compounding, 10 years = $18,220.51 Scenario B: Annual compounding, 20 years = $32,071.35\ngraph LR A[\"10 yearsdaily compounding$18,220\"] B[\"20 yearsannual compounding$32,071\"] A -.-\u003e|\"10 more years\"| C[\"20 yearsdaily compounding$33,201\"] style B fill:#5fb878 style C fill:#ff4088 Key insight: An extra 10 years beats better compounding frequency. Time is your most powerful tool.\nWhere Can You Get Compound Interest? United States Daily Compounding:\nMoney market funds (Fidelity, Vanguard, Schwab) High-yield savings accounts (Marcus, Ally Bank) CDs (Certificates of Deposit) Monthly/Quarterly:\nMost bonds (if you reinvest interest) Dividend-paying stocks (DRIP programs) Through Reinvestment:\n401(k) - All gains compound tax-deferred IRA (Traditional and Roth) Index funds / ETFs with dividend reinvestment India Annual Compounding:\nPPF (Public Provident Fund) - 7.1%, tax-free EPF (Employee Provident Fund) - 8.15% Sukanya Samriddhi Yojana - 8.2% Quarterly Compounding:\nFixed Deposits (banks) Recurring Deposits National Savings Certificate (NSC) Through Market Growth:\nMutual funds with dividend reinvestment SIP (Systematic Investment Plan) NPS (National Pension System) Practical Examples: How Your Money Grows Let\u0026rsquo;s look at real numbers. Here\u0026rsquo;s what happens when you invest $10,000 at different rates over various time periods (assumes annual compounding for simplicity):\nConservative Rate (5% - High-Yield Savings, CDs) Years Amount Total Gain 1 $10,500 $500 3 $11,576 $1,576 5 $12,763 $2,763 10 $16,289 $6,289 20 $26,533 $16,533 30 $43,219 $33,219 Takeaway: Even at 5%, your money more than doubles in 15 years and quadruples in 30.\nModerate Rate (8% - Typical Stock Market Long-Term Average) Years Amount Total Gain 1 $10,800 $800 3 $12,597 $2,597 5 $14,693 $4,693 10 $21,589 $11,589 20 $46,610 $36,610 30 $100,627 $90,627 Takeaway: At 8%, your money doubles roughly every 9 years. After 30 years, that $10,000 becomes over $100,000.\nAggressive Rate (10% - High-Growth Stocks, Index Funds) Years Amount Total Gain 1 $11,000 $1,000 3 $13,310 $3,310 5 $16,105 $6,105 10 $25,937 $15,937 20 $67,275 $57,275 30 $174,494 $164,494 Takeaway: At 10%, money doubles approximately every 7 years. After 30 years, $10,000 grows to over $174,000.\nMonthly Contribution Example What if instead of a one-time $10,000, you invest $500/month ($6,000/year) at 8% annual return?\nYears Amount Your Contributions Earnings 1 $6,244 $6,000 $244 3 $19,780 $18,000 $1,780 5 $36,738 $30,000 $6,738 10 $91,473 $60,000 $31,473 20 $294,510 $120,000 $174,510 30 $745,180 $180,000 $565,180 Takeaway: Regular contributions combined with compound interest is incredibly powerful. After 30 years, you\u0026rsquo;d have contributed $180,000 but end up with $745,000 - more than 4x your contributions!\nThe Rule of 72 Quick mental math: To estimate how long it takes to double your money, divide 72 by the interest rate:\nAt 6%: 72 ÷ 6 = 12 years to double At 8%: 72 ÷ 8 = 9 years to double At 10%: 72 ÷ 10 = 7.2 years to double This is why time and rate both matter so much.\nThe Bottom Line Three key takeaways:\nCompound interest is powerful - Your money makes money, which makes more money Frequency helps, but not dramatically - Daily vs annual might add 1-2% over time Time matters most - 20 years of annual compounding beats 10 years of daily compounding What to do:\nStart early (even small amounts) Reinvest your earnings (dividends, interest) Be patient - compounding needs time to work its magic Don\u0026rsquo;t obsess over compounding frequency - focus on getting started Remember: Thanks to Preeti Agarwal for painting this rock for me. This image has been digitally enhanced.\n","tags":["finance","investing","compound-interest","personal-finance"],"categories":["Finance"]},{"title":"KaTeX Math Notation Reference","date":"2024-10-01","permalink":"https://santoshmano.com/blog/katex-math-notation-reference/","summary":"If you need to write mathematical notation in markdown files, KaTeX is the way to go. It\u0026rsquo;s fast, renders beautifully, and uses familiar LaTeX syntax.\nWhat is KaTeX? KaTeX is a math typesetting library that renders LaTeX math notation on the web. It\u0026rsquo;s faster than MathJax and produces crisp, readable formulas. If you\u0026rsquo;ve ever used LaTeX in academic papers, you already know the syntax.\nKaTeX works in many contexts: Hugo sites, GitHub markdown, Jekyll, documentation sites, and more.\n","content":"If you need to write mathematical notation in markdown files, KaTeX is the way to go. It\u0026rsquo;s fast, renders beautifully, and uses familiar LaTeX syntax.\nWhat is KaTeX? KaTeX is a math typesetting library that renders LaTeX math notation on the web. It\u0026rsquo;s faster than MathJax and produces crisp, readable formulas. If you\u0026rsquo;ve ever used LaTeX in academic papers, you already know the syntax.\nKaTeX works in many contexts: Hugo sites, GitHub markdown, Jekyll, documentation sites, and more.\nSetting Up KaTeX Setup varies by platform:\nHugo (with Stack theme or similar): Many Hugo themes support KaTeX out of the box. If yours doesn\u0026rsquo;t, add this to layouts/partials/head/custom.html:\n1 2 3 4 \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css\u0026#34;\u0026gt; \u0026lt;script defer src=\u0026#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script defer src=\u0026#34;https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js\u0026#34; onload=\u0026#34;renderMathInElement(document.body);\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; GitHub Markdown: GitHub renders KaTeX automatically. Just use the syntax below - no setup needed.\nOther platforms: Most static site generators and documentation tools support KaTeX through plugins or themes. Check your platform\u0026rsquo;s documentation.\nOnce set up, the syntax below works everywhere.\nBasic Syntax Inline Math Use single dollar signs for inline math:\n1 The quadratic formula is $x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$. Renders as: The quadratic formula is $x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$.\nDisplay Math (Block) Use double dollar signs for centered, display-style equations:\n1 2 3 $$ E = mc^2 $$ Renders as:\n$$ E = mc^2 $$\nCommon Examples Fractions 1 2 3 $$ \\frac{a}{b} \\quad \\frac{1}{2} \\quad \\frac{\\pi}{4} $$ $$ \\frac{a}{b} \\quad \\frac{1}{2} \\quad \\frac{\\pi}{4} $$\nExponents and Subscripts 1 2 3 $$ x^2 \\quad y^{10} \\quad a_1 \\quad b_{n+1} $$ $$ x^2 \\quad y^{10} \\quad a_1 \\quad b_{n+1} $$\nSquare Roots 1 2 3 $$ \\sqrt{2} \\quad \\sqrt{x^2 + y^2} \\quad \\sqrt[3]{8} $$ $$ \\sqrt{2} \\quad \\sqrt{x^2 + y^2} \\quad \\sqrt[3]{8} $$\nGreek Letters 1 2 3 $$ \\alpha, \\beta, \\gamma, \\delta, \\epsilon, \\theta, \\pi, \\sigma, \\omega $$ $$ \\alpha, \\beta, \\gamma, \\delta, \\epsilon, \\theta, \\pi, \\sigma, \\omega $$\nSummation and Products 1 2 3 $$ \\sum_{i=1}^{n} i = \\frac{n(n+1)}{2} $$ $$ \\sum_{i=1}^{n} i = \\frac{n(n+1)}{2} $$\n1 2 3 $$ \\prod_{i=1}^{n} i = n! $$ $$ \\prod_{i=1}^{n} i = n! $$\nIntegrals 1 2 3 $$ \\int_0^1 x^2 \\, dx = \\frac{1}{3} $$ $$ \\int_0^1 x^2 , dx = \\frac{1}{3} $$\nLimits 1 2 3 $$ \\lim_{x \\to \\infty} \\frac{1}{x} = 0 $$ $$ \\lim_{x \\to \\infty} \\frac{1}{x} = 0 $$\nMatrices 1 2 3 4 5 6 $$ \\begin{bmatrix} a \u0026amp; b \\\\ c \u0026amp; d \\end{bmatrix} $$ $$ \\begin{bmatrix} a \u0026amp; b \\ c \u0026amp; d \\end{bmatrix} $$\nSystems of Equations 1 2 3 4 5 6 $$ \\begin{cases} x + y = 5 \\\\ 2x - y = 1 \\end{cases} $$ $$ \\begin{cases} x + y = 5 \\ 2x - y = 1 \\end{cases} $$\nReal-World Example: Compound Interest Here\u0026rsquo;s a practical formula you might actually use:\n1 2 3 4 5 6 7 8 9 10 $$ A = P\\left(1 + \\frac{r}{n}\\right)^{nt} $$ Where: - $A$ = final amount - $P$ = principal (initial investment) - $r$ = annual interest rate (decimal) - $n$ = compounding frequency per year - $t$ = time in years Renders as:\n$$ A = P\\left(1 + \\frac{r}{n}\\right)^{nt} $$\nWhere:\n$A$ = final amount $P$ = principal (initial investment) $r$ = annual interest rate (decimal) $n$ = compounding frequency per year $t$ = time in years Quick Reference What You Want LaTeX Syntax Result Fraction \\frac{a}{b} $\\frac{a}{b}$ Exponent x^2 $x^2$ Subscript x_1 $x_1$ Square root \\sqrt{x} $\\sqrt{x}$ Summation \\sum_{i=1}^{n} $\\sum_{i=1}^{n}$ Integral \\int_a^b $\\int_a^b$ Limit \\lim_{x \\to \\infty} $\\lim_{x \\to \\infty}$ Pi \\pi $\\pi$ Infinity \\infty $\\infty$ Less/Greater \\leq \\geq $\\leq$ $\\geq$ Not equal \\neq $\\neq$ Approximately \\approx $\\approx$ Common Operators Multiplication: \\times → $\\times$ Division: \\div → $\\div$ Plus/minus: \\pm → $\\pm$ Dot product: \\cdot → $\\cdot$ Spacing Use these for better spacing:\n\\, — small space \\quad — medium space \\qquad — large space Example: $a \\, b \\quad c \\qquad d$ renders as $a , b \\quad c \\qquad d$\nTips Escaping special characters: If you need to show actual dollar signs in text, escape them: \\$100\nAlignment: Use \u0026amp; for alignment in multi-line equations with aligned environment:\n1 2 3 4 5 6 $$ \\begin{aligned} f(x) \u0026amp;= x^2 + 2x + 1 \\\\ \u0026amp;= (x + 1)^2 \\end{aligned} $$ $$ \\begin{aligned} f(x) \u0026amp;= x^2 + 2x + 1 \\ \u0026amp;= (x + 1)^2 \\end{aligned} $$\nCurly braces: Use \\{ and \\} for literal braces: ${1, 2, 3}$\nResources KaTeX Supported Functions - Complete reference Detexify - Draw a symbol to find its LaTeX command LaTeX Math Symbols - Comprehensive PDF That\u0026rsquo;s all you need to add beautiful math notation to your posts. The syntax might look intimidating at first, but you\u0026rsquo;ll quickly remember the common patterns.\n","tags":["katex","math","latex","markdown","documentation"],"categories":["Engineering"]},{"title":"Essential Vim Commands and Shell Vi Mode","date":"2024-09-20","permalink":"https://santoshmano.com/blog/vim-commands-and-shell-vi-mode/","summary":"Essential Vim Commands and Shell Vi Mode A practical guide to the most commonly used vim commands and shell vi mode. This covers the 20% of commands you\u0026rsquo;ll use 80% of the time.\nSetting Up Vi Mode in Shell Zsh Add to ~/.zshrc:\n1 2 3 4 5 # Enable vi mode bindkey -v # Reduce delay when switching modes export KEYTIMEOUT=1 Bash Add to ~/.bashrc:\n1 2 # Enable vi mode set -o vi Apply and Test 1 2 3 4 5 6 7 8 9 # Reload configuration source ~/.zshrc # for zsh source ~/.bashrc # for bash # Test it: # 1. Type some text # 2. Press ESC (enter command mode) # 3. Press k (navigate history) # 4. Press i (back to insert mode) Shell Vi Mode - Essential Commands The Basics Command Action ESC Enter command mode i Enter insert mode a Insert after cursor A Insert at end of line Navigation Command Action h, j, k, l Left, down, up, right w Next word b Previous word 0 Start of line $ End of line Editing Command Action x Delete character dd Delete line D Delete to end of line cc Delete line and insert u Undo History \u0026amp; Search Command Action k / j Previous / next in history /text Search history forward n Next search result Essential Vim Commands Opening Files 1 2 vim filename.txt # Open file vim +42 filename.txt # Open at line 42 The Two Modes You Need ESC - Normal mode (navigate and command) i - Insert mode (type text) Saving and Quitting Command Action :w Save :q Quit :wq or ZZ Save and quit :q! Quit without saving Navigation Command Action h, j, k, l Left, down, up, right w Next word b Previous word 0 Beginning of line $ End of line gg First line G Last line :42 Go to line 42 Ctrl-d / Ctrl-u Scroll down/up Editing Command Action i Insert before cursor a Insert after cursor I Insert at line start A Insert at line end o Open line below O Open line above x Delete character dd Delete line D Delete to end of line cc Change entire line J Join line with next u Undo Ctrl-r Redo . Repeat last command Copy, Cut, Paste Command Action yy Copy line yw Copy word y$ Copy to end of line dd Cut line dw Cut word p Paste after P Paste before Search Command Action /pattern Search forward ?pattern Search backward n Next result N Previous result * Search word under cursor Replace Command Action :s/old/new/ Replace first in line :s/old/new/g Replace all in line :%s/old/new/g Replace all in file :%s/old/new/gc Replace with confirmation Visual Mode (Selection) Command Action v Visual character mode V Visual line mode y Copy selection d Delete selection Quick Reference Card Most Common Workflow:\n","content":"Essential Vim Commands and Shell Vi Mode A practical guide to the most commonly used vim commands and shell vi mode. This covers the 20% of commands you\u0026rsquo;ll use 80% of the time.\nSetting Up Vi Mode in Shell Zsh Add to ~/.zshrc:\n1 2 3 4 5 # Enable vi mode bindkey -v # Reduce delay when switching modes export KEYTIMEOUT=1 Bash Add to ~/.bashrc:\n1 2 # Enable vi mode set -o vi Apply and Test 1 2 3 4 5 6 7 8 9 # Reload configuration source ~/.zshrc # for zsh source ~/.bashrc # for bash # Test it: # 1. Type some text # 2. Press ESC (enter command mode) # 3. Press k (navigate history) # 4. Press i (back to insert mode) Shell Vi Mode - Essential Commands The Basics Command Action ESC Enter command mode i Enter insert mode a Insert after cursor A Insert at end of line Navigation Command Action h, j, k, l Left, down, up, right w Next word b Previous word 0 Start of line $ End of line Editing Command Action x Delete character dd Delete line D Delete to end of line cc Delete line and insert u Undo History \u0026amp; Search Command Action k / j Previous / next in history /text Search history forward n Next search result Essential Vim Commands Opening Files 1 2 vim filename.txt # Open file vim +42 filename.txt # Open at line 42 The Two Modes You Need ESC - Normal mode (navigate and command) i - Insert mode (type text) Saving and Quitting Command Action :w Save :q Quit :wq or ZZ Save and quit :q! Quit without saving Navigation Command Action h, j, k, l Left, down, up, right w Next word b Previous word 0 Beginning of line $ End of line gg First line G Last line :42 Go to line 42 Ctrl-d / Ctrl-u Scroll down/up Editing Command Action i Insert before cursor a Insert after cursor I Insert at line start A Insert at line end o Open line below O Open line above x Delete character dd Delete line D Delete to end of line cc Change entire line J Join line with next u Undo Ctrl-r Redo . Repeat last command Copy, Cut, Paste Command Action yy Copy line yw Copy word y$ Copy to end of line dd Cut line dw Cut word p Paste after P Paste before Search Command Action /pattern Search forward ?pattern Search backward n Next result N Previous result * Search word under cursor Replace Command Action :s/old/new/ Replace first in line :s/old/new/g Replace all in line :%s/old/new/g Replace all in file :%s/old/new/gc Replace with confirmation Visual Mode (Selection) Command Action v Visual character mode V Visual line mode y Copy selection d Delete selection Quick Reference Card Most Common Workflow:\n1. 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 Essential Shortcuts:\n# 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 \u0026#39;text\u0026#39; n - Next result # Save/Quit :w - Save :q - Quit :wq - Save and quit :q! - Quit without saving Vim Configuration Permanent Settings (.vimrc) Create ~/.vimrc with basics:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 \u0026#34; Essentials set number \u0026#34; Line numbers set cursorline \u0026#34; Highlight current line set hlsearch \u0026#34; Highlight search results set incsearch \u0026#34; Search as you type set ignorecase \u0026#34; Case insensitive search set smartcase \u0026#34; Case sensitive if uppercase used \u0026#34; Indentation set tabstop=4 \u0026#34; Tab width set shiftwidth=4 \u0026#34; Indent width set expandtab \u0026#34; Spaces instead of tabs set autoindent \u0026#34; Auto indent \u0026#34; Usability set showcmd \u0026#34; Show command set wildmenu \u0026#34; Command completion set showmatch \u0026#34; Show matching brackets Runtime Settings Apply these settings within vim for the current session:\n1 2 3 4 5 :se ic \u0026#34; ignore case for search :se noai \u0026#34; turn off auto indent :se hlsearch \u0026#34; highlight search matches :highlight Comment ctermfg=blue \u0026#34; change color of commented text :se syntax \u0026#34; enable syntax highlighting These are shortcuts for :set. Add them to .vimrc to make permanent (without the colon).\nTips for Daily Use 1. Learn the Movement Keys First Before anything else, get comfortable with h, j, k, l and w, b. Your hands never leave home row.\n2. Use . (Dot) Command The dot command repeats your last change. Super powerful:\ncw new\u0026lt;ESC\u0026gt; - Change word to \u0026#34;new\u0026#34; w - Move to next word . - Repeat the change 3. Shell Vi Mode Tricks 1 2 3 4 5 # After typing a long command: ESC - Enter command mode 0 - Jump to start w w w - Move forward 3 words i - Insert and edit 4. Don\u0026rsquo;t Overthink It Start with these basics. Add more as you need them. You don\u0026rsquo;t need to master everything at once.\nCommon Mistakes Stuck in Insert Mode? Press ESC\nCan\u0026rsquo;t Exit Vim? Type :q! and press Enter\nCommands Not Working? Make sure you\u0026rsquo;re in normal mode (press ESC)\nSlow Mode Switching? Add export KEYTIMEOUT=1 to your shell config\nResources Run vimtutor in your terminal - 30 minute interactive tutorial Vim Documentation OpenVim Tutorial - Interactive in browser Practice Exercise Try this workflow:\nEnable vi mode: bindkey -v (zsh) or set -o vi (bash) Type: ls -la /usr/local/bin Press ESC Press 0 (go to start) Press w three times (skip \u0026ldquo;ls -la\u0026rdquo;) Press cw (change word) Type a new path Press Enter The key is practice. Use it daily and it becomes second nature.\nRemember: You only need to know 20% of vim to be 80% effective. Start here, expand later.\nRelated Posts ctags, cscope, and Screen: My IDE for 12 Years Using GNU Screen on Unix How I Use tmux on Mac ","tags":["Vim","Shell","Productivity","Terminal","Unix"],"categories":["Reference"]},{"title":"How I Use tmux on Mac","date":"2024-09-05","permalink":"https://santoshmano.com/blog/tmux-mac-tutorial/","summary":"I started using tmux about a year ago and honestly can\u0026rsquo;t imagine going back. If you spend a lot of time in the terminal like I do, tmux is a game-changer.\nWhy I Use tmux I used to have like 10 terminal windows open, constantly switching between them. SSH sessions would die when my laptop went to sleep. I\u0026rsquo;d lose my carefully arranged split panes when I closed a terminal by accident.\n","content":"I started using tmux about a year ago and honestly can\u0026rsquo;t imagine going back. If you spend a lot of time in the terminal like I do, tmux is a game-changer.\nWhy I Use tmux I used to have like 10 terminal windows open, constantly switching between them. SSH sessions would die when my laptop went to sleep. I\u0026rsquo;d lose my carefully arranged split panes when I closed a terminal by accident.\ntmux 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.\nGetting Started Install it with Homebrew:\n1 brew install tmux That\u0026rsquo;s it. Run tmux and you\u0026rsquo;re in.\nThe Basics (What I Actually Use Daily) tmux uses a \u0026ldquo;prefix key\u0026rdquo; for commands - by default it\u0026rsquo;s Ctrl-b. You press that first, release, then press the command key.\nSessions - The Killer Feature This is why tmux is worth it:\n1 2 3 4 5 6 7 8 9 10 11 # Start a named session tmux new -s myproject # Detach (close terminal, session keeps running) Ctrl-b d # Come back later, everything\u0026#39;s still there tmux attach -t myproject # List all your sessions tmux ls I have persistent sessions for different projects. My work session, my personal projects session, experiments session. They\u0026rsquo;re always running, I just attach/detach as needed.\nWindow Management Think of these like browser tabs:\n1 2 3 4 5 6 7 8 9 10 11 # New window Ctrl-b c # Next/previous window Ctrl-b n / Ctrl-b p # Jump to window 0-9 Ctrl-b 0-9 # Rename window (I do this for every window) Ctrl-b , I typically have 3-4 windows per session: one for code, one for servers, one for git operations, one for random commands.\nNote on split screens: I use iTerm\u0026rsquo;s built-in split panes instead of tmux panes. iTerm handles splits well, and it\u0026rsquo;s one less thing to manage in tmux.\nMy ~/.tmux.conf I spent way too long tweaking this, but here\u0026rsquo;s what actually matters:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # Mouse support set -g mouse on # Start window numbering at 1 (easier to reach than 0) set -g base-index 1 # More scrollback history set -g history-limit 10000 # Better colors set -g default-terminal \u0026#34;screen-256color\u0026#34; # Reload config quickly bind r source-file ~/.tmux.conf \\; display \u0026#34;Config reloaded!\u0026#34; # Don\u0026#39;t auto-rename my carefully named windows set-option -g allow-rename off # Simple status bar set -g status-style bg=black,fg=white set -g status-left \u0026#39;#[fg=green]#S \u0026#39; set -g status-right \u0026#39;#[fg=cyan]%d %b %R\u0026#39; Put that in ~/.tmux.conf and reload with Ctrl-b : then source-file ~/.tmux.conf.\nMy Actual Workflow Starting my day:\n1 2 # Attach to my main work session tmux attach -t work Everything\u0026rsquo;s exactly where I left it yesterday. Editor still open, servers still running, git still on the right branch.\nWorking on a side project:\n1 2 3 4 5 # Detach from work Ctrl-b d # Start or attach to project session tmux attach -t sideproject Context switch in 2 seconds.\nSSH-ing to a server:\n1 2 ssh myserver tmux attach My remote session persists even if my connection drops. I can pick up right where I left off.\nWhat Took Me a While to Learn Copy mode: Ctrl-b [ lets you scroll back and copy text. Use arrow keys to navigate, Space to start selection, Enter to copy, then Ctrl-b ] to paste. Took me forever to figure this out.\nDetaching vs Closing: Ctrl-b d detaches (session keeps running). exit in all windows actually closes the session. I used to confuse these.\nCommand mode: Ctrl-b : opens a command prompt. You can type any tmux command here. I use it for killing sessions: :kill-session -t oldproject\nSession groups (viewing different windows simultaneously): This took me forever to figure out. When you attach to the same session from multiple terminals using tmux attach, all terminals mirror each other - they show the same window. Not what you want.\nIf you want independent views of different windows within the same session, use session groups:\n1 2 3 4 5 6 7 8 9 10 11 # Terminal 1: Create the main session tmux new -s work # Terminal 2: Create a new session grouped with \u0026#39;work\u0026#39; tmux new -t work -s work-view2 # Terminal 3: Another grouped session tmux new -t work -s work-view3 # Or use the short form (tmux auto-generates unique names) tmux new -t work What this does:\nAll sessions share the same windows (0, 1, 2, 3, etc.) Each terminal can view a different window independently Changes in one terminal (creating/closing windows) appear in all But each terminal can switch windows independently! Verify it\u0026rsquo;s working:\n1 2 3 4 5 6 tmux ls # You\u0026#39;ll see something like: # work: 5 windows (created Mon Nov 11 10:00:00 2025) # work-view2: 5 windows (created Mon Nov 11 10:01:00 2025) (group work) # work-view3: 5 windows (created Mon Nov 11 10:02:00 2025) (group work) The (group work) indicates they share the same windows.\nWhat NOT to do:\n1 2 # ❌ This causes mirroring (all terminals show the same window) tmux attach -t work # Don\u0026#39;t use this in multiple terminals Bonus alias (add to ~/.zshrc or ~/.bashrc):\n1 2 3 4 alias tmux-join=\u0026#39;tmux new-session -t\u0026#39; # Usage: # tmux-join work 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.\nQuick Reference (What I Look Up Every Time) What I Want Key Detach from session Ctrl-b d New window Ctrl-b c Next/prev window Ctrl-b n/p Copy mode (scroll) Ctrl-b [ List all commands Ctrl-b ? Is It Worth Learning? If you live in the terminal: absolutely yes.\nThe learning curve is real - for the first few days I kept closing tmux by accident and getting confused. But once it clicks, you\u0026rsquo;ll wonder how you worked without it.\nStart simple: just use sessions and detach/attach. That alone is worth it. Then gradually add windows and panes as you get comfortable.\nFor me, tmux means I can close my laptop, open it somewhere else, and continue exactly where I left off. That\u0026rsquo;s powerful.\nResources tmux cheat sheet - I still reference this Official docs: https://github.com/tmux/tmux/wiki Book: \u0026ldquo;tmux 2\u0026rdquo; by Brian Hogan - actually worth reading That\u0026rsquo;s my tmux setup. Not fancy, but works great for me. If you have questions or want to share your setup, find me on X.\n","tags":["tmux","terminal","mac","productivity"],"categories":["Engineering"]},{"title":"Writing in Markdown: A Simple Guide","date":"2024-08-15","permalink":"https://santoshmano.com/blog/markdown-basics-guide/","summary":"I write every post on this blog in Markdown. It\u0026rsquo;s simple, clean, and lets me focus on writing without fussing over formatting buttons or HTML tags.\nIf you\u0026rsquo;ve never used Markdown before, it might look weird at first - you\u0026rsquo;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\u0026rsquo;ll find yourself wishing every text box supported Markdown.\n","content":"I write every post on this blog in Markdown. It\u0026rsquo;s simple, clean, and lets me focus on writing without fussing over formatting buttons or HTML tags.\nIf you\u0026rsquo;ve never used Markdown before, it might look weird at first - you\u0026rsquo;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\u0026rsquo;ll find yourself wishing every text box supported Markdown.\nWhat is Markdown? Markdown is a way to write formatted text using plain text. Instead of clicking \u0026ldquo;Bold\u0026rdquo; or selecting \u0026ldquo;Heading 1\u0026rdquo; from a dropdown, you just type **bold** or # Heading 1. When your Markdown file gets processed (by Hugo, Jekyll, GitHub, etc.), it converts these markers into proper HTML.\nThe beauty? You can write Markdown in any text editor - VS Code, Sublime, even Notepad. No special software needed.\nBasic Formatting Headings Use hash marks for headings. More hashes = smaller heading.\n1 2 3 4 # Heading 1 ## Heading 2 ### Heading 3 #### Heading 4 Emphasis Bold text with double asterisks or underscores:\n1 2 **This is bold** __This is also bold__ Italic text with single asterisks or underscores:\n1 2 *This is italic* _This is also italic_ Bold and italic together:\n1 ***Bold and italic*** Lists Unordered lists with dashes, asterisks, or plus signs:\n1 2 3 - Item one - Item two - Item three Ordered lists with numbers:\n1 2 3 1. First item 2. Second item 3. Third item Nested lists? Just indent:\n1 2 3 4 - Main item - Sub item - Another sub item - Another main item Links and Images Links use brackets and parentheses:\n1 2 [Link text](https://example.com) [Link with title](https://example.com \u0026#34;Hover text\u0026#34;) Images are just like links with an exclamation mark in front:\n1 2 ![Alt text](/path/to/image.jpg) ![Image with title](/path/to/image.jpg \u0026#34;Image title\u0026#34;) Code Inline code uses backticks:\n1 Use the `hugo server` command to start the dev server. Code blocks use triple backticks with optional language:\n1 2 3 4 ```python def hello(): print(\u0026#34;Hello, world!\u0026#34;) ``` Blockquotes Use the greater-than symbol:\n1 2 \u0026gt; This is a blockquote. \u0026gt; It can span multiple lines. Horizontal Rules Three or more dashes, asterisks, or underscores:\n1 --- Tables Tables use pipes and dashes:\n1 2 3 4 | Column 1 | Column 2 | Column 3 | |----------|----------|----------| | Data 1 | Data 2 | Data 3 | | Data 4 | Data 5 | Data 6 | Which renders as:\nColumn 1 Column 2 Column 3 Data 1 Data 2 Data 3 Data 4 Data 5 Data 6 Align columns with colons:\n1 2 3 4 | Left | Center | Right | |:-----|:------:|------:| | L1 | C1 | R1 | | L2 | C2 | R2 | What I Actually Use I don\u0026rsquo;t use all of Markdown\u0026rsquo;s features in every post. Here\u0026rsquo;s what I use most:\nHeadings - Structure every article with ## and ### Bold and italic - Emphasis where it matters Code blocks - Command examples and code snippets Lists - Breaking down steps or options Links - Connecting to related articles or references I rarely use blockquotes or tables unless the content really calls for it.\nHugo-Specific Features Since this blog runs on Hugo, I also use:\nFront Matter Every post starts with YAML front matter:\n1 2 3 4 5 6 7 8 --- title: \u0026#34;Your Post Title\u0026#34; date: 2025-01-14T10:00:00-08:00 draft: false tags: [\u0026#34;tag1\u0026#34;, \u0026#34;tag2\u0026#34;] categories: [\u0026#34;category\u0026#34;] description: \u0026#34;Short description for SEO and previews\u0026#34; --- Mermaid Diagrams 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.\n1 2 3 4 5 ```mermaid graph LR A[Write Markdown] --\u0026gt; B[Run Hugo] B --\u0026gt; C[Get HTML] ``` Which renders as:\ngraph LR A[Write Markdown] --\u003e B[Run Hugo] B --\u003e C[Get HTML] I wrote a whole post about using Mermaid diagrams in Hugo if you want to see more examples and learn how to add it to your own Hugo site.\nTips for Writing Use a Markdown-aware editor - VS Code, Typora, or iA Writer all have live preview. You can see formatting as you type.\nKeep it simple - Don\u0026rsquo;t overthink formatting. Focus on writing. Add formatting after.\nPreview before publishing - Run hugo server -D locally to see how your post looks before publishing.\nLearn as you go - Start with headings, bold, and code blocks. Add more formatting techniques as you need them.\nCommon Mistakes Extra spaces in lists - Markdown is picky about indentation. Use consistent spacing.\nForgetting the blank line - Always put a blank line before and after code blocks, lists, and headings. Makes Markdown parsers happy.\nNot escaping special characters - If you need a literal asterisk or underscore, escape it with a backslash: \\* or \\_.\nThat\u0026rsquo;s It Markdown isn\u0026rsquo;t complicated. It\u0026rsquo;s just a few symbols that make sense once you use them a few times. Write a couple of posts and you\u0026rsquo;ll have it down.\nThe reason I like Markdown is that my content is just text files. No proprietary formats, no databases, no vendor lock-in. Just .md files I can open in any editor, now or 10 years from now.\nThat\u0026rsquo;s powerful.\n","tags":["markdown","writing","blogging"],"categories":["Engineering"]},{"title":"Using GNU Screen on Unix","date":"2024-08-10","permalink":"https://santoshmano.com/blog/unix-screen-utility/","summary":"Back in the day, I used GNU Screen religiously when working on HP-UX. I\u0026rsquo;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.\nScreen is a terminal multiplexer - it lets you create multiple terminal windows within one session. The killer feature? Sessions persist even when you disconnect.\n","content":"Back in the day, I used GNU Screen religiously when working on HP-UX. I\u0026rsquo;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.\nScreen is a terminal multiplexer - it lets you create multiple terminal windows within one session. The killer feature? Sessions persist even when you disconnect.\nWhy Screen Was Essential When you\u0026rsquo;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\u0026rsquo;s still there.\nI used it for years for long-running kernel builds, deployment scripts, and SSH sessions to production servers.\nWhy I Switched to tmux 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\u0026rsquo;re starting fresh today, I\u0026rsquo;d recommend tmux instead.\nThat said, Screen still works great and you\u0026rsquo;ll find it on almost any Unix system.\nEssential Commands Session Management screen -S — create new sessions screen -x — attach to existing session screen -d -r — reattach with forced detachment if needed screen -d — detach from terminal screen -list — display status screen -dr owner/sessionid.name — connect to another user\u0026rsquo;s session (root access required) Within Screen ^a c — create new window ^a d — detach from session ^a spacebar — navigate to next window ^a backspace or ^a del — navigate to previous window ^a 2 — jump to window 2 ^a w — list windows ^a ^a — toggle between windows ^a SHIFT-a — rename window (^ represents Control key)\nConfiguration Scrollback Buffer By default, Screen has limited scrollback. To increase it, set this within a running session:\n:scrollback 10000 Or add it to your ~/.screenrc:\n1 scrollback 10000 Status Line (.screenrc) Here\u0026rsquo;s a useful status line configuration that shows window list, system info, and timestamp:\n1 caption always \u0026#34;%{= kw}%-w%{= BW}%n %t%{-}%+w %-= @%H - %LD %d %LM - %c\u0026#34; This displays:\nWindow list with current window highlighted Hostname Date and time Updates automatically Getting Started Screen comes pre-installed on most Unix systems. Just type screen to start a session.\nThe keybindings take some getting used to, but they become muscle memory fast. You can customize everything in a ~/.screenrc file.\nHistorical Note This article is from 2010 when I was actively using Screen. I\u0026rsquo;ve since switched to tmux, but Screen still works great if you prefer it or need to work on systems where it\u0026rsquo;s already installed.\nRelated Posts ctags, cscope, and Screen: My IDE for 12 Years How I Use tmux on Mac Essential Vim Commands ","tags":["unix","linux","screen","terminal","productivity"],"categories":["Engineering","Reference"]},{"title":"How I Set Up This Site with Hugo, Netlify, and Cloudflare","date":"2024-07-05","permalink":"https://santoshmano.com/blog/deploying-hugo-netlify-cloudflare/","summary":"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\u0026rsquo;t want to deal with databases, server maintenance, or complex CMS systems.\nAfter 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.\n","content":"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\u0026rsquo;t want to deal with databases, server maintenance, or complex CMS systems.\nAfter 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.\nWhy I Chose This Setup I picked Hugo because it\u0026rsquo;s incredibly fast and generates pure static HTML. No server-side processing, no security vulnerabilities to worry about. The Stack theme caught my eye immediately – clean, card-based design that just works.\nFor hosting, Netlify 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.\nCloudflare 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.\nThe entire workflow: write locally → push to GitHub → Netlify auto-deploys → Cloudflare serves it globally.\nSetting Up Locally I\u0026rsquo;m on a Mac, so I used Homebrew to install everything I needed:\n1 brew install hugo go git After installation, I verified everything was working:\n1 2 3 hugo version go version git --version Then I created the site structure and set it up as a Hugo module:\n1 2 3 mkdir santoshmano \u0026amp;\u0026amp; cd santoshmano hugo new site . hugo mod init github.com/santoshmano/santoshmano.com Configuring the Stack Theme I created a hugo.toml configuration file with these settings:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 baseURL = \u0026#34;https://santoshmano.com/\u0026#34; title = \u0026#34;Santosh Manoharan\u0026#34; languageCode = \u0026#34;en-us\u0026#34; paginate = 10 enableRobotsTXT = true [module] [[module.imports]] path = \u0026#34;github.com/CaiJimmy/hugo-theme-stack/v3\u0026#34; [params] enableSearch = true showReadingTime = true showCodeCopyButtons = true mainSections = [\u0026#34;blog\u0026#34;] [params.colorScheme] toggle = true default = \u0026#34;auto\u0026#34; [taxonomies] tag = \u0026#34;tags\u0026#34; category = \u0026#34;categories\u0026#34; [markup] [markup.goldmark.renderer] unsafe = true [markup.highlight] noClasses = false lineNos = true To preview locally, I ran:\n1 hugo server -D This starts a development server at http://localhost:1313 with live reload, which made testing changes incredibly fast. When I was ready to build for production, I used:\n1 hugo --minify Pushing to GitHub I initialized a git repository and pushed everything to GitHub:\n1 2 3 4 5 6 git init git add . git commit -m \u0026#34;Initial Hugo setup with Stack theme\u0026#34; git branch -M main git remote add origin https://github.com/santoshmano/santoshmano.com.git git push -u origin main Deploying to Netlify I logged into Netlify and connected my GitHub repository. The setup was straightforward:\nClicked \u0026ldquo;Add new site\u0026rdquo; → \u0026ldquo;Import from GitHub\u0026rdquo; Selected my repository Configured the build settings: Build command: hugo --minify Publish directory: public Added an environment variable: Key: HUGO_VERSION Value: 0.139.0 Hit \u0026ldquo;Deploy site\u0026rdquo; Within minutes, my site was live at a Netlify subdomain.\nAdding netlify.toml For better control over the build process, I added a netlify.toml file to my project root:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 [build] command = \u0026#34;hugo --minify\u0026#34; publish = \u0026#34;public\u0026#34; [build.environment] HUGO_VERSION = \u0026#34;0.139.0\u0026#34; HUGO_ENV = \u0026#34;production\u0026#34; HUGO_ENABLEGITINFO = \u0026#34;true\u0026#34; [context.production.environment] HUGO_ENV = \u0026#34;production\u0026#34; [context.deploy-preview.environment] HUGO_VERSION = \u0026#34;0.139.0\u0026#34; Connecting My Custom Domain with Cloudflare Since my domain was already registered with Cloudflare, I kept it there for DNS management instead of switching to Netlify\u0026rsquo;s DNS.\nDNS Configuration In Cloudflare\u0026rsquo;s DNS settings, I added two CNAME records:\nFor the root domain (santoshmano.com):\nType: CNAME Name: @ Content: santoshmano.netlify.app Proxy status: Proxied (🟠 orange cloud ON) TTL: Auto For the www subdomain:\nType: CNAME Name: www Content: santoshmano.netlify.app Proxy status: Proxied (🟠 orange cloud ON) TTL: Auto SSL/TLS Configuration In Cloudflare\u0026rsquo;s SSL/TLS settings, I set the encryption mode to Full. This ensures proper end-to-end encryption between Cloudflare and Netlify.\nAdding the Domain in Netlify Back in Netlify, I added my custom domain:\nWent to Site settings → Domain management Clicked \u0026ldquo;Add a domain\u0026rdquo; Entered santoshmano.com and verified it Repeated the process for www.santoshmano.com Set santoshmano.com as the primary domain Setting Up HTTPS In Netlify\u0026rsquo;s HTTPS section, I clicked \u0026ldquo;Verify DNS configuration\u0026rdquo; and then \u0026ldquo;Provision certificate\u0026rdquo;. Netlify automatically issued a Let\u0026rsquo;s Encrypt SSL certificate, which took about 5-10 minutes.\nTesting Everything After waiting for DNS propagation (around 15 minutes in my case), I tested:\n✅ https://santoshmano.com → loaded perfectly ✅ https://www.santoshmano.com → redirected to the main domain ✅ https://santoshmano.netlify.app → also worked Issues I Ran Into A few hiccups along the way that might save you some time:\nCertificate provisioning took longer than expected - I had to wait about 15 minutes and click \u0026ldquo;Verify DNS\u0026rdquo; a couple of times before it went through. Patience is key. Initially forgot to set SSL mode to \u0026ldquo;Full\u0026rdquo; in Cloudflare - This caused redirect loops. Once I fixed the SSL/TLS setting, everything worked smoothly. The Hugo version matters - Netlify was using an older Hugo version by default, which broke the Stack theme. Setting HUGO_VERSION in the environment variables fixed it. How It All Fits Together The architecture is elegantly simple:\nMy 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) Every time I push to GitHub, Netlify automatically rebuilds and deploys the site. Cloudflare\u0026rsquo;s CDN ensures fast load times globally.\nReflections 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.\nThe Stack theme has been great out of the box, though I did add some custom styling in assets/scss/custom.scss to tweak the dark mode colors and accent color to my liking.\nIf you\u0026rsquo;re considering building a personal site or blog, I\u0026rsquo;d highly recommend this stack. It\u0026rsquo;s fast, secure, free (for most personal use cases), and requires minimal maintenance.\nUseful Links Hugo Documentation Stack Theme Documentation Netlify Documentation Cloudflare DNS Documentation ","tags":["hugo","netlify","cloudflare","deployment","jamstack","static-site"],"categories":["Engineering"]},{"title":"Hello World","date":"2024-07-01","permalink":"https://santoshmano.com/blog/hello-world/","summary":"","content":"","tags":[],"categories":["Life"]},{"title":"Couch to Goggins 4x4x48 Challenge","date":"2021-03-11","permalink":"https://santoshmano.com/blog/couch-to-goggins-4x4x48-challenge/","summary":"A type 1 diabetic\u0026rsquo;s notes on learning to balance food, insulin, exercise \u0026amp; mind\n","content":"A type 1 diabetic\u0026rsquo;s notes on learning to balance food, insulin, exercise \u0026amp; mind\nImage credit: https://www.gogginschallenge.com/\nI 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\u0026rsquo;t. Goggins had a challenge coming up and I decided to use it to kickstart myself.\nThe challenge 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.\nI 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\u0026rsquo;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.\nI 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.\nI planned a few things out in my head on the day of the challenge:\nRide my bike instead of a run as it is easier with my current weight \u0026amp; knee. Ride a fixed route, as I can focus on my health instead of route challenges. Stock a few things I can eat and drink, and stock glucose tablets. Keep a few ice packs in the freezer, fix my bikes, and continuous glucose monitors. The rest I thought I will figure out along the way.\nAs 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 Lex Fridman/Andrew Huberman 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 —\n\u0026ldquo;Suck It Up\u0026rdquo; and \u0026ldquo;Stay Hard\u0026rdquo;\nDisclaimer: 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\u0026rsquo;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.\nSummary Below is the visualization summary of the data I noted down about my ride, food, insulin during the challenge:\nMarch 5 \u0026amp; 6 was hard with constant lows, numerous corrections, varying glucose levels even though it was mostly in range. 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. Day 1\nDay 2\nDay 3\nRide Notes Decided to ride indoors at 8 pm, 12 am \u0026amp; 4 am, on my new unused stationary bike, and outdoors at 8 am, 12 pm \u0026amp; 4 pm, on an old creaking hybrid, in a fixed known route that I had done several times before. 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. 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. 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. 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. 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. 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. 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. 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. Food and Glucose Notes 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. 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. Observed something interesting repeatedly, ate carbs like banana/orange before the bike ride so that I don\u0026rsquo;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. 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. 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.\nFew people I would like to thanks, I got first introduced to learning how to manage my diabetes via Sami Inkinen of VirtaHealth 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 TypeoneGrit and the decades of learned wisdom of Dr. Bernstein who wrote the diabetes bible, The Diabetes Solution. The fitness, diet, and habit-building techniques I learned at Ketogains. I will write a different post mentioning all the wonderful things I have learned for these folks.\nKey Takeaways 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. 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. 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. 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. 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\u0026rsquo;t do this I will be battling lows all through, and when low they energy also goes low. Electrolytes work like magic, I tend to forget it sometimes. 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. 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. 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 :) 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. 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!\nWould love to hear your feedback: santosh.mano@gmail.com\nOriginally published on Medium on March 11, 2021.\n","tags":["fitness","diabetes","challenge","cycling","type1diabetes","goggins"],"categories":["Health"]},{"title":"Exercise and Sugars","date":"2017-01-27","permalink":"https://santoshmano.com/blog/exercise-and-sugars/","summary":"Personal observations about how different exercise types affect blood glucose (BG) levels in diabetes management.\nMorning Context I started with elevated blood sugar due to \u0026ldquo;Dawn Phenomenon and some unwise overeating of protein the previous night.\u0026rdquo; After breakfast and a 2-unit insulin correction, exercise began at 11 AM.\nAerobic Exercise Phase 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.\n","content":"Personal observations about how different exercise types affect blood glucose (BG) levels in diabetes management.\nMorning Context I started with elevated blood sugar due to \u0026ldquo;Dawn Phenomenon and some unwise overeating of protein the previous night.\u0026rdquo; After breakfast and a 2-unit insulin correction, exercise began at 11 AM.\nAerobic Exercise Phase 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.\nCorrection \u0026amp; Anaerobic Exercise Consuming 12g carbs (3 glucose tablets) followed by shoulder weight training raised glucose to 123 mg/dL. I observed that \u0026ldquo;intense weight lifting\u0026rdquo; caused the elevation, contrasting with previous experiences where similar situations resulted in 65-80 mg/dL.\nSecondary Aerobic Phase Returning to cycling for 25 minutes (100 calories) reversed the trend, dropping BG to 85 mg/dL. Within 5 minutes of resuming aerobic activity, \u0026ldquo;my BG rise stopped and it started to drop down.\u0026rdquo;\nConclusion This represents \u0026ldquo;my conclusive 4th experiment\u0026rdquo; demonstrating: how my BG goes down with Aerobic exercises and goes up with few Anaerobic exercises like lifting heavy weights.\nThe pattern is clear:\nAerobic exercise (walking, cycling) → Blood glucose decreases Anaerobic exercise (heavy weight lifting) → Blood glucose increases ","tags":["diabetes","exercise","health","fitness","blood-glucose"],"categories":["Health"]},{"title":"Endurance Exercises","date":"2017-01-09","permalink":"https://santoshmano.com/blog/endurance-exercises/","summary":"Five muscular endurance exercises sourced from Healthline to build strength and stamina.\n1. Plank Start prone with forearms supporting upper body Tighten and clench your lower back and shoulders to elevate your hips Hold: 30-45 seconds per set Sets: 5 2. Body Weight Squats Stand with feet wider than shoulder-width Drop to 90-degree knee angle Drive your body weight through your heels and push yourself back upright Reps: 25 repetitions Sets: 5 3. Walking Lunges ","content":"Five muscular endurance exercises sourced from Healthline to build strength and stamina.\n1. Plank Start prone with forearms supporting upper body Tighten and clench your lower back and shoulders to elevate your hips Hold: 30-45 seconds per set Sets: 5 2. Body Weight Squats Stand with feet wider than shoulder-width Drop to 90-degree knee angle Drive your body weight through your heels and push yourself back upright Reps: 25 repetitions Sets: 5 3. Walking Lunges Stand with feet shoulder-width apart Step forward, drop hips until back leg touches ground Reps: 30 lunges (15 per leg) Sets: 5 4. Pushups Start prone, push off ground into plank Lower yourself back downwards, letting your chest touch the ground Reps: 15 repetitions Sets: 5 5. Situps Lay supine with bent knees, feet flat Clench your stomach muscles to bring your torso up so that it\u0026rsquo;s flush Reps: 25 repetitions Sets: 5 Source: Healthline - Muscular Endurance Exercises\n","tags":["exercise","fitness","endurance","strength-training"],"categories":["Health"]},{"title":"Grit Reading Material","date":"2016-12-24","permalink":"https://santoshmano.com/blog/grit-reading-material/","summary":"A compilation of learning resources focused on diabetes management and fitness.\nDr. Bernstein\u0026rsquo;s Books Key Resources Books \u0026amp; Audiobooks Diabetes Solution - Available on Audible Video Resources Dr. Bernstein\u0026rsquo;s Diabetes University - Comprehensive video playlist covering diabetes management Dr. Dikeman\u0026rsquo;s Presentation - Low Carb USA conference talk Online Collections Pinterest Boards - TypeOneGrit Boards Google Photos - Collection of quotes and excerpts Grit Recipes - Recipe collection for diabetes management About These Resources 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.\n","content":"A compilation of learning resources focused on diabetes management and fitness.\nDr. Bernstein\u0026rsquo;s Books Key Resources Books \u0026amp; Audiobooks Diabetes Solution - Available on Audible Video Resources Dr. Bernstein\u0026rsquo;s Diabetes University - Comprehensive video playlist covering diabetes management Dr. Dikeman\u0026rsquo;s Presentation - Low Carb USA conference talk Online Collections Pinterest Boards - TypeOneGrit Boards Google Photos - Collection of quotes and excerpts Grit Recipes - Recipe collection for diabetes management About These Resources 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.\n","tags":["diabetes","health","resources","reading"],"categories":["Health"]},{"title":"Standard Input and Output Redirection","date":"2013-03-21","permalink":"https://santoshmano.com/blog/standard-input-output-redirection/","summary":"This post explains how the shell and Unix commands handle input/output streams and how to redirect them.\nOverview \u0026ldquo;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).\u0026rdquo;\nBy default, stdin connects to the keyboard while stdout and stderr display on the terminal screen. File redirection uses metacharacters to specify alternative destinations.\nC Shell Family Key redirection operators:\n","content":"This post explains how the shell and Unix commands handle input/output streams and how to redirect them.\nOverview \u0026ldquo;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).\u0026rdquo;\nBy default, stdin connects to the keyboard while stdout and stderr display on the terminal screen. File redirection uses metacharacters to specify alternative destinations.\nC Shell Family Key redirection operators:\nCharacter Action \u0026gt; Redirect standard output \u0026gt;\u0026amp; Redirect stdout and stderr ! Redirect stdout; overwrite existing file \u0026gt;\u0026amp;! Redirect stdout/stderr; force overwrite | Pipe stdout to another command \u0026gt;\u0026gt; Append to stdout \u0026gt;\u0026gt;\u0026amp; Append stdout and stderr Example commands:\nwho \u0026gt; names — save output to file (pwd; ls -l) \u0026gt; out — redirect multiple commands who \u0026gt;\u0026amp; /dev/null — suppress all output Bourne Shell Family Uses numeric file descriptors (0=stdin, 1=stdout, 2=stderr):\nCharacter Action \u0026gt; Redirect stdout 2\u0026gt; Redirect stderr 2\u0026gt;\u0026amp;1 Redirect stderr to stdout \u0026gt;\u0026gt; Append stdout 2\u0026gt;\u0026amp;1| Pipe both streams Example commands:\nwho \u0026gt; names — redirect output who 2\u0026gt; /dev/null — suppress errors only cat file \u0026gt; out 2\u0026gt; error — separate output and error files Source Reference material adapted from Math/CS at University of Picardie\n","tags":["unix","linux","shell","bash","redirection","stdio"],"categories":["Engineering"]},{"title":"Bit Twiddling Hacks","date":"2011-02-07","permalink":"https://santoshmano.com/blog/bit-twiddling-hacks/","summary":"An excellent resource on bit manipulation techniques and low-level bitwise operations.\nResource Check out Bit Twiddling Hacks by Sean Eron Anderson at Stanford\u0026rsquo;s graphics lab.\nThis comprehensive guide covers various bitwise operations and optimizations, including:\nCounting set bits Determining if integers have opposite signs Computing absolute values without branching Swapping values without temporary variables Finding minimum/maximum without branching And many more clever bit manipulation techniques These techniques are particularly useful for performance-critical code and understanding low-level programming concepts.\n","content":"An excellent resource on bit manipulation techniques and low-level bitwise operations.\nResource Check out Bit Twiddling Hacks by Sean Eron Anderson at Stanford\u0026rsquo;s graphics lab.\nThis comprehensive guide covers various bitwise operations and optimizations, including:\nCounting set bits Determining if integers have opposite signs Computing absolute values without branching Swapping values without temporary variables Finding minimum/maximum without branching And many more clever bit manipulation techniques These techniques are particularly useful for performance-critical code and understanding low-level programming concepts.\n","tags":["algorithms","bit-manipulation","optimization","c","programming"],"categories":["Engineering"]},{"title":"Algorithmic Efficiency - Various Orders and Examples","date":"2010-09-04","permalink":"https://santoshmano.com/blog/algorithmic-efficiency/","summary":"This post discusses various algorithmic time complexities and their practical examples.\nO(1) - Constant Time An algorithm that runs the same no matter what the input exemplifies constant time complexity, returning identical results regardless of input size.\nO(log n) - Logarithmic Time 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.\n","content":"This post discusses various algorithmic time complexities and their practical examples.\nO(1) - Constant Time An algorithm that runs the same no matter what the input exemplifies constant time complexity, returning identical results regardless of input size.\nO(log n) - Logarithmic Time 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.\nO(n) - Linear Time 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.\nO(n log n) - Linearithmic Time Merge sort exemplifies this efficiency class. The algorithm \u0026ldquo;breaks up an array into two halves, sorts those two halves by recursively calling itself on them, and then merging the result back\u0026rdquo; yielding O(n log n) overall complexity.\nO(n²) - Quadratic Time Selection sort and comparable algorithms operate within polynomial time, representing reasonable but less efficient solutions.\nO(2ⁿ) - Exponential Time Exponential algorithms address difficult problems like factoring large binary numbers. Trial-and-error approaches require \u0026ldquo;twice as many tests\u0026rdquo; per additional digit, demonstrating impractical scalability.\nSource: cprogramming.com\n","tags":["algorithms","complexity","big-o","computer-science"],"categories":["Engineering"]},{"title":"IBM Instant Capacity Products","date":"2010-09-04","permalink":"https://santoshmano.com/blog/ibm-instant-capacity/","summary":"IBM offers several Capacity on Demand (CoD) solutions designed to help organizations activate processors and memory without disrupting operations.\nIBM\u0026rsquo;s Product Offerings 1. Capacity Upgrade on Demand (Permanent) 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.\n2. Trial Capacity on Demand Provides 30-day trial periods for evaluating additional capacity.\n3. On/Off Capacity on Demand (Manual) Allows short-term activation similar to Ticap offerings.\n","content":"IBM offers several Capacity on Demand (CoD) solutions designed to help organizations activate processors and memory without disrupting operations.\nIBM\u0026rsquo;s Product Offerings 1. Capacity Upgrade on Demand (Permanent) 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.\n2. Trial Capacity on Demand Provides 30-day trial periods for evaluating additional capacity.\n3. On/Off Capacity on Demand (Manual) Allows short-term activation similar to Ticap offerings.\n4. Utility Capacity on Demand (Automatic) Automatically manages processor allocation from shared pools, measured in processor-minute increments for unpredictable workload spikes.\n5. Capacity BackUp Designed for disaster recovery with \u0026ldquo;a minimum set of active processors\u0026rdquo; and numerous inactive processors available for emergency activation. Includes complimentary activation days.\nKey Features Capacity on Demand allows you to easily activate processors and memory without disruption to your operations, paying for increased capacity as needs grow.\nBoth prepay and post-pay options are available for most solutions.\nNote Finding IBM\u0026rsquo;s GICAP equivalent to HP\u0026rsquo;s offering in this category proved difficult.\n","tags":["ibm","capacity-planning","enterprise","infrastructure"],"categories":["Engineering"]},{"title":"Linux RPM Commands","date":"2010-09-04","permalink":"https://santoshmano.com/blog/linux-rpm-commands/","summary":"This post provides a quick reference guide for common RPM (Red Hat Package Manager) commands used in Linux systems.\nBasic Package Operations List installed packages:\n1 rpm -qa Install a package:\n1 rpm -ivh foo-1.0-2.i386.rpm Test installation (without actually installing):\n1 rpm -ivh --test pkgname Remove a package:\n1 rpm -e foo Upgrade a package:\n1 rpm -Uvh foo-1.0-2.i386.rpm Freshen a package (upgrade only if previous version exists):\n","content":"This post provides a quick reference guide for common RPM (Red Hat Package Manager) commands used in Linux systems.\nBasic Package Operations List installed packages:\n1 rpm -qa Install a package:\n1 rpm -ivh foo-1.0-2.i386.rpm Test installation (without actually installing):\n1 rpm -ivh --test pkgname Remove a package:\n1 rpm -e foo Upgrade a package:\n1 rpm -Uvh foo-1.0-2.i386.rpm Freshen a package (upgrade only if previous version exists):\n1 rpm -Fvh pkgname Query and Information Commands Query a package:\n1 rpm -q foo Display package information:\n1 rpm -qi foo List files in a package:\n1 rpm -ql foo Find which package a file belongs to:\n1 rpm -qf filename Display file list and package information:\n1 rpm -qfl pkgname Package Verification Check RPM signature:\n1 rpm --checksig foo Operation Reference Table Operation Short Option Long Option Upgrade/install -U \u0026ndash;upgrade Install -I \u0026ndash;install Remove -e \u0026ndash;erase Query -q \u0026ndash;query Verify -V \u0026ndash;verify Check signature -K \u0026ndash;checksig Freshen -F \u0026ndash;freshen Initialize database — \u0026ndash;initdb Rebuild database — \u0026ndash;rebuilddb Source: Fedora RPM Guide\n","tags":["linux","rpm","package-management","redhat","fedora"],"categories":["Engineering"]},{"title":"Sort Benchmark","date":"2010-09-04","permalink":"https://santoshmano.com/blog/sort-benchmark/","summary":"Check out comprehensive sorting algorithm benchmarks at sortbenchmark.org.\nThis site provides detailed performance comparisons and benchmarks for various sorting algorithms across different data sets and conditions.\n","content":"Check out comprehensive sorting algorithm benchmarks at sortbenchmark.org.\nThis site provides detailed performance comparisons and benchmarks for various sorting algorithms across different data sets and conditions.\n","tags":["algorithms","sorting","benchmarks","performance"],"categories":["Engineering"]},{"title":"Steps to Create a Filesystem on HPUX","date":"2010-09-04","permalink":"https://santoshmano.com/blog/hpux-filesystem-creation/","summary":"A comprehensive guide to creating filesystems on HP-UX systems using Logical Volume Manager (LVM).\nCheck List of Disks Available 1 2 3 4 5 6 7 8 9 10 11 # ioscan -funC disk Class I H/W Path Driver S/W State H/W Type Description ======================================================================= disk 3 0/0/0/2/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAS3367NC /dev/dsk/c0t6d0 /dev/dsk/c0t6d0s2 /dev/rdsk/c0t6d0 /dev/rdsk/c0t6d0s2 /dev/dsk/c0t6d0s1 /dev/dsk/c0t6d0s3 /dev/rdsk/c0t6d0s1 /dev/rdsk/c0t6d0s3 disk 0 0/0/0/2/1.2.0 sdisk CLAIMED DEVICE HP DVD-ROM 305 /dev/dsk/c1t2d0 /dev/rdsk/c1t2d0 disk 4 0/0/0/3/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAP3367NC /dev/dsk/c2t6d0 /dev/dsk/c2t6d0s2 /dev/rdsk/c2t6d0 /dev/rdsk/c2t6d0s2 /dev/dsk/c2t6d0s1 /dev/dsk/c2t6d0s3 /dev/rdsk/c2t6d0s1 /dev/rdsk/c2t6d0s3 Check Disks Already in Use 1 2 3 # strings /etc/lvmtab /dev/vg00 /dev/dsk/c0t6d0s2 Create Filesystem Using Free Disk Step 1: Create Physical Volume 1 2 # pvcreate -f /dev/rdsk/c2t6d0 Physical volume \u0026#34;/dev/rdsk/c2t6d0\u0026#34; has been successfully created. Step 2: Create Volume Group Directory and Device Node 1 2 # mkdir /dev/vg01 # mknod /dev/vg01/group c 64 0x010000 Step 3: Create Volume Group 1 2 3 4 # vgcreate /dev/vg01 /dev/dsk/c2t6d0 Increased the number of physical extents per physical volume to 8683. Volume group \u0026#34;/dev/vg01\u0026#34; has been successfully created. Volume Group configuration for /dev/vg01 has been saved in /etc/lvmconf/vg01.conf Step 4: Create Logical Volume 1 2 3 4 # lvcreate -L 20000 -n depot /dev/vg01 Logical volume \u0026#34;/dev/vg01/depot\u0026#34; has been successfully created with character device \u0026#34;/dev/vg01/rdepot\u0026#34;. Logical volume \u0026#34;/dev/vg01/depot\u0026#34; has been successfully extended. Volume Group configuration for /dev/vg01 has been saved in /etc/lvmconf/vg01.conf Step 5: Create Filesystem 1 2 3 4 # mkfs -F vxfs /dev/vg01/rdepot version 6 layout 20480000 sectors, 20480000 blocks of size 1024, log size 16384 blocks largefiles supported Step 6: Create Mount Point and Mount Filesystem 1 2 # mkdir /depot # mount /dev/vg01/depot /depot Configure Automatic Mounting on Reboot Edit /etc/fstab to add the new filesystem:\n","content":"A comprehensive guide to creating filesystems on HP-UX systems using Logical Volume Manager (LVM).\nCheck List of Disks Available 1 2 3 4 5 6 7 8 9 10 11 # ioscan -funC disk Class I H/W Path Driver S/W State H/W Type Description ======================================================================= disk 3 0/0/0/2/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAS3367NC /dev/dsk/c0t6d0 /dev/dsk/c0t6d0s2 /dev/rdsk/c0t6d0 /dev/rdsk/c0t6d0s2 /dev/dsk/c0t6d0s1 /dev/dsk/c0t6d0s3 /dev/rdsk/c0t6d0s1 /dev/rdsk/c0t6d0s3 disk 0 0/0/0/2/1.2.0 sdisk CLAIMED DEVICE HP DVD-ROM 305 /dev/dsk/c1t2d0 /dev/rdsk/c1t2d0 disk 4 0/0/0/3/0.6.0 sdisk CLAIMED DEVICE HP 36.4GMAP3367NC /dev/dsk/c2t6d0 /dev/dsk/c2t6d0s2 /dev/rdsk/c2t6d0 /dev/rdsk/c2t6d0s2 /dev/dsk/c2t6d0s1 /dev/dsk/c2t6d0s3 /dev/rdsk/c2t6d0s1 /dev/rdsk/c2t6d0s3 Check Disks Already in Use 1 2 3 # strings /etc/lvmtab /dev/vg00 /dev/dsk/c0t6d0s2 Create Filesystem Using Free Disk Step 1: Create Physical Volume 1 2 # pvcreate -f /dev/rdsk/c2t6d0 Physical volume \u0026#34;/dev/rdsk/c2t6d0\u0026#34; has been successfully created. Step 2: Create Volume Group Directory and Device Node 1 2 # mkdir /dev/vg01 # mknod /dev/vg01/group c 64 0x010000 Step 3: Create Volume Group 1 2 3 4 # vgcreate /dev/vg01 /dev/dsk/c2t6d0 Increased the number of physical extents per physical volume to 8683. Volume group \u0026#34;/dev/vg01\u0026#34; has been successfully created. Volume Group configuration for /dev/vg01 has been saved in /etc/lvmconf/vg01.conf Step 4: Create Logical Volume 1 2 3 4 # lvcreate -L 20000 -n depot /dev/vg01 Logical volume \u0026#34;/dev/vg01/depot\u0026#34; has been successfully created with character device \u0026#34;/dev/vg01/rdepot\u0026#34;. Logical volume \u0026#34;/dev/vg01/depot\u0026#34; has been successfully extended. Volume Group configuration for /dev/vg01 has been saved in /etc/lvmconf/vg01.conf Step 5: Create Filesystem 1 2 3 4 # mkfs -F vxfs /dev/vg01/rdepot version 6 layout 20480000 sectors, 20480000 blocks of size 1024, log size 16384 blocks largefiles supported Step 6: Create Mount Point and Mount Filesystem 1 2 # mkdir /depot # mount /dev/vg01/depot /depot Configure Automatic Mounting on Reboot Edit /etc/fstab to add the new filesystem:\n1 2 3 4 5 6 7 8 9 10 # System /etc/fstab file. Static information about the file systems # See fstab(4) and sam(1M) for further details on configuring devices. /dev/vg00/lvol3 / vxfs delaylog 0 1 /dev/vg00/lvol1 /stand vxfs tranflush 0 1 /dev/vg00/lvol4 /tmp vxfs delaylog 0 2 /dev/vg00/lvol5 /home vxfs delaylog 0 2 /dev/vg00/lvol6 /opt vxfs delaylog 0 2 /dev/vg00/lvol7 /usr vxfs delaylog 0 2 /dev/vg00/lvol8 /var vxfs delaylog 0 2 /dev/vg01/depot /depot vxfs delaylog 0 2 The filesystem will now mount automatically on system reboot.\n","tags":["hpux","unix","filesystem","lvm","storage","system-administration"],"categories":["Engineering"]},{"title":"Sun's Instant Capacity Offerings","date":"2010-09-04","permalink":"https://santoshmano.com/blog/sun-instant-capacity/","summary":"Sun Microsystems offers Capacity on Demand (COD) solutions for enterprise infrastructure management.\nResources COD Buyers Guide PDF SUN COD Datasheet PDF These documents provide comprehensive information about Sun\u0026rsquo;s capacity planning and on-demand resource allocation offerings.\n","content":"Sun Microsystems offers Capacity on Demand (COD) solutions for enterprise infrastructure management.\nResources COD Buyers Guide PDF SUN COD Datasheet PDF These documents provide comprehensive information about Sun\u0026rsquo;s capacity planning and on-demand resource allocation offerings.\n","tags":["sun","capacity-planning","enterprise","infrastructure"],"categories":["Engineering"]},{"title":"The Invaluable Find Command","date":"2010-09-04","permalink":"https://santoshmano.com/blog/invaluable-find-command/","summary":"A powerful command-line technique for searching file contents across a directory structure:\n1 find . -name \u0026#34;*\u0026#34; -exec grep string {} \\; -print This command searches the current directory and all subdirectories for files containing a specified string pattern. The find command locates files, while grep searches within each file for the specified string.\n","content":"A powerful command-line technique for searching file contents across a directory structure:\n1 find . -name \u0026#34;*\u0026#34; -exec grep string {} \\; -print This command searches the current directory and all subdirectories for files containing a specified string pattern. The find command locates files, while grep searches within each file for the specified string.\n","tags":["linux","unix","find","grep","command-line"],"categories":["Engineering"]},{"title":"The Linux Documentation Project","date":"2010-09-04","permalink":"https://santoshmano.com/blog/linux-documentation-project/","summary":"Pretty neat documentation at tldp.org\nKey Resources The Linux Kernel - Documentation covering core kernel topics The Linux Programmer\u0026rsquo;s Guide - Features comprehensive coverage of inter-process communication (IPC) mechanisms The Linux Documentation Project provides comprehensive reference materials for Linux developers and system administrators.\n","content":"Pretty neat documentation at tldp.org\nKey Resources The Linux Kernel - Documentation covering core kernel topics The Linux Programmer\u0026rsquo;s Guide - Features comprehensive coverage of inter-process communication (IPC) mechanisms The Linux Documentation Project provides comprehensive reference materials for Linux developers and system administrators.\n","tags":["linux","documentation","kernel","ipc"],"categories":["Engineering"]},{"title":"Virtualization for Dummies","date":"2010-09-04","permalink":"https://santoshmano.com/blog/virtualization-for-dummies/","summary":"A foundational educational document about virtualization technology is available from Sun and AMD.\n\u0026ldquo;Virtualization for Dummies\u0026rdquo; is a beginner-friendly guide that explains core virtualization concepts, perfect for those getting started with virtualization technologies.\nThis collaborative resource from Sun and AMD provides accessible explanations of fundamental virtualization principles and practices.\n","content":"A foundational educational document about virtualization technology is available from Sun and AMD.\n\u0026ldquo;Virtualization for Dummies\u0026rdquo; is a beginner-friendly guide that explains core virtualization concepts, perfect for those getting started with virtualization technologies.\nThis collaborative resource from Sun and AMD provides accessible explanations of fundamental virtualization principles and practices.\n","tags":["virtualization","resources","learning"],"categories":["Engineering"]},{"title":"C Traps and Pitfalls","date":"2010-08-15","permalink":"https://santoshmano.com/blog/c-traps-and-pitfalls/","summary":"Click here to jump to a nice writeup on C\u0026rsquo;s traps and pitfalls.\nThis comprehensive resource explores common mistakes and tricky aspects developers encounter when working with C, covering situations where the language\u0026rsquo;s design can lead to unexpected behavior or code errors.\n","content":"Click here to jump to a nice writeup on C\u0026rsquo;s traps and pitfalls.\nThis comprehensive resource explores common mistakes and tricky aspects developers encounter when working with C, covering situations where the language\u0026rsquo;s design can lead to unexpected behavior or code errors.\n","tags":["c","programming","best-practices"],"categories":["Engineering"]}]