<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>fennel on QL&#39;s blog</title>
    <link>/tags/fennel/</link>
    <description>Recent content in fennel on QL&#39;s blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 29 Mar 2022 19:47:00 +0200</lastBuildDate><atom:link href="/tags/fennel/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>A fennel REPL for Hammerspoon</title>
      <link>/posts/a-fennel-repl-for-hammer-spoon/</link>
      <pubDate>Tue, 29 Mar 2022 19:47:00 +0200</pubDate>
      
      <guid>/posts/a-fennel-repl-for-hammer-spoon/</guid>
      <description>The Fennel programming language is one of my favorite programming languages. It gets a lot of things done right:
Modern syntax (Clojure-like, but better) Immutable by default Excellent pattern matching If I ever find myself working with a Lua interpreter (Hammerspoon, Neovim, TIC-80, etc.), Fennel is often my go-to for concise and efficient code.
The question is, can I have a REPL for Hammerspoon? There are multiple options available, like nREPL via jeejah, but I find it limited compared to the REPL that comes with fennel-mode.</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://fennel-lang.org/&#34;&gt;The Fennel programming language&lt;/a&gt; is one of my favorite programming languages. It gets a lot of things done right:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modern syntax (Clojure-like, but better)&lt;/li&gt;
&lt;li&gt;Immutable by default&lt;/li&gt;
&lt;li&gt;Excellent pattern matching&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I ever find myself working with a Lua interpreter (Hammerspoon, Neovim, TIC-80, etc.), Fennel is often my go-to for concise and efficient code.&lt;/p&gt;
&lt;p&gt;The question is, can I have a REPL for Hammerspoon? There are multiple options available, like nREPL via &lt;a href=&#34;https://gitlab.com/technomancy/jeejah&#34;&gt;jeejah&lt;/a&gt;, but I find it limited compared to the REPL that comes with &lt;a href=&#34;https://github.com/emacsmirror/fennel-mode&#34;&gt;fennel-mode&lt;/a&gt;. Hammerspoon does come with an interactive shell, and I would like to adapt it to work with &lt;code&gt;fennel-mode&lt;/code&gt;. In fact, it&amp;rsquo;s very possible. Hammerspoon comes with a hook, &lt;code&gt;_consoleInputPreparser&lt;/code&gt;, that can be hacked to evaluate an expression. Essentially, we can run a REPL in a coroutine and resume it whenever the user inputs something.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-clojure&#34; data-lang=&#34;clojure&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;:hs.ipc&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;local&lt;/span&gt; fennel (&lt;span style=&#34;color:#a6e22e&#34;&gt;require&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;:fennel&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;let &lt;/span&gt;[coro (&lt;span style=&#34;color:#a6e22e&#34;&gt;coroutine.create&lt;/span&gt; fennel.repl)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#a6e22e&#34;&gt;coroutine.resume&lt;/span&gt; coro {&lt;span style=&#34;color:#e6db74&#34;&gt;:readChunk&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;fn &lt;/span&gt;[]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       (&lt;span style=&#34;color:#66d9ef&#34;&gt;let &lt;/span&gt;[input (&lt;span style=&#34;color:#a6e22e&#34;&gt;coroutine.yield&lt;/span&gt;)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         (.. input &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          &lt;span style=&#34;color:#e6db74&#34;&gt;:onValues&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;fn &lt;/span&gt;[xs]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                      (print (&lt;span style=&#34;color:#a6e22e&#34;&gt;table.concat&lt;/span&gt; xs &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\t&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                          &lt;span style=&#34;color:#e6db74&#34;&gt;:onError&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;fn &lt;/span&gt;[_ msg]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                     (print msg))})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (set hs._consoleInputPreparser (&lt;span style=&#34;color:#66d9ef&#34;&gt;fn &lt;/span&gt;[s]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   (&lt;span style=&#34;color:#a6e22e&#34;&gt;coroutine.resume&lt;/span&gt; coro s)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is the result:&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/ox-hugo/2023-03-29_09-39-06_screenshot.png&#34;   /&gt;
    
  &lt;/figure&gt;


&lt;p&gt;And of course, you can evaluate code and get completion with &lt;code&gt;fennel-mode&lt;/code&gt;, too.&lt;/p&gt;

  &lt;figure class=&#34;left&#34; &gt;
    &lt;img src=&#34;/ox-hugo/2023-03-29_09-42-36_screenshot.png&#34;   /&gt;
    
  &lt;/figure&gt;


</content>
    </item>
    
  </channel>
</rss>
