Ken Huang https://whatacold.io/ Recent content on Ken Huang Hugo en [email protected] (Ken Huang) [email protected] (Ken Huang) Tue, 10 Mar 2026 23:21:20 +0800 Your Screenshots Deserve Better. Introducing Backdrop. https://whatacold.io/blog/2026-03-10-backdrop-intro/ Tue, 10 Mar 2026 22:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2026-03-10-backdrop-intro/ <p> Have you ever been there? You&#39;ve just finished a brilliant piece of code, designed a slick UI, or found the perfect example for a tutorial. You take a screenshot to share your work, but when you look at it… it&#39;s just… plain.</p> <p> You could share it as is, but it lacks professionalism. Or, you could spend the next 15 minutes wrestling with a heavy-duty design tool, carefully placing it on a background, adding a shadow, and rounding the corners, all for a single image.</p> 🥷 Clojure Pro Tip 5: Hiccup Raw https://whatacold.io/blog/2025-05-15-clojure-tip-hiccup-raw/ Thu, 15 May 2025 12:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-05-15-clojure-tip-hiccup-raw/ <p> In case you don’t know it, we can use raw strings, like embedding JS code, in hiccup.</p> <p> I just found out we can use <a href="https://weavejester.github.io/hiccup/hiccup2.core.html#var-raw">raw</a> to prevent strings from getting escaped. I used to have to define a dedicated app.js for that, which would need an extra HTTP request.</p> <figure> <img src="https://whatacold.io/img/clojure-hiccup-raw.jpg" alt="Hiccup raw in action" title="Click to enlarge the image"/> <figcaption> Hiccup raw in action </figcaption> </figure> <p> Looking back, I should’ve found this at the very beginning, as it’s just mentioned on <a href="https://github.com/weavejester/hiccup">its GitHub homepage</a>, but somehow I missed it.</p> 🥷 Clojure Pro Tip 4: Cider ClojureDocs https://whatacold.io/blog/2025-04-29-clojure-tip-cider-clojuredocs/ Tue, 29 Apr 2025 12:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-04-29-clojure-tip-cider-clojuredocs/ <p> Sometimes, we may want a few examples of a Clojure API for inspiration while developing, especially when reading other people&#39;s or open source code.</p> <p> With <a href="https://cider.mx/">Cider</a> in <a href="https://www.gnu.org/software/emacs/">Emacs</a>, we can run <code class="verbatim">M-x cider-doc</code> to see the docstring for the symbol. We can even use <code class="verbatim">M-x cider-clojuredocs</code> for some examples if the symbol is from the language core.</p> <figure> <img src="https://whatacold.io/img/clojure-cider-clojuredocs.jpg" alt="Running M-x cider-clojuredocs" title="Click to enlarge the image"/> <figcaption> Running M-x cider-clojuredocs </figcaption> </figure> <p> I happened to find this command recently. I bet I was not the only one who didn&#39;t know it, thus I&#39;m sharing.</p> 🥷 Clojure Pro Tip 3: the Thread-As Macro https://whatacold.io/blog/2025-04-23-clojure-tip-thread-as/ Wed, 23 Apr 2025 12:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-04-23-clojure-tip-thread-as/ <p> So you&#39;re more than excited to find out how Clojure&#39;s thread macros can make code clean and concise, you just love it! But at some point you&#39;ll be trapped a bit as the threaded argument&#39;s positions are inconsistent using <a href="https://clojuredocs.org/clojure_core/clojure.core/-%3E">-&gt;</a> or <a href="https://clojuredocs.org/clojure_core/clojure.core/-%3E%3E">-&gt;&gt;</a>.</p> <p> Luckily, you can use <a href="https://clojuredocs.org/clojure_core/clojure.core/as-%3E">as-&gt;</a> to place the argument wherever you like:</p> <figure> <img src="https://whatacold.io/img/clojure-thread-as.jpg" alt="Lambda vs. thread-as" title="Click to enlarge the image"/> <figcaption> Lambda vs. thread-as </figcaption> </figure> 🥷 Clojure Pro Tip 2: group-by https://whatacold.io/blog/2025-04-18-clojure-group-by/ Fri, 18 Apr 2025 12:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-04-18-clojure-group-by/ <p> It&#39;s amazingly easy to group things in Clojure. The language core provides a <a href="https://clojuredocs.org/clojure_core/clojure.core/group-by">group-by</a> function directly. Together with many built-in functions or key functions, it creates a ton of possibilities, and we can also bake our grouping function if none is satisfying.</p> <figure> <img src="https://whatacold.io/img/clojure-group-by.jpg" alt="group-by" title="Click to enlarge the image"/> <figcaption> group-by </figcaption> </figure> <p> Example from <a href="https://github.com/functional-koans/clojure-koans">Clojure Koans</a>.</p> Collecting Events to Google Analytics using ClojureScript https://whatacold.io/blog/2025-04-11-google-analytics-clojurescript/ Fri, 11 Apr 2025 22:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-04-11-google-analytics-clojurescript/ <p> When you’re building a side project, chances are you need to collect user events so that you can understand user behaviors better and eventually improve your product.</p> <p> So recently I made a small ClojureScript library for that, it supports web apps or chrome extensions. Check it out at <a href="https://github.com/whatacold/google-analytics,">https://github.com/whatacold/google-analytics,</a> it also contains a <a href="https://github.com/whatacold/google-analytics/tree/master/demo">demo project</a> using <a href="https://shadow-cljs.github.io/docs/UsersGuide.html">shadow-cljs</a> as the build tool.</p> <p> Hope it helps, and give it a star ⭐ on GitHub and share it if it does, thanks!</p> 🥷 Clojure Pro Tip 1: the Discard Reader Symbol https://whatacold.io/blog/2025-04-05-clojure-tip-discard-reader-symbol/ Sat, 05 Apr 2025 12:49:27 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-04-05-clojure-tip-discard-reader-symbol/ <p> In Clojure, we can use <a href="https://clojuredocs.org/clojure.core/comment">comment</a> (aka Rich Comment Blocks) for tests or experiments in development. However, since a comment evaluates to nil, you may run into surprising results or even errors if you misuse it.</p> <figure> <img src="https://whatacold.io/img/clojure-discard-reader-symbol.jpg" alt="Comment vs. Discard" title="Click to enlarge the image"/> <figcaption> Comment vs. Discard </figcaption> </figure> <p> In these scenarios, you may tend to use <code class="verbatim">;</code> to comment them out, but a better choice is to use the <a href="https://clojure.org/guides/weird_characters#_discard">discard reader symbol <code class="verbatim">#_</code></a>.</p> Rewrite of a Flask Web App in Clojure https://whatacold.io/blog/2025-02-22-flask-clojure-rewrite/ Sat, 22 Feb 2025 22:46:05 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-02-22-flask-clojure-rewrite/ <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Intro </h2> <div id="outline-text-headline-1" class="outline-text-2"> <p> A few years ago, I made a simple web app in <a href="https://flask.palletsprojects.com/en/stable/">Flask</a> to deal with some text processing problems from my daily work. It has two main features:</p> <ul> <li>Feature #1: generating <code class="verbatim">compile_commands.json</code> for GNU Makefile projects written in C/C++ using the output of the <code class="verbatim">make</code> command. Because, unlike CMake, the make command can&#39;t generate it.</li> <li>Feature #2: extract text using Python regex. It&#39;s handy when I feel like sed/awk/grep&#39;s line-oriented processing isn&#39;t enough for the task at hand.</li> </ul> <p><em>BTW, I&#39;m improving my English by watching YouTube videos every single day; If you&#39;re also learning English, or any languages, LanguagePuppy can definitely help you. It&#39;s a Chrome extension I developed using Clojure. Check it out:</em></p> Constructing Clojure Maps Conditionally https://whatacold.io/blog/2025-01-05-construct-a-map-clojure/ Sun, 05 Jan 2025 10:40:07 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2025-01-05-construct-a-map-clojure/ <p> I was wondering how to construct a multi-key map conditionally while I was coding in Clojure. Ideally, I would like to build it &#34;in one pass&#34; like <code class="verbatim">{:bar 2 (when true :baz 3)}</code>, but from what I had collected from Blue Sky, it seemed that&#39;s impossible, or it&#39;s just not an idiomatic way to program like that in Clojure. (Or, is this just a side effect of writing too much imperative code?)</p> Getting Started with Cider for Clojure Programming https://whatacold.io/blog/2024-12-22-getting-started-with-cider/ Sun, 22 Dec 2024 17:17:15 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-12-22-getting-started-with-cider/ <p> Here is the outline for my cider tutorial on YouTube, covering basic things you need to know to get started with cider, and starting exploring the fun of clojure programming with the REPL-driven programming approach.</p> <p> <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/evmRpr_DEBQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> </p> <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Jack In to a REPL </h2> <div id="outline-text-headline-1" class="outline-text-2"> <dl> <dt> C-c M-j (cider-jack-in-clj) </dt> <dd>start a nREPL and jack in. It works in a project or with a <strong>sole .clj file</strong>.</dd> <dt> M-x cider-connect-clj </dt> <dd>run the command and then fill in hostname and port. It could be useful in some cases. e.g. on Windows, I can start the nREPL manually and then connect to it separately.</dd> </dl> </div> </div> <div id="outline-container-headline-2" class="outline-2"> <h2 id="headline-2"> Evaluate Things </h2> <div id="outline-text-headline-2" class="outline-text-2"> <dl> <dt> C-M-x (cider-eval-defun-at-point) </dt> <dd>evaluate current top-level form.</dd> <dt> C-x C-e (cider-eval-last-sexp) </dt> <dd>evaluate the preceding form.</dd> <dt> C-c C-k (cider-load-buffer) </dt> <dd>evaluate/load the current buffer.</dd> <dt> C-c C-p (cider-pprint-eval-last-sexp) </dt> <dd>Pprint the result in a dedicated buffer. Great thing to do when the result is too large to fit in the echo area.</dd> </dl> <p>Note: I prefer to use the same key bindings as for Elisp, given that cider might bind a few keys to a single command!</p> A Few Quick Notes About babashka/fs https://whatacold.io/blog/2024-12-07-babashka-fs-notes/ Sat, 07 Dec 2024 22:24:41 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-12-07-babashka-fs-notes/ <p> Recently I&#39;ve used <a href="https://github.com/babashka/fs/blob/master/API.md">babashka/fs</a> a little bit, here are some quick notes for it:</p> <ul> <li>Path vs File. Use Path whenever possible, according to <a href="https://stackoverflow.com/a/26658436">this SO answer to &#34;Java: Path vs File&#34;</a>. This is actually Java related.</li> <li>It&#39;s ok to use a <code class="verbatim">path</code> as a key for a clojure map. At my first try, I somehow came to the conclusion that it&#39;s not ok, while I was refactoring the <a href="https://github.com/scicloj/clay/blob/main/src/scicloj/clay/v2/live_reload.clj">live reload</a> for clay. And later I found that it&#39;s totally fine to use it as a key. 😞</li> <li>Use <a href="https://github.com/babashka/fs/blob/master/API.md#babashka.fs/path">fs/path</a> to construct file/directory paths, for example, <code class="verbatim">(fs/path &#34;/tmp&#34; &#34;foo&#34; &#34;bar&#34; &#34;baz.clj&#34;)</code> will result in a path object for <code class="verbatim">/tmp/foo/bar/baz.clj</code> on linux. If you&#39;re coming from Python, it might remind you of <a href="https://docs.python.org/3/library/os.path.html">os.path.join(path, *paths)</a>.</li> <li>Use <code class="verbatim">fs/createdirs</code> for <code class="verbatim">mkdir -p</code>, though its name is a bit misleading, I first thought it&#39;s for creating a few dirs.</li> <li><code class="verbatim">fs/with-temp-dir</code> is convenient for <a href="https://github.com/scicloj/clay/blob/main/test/scicloj/clay/v2/live_reload_test.clj">creating tests</a>.</li> </ul> Doing Unit test in Clojure Is Easy https://whatacold.io/blog/2024-11-27-clojure-unit-test/ Thu, 28 Nov 2024 23:10:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-27-clojure-unit-test/ <p> While refactoring the <a href="https://github.com/scicloj/clay/blob/main/src/scicloj/clay/v2/live_reload.clj">live reload</a> feature of <a href="https://github.com/scicloj/clay">Clay</a>, I realized I&#39;d better break long functions into smaller and functional ones (as many as I can), which is also a <a href="https://guide.clojure.style/#be-functional">common practice</a> in the clojure community.</p> <p> Small pure functions not only are easy to verify on the development process (using a REPL), but also are easy to test. And unit tests are easy to write in clojure, just use <code class="verbatim">deftest</code> from <code class="verbatim">clojure.test</code>, a very basic one looks like this:</p> Clj-async-profiler Rocks https://whatacold.io/blog/2024-11-28-beholder-clj-async-profiler/ Thu, 28 Nov 2024 22:23:32 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-28-beholder-clj-async-profiler/ <p> While developing the live reload feature for <a href="https://scicloj.github.io/clay/">Clay</a>, a minimalistic Clojure tool for data visualization and literate programming, I found that it constantly takes ~1 minute for <a href="https://github.com/nextjournal/beholder">beholder</a> to watch a directory. After some code inspect, I was still having no idea why it happened.</p> <p> So I decided to use a profiler to find out what&#39;s going one under the hood, and Google immediately took me to <a href="https://clojure-goes-fast.com/kb/profiling/clj-async-profiler/">clj-async-profiler</a>. It&#39;s easy to set up following its <a href="https://clojure-goes-fast.com/kb/profiling/clj-async-profiler/basic-usage/">basic usage docs</a>:</p> TailwindCSS Docs Index https://whatacold.io/blog/2024-11-23-tailwindcss-docs-index/ Sat, 23 Nov 2024 19:50:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-23-tailwindcss-docs-index/ <p> Just re-organize the <a href="https://tailwindcss.com/docs/installation">TailwindCSS Docs</a> index in a flatter and more searchable way.</p> <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Getting Started </h2> <div id="outline-text-headline-1" class="outline-text-2"> <p><a href="https://tailwindcss.com/docs/installation">Installation</a> | <a href="https://tailwindcss.com/docs/editor-setup">Editor Setup</a> | <a href="https://tailwindcss.com/docs/using-with-preprocessors">Using with Preprocessors</a> | <a href="https://tailwindcss.com/docs/optimizing-for-production">Optimizing for Production</a> | <a href="https://tailwindcss.com/docs/browser-support">Browser Support</a> | <a href="https://tailwindcss.com/docs/upgrade-guide">Upgrade Guide</a></p> </div> </div> <div id="outline-container-headline-2" class="outline-2"> <h2 id="headline-2"> Core Concepts </h2> <div id="outline-text-headline-2" class="outline-text-2"> <p><a href="https://tailwindcss.com/docs/utility-first">Utility-First Fundamentals</a> | <a href="https://tailwindcss.com/docs/hover-focus-and-other-states">Hover, Focus, and Other States</a> | <a href="https://tailwindcss.com/docs/responsive-design">Responsive Design</a> | <a href="https://tailwindcss.com/docs/dark-mode">Dark Mode</a> | <a href="https://tailwindcss.com/docs/reusing-styles">Reusing Styles</a> | <a href="https://tailwindcss.com/docs/adding-custom-styles">Adding Custom Styles</a> | <a href="https://tailwindcss.com/docs/functions-and-directives">Functions &amp; Directives</a></p> </div> </div> <div id="outline-container-headline-3" class="outline-2"> <h2 id="headline-3"> Customization </h2> <div id="outline-text-headline-3" class="outline-text-2"> <p><a href="https://tailwindcss.com/docs/configuration">Configuration</a> | <a href="https://tailwindcss.com/docs/content-configuration">Content</a> | <a href="https://tailwindcss.com/docs/theme">Theme</a> | <a href="https://tailwindcss.com/docs/screens">Screens</a> | <a href="https://tailwindcss.com/docs/customizing-colors">Colors</a> | <a href="https://tailwindcss.com/docs/customizing-spacing">Spacing</a> | <a href="https://tailwindcss.com/docs/plugins">Plugins</a> | <a href="https://tailwindcss.com/docs/presets">Presets</a></p> </div> </div> <div id="outline-container-headline-4" class="outline-2"> <h2 id="headline-4"> Base Styles </h2> <div id="outline-text-headline-4" class="outline-text-2"> <p><a href="https://tailwindcss.com/docs/preflight">Preflight</a></p> </div> </div> <div id="outline-container-headline-5" class="outline-2"> <h2 id="headline-5"> Layout </h2> <div id="outline-text-headline-5" class="outline-text-2"> <p><a href="https://tailwindcss.com/docs/aspect-ratio">Aspect Ratio</a> | <a href="https://tailwindcss.com/docs/container">Container</a> | <a href="https://tailwindcss.com/docs/columns">Columns</a> | <a href="https://tailwindcss.com/docs/break-after">Break After</a> | <a href="https://tailwindcss.com/docs/break-before">Break Before</a> | <a href="https://tailwindcss.com/docs/break-inside">Break Inside</a> | <a href="https://tailwindcss.com/docs/box-decoration-break">Box Decoration Break</a> | <a href="https://tailwindcss.com/docs/box-sizing">Box Sizing</a> | <a href="https://tailwindcss.com/docs/display">Display</a> | <a href="https://tailwindcss.com/docs/float">Floats</a> | <a href="https://tailwindcss.com/docs/clear">Clear</a> | <a href="https://tailwindcss.com/docs/isolation">Isolation</a> | <a href="https://tailwindcss.com/docs/object-fit">Object Fit</a> | <a href="https://tailwindcss.com/docs/object-position">Object Position</a> | <a href="https://tailwindcss.com/docs/overflow">Overflow</a> | <a href="https://tailwindcss.com/docs/overscroll-behavior">Overscroll Behavior</a> | <a href="https://tailwindcss.com/docs/position">Position</a> | <a href="https://tailwindcss.com/docs/top-right-bottom-left">Top / Right / Bottom / Left</a> | <a href="https://tailwindcss.com/docs/visibility">Visibility</a> | <a href="https://tailwindcss.com/docs/z-index">Z-Index</a></p> Adding Clojure Dependencies from the Command Line https://whatacold.io/blog/2024-11-09-clj-deps-cmdline/ Sat, 09 Nov 2024 21:02:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-09-clj-deps-cmdline/ <p> While debugging a <a href="https://github.com/scicloj/clay/issues/176">live reload issue</a> of Clay a few days ago, I learned from <a href="https://github.com/kloimhardt">Markus Agwin</a> that we can actually add dependencies on the fly from the command line, just like this: <code class="verbatim">clj -Sdeps &#34;{:deps {org.scicloj/clay {:mvn/version \&#34;2-beta21\&#34;}}}&#34;</code>.</p> <p> Even better, we can add dependency from a Git repo and specify the commit hash: <code class="verbatim">clj -Sdeps &#34;{:deps {io.github.scicloj/clay {:git/url \&#34;https://github.com/scicloj/clay.git\&#34; :git/sha \&#34;35a46541db66ae6b4e1af628b7c24c42d3be418f\&#34;}}}&#34;</code>, which is really helpful for experimenting and verifying things.</p> <p> Some clj links (<code class="verbatim">clj --help</code> has a pointer for these URLs):</p> Bitten by Lazy Sequence of map https://whatacold.io/blog/2024-11-10-clojure-lazy-seq-case/ Sat, 09 Nov 2024 21:02:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-10-clojure-lazy-seq-case/ <p> While impletenting the live reload feature for <a href="https://github.com/scicloj/clay">Clay</a> a few weeks ago, unfortunately, I was bitten by the laziness of <a href="https://clojuredocs.org/clojure.core/map">map</a>. It seems quite obvious we all know that its result is a lazy sequence, but I just can&#39;t help fall into the &#34;trap&#34;.</p> <p> At that time I was adding a vector to keep track of all <a href="https://github.com/nextjournal/beholder">beholder</a> instances watching file changes in user specified directories. So then when it&#39;s time to stop all the watchers, I used something like to achieve the goal:</p> Anonymous Functions in Thread Macros https://whatacold.io/blog/2024-11-08-clojure-thread-macro-anonymous-function/ Fri, 08 Nov 2024 21:02:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-08-clojure-thread-macro-anonymous-function/ <p> While adding <a href="https://github.com/scicloj/clay/pull/165">the live reload feature</a> to Clay, I encountered a problem of applying anonymous functions to thread macros. For example, below is a simple snippet trying to wrap the input directory as a vector with the help of thread macro, but surprisingly, it errors out. After some searching, I figured out that I need to put the anonymous function into another pair of parentheses:</p> <div class="src src-clojure"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clojure" data-lang="clojure"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">-&gt; </span><span class="s">&#34;/tmp/&#34;</span> </span></span><span class="line"><span class="cl"> <span class="o">#</span><span class="p">(</span><span class="k">if </span><span class="p">(</span><span class="nb">vector? </span><span class="nv">%</span><span class="p">)</span> <span class="nv">%</span> <span class="p">[</span><span class="nv">%</span><span class="p">]))</span> </span></span><span class="line"><span class="cl"><span class="c1">;; =&gt; Syntax error (ClassCastException) compiling fn* at (simple4all.clj:19:1).</span> </span></span><span class="line"><span class="cl"><span class="c1">;; class java.lang.String cannot be cast to class clojure.lang.ISeq (java.lang.String is in module java.base of loader &#39;bootstrap&#39;; clojure.lang.ISeq is in unnamed module of loader &#39;app&#39;)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">-&gt; </span><span class="s">&#34;/tmp/&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="o">#</span><span class="p">(</span><span class="k">if </span><span class="p">(</span><span class="nb">vector? </span><span class="nv">%</span><span class="p">)</span> <span class="nv">%</span> <span class="p">[</span><span class="nv">%</span><span class="p">])))</span> </span></span><span class="line"><span class="cl"><span class="c1">;; =&gt; [&#34;/tmp/&#34;]</span></span></span></code></pre></div> </div> <p> Paul has a nice explanation on <a href="https://stackoverflow.com/a/7838577">Stack Overflow</a>, <a href="https://clojuredocs.org/clojure.core/-%3E">thread macros</a> need the function forms to be lists, but anonymous functions are already lists, so the first expression, <code class="verbatim">&#34;/tmp/&#34;</code> in this example, will just be inserted into that list, just as illustrated below:</p> Starting a Clojure nREPL Manually for Cider https://whatacold.io/blog/2024-11-08-cider-clojure-repl-cmdline/ Fri, 08 Nov 2024 00:02:56 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2024-11-08-cider-clojure-repl-cmdline/ <p> While troubleshooting and fixing a <a href="https://github.com/scicloj/clay/issues/176">live reload bug</a> in <a href="https://github.com/scicloj/clay">Clay</a> today, which required to start a minimal Clojure environment, I figured out how to start a nREPL from the command line.</p> <p> Instead of using <code class="verbatim">M-x cider-jack-in-clj</code> directly from Emacs, actually we can manully bring up an nREPL with this: <code class="verbatim">clj -Sdeps &#34;{:deps {org.scicloj/clay {:mvn/version \&#34;2-beta21\&#34;} cider/cider-nrepl {:mvn/version \&#34;0.50.2\&#34;}}}&#34; -m nrepl.cmdline --middleware &#34;[cider.nrepl/cider-middleware]&#34;</code> (The clay part is only necessary for this debugging), and then connect to this nREPL using the Emacs command <code class="verbatim">M-x cider-connect-clj</code>.</p> Join Every N Lines By A Separator in Emacs https://whatacold.io/blog/2023-11-25-emacs-join-every-n-lines/ Sat, 25 Nov 2023 12:24:24 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2023-11-25-emacs-join-every-n-lines/ <p> It has been some time since I came along the idea of the <a href="https://whatacold.io/blog/2023-06-12-emacs-join-lines/">w/join-lines</a> command to join lines. After that, sometimes I found that it would be even better to join every a few lines.</p> <p> Let&#39;s see the example below, suppose we&#39;ve copies some data from somewhere, and now we want to yank it into an Emacs buffer and slightly modify it to be like an matrix.</p> <p> That is, make it from:</p> Restoring Emacs' Window Layouts https://whatacold.io/blog/2023-11-19-emacs-winner-mode/ Sun, 19 Nov 2023 13:02:42 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2023-11-19-emacs-winner-mode/ <p> If you&#39;ve been using Emacs for a while, I bet you must have encountered the annoying problem that your Emacs window layout gets messed up after some operations, such as looking for a help (e.g. <code class="verbatim">C-h k</code>), or checking things in the magit status buffer.</p> <figure> <img src="https://whatacold.io/img/r-mo-w-_iZqdviAo-unsplash-window.jpg" alt="Photo by R Mo on Unsplash" title="Click to enlarge the image"/> <figcaption> Photo by R Mo on Unsplash </figcaption> </figure> <p> I&#39;m happy if I can just get back to the previous layout that I had before, and guess what? Emacs happens to have that capability built in – the <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Convenience.html">winner-mode</a> package, what a surprise!</p> Emphasize Text By Dragging Mouse in Org-mode https://whatacold.io/blog/2023-08-14-org-emphasis-dragging-mouse/ Mon, 14 Aug 2023 22:48:20 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2023-08-14-org-emphasis-dragging-mouse/ <p> Long story short, I came up with an idea to emphasize content while I was reviewing an org-mode document a few months ago after I was tired of typing tedious <code class="verbatim">*</code> around the content repeatedly. And I&#39;ve been longing for this feature since then, because I was unfamiliar with mouse-based key bindings, and neither did I have the time to investigate it.</p> <p> Today I finally nailed it down while I was attending a boring meeting, and it turned out to be quite simple. The exploration journey was not much different than before. First, I managed to find out how to bind a command to a mouse event, taking advantage of the good-old <code class="verbatim">C-h k</code> and <code class="verbatim">(info &#34;emacs&#34;)</code> (or <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Mouse-Buttons.html">here at gnu.org</a>). And then wrote a few lines of code to perform the task standing on the shoulder of <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html">Advice</a>.</p> Join Lines By A Separator in Emacs https://whatacold.io/blog/2023-06-12-emacs-join-lines/ Mon, 12 Jun 2023 22:23:12 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2023-06-12-emacs-join-lines/ <p> So sometimes I need to join a few lines by a separator while I&#39;m coding, for example, turn the below lines,</p> <div class="src src-text"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">foo </span></span><span class="line"><span class="cl">bar </span></span><span class="line"><span class="cl">baz</span></span></code></pre></div> </div> <p> into <code class="verbatim">foo + bar + baz</code>. (This is a silly example, I will update if I come up with a better one :-P )</p> <p> When I was in a rush in the past, I usually baked a keyboard macro temporarily and then applied it to achieve this goal, thought reliable, it&#39;s a little bit cumbersome to record it. So I wonder maybe it would be a good idea to have a command for it.</p> Hugo Blogging in Emacs https://whatacold.io/blog/2022-10-10-emacs-hugo-blogging/ Mon, 10 Oct 2022 22:50:48 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-10-10-emacs-hugo-blogging/ <p> When I started to use <a href="https://gohugo.io/">Hugo</a> to write this blog last year, I noticed that there is an <a href="https://github.com/masasam/emacs-easy-hugo">easy-hugo</a> package of Emacs many people use. So I installed it at that time, but I didn&#39;t use many of its features since then. In fact, the only command I used was <code class="verbatim">easy-hugo-current-time</code>. I used it to update the Hugo timestamps manually as in the format of <code class="verbatim">2022-10-15T09:45:35+08:00</code>.</p> <p> My most desirable feature is to use it to select tags easily when I start to write a new post, but I never got it to work.</p> Auto-complete Accounts From Other Beancount Files in Emacs https://whatacold.io/blog/2022-09-10-emacs-beancount-account-files/ Sat, 10 Sep 2022 11:13:38 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-09-10-emacs-beancount-account-files/ <figure> <img src="https://whatacold.io/img/2022-09-10-beancount-mode-comple-accounts-from-files.jpg" alt="Auto-complete accounts from another accounts.bean file" title="Click to enlarge the image"/> <figcaption> Auto-complete accounts from another accounts.bean file </figcaption> </figure> <p> If you&#39;re using Beancount with Emacs, you may be using <a href="https://github.com/beancount/beancount-mode">beancount-mode</a>. It can auto-complete the accounts defined in the current buffer when we are typing in new transactions so that we can do it more efficiently.</p> <p> But it can <strong><strong>only</strong></strong> auto-complete the accounts from the current buffer, which makes it less useful when we have a stand-alone file or a few files of beancount accounts.</p> A Bookmarklet for Copying a Link as an Org-mode Link https://whatacold.io/blog/2022-08-08-org-link-bookmarklet/ Mon, 08 Aug 2022 23:33:05 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-08-08-org-link-bookmarklet/ <p> In this blog post, I&#39;d like to share a <a href="https://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> for copying a web page&#39;s URL as an org-mode link on Firefox, Chrome, or whatever web browsers support bookmarklets.</p> <p> It&#39;s handy when the URL isn&#39;t SEO-friendly, which means you can&#39;t tell what its content is about at first glance of the URL. So a little description text on the link would help.</p> <p> Here is the bookmarklet:</p> <div class="src src-js"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">javascript</span><span class="o">:</span><span class="nb">window</span><span class="p">.</span><span class="nx">prompt</span><span class="p">(</span><span class="s2">&#34;Copy to clipboard: Ctrl+C, Esc&#34;</span><span class="p">,</span> <span class="s2">&#34;[[&#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span> <span class="o">+</span> <span class="s2">&#34;][&#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">title</span> <span class="o">+</span> <span class="s2">&#34; - &#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">+</span> <span class="s2">&#34;]]&#34;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Don&#39;t know why the page becomes blank after using it on Firefox, so use alert instead. </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">javascript</span><span class="o">:</span><span class="nx">alert</span><span class="p">(</span><span class="s2">&#34;[[&#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span> <span class="o">+</span> <span class="s2">&#34;][&#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">title</span> <span class="o">+</span> <span class="s2">&#34; - &#34;</span> <span class="o">+</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">+</span> <span class="s2">&#34;]]&#34;</span><span class="p">);</span></span></span></code></pre></div> </div> <p> Add a new bookmark on the browser, give it a name, such as <code>(org-link)</code>, and then copy and paste the content as URL, just like below on Firefox:</p> Emacs Debugging Techniques https://whatacold.io/blog/2022-07-17-emacs-elisp-debug/ Sun, 17 Jul 2022 09:57:31 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-07-17-emacs-elisp-debug/ <p> If you are new to Emacs, you may run into some errors, especially after you copied some elisp snippets from the Internet or elsewhere. Don&#39;t panic! It happens, it&#39;s just part of the learning process. Even an experienced Emacs user could run into there issues from time to time.</p> <p> <em>BTW, I&#39;m improving my English by watching YouTube videos every single day; If you&#39;re also learning English, or any languages, LanguagePuppy can definitely help you. It&#39;s a Chrome extension I developed using Clojure. Check it out:</em></p> Duplicate the current line in Emacs https://whatacold.io/blog/2022-05-23-emacs-duplicate-line/ Mon, 23 May 2022 21:29:28 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-05-23-emacs-duplicate-line/ <figure> <img src="https://whatacold.io/img/2022-05-23-emacs-duplicate-current-line.jpg" alt="Duplicate the current in Emacs" title="Click to enlarge the image"/> <figcaption> Duplicate the current in Emacs </figcaption> </figure> <p> Duplicating the current line is frequent editing for me when I am coding. Initially, I copied a snippet as a command in Emacs from the Internet:</p> <div class="src src-elisp"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-elisp" data-lang="elisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">w/duplicate-line</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;Duplicate the current line.&#34;</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">move-beginning-of-line</span> <span class="mi">1</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">kill-line</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">yank</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">open-line</span> <span class="mi">1</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">next-line</span> <span class="mi">1</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nv">yank</span><span class="p">))</span></span></span></code></pre></div> </div> <p> Most of the time, I was happy with it, but it has mainly two drawbacks:</p> <ol> <li>It cannot keep the column position when moving to the next line</li> <li>It messes up with the yank ring as it yanks the text under the hood</li> </ol> <p>So today, I took some time to fix these two problems, and I also want it to be capable of commenting the current line out if I prefix the command.</p> Adjust the laptop's screen brightness in Emacs https://whatacold.io/blog/2022-05-21-adjust-screen-brightness-emacs/ Sat, 21 May 2022 11:50:25 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-05-21-adjust-screen-brightness-emacs/ <figure> <img src="https://whatacold.io/img/2022-05-21-adjust-screen-brightness-emacs.jpg" alt="Adjust the screen brightness in Emacs" title="Click to enlarge the image"/> <figcaption> Adjust the screen brightness in Emacs </figcaption> </figure> <p> If you&#39;re using i3wm on Linux, how do you adjust the laptop&#39;s screen brightness?</p> <p> Most of the time, I use the laptop with an external monitor. But when I am out, I have no monitors. And it seems no easy way to adjust the brightness in i3wm. Being too bright or dim is terrible for the eyes.</p> How to Kill a "Visible" Buffer Quickly in Emacs https://whatacold.io/blog/2022-04-09-emacs-kill-other-buffer/ Sat, 09 Apr 2022 23:11:36 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-04-09-emacs-kill-other-buffer/ <figure> <img src="https://whatacold.io/img/2022-04-09-ace-window-selecting-window.jpg" alt="Selecting Emacs windows using ace-window" title="Click to enlarge the image"/> <figcaption> Selecting Emacs windows using ace-window </figcaption> </figure> <p> Recently I&#39;ve been building a simple Emacs config for myself, along the way I re-discovered some fantastic packages, for example, I found that <a href="https://github.com/abo-abo/ace-window">ace-window</a> is a simple yet powerful package to enhance the default <code class="verbatim">other-window</code> command to select other windows quickly when it has more than two windows in a frame.</p> <p> I replaced the key binding of <code class="verbatim">other-window</code> to ace-window by simply doing <code>(global-set-key (kbd &#34;C-x o&#34;) #&#39;ace-window)</code>, then when there are &gt;2 windows, it will show a white-in-red number at the top-left corner for every window, hit the number (1, 2, 3, …) and then Emacs will select the corresponding window (as demonstrated in the above screenshot).</p> How to append items to the CSV file without header row? https://whatacold.io/blog/2022-04-09-scrapy-csv-without-header/ Sat, 09 Apr 2022 22:32:11 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-04-09-scrapy-csv-without-header/ <figure> <img src="https://docs.scrapy.org/en/latest/_images/scrapy_architecture_02.jpg" alt="Scrapy Architecture" title="Click to enlarge the image"/> <figcaption> Scrapy Architecture </figcaption> </figure> <p> Scrapy provides a few <a href="https://docs.scrapy.org/en/latest/topics/exporters.html">item exporters</a> by default to export items in commonly used file formats like CSV/JSON/XML. I usually use CSV to export items, it is pretty convenient, and it comes in two ways:</p> <ul> <li>appending mode, for example, <code>scrapy crawl foo -o test.csv</code></li> <li>overwriting mode with <code class="verbatim">-O</code> option, like <code>scrapy crawl foo -O test.csv</code></li> </ul> <p>But in the appending mode, it&#39;s a bit annoying that it always appends the header row before the newly scraped items, which is not correctly in terms of CSV format.</p> About Me https://whatacold.io/about/ Wed, 09 Mar 2022 12:37:20 +0800[email protected] (Ken Huang) https://whatacold.io/about/ <p> Hey, welcome to my blog site!</p> <p> This is Ken, who is passionate about technology and a lifelong learner. Here I share my experiments and thinking on technology, especially Clojure/ClojureScript and Emacs stuff. Bookmark this site or follow me on social media, the links are at the bottom.</p> <p> Besides, I also make and post videos to my <a href="https://www.youtube.com/@kenhuang-tech">YouTube channel</a> from time to time, please subscribe if you&#39;re interested!❤️</p> <p> <img src="https://whatacold.io/img/me.jpg" alt="/img/me.jpg" title="/img/me.jpg" /></p> <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Interesting OSS Projects I Contributed </h2> <div id="outline-text-headline-1" class="outline-text-2"> <ul> <li><a href="https://github.com/scicloj/clay">Clay</a> is a note-taking and data visualization software written in Clojure, and it&#39;s REPL friendly.</li> <li><a href="https://github.com/eyeinsky/org-anki">org-anki</a> is an Emacs package helping you sync notes in org-mode to <a href="https://en.wikipedia.org/wiki/Anki_(software)">Anki</a>, and learn better in general.</li> <li><a href="https://github.com/qtile/qtile">Qtile</a> is a full-featured, hackable tiling window manager written and configured in Python.</li> <li><a href="https://github.com/doxygen/doxygen">Doxygen</a> is the de facto standard tool for generating documentation from annotated C++ sources.</li> </ul> </div> </div> <div id="outline-container-headline-2" class="outline-2"> <h2 id="headline-2"> Interesting Personal Projects </h2> <div id="outline-text-headline-2" class="outline-text-2"> <p>(I use these tools from day to day, both at work and in daily life, so it&#39;s truly &#34;For Developers, By Developers&#34;!)</p> Eglot for Better Programming Experience in Emacs https://whatacold.io/blog/2022-01-22-emacs-eglot-lsp/ Sat, 22 Jan 2022 11:36:18 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-01-22-emacs-eglot-lsp/ <p> <a href="https://microsoft.github.io/language-server-protocol/">LSP</a>, or Language Server Protocol, makes programming easier by introducing features like more precise auto-completion and definition lookup. It may have scratched your itches, and you may wonder what the experience is like in Emacs.</p> <p> <em>BTW, I&#39;m improving my English by watching YouTube videos every single day; If you&#39;re also learning English, or any languages, LanguagePuppy can definitely help you. It&#39;s a Chrome extension I developed using Clojure. Check it out:</em></p> How to Reload i3status config On the Fly https://whatacold.io/blog/2022-01-14-i3wm-i3status-reload-config/ Fri, 14 Jan 2022 22:36:13 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-01-14-i3wm-i3status-reload-config/ <p> Sometimes I want to change the status (<code class="verbatim">i3status</code>) of <code class="verbatim">i3wm</code> temporarily, but it seems that <code class="verbatim">i3wm</code> doesn&#39;t support it directly, although reloading the config for <code class="verbatim">i3wm</code> itself is a piece of cake (<code class="verbatim">bindsym $mod+Shift+c reload</code> in the config, or <code class="verbatim">i3-msg -t command reload</code> in the command line).</p> <p> But this issue scratched my itch, and I swear that I must solve it today.</p> <p> <em>BTW, I&#39;m improving my English by watching YouTube videos every single day; If you&#39;re also learning English, or any languages, LanguagePuppy can definitely help you. It&#39;s a Chrome extension I developed using Clojure. Check it out:</em></p> Language Shadowing with subed in Emacs https://whatacold.io/blog/2022-01-12-language-shadowing-with-subed-emacs/ Wed, 12 Jan 2022 21:41:54 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2022-01-12-language-shadowing-with-subed-emacs/ <p> So I&#39;m trying to improve my English speaking skill by shadowing while watching TV episodes. The workflow before was to loop over video clips using mpv:</p> <ol> <li>hit <code class="verbatim">l</code> to mark the start of the loop</li> <li>play the video and wait for it to be at the end of the loop</li> <li>hit <code class="verbatim">l</code> again to mark the end</li> </ol> <p>Then mpv will loop over the clip, it basically works, but it&#39;s a bit hard and tedious to set the start and end precisely.</p> Writing a Python Script in Emacs in 45 Minutes! https://whatacold.io/blog/2021-12-11-writing-python-in-emacs/ Sat, 11 Dec 2021 09:24:53 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-12-11-writing-python-in-emacs/ <p> Note: watch my live coding session of this article: <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"> <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/MXF81Q0a91M?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe> </div> </p> <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Intro </h2> <div id="outline-text-headline-1" class="outline-text-2"> <p> If you&#39;ve heard some rumors of Emacs that it has a very steep learning curve (or that Emacs makes a computer slow), you may be too scared to look at it. It indeed has some learning curve (learning anything does have one), but it isn&#39;t very steep. I learned this after getting my hands dirty with Emacs a few years ago.</p> Beautiful Soup 4 Cheatsheet https://whatacold.io/blog/2021-12-05-beautifulsoup4-cheatsheet/ Sat, 25 Sep 2021 23:01:40 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-12-05-beautifulsoup4-cheatsheet/ <figure> <img src="https://www.crummy.com/software/BeautifulSoup/bs4/doc/_images/6.1.jpg" alt="Beautiful Soup" title="Click to enlarge the image"/> <figcaption> Beautiful Soup </figcaption> </figure> <p> Detailed docs: <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">the Beautiful Soup 4 Docs</a>.</p> <p> Assume <code class="verbatim">t</code> is an object of <code class="verbatim">Tag</code>.</p> <div id="outline-container-headline-1" class="outline-2"> <h2 id="headline-1"> Core concepts (classes) </h2> <div id="outline-text-headline-1" class="outline-text-2"> <ul> <li><code class="verbatim">Tag</code>, a Tag object corresponds to an XML or HTML tag.</li> <li><code class="verbatim">BeautifulSoup</code>, the BeautifulSoup object represents the parsed document as a whole. You can treat it like a special Tag. It needs a parser to parse the document, a built-in parser is <code class="verbatim">&#34;html.parser&#34;</code>, e.g. <code>soup = BeautifulSoup(&#34;&lt;html&gt;a web page&lt;/html&gt;&#34;, &#39;html.parser&#39;)</code></li> <li><code class="verbatim">NavigableString</code>, a string corresponds to a bit of text (as you see it in the browser) within a tag. A NavigableString is just like a Python Unicode string, except that it also supports some of the features for navigating the tree and searching the tree.</li> </ul> </div> </div> <div id="outline-container-headline-2" class="outline-2"> <h2 id="headline-2"> The <code class="verbatim">Tag</code> class </h2> <div id="outline-text-headline-2" class="outline-text-2"> <p> Object attributes:</p> Clojure reduce: one case for text processing https://whatacold.io/blog/2021-09-19-clojure-reduce-text-processing/ Sun, 19 Sep 2021 10:39:23 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-09-19-clojure-reduce-text-processing/ <p> As a practice, I managed to illustrate <strong>Clojure files</strong> using <a href="https://whatacold.io/blog/2021-08-07-illustrate-clojure-snippet/">illustrate.clj</a>, but my original idea was to annotate org-mode files of blogs. It&#39;s not uncommon that a blog post has some code snippets.</p> <p> But it missed the feature until last night, as I wasn&#39;t sure how to implement it appropriately before and didn&#39;t have enough time.</p> <p> For example, I may have an org-mode like this:</p> <div class="src src-org"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-org" data-lang="org"><span class="line"><span class="cl">sum of two numbers: </span></span><span class="line"><span class="cl"><span class="c">#+begin_src </span><span class="cs">clojure</span><span class="c"> </span></span></span><span class="line"><span class="cl"><span class="c"></span><span class="p">(</span><span class="nb">+ </span><span class="mi">1</span> <span class="mi">2</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="c">#+end_src</span></span></span></code></pre></div> </div> <p> I want to have a result comment (<code class="verbatim">(;; =&gt; 3)</code>) after each top-level form after using <code class="verbatim">illustrate.clj</code>: sum of two numbers:</p> illustrate.clj to Illustrate Clojure Snippet https://whatacold.io/blog/2021-08-07-illustrate-clojure-snippet/ Sat, 07 Aug 2021 18:49:25 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-08-07-illustrate-clojure-snippet/ <p> To get my hands dirty with Clojure, I am trying to find or implement Clojure&#39;s string functions in the sense of Python. Python has powerful string APIs, and I also want to see how powerful Clojure could be in this field. That would be interesting.</p> <p> As shown in the <a href="https://clojure.org/api/cheatsheet">cheatsheet</a>, Clojure has implemented most of them, and there are some that I have to implement myself, like <a href="https://whatacold.io/blog/2021-07-25-clojure-string-title-case/">title-case</a>.</p> <p> Along the way, I found it was a little cumbersome to append the evaluation result and the result of calling them, for example,</p> String Title Case in Clojure https://whatacold.io/blog/2021-07-25-clojure-string-title-case/ Sun, 25 Jul 2021 11:51:39 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-07-25-clojure-string-title-case/ <p> These days I like to write scripts for some tasks in Python instead of shell. One important reason I think that&#39;s because Python is powerful at string manipulation.</p> <p> Recently I&#39;m learning Clojure, and I&#39;m trying to find similar ways in Clojure, one of them is <code class="verbatim">s.title()</code> for getting a title-cased version of a string. For example,</p> <div class="src src-text"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&gt;&gt;&gt; &#39; Hello world&#39;.title() </span></span><span class="line"><span class="cl">&#39; Hello World&#39;</span></span></code></pre></div> </div> <p> How to do that in Clojure? To make the problem simple, let&#39;s assume that the input string only has letters and spaces, that is, <code class="verbatim">[a-zA-Z ]</code> in regex pattern.</p> String Manipulation in Clojure https://whatacold.io/blog/2021-07-22-clojure-string-manipulation/ Thu, 22 Jul 2021 23:29:11 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-07-22-clojure-string-manipulation/ <p> Python string APIs are powerful and concise, that is an important reason I use it to do a lot of scripting these days, <code class="verbatim">join</code>, <code class="verbatim">split</code>, <code class="verbatim">strip</code>, to name a few.</p> <p> Since I am learning Clojure recently, I am wondering, how is string manipulation like in Clojure and how to implement equivalent ones?</p> <p> I think it&#39;s an excellent opportunity to get familiar with Clojure. Before diving into the implementation, how to declare a multi-line string?</p> Send Notifications from Emacs with i3wm and Dunst https://whatacold.io/blog/2021-07-17-emacs-i3wm-dunst/ Sat, 17 Jul 2021 12:22:10 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-07-17-emacs-i3wm-dunst/ <p> I barely use notifications, but recently I think it&#39;s a valuable way to remind me things like helping me nurture habits, or to notify me of emergencies like a critically low laptop battery.</p> <p> So I try to integrate notifications to org-mode and Emacs today.</p> <p> The <code class="verbatim">org-notify</code> package from <code class="verbatim">org-contrib</code> (install it by <code class="verbatim">(package-install &#39;org-contrib)</code> ) could do this job easily before, so I first test it in the minibuffer with <code class="verbatim">(org-notify &#34;test&#34;)</code>.</p> <p> Unfortunately, it errors out:</p> A Random Password Generator in Babashka https://whatacold.io/blog/2021-07-11-babashka-random-password-generator/ Sun, 11 Jul 2021 09:18:41 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2021-07-11-babashka-random-password-generator/ <p> I&#39;m used to learning by practicing, so when I learned Clojure, I always kept an eye on chances to write code in it.</p> <p> Scripting is an excellent field to practice, but the experience is not so good. On the one hand, it&#39;s too hacky to wrap Clojure code in a shell script with the shell bang. On the other hand, the startup time of JVM is too long to hurt the user experience.</p> An Online Python re.findall Service https://whatacold.io/blog/2020-10-21-a-python-re.findall-service/ Wed, 21 Oct 2020 22:51:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-10-21-a-python-re.findall-service/ <p> As a programmer, I know that <a href="https://www.gnu.org/s/grep/manual/grep.html">grep</a>, <a href="https://www.gnu.org/software/sed/manual/sed.html">sed</a> and <a href="https://www.gnu.org/software/gawk/manual/gawk.html">awk</a> are powerful for processing text, but they sometimes aren&#39;t that straight-forward for specific tasks, as I need to think about how to filter the lines and the columns out.</p> <p> So I wonder if there is a handy way to do these tasks?</p> <p> After using it for a while, I think using regex directly can help, so I launched a <a href="https://texttoolkit.com/re.findall">re.findall service</a> building on top of Python <code class="verbatim">re.findall</code> API.</p> Generate Call Graphs Using Doxygen in Emacs https://whatacold.io/blog/2020-08-22-generate-call-graphs-using-doxygen-in-emacs/ Sat, 22 Aug 2020 18:57:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-08-22-generate-call-graphs-using-doxygen-in-emacs/ <p> <a href="https://www.doxygen.nl/">Doxygen</a> is a nice tool for generating documentations for well-annotated C/C++ projects, the one feature that I like most is generating call graphs and class diagrams, so that I can learn a project quickly by browsing the diagrams from a higher point of view.</p> <p> I take the following steps to generate call graphs for a project on terminals on Linux:</p> <ol> <li><code class="verbatim">cd /path/to/a/project/</code>, and generate a template config file by <code class="verbatim">doxygen -s -g doxygen.conf</code> (Omit <code class="verbatim">-s</code> to generate it with detailed comments).</li> <li> <p>Tweak the file by specifying input and output directories, and set <code class="verbatim">HAVE_DOT</code> and <code>CALL_GRAPH</code> to <code class="verbatim">YES</code>.</p> Is It Safe to Use Redis As a Data Store? https://whatacold.io/blog/2020-06-25-is-it-safe-to-use-redis-as-a-data-store/ Thu, 25 Jun 2020 22:37:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-06-25-is-it-safe-to-use-redis-as-a-data-store/ <p> Traditionally we are used to storing data in an RDBMS like MySQL, and avoid using in-memory solutions such as Redis, to have a confidence of no data loss. Sometimes I find that we are so stubborn with MySQL that ending up with a complicated design, and I&#39;ve even seen a solution that stores data in MySQL and then using Redis as a cache for it to improve read performance in the meanwhile. And to make the data in the cache as consistent as possible with the data in MySQL, it introduces other mechanisms, but the result is still not 100% consistent.</p> A Trick to Troubleshoot Emacs Subprocess Creating https://whatacold.io/blog/2020-05-30-a-trick-to-troubleshoot-emacs-subprocess-creating/ Sat, 30 May 2020 11:52:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-05-30-a-trick-to-troubleshoot-emacs-subprocess-creating/ <p> There are many packages of Emacs that leverage subprocesses to do their jobs, <a href="https://magit.vc/">Magit</a>, <a href="https://github.com/joaotavora/eglot">eglot</a>, <a href="https://github.com/jorgenschaefer/elpy">elpy</a>, to name a few. And there are times that a subprocess doesn&#39;t work as expected, for example, Magit is slow, and you&#39;re sure that it&#39;s ok when running git commands on shell. So how to spot these problems effectively and quickly?</p> <p> The problem is that we don&#39;t know what&#39;s going on exactly, so here I want to share a few Elisp advices to make the subprocess creating visible, and print the exact program and its arguments to the <code class="verbatim">*Message*</code> buffer. Visibility is the key.</p> ppcompile: An Emacs Package to Help Coding Locally https://whatacold.io/blog/2020-03-07-ppcompile-to-help-stay-coding-locally/ Sat, 07 Mar 2020 23:50:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-03-07-ppcompile-to-help-stay-coding-locally/ <p> If you are a C/C++ programmer like me, you may experience jumping around different machines to write and compile your code, or you may write code on different machines for different projects, and scp/rsync/ftp the projects around. It works, but it&#39;s a bit tedious and takes too much burden on our brains.</p> <p> For example, say I have two projects that should be compiled on their compiling machines respectively. There are two obvious workflows for writing code for them &#34;simultaneously&#34;:</p> The Binary Search Idea for Narrowing Down Problem Space https://whatacold.io/blog/2020-02-04-binary-search-algorithm-vs-problem-solving/ Tue, 04 Feb 2020 18:48:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2020-02-04-binary-search-algorithm-vs-problem-solving/ <p> <a href="https://en.wikipedia.org/wiki/Binary_search_algorithm">Binary search algorithm</a> is a search algorithm that finds the position of a target value within a sorted array. It cuts off the target array in half in a pass, so that it has a worst-case performance of <code class="verbatim">O(log n)</code>.</p> <figure> <img src="https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg" alt="https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg" title="https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg" /><figcaption> Visualization of the binary search algorithm where 7 is the target value(@wikipedia) </figcaption> </figure> <p> We all know that it&#39;s an efficient searching algorithm, but the strategy behind it also applies for narrowing down other problem space, for example, finding out when a bug is first introduced in a series of git commits.</p> Manage SSH Connections with ~/.ssh/config https://whatacold.io/blog/2019-12-22-manage-ssh-connections-with-ssh-config/ Sun, 22 Dec 2019 18:52:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-12-22-manage-ssh-connections-with-ssh-config/ <p> I used to manage <a href="https://en.wikipedia.org/wiki/SSH_(Secure_Shell)">SSH</a> connection with such GUI apps as <a href="https://mobaxterm.mobatek.net/">MobaXterm</a>, when I wrote code on Windows at work. As I changed my workflow to use a tiling window manager in a <a href="https://www.virtualbox.org/">VirtualBox</a> guest OS, I continued to improve my way of managing SSH connections, which I want to share here if you don&#39;t know yet.</p> <p> At first, I baked a helper Python script, which I named as qssh for &#34;quick ssh&#34;, to help me assemble ssh arguments for me(such as username, Ip, port, etc.), so that I can easily access a host by giving it only one argument, e.g. <code class="verbatim">qssh foo</code>.</p> Why Can't Git Fetch Remote Branches Other Than Master? https://whatacold.io/blog/2019-12-01-why-cant-git-fetch-remote-branches-other-than-master/ Sun, 01 Dec 2019 16:00:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-12-01-why-cant-git-fetch-remote-branches-other-than-master/ <p> Last week I came into a problem with Git, that I can&#39;t fetch the remote branch that I just pushed to. It was so weird because I can push it. It never happens before, and it happened when I was in a rush to rebase my code, as someone in my team pushed his code.</p> <p> After searching, it seemed that the configuration of <code class="verbatim">fetch</code> of that repo was different(this <a href="https://stackoverflow.com/questions/11623862/fetch-in-git-doesnt-get-all-branches">Stack Overflow</a> thread for example) than before, it was specified that only <code class="verbatim">master</code> can be fetched. It worked after I changed it to <code class="verbatim">+refs/heads/*:refs/remotes/origin/*</code>.</p> Open New Urxvt from within Emacs https://whatacold.io/blog/2019-11-25-start-a-new-urxvt-terminal-on-emacs/ Mon, 25 Nov 2019 22:47:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-11-25-start-a-new-urxvt-terminal-on-emacs/ <p> I have been really enjoying the more concentration workflow <a href="http://www.qtile.org/">qtile</a>, a tiling window manager, brings me, since I started using it a few months ago. I am more focus on the current task now as all the windows I care about are laid out on the same screen.</p> <p> As I get more used to qtile at every day&#39;s work, I noticed that I became more depend on short-life terminal sessions. Sometimes I need to quickly execute some commands on the current buffer on <a href="https://www.gnu.org/software/emacs/">Emacs</a>, such as searching text which having many matches and quit that terminal after I&#39;m done. So I wondered what could be the best way to achieve that.</p> Build Docker Images for Qtile https://whatacold.io/blog/2019-10-07-build-docker-images-for-qtile/ Mon, 07 Oct 2019 13:25:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-10-07-build-docker-images-for-qtile/ <p> One of <a href="https://zh.wikipedia.org/zh-cn/Docker">Docker</a>&#39;s use cases is to set up identical development environments easily and quickly for a dev team. Recently, I had an opportunity to give it a try, and build Docker images for <a href="https://github.com/qtile/qtile">Qtile</a>, as it didn&#39;t have one yet as I get involved. With the images, it&#39;s easy to set up the environment to easily run the tests, and build the documentation.</p> <p> The best way to have a basic idea of Docker is to think it like a chroot environment, as Chris Tankersley stated in his <a href="https://leanpub.com/dockerfordevs">Docker for Developers</a>. And two basic concepts of Docker are image and container, containers to images are what objects to classes as in OOP terminology.</p> How To Run Bleeding-edge Qtile Within a Virtualenv https://whatacold.io/blog/2019-09-29-how-to-run-the-bleeding-edge-code-of-qtile/ Sun, 29 Sep 2019 17:05:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-09-29-how-to-run-the-bleeding-edge-code-of-qtile/ <p> For having been using <a href="https://www.gnome.org/">GNOME</a> for quite a long time, I was considering trying some tiling window managers to see what it&#39;s like a few weeks ago. Along the way, I found a nice window manager written in Python: <a href="http://www.qtile.org">Qtile</a>, what interests me most is that it&#39;s a <strong>hackable</strong> window manager, which makes it flexible to extend or change its behaviors.</p> <p> Well, switching to use a tiling window manager is far simpler than I thought. There are two ways to have it:</p> How To Revert a Series of Git Commits? https://whatacold.io/blog/2019-09-24-how-to-revert-a-series-of-commits-with-git/ Tue, 24 Sep 2019 23:14:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-09-24-how-to-revert-a-series-of-commits-with-git/ <p> Sometimes, I need to revert a series of commits that I&#39;ve already pushed, doing a git hard <a href="https://git-scm.com/docs/git-reset">reset</a> (<code class="verbatim">git reset --hard</code>) is not an option, as someone may already have new commits based on mine.</p> <p> For example, assume that I&#39;ve made a few commits like below:</p> <pre class="example"> 65a2c62 * commit 10 25cad43 * commit 9 72ad583 * commit 8 ceebf9a * commit 7 acf8a11 * commit 6 28d526f * commit 5 63af1e2 * commit 4 982c71c * commit 3 0fb4c2d * commit 2 acf9da1 * commit 1 b5f9933 * commit 0 </pre> <p> For whatever reason, I need to &#34;drop&#34; the changes made by commit 6 to commit 10, that is, go back to &#34;commit 5&#34; without deleting these commits.</p> How to Change Web Page Titles Easily https://whatacold.io/blog/2019-08-18-how-to-rename-web-page-titles-in-a-lightweight-way/ Sun, 18 Aug 2019 14:57:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-08-18-how-to-rename-web-page-titles-in-a-lightweight-way/ <p> There are times that I need to open many web pages of some specific websites within a browser, and there are so many tabs that I can&#39;t efficiently access one of them, as their favicons are all the same.</p> <p> So I tried to find a way to rename their titles, preferably in a lightweight way, so that I can spot them quickly with my eyes.</p> <p> The first thought came into my mind was to find some browser extensions to do the job. It was easy to install one with no time. But I was not very happy with the experience. It seems that it keeps the rule of renaming titles based on the URL so that the title will always be renamed if I refreshing it, which is not what I want. I&#39;d rather want to do it in an ad-hoc way.</p> Generating org-mode Outlines for wikiHow Articles https://whatacold.io/blog/2019-07-20-generating-org-mode-outlines-for-wikihow-articles/ Sat, 20 Jul 2019 20:04:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-07-20-generating-org-mode-outlines-for-wikihow-articles/ <p> Recently I found some great articles on <a href="https://www.wikihow.com">wikiHow</a>, then I want to keep notes of them in <a href="https://orgmode.org/">org-mode</a> files.</p> <p> At first, I manually copied the ToC of articles, but soon I found it&#39;s tedious and takes a lot of time. Today I wrote a <a href="https://requests.readthedocs.io/">requests</a>-based Python script to help me extract the ToCs (Table of Content) into org-mode outlines. It takes two arguments, the first one is the URL, the second one is the containing heading&#39;s level for the generated ToC in org-mode.</p> Understanding align-regexp of Emacs https://whatacold.io/blog/2019-07-20-understanding-align-regexp-of-emacs/ Sat, 20 Jul 2019 13:50:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-07-20-understanding-align-regexp-of-emacs/ <p> <a href="https://www.gnu.org/software/emacs/">Emacs</a>&#39; <code class="verbatim">M-x align-regex</code> is neat when I want to align some similar text, especially when we&#39;re coding. I use its trivial version(without prefix arg) regularly on day-to-day programming work before.</p> <p> For example, I can use it to align below code quickly by:</p> <ol> <li>Choose the region</li> <li><code class="verbatim">M-x align-regexp</code> and type <code>=</code> and <code class="verbatim">Enter</code></li> </ol> <div class="src src-python"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">aaaaaaaaaaaaaa</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="n">bbb</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="n">cccccccc</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span></span></span></code></pre></div> </div> <p> It will be aligned to below code, now it&#39;s better to read:</p> <div class="src src-python"> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">aaaaaaaaaaaaaa</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="n">bbb</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="n">cccccccc</span> <span class="o">=</span> <span class="n">fields</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span></span></span></code></pre></div> </div> <p> A few days ago, I found myself don&#39;t understand how it works when I read the code of <a href="https://github.com/manateelazycat/smart-align">smart-align</a>, A simple <code class="verbatim">align-regexp</code> wrapper for easier usage. I was confused by the parameters, especially <code class="verbatim">REGEXP</code> and <code class="verbatim">GROUP</code>, and <code class="verbatim">SPACING</code>, here is its signature:</p> ER Diagrams in Plain Text https://whatacold.io/blog/2019-07-06-render-erd-on-the-web/ Sat, 06 Jul 2019 11:59:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-07-06-render-erd-on-the-web/ <p> If you ever wonder how to plot <a href="https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model">ER diagrams</a> in plain text, you may have already heard of <a href="https://github.com/BurntSushi/erd">erd</a>. It&#39;s a cool command line program written by Andrew Gallant in Haskell, to &#34;compile&#34; plain text files into nicely looking images, leveraging the power of <a href="https://graphviz.org/">GraphViz</a>.</p> <p> I&#39;ve used erd for some time, it&#39;s cool and the syntax is quite simple. It&#39;s also quite simple to install it on Linux, just install GraphViz and erd itself, by following the instructions in the README page.</p> Fine-tune Curly Braces Style of Yasnippet Snippet on the Fly https://whatacold.io/blog/2019-02-24-fine-tune-style-of-yasnippet-snippet-on-the-fly/ Sun, 24 Feb 2019 16:48:00 +0800[email protected] (Ken Huang) https://whatacold.io/blog/2019-02-24-fine-tune-style-of-yasnippet-snippet-on-the-fly/ <p> <a href="https://github.com/joaotavora/yasnippet">Yasnippet</a> is a good friend to help us type less and write more, whenever we write some text snippets repeatedly. And there is also an official repository called <a href="https://github.com/AndreaCrotti/yasnippet-snippets">yasnippet-snippets</a> that contains various snippets for many programming languages (modes), so that we can have many snippets in no time by installing it.</p> <p> But there is a little problem when it comes to conforming to different coding styles.</p> <p> Take the <code class="verbatim">if</code> snippet for example, normally it will generate code like this:</p>