<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" >

  <title>Erik L. Arneson — Writer and Software Developer</title>
  <subtitle>Erik L. Arneson is a freelance writer and software developer with WordPress experience. He is located in Portland, Oregon.</subtitle>
  <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator>
  <link href="https://arnesonium.com/feeds/golang.xml" rel="self" type="application/atom+xml" />
  <link href="https://arnesonium.com/" rel="alternate" type="text/html" />
  <updated>2026-06-18T15:03:10+00:00</updated>
  <id>https://arnesonium.com/feeds/golang.xml</id>
  <author>
    <name>Erik L. Arneson</name>
  </author>
      <entry>
        
        <title>Process Automation for an Oregon Charitable Foundation</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2026/05/process-automation-oregon-charitable-foundation" rel="alternate" type="text/html" title="Process Automation for an Oregon Charitable Foundation" />
        <updated>2026-05-22T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2026/05/sref</id>
          <category term="cloud" />
        
          <category term="cloud-computing" />
        
          <category term="golang" />
        
          <category term="svelte" />
        
          <category term="typescript" />
        
          <category term="automation" />
        
          <category term="case-study" />
        
          <category term="google-cloud" />
        
          <category term="programming" />
        
          <category term="testing" />
        
          <category term="web-development" />
        
          <category term="software-development" />
        <content type="html" xml:base="https://arnesonium.com/2026/05/process-automation-oregon-charitable-foundation">&lt;p&gt;The &lt;a href=&quot;https://orsrscholarships.com/&quot;&gt;Oregon Scottish Rite Education Foundation&lt;/a&gt; awards scholarships annually to students across Oregon
who are entering into college or trade schools. Over the past few years, their foundation has grown,
requiring them to distribute more scholarships than ever. However, since the foundation board is
small and composed entirely of volunteers, they were looking for some way to automate their application process to
reduce the number of manual steps required.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;initial-approach&quot;&gt;Initial Approach&lt;/h2&gt;

&lt;p&gt;Members of the board approached me with a wish list of features and requirements. They wanted a
system to integrate seamlessly with their website, while incoming applications should be
automatically checked, sorted, and categorized by county. They already had a spreadsheet system for
tracking applicants as well as a cloud storage system for storing supporting documents; they wanted
the automation system to integrate with these existing components.&lt;/p&gt;

&lt;p&gt;Since the board was already utilizing Google Business products for cloud documents and storage, I
decided that the best approach would be to lean into Google Cloud services. Following their list of
requirements, I implemented a &lt;a href=&quot;https://cloud.google.com/run&quot;&gt;Google Cloud Run&lt;/a&gt; service in &lt;a href=&quot;https://go.dev/&quot;&gt;Go&lt;/a&gt; that processed incoming applications
from their website, then updated the spreadsheet while preparing their cloud storage system for each
application’s supporting documents. The spreadsheet now contained all the application data,
including a link to an automatically generated PDF version of the application and a link to the
cloud storage location.&lt;/p&gt;

&lt;p&gt;This initial approach cut out an enormous amount of manual work. Previously, applications were
submitted via the website and emailed to a board member, who then manually sorted them by county and
generated PDFs for storage and later distribution.&lt;/p&gt;

&lt;h2 id=&quot;implementation-challenges&quot;&gt;Implementation Challenges&lt;/h2&gt;

&lt;p&gt;The application submission window for the Oregon Scottish Rite Education Foundation runs from
December through March of each year, which gave us a limited amount of time to observe incoming live
data and how the automation was performing.&lt;/p&gt;

&lt;p&gt;My initial approach worked fairly well, and handled 94% of incoming applications properly. However,
the last 6% ran into various problems that prevented correct processing. One error arose from a
misspelling in a county name, which was caught early and corrected. Another series of errors arose
from processing errors with the Google Sheets API, which has both rate limiting and more mysterious,
inexplicable errors. I added additional error correction and error checking, but there was still
some additional manual work to enter data from a handful of applications.&lt;/p&gt;

&lt;p&gt;By the end of the application period, we had managed to reduce the amount of manual data entry and
processing by a large percentage, maybe as much as 60%. After discussing the current process
automation with the board, we began to see opportunities for further automation and improvement.&lt;/p&gt;

&lt;h2 id=&quot;additional-development&quot;&gt;Additional Development&lt;/h2&gt;

&lt;p&gt;After the first year’s application submission window, I began working with one of the board members
to plan out how the process could be improved even more. My list of improvements were primarily on
the backend, and involved robuster error detection and reporting, as well as a backup data store
that would allow the automation to recover from the Google Sheets API errors more elegantly.&lt;/p&gt;

&lt;p&gt;The board proposed an additional feature set that would further reduce manual data processing, by
allowing applicants to upload supporting documents such as letters of recommendation and high school
transcripts. These uploaded documents would then be processed and stored in the proper cloud storage
location, thus reducing the amount of manual file management required by volunteers.&lt;/p&gt;

&lt;p&gt;Implementing these two new features went very smoothly. It required the development of a new
frontend, using &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;Typescript&lt;/a&gt; and &lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt;. This frontend allowed applicants to upload their supporting
documents via a unique link given to each of them by automated email. It used both &lt;a href=&quot;https://cloud.google.com/storage&quot;&gt;Google Cloud
Storage&lt;/a&gt; and the Google Drive API to store these files.&lt;/p&gt;

&lt;p&gt;The improvements on the backend used &lt;a href=&quot;https://cloud.google.com/products/datastore&quot;&gt;Google Cloud Datastore&lt;/a&gt; and a more robust error recovery system.
It now backed up all incoming scholarship applications until they could reliably and more slowly be
added to the spreadsheet with the Google Sheets API, thus nearly eliminating all rate limiting
errors. In addition, progress reports and error output could now be viewed using a new frontend
administrative interface.&lt;/p&gt;

&lt;h2 id=&quot;results&quot;&gt;Results&lt;/h2&gt;

&lt;p&gt;This round of improvements produced significant results. Over the entire span of the second year of
application submissions, error rates dropped from 6% to &lt;em&gt;just one unrecoverable error.&lt;/em&gt; While I had
been hoping for improvement, even I was surprised by how much of an improvement we achieved!&lt;/p&gt;

&lt;p&gt;The board reported that the amount of manual processing was reduced by another 80-90%, with only a
few applicants resorting to email for sending in their supporting documents. While we have discussed
further improvements to the process automation for the next application submission window, the board
is satisfied with the improvements provided by the level of automation implemented so far.&lt;/p&gt;

&lt;h2 id=&quot;lessons&quot;&gt;Lessons&lt;/h2&gt;

&lt;p&gt;This project benefited a lot by reviewing requirements and expectations frequently with the client.
They were great at providing me with very clear goals from the beginning, and as we progressed and
it became clear where the most volunteer time was being spent, we were able to identify more tasks
for automation.&lt;/p&gt;

&lt;p&gt;On the development side of things, three things were clear. First, cloud services really make the
development and deployment of process automation tools like this a breeze. Costs can be kept low
while still providing robust infrastructure for hosting.&lt;/p&gt;

&lt;p&gt;Second, I learned once more the importance of unit tests. I wrote unit tests for most elements of
the automation software, which allowed me to catch breaking changes and test features very quickly.
&lt;a href=&quot;https://www.ibm.com/think/topics/test-driven-development&quot;&gt;Test-driven development&lt;/a&gt; can be a great way to run a project, and though I did not follow all of its
parameters strictly, that particular philosophy did guide my decision.&lt;/p&gt;

&lt;p&gt;Third, once more I was reminded of how the best-planned software runs into difficulties when it
collides with the real world. I failed to anticipate the Google Sheets API issues and did not
implement enough comprehensive error correction early on. That is not an error I shall repeat again!&lt;/p&gt;

&lt;p&gt;Finally, I learned that even with a project that seems as straightforward as this one, it is
important to control expectations early. This turned into a multiyear project because we saw room
for improvement. I think it is important for a business or organization looking for process
automation to understand that it can be an ongoing series of improvements; not everything will be
accomplished or perfected after one pass.&lt;/p&gt;

&lt;p&gt;Overall, I found this to be a rewarding project. I enjoyed working on software that was aiding a
good cause: helping high school graduates fund their education. It was also very nice to work for a
charitable foundation instead of a for-profit business; it made all of my programming feel a lot
better. I hope to work for more charitable foundations in the future.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Interviewed on &quot;Prot Speaks&quot;</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2025/08/interviewed-on-prot-speaks" rel="alternate" type="text/html" title="Interviewed on "Prot Speaks"" />
        <updated>2025-08-18T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2025/08/prot-speaks-interview</id>
          <category term="emacs" />
        
          <category term="podcast" />
        
          <category term="programming" />
        
          <category term="org-mode" />
        
          <category term="lisp" />
        
          <category term="golang" />
        
          <category term="portland" />
        <content type="html" xml:base="https://arnesonium.com/2025/08/interviewed-on-prot-speaks">&lt;p&gt;Well-known Emacs package creator Protesilaos Stavrou interviewed me for his video podcast series, “Prot Asks.” We talked about a wide variety of topics, from Emacs to podcasting to Portland to public transit. I thought it was a great time, and perhaps you will like it, too!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;You can read and view the video &lt;a href=&quot;https://protesilaos.com/codelog/2025-08-17-prot-asks-erik-emacs-1990s-portland-oregon-podcasting/&quot;&gt;on Prot’s website and blog&lt;/a&gt;, or you can go &lt;a href=&quot;https://www.youtube.com/watch?v=6wkfFdiwpyU&quot;&gt;straight to YouTube&lt;/a&gt;, or you can watch it embedded here below.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/6wkfFdiwpyU?si=ocNz3f6ehqEYYC2G&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Note that Prot is looking for people to talk to on this series! You can join in by &lt;a href=&quot;https://protesilaos.com/prot-asks/&quot;&gt;signing up on his website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;P.S. In the video, I promised that I would do another Emacs Carnival blog post, and I will, I swear! It is in my org-mode to-do file.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>maybe: A command-line tool that succeeds sometimes</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2025/02/maybe-succeeds-sometimes" rel="alternate" type="text/html" title="maybe: A command-line tool that succeeds sometimes" />
        <updated>2025-02-13T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2025/02/maybe-succeeds-sometimes</id>
          <category term="programming" />
        
          <category term="golang" />
        
          <category term="github" />
        <content type="html" xml:base="https://arnesonium.com/2025/02/maybe-succeeds-sometimes">&lt;p&gt;I just released &lt;a href=&quot;https://github.com/pymander/maybe/releases/tag/v1.0.0&quot;&gt;version 1.0.0 of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;&lt;/a&gt;, a command-line utility that succeeds some of the time. It
is written in Go and is not very many lines of code, but I do hope that it can be useful for people.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;some-history&quot;&gt;Some History&lt;/h2&gt;

&lt;p&gt;I recently got a &lt;a href=&quot;https://amzn.to/3CYb9he&quot;&gt;Korg Volca Drums&lt;/a&gt; drum synthesizer. It has a sequencer that allows you to program
the probability of a particular instrument playing on a particular step, and I thought that was a
really cool feature. This inspired me to think about cron jobs that happen only some of the time.
Maybe the cron job would run, maybe it wouldn’t.&lt;/p&gt;

&lt;p&gt;This inspired me to write &lt;a href=&quot;https://github.com/pymander/maybe&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;&lt;/a&gt;, a command-line utility that returns either success or failure,
based on flags you pass it. It defaults to succeeding 50 percent of the time, but you can change
that. This means you could make a cron job like this, which would run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do-something.sh&lt;/code&gt; 40 percent
of the time.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# At midnight every Sunday, do something sometimes.&lt;/span&gt;
0 0 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; 0     maybe &lt;span class=&quot;nt&quot;&gt;-chance&lt;/span&gt; 40 &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-something&lt;/span&gt;.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-future-of-maybe&quot;&gt;The Future of maybe&lt;/h2&gt;

&lt;p&gt;I don’t think I will stop at version 1.0.0. I have already considered what may happen to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt; in
the future. Here are some things that I would like to do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add cryptographically secure randomness. There is no reason to use Go’s default random library.
Let us try to be as random as possible.&lt;/li&gt;
  &lt;li&gt;More granularity to the randomness. What if you want to run something 40.5 percent of the time?&lt;/li&gt;
  &lt;li&gt;Experiment with GitHub actions, such as building binaries for every operating system that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt;
should support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, the opportunities for improvement are many. And maybe (ha ha!) you will see
improvements soon!&lt;/p&gt;

&lt;p&gt;Perhaps this is a good time to visit &lt;a href=&quot;https://github.com/pymander/maybe&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe&lt;/code&gt; on GitHub&lt;/a&gt; and star the repo so others can find it?&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Configuring Emacs 29.1 for Go Development</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2023/08/configuring-emacs-29-1-for-golang" rel="alternate" type="text/html" title="Configuring Emacs 29.1 for Go Development" />
        <updated>2023-08-01T00:00:00+00:00</updated>
        <id>https://arnesonium.com/2023/08/golang-emacs</id>
          <category term="emacs" />
        
          <category term="programming" />
        
          <category term="golang" />
        
          <category term="lisp" />
        
          <category term="emacs-lisp" />
        <content type="html" xml:base="https://arnesonium.com/2023/08/configuring-emacs-29-1-for-golang">&lt;p&gt;Now that I have &lt;a href=&quot;https://arnesonium.com/2023/07/emacs-29-1-on-ubuntu-22-04-lts&quot;&gt;installed Emacs 29.1&lt;/a&gt;, I needed to get it set up for Go development for a project. I was interested in taking advantage of both the new Tree-Sitter integration, and the new Eglot language server client. However, they were mildly tricky to set up! Here is what I did.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;configuring-tree-sitter-for-go&quot;&gt;Configuring Tree-Sitter for Go&lt;/h2&gt;

&lt;p&gt;If you follow the excellent &lt;a href=&quot;https://www.masteringemacs.org/article/how-to-get-started-tree-sitter&quot;&gt;How to Get Started with Tree-Sitter&lt;/a&gt; instructions from Mickey Peterson, you will have a great head-start on getting Tree-Sitter working for most of your favorite languages (and probably Java, too). However, those instructions didn’t cover everything I needed for Go. When I tried running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x go-ts-mode&lt;/code&gt;, Emacs complained about a missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt; module. Baffling!&lt;/p&gt;

&lt;p&gt;I couldn’t find any information in the Emacs documentation about where to find this missing module. I looked around on the net and found &lt;a href=&quot;https://github.com/camdencheek/tree-sitter-go-mod&quot;&gt;Camden Cheek’s tree-sitter-go-mod&lt;/a&gt;, and added that to my list of recipes. My &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;treesit-language-source-alist&lt;/code&gt; then looked like this:&lt;/p&gt;

&lt;div class=&quot;language-elisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;treesit-language-source-alist&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-bash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cmake&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/uyha/tree-sitter-cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;css&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-css&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;elisp&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/Wilfred/tree-sitter-elisp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-go&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gomod&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/camdencheek/tree-sitter-go-mod&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dockerfile&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/camdencheek/tree-sitter-dockerfile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;javascript&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-javascript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/alemuller/tree-sitter-make&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;markdown&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/ikatyang/tree-sitter-markdown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-python&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toml&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-toml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tsx&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-typescript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tsx/src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;typescript&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/tree-sitter/tree-sitter-typescript&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;master&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;typescript/src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://github.com/ikatyang/tree-sitter-yaml&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the package is named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-mod&lt;/code&gt; but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go-ts-mode&lt;/code&gt; expects it to be named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt;. I wish this were documented somewhere! In any case, I was then able to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x treesit-install-language-grammar&lt;/code&gt; for both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt;. Finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x go-ts-mode&lt;/code&gt; worked!&lt;/p&gt;

&lt;p&gt;After going through this process, I found &lt;a href=&quot;https://robbmann.io/posts/emacs-treesit-auto/&quot;&gt;Robert Enzmann’s post about automatically using Tree-Sitter&lt;/a&gt;. He has created the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;treesit-auto&lt;/code&gt; package, now available on MELPA, that does most of this work for you. It is a much faster way of solving the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gomod&lt;/code&gt; mystery, so give it a shot!&lt;/p&gt;

&lt;h2 id=&quot;configuring-eglot-for-go&quot;&gt;Configuring Eglot for Go&lt;/h2&gt;

&lt;p&gt;I’d been using &lt;a href=&quot;https://github.com/emacs-lsp/lsp-mode&quot;&gt;lsp-mode&lt;/a&gt; for ages, but with Emacs 29.1 including &lt;a href=&quot;https://joaotavora.github.io/eglot/&quot;&gt;Eglot&lt;/a&gt;, I decided to make the switch.&lt;/p&gt;

&lt;p&gt;In my Go project, I ran &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M-x eglot&lt;/code&gt; and was immediately met with an error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[eglot] Server reports (type=1): Error loading workspace folders (expected 1, got 0)
failed to load view for file:///path/to/my/project: err: go command required, not found: exec: &quot;go&quot;: executable file not found in $PATH: stderr: 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve got Go installed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/go&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/go/bin&lt;/code&gt; is definitely in my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec-path&lt;/code&gt; variable in Emacs. It looked like Eglot wasn’t propagating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exec-path&lt;/code&gt; down to its subprocesses. How annoying! I did a quick search through the list of Eglot-related variables and the Eglot documentation and no solution seemed immediately forthcoming.&lt;/p&gt;

&lt;p&gt;So I took the cheap way out and made a symlink. In my shell, I ran:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; /usr/local/go/bin/go /usr/local/bin/go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is a dumb trick, and I am sure there is a better way to solve it. Do you know of one? Please comment and let me know!&lt;/p&gt;

&lt;h2 id=&quot;what-else&quot;&gt;What Else?&lt;/h2&gt;

&lt;p&gt;My exploration has revealed that there’s a lot of work left to do in the Emacs Tree-Sitter world. There are plenty of languages major modes that don’t yet have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts-mode&lt;/code&gt; equivalent, and plenty of others that still need a lot of work.&lt;/p&gt;

&lt;p&gt;It’s too soon for me to say if this setup is preferrable to my previous configuration. But I am really looking forward to playing around with Eglot’s features and exploring the capabilities of Tree-Sitter.&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Link Rodeo: Go Package Management and Boring Technology</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology/" rel="alternate" type="text/html" title="Link Rodeo: Go Package Management and Boring Technology" />
        <updated>2015-04-06T15:47:00+00:00</updated>
        <id>https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology</id>
          <category term="best-practices" />
        
          <category term="golang" />
        
          <category term="javascript" />
        
          <category term="management" />
        
          <category term="node-js" />
        
          <category term="ocaml" />
        
          <category term="programming" />
        <content type="html" xml:base="https://arnesonium.com/2015/04/link-rodeo-go-package-management-and-boring-technology/">&lt;p&gt;Here are a number of interesting topics for you to think about this week.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I’ve been learning the &lt;a href=&quot;http://arnesonium.com/tag/golang/&quot; title=&quot;Go language&quot;&gt;Go programming language&lt;/a&gt; recently, and in the process I’ve been having conversations about it with friends and colleagues. Go has a unique package management system that has already caused me a number of headaches. The recommended method for taking care of package dependencies is lacking, at best. Over at Nerdbucket, my buddy Nerdmaster has written &lt;a href=&quot;http://blog.nerdbucket.com/go-dependency-freezing/article&quot; title=&quot;Go Dependency Freezing at Nerdbucket&quot; target=&quot;_blank&quot;&gt;a thoughtful piece about it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While I’m talking about new technology, I’d also like to contradict myself by agreeing with Dan McKinley’s great piece, &lt;a href=&quot;http://mcfunley.com/choose-boring-technology&quot; title=&quot;Choose Boring Technology by Dan McKinley&quot; target=&quot;_blank&quot;&gt;“Choose Boring Technology.”&lt;/a&gt; He argues that a project should be careful about adopting lots of new tools and technologies. It reminds me of a time recently when I was looking for a Node.js programmer, and one of the replies I got back was, “For us, Node.js is glue. Its ecosystem is still too young to support anything long-term. Libraries and packages move too fast to build a product that will need actual maintenance.” I’ve had the same feeling about many technologies I’ve wanted to try, such as &lt;a href=&quot;http://ocsigen.org/&quot; title=&quot;Ocsigen&quot; target=&quot;_blank&quot;&gt;Ocsigen for OCaml&lt;/a&gt;, which has a build system and API that is always several steps ahead of its documentation.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;This post’s featured photo is courtesy of Flickr user &lt;a href=&quot;https://www.flickr.com/photos/municipiopinas/8161449094/&quot; target=&quot;_blank&quot;&gt;MunicipioPinas&lt;/a&gt;.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Create a Document From Twitter with TweetBook</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook/" rel="alternate" type="text/html" title="Create a Document From Twitter with TweetBook" />
        <updated>2015-04-01T17:48:56+00:00</updated>
        <id>https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook</id>
          <category term="golang" />
        
          <category term="google-cloud" />
        
          <category term="programming" />
        
          <category term="publishing" />
        
          <category term="tweetbook" />
        
          <category term="twitter" />
        
          <category term="web-development" />
        <content type="html" xml:base="https://arnesonium.com/2015/04/create-a-document-from-twitter-with-tweetbook/">&lt;p&gt;I just released &lt;a href=&quot;http://tweetbook.arnesonium.com/&quot; title=&quot;TweetBook&quot; target=&quot;_blank&quot;&gt;TweetBook&lt;/a&gt;, a web application to transform a Twitter stream into a simple document that can easily be turned into a photo album.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;A client came to me complaining that there was no available solution to export a Twitter feed as a document filled with images. There are various other Twitter-to-document converters out there, but they all focus on the text. The client asked me to build a tool to fill this void.&lt;/p&gt;

&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;Since I’ve been working with Google App Engine a lot lately, I used Go to write a tool that retrieves Tweets from a search or timeline. It provides a number of formatting options, and then creates a simple document suitable for exporting into an HTML or PDF file.&lt;/p&gt;

&lt;h2&gt;Try It Out!&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;As of 2022, this application is seven years old and probably doesn’t work anymore.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The client told me to do whatever I wanted with the code, so I’m making it available for use! &lt;strong&gt;&lt;a href=&quot;http://tweetbook.arnesonium.com/&quot; title=&quot;TweetBook&quot; target=&quot;_blank&quot;&gt;Click here to try TweetBook!&lt;/a&gt;&lt;/strong&gt; If you find it useful, please consider funding further development by contributing a small amount with this button:&lt;/p&gt;

&lt;form action=&quot;https://www.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot; target=&quot;_top&quot;&gt;
 &lt;button type=&quot;submit&quot; class=&quot;btn&quot;&gt;Contribute $1.99 &amp;raquo;&lt;/button&gt;&lt;input type=&quot;hidden&quot; name=&quot;cmd&quot; value=&quot;_s-xclick&quot; /&gt;&lt;input type=&quot;hidden&quot; name=&quot;hosted_button_id&quot; value=&quot;3PNSJJHRF9XWA&quot; /&gt;
 &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://www.paypalobjects.com/en_US/i/scr/pixel.gif&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;
&lt;/form&gt;

&lt;h2&gt;Do You Have a Suggestion? A Bug Report?&lt;/h2&gt;
&lt;p&gt;If you have additional ideas for TweetBook, please visit my &lt;a href=&quot;http://arnesonium.com/contact/&quot; title=&quot;Contact&quot;&gt;Contact page&lt;/a&gt;. I’m eager to hear your feedback and get suggestions and bug reports!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Prime Number Service on Google App Engine</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/prime-number-google-app-engine/" rel="alternate" type="text/html" title="Prime Number Service on Google App Engine" />
        <updated>2015-02-20T22:37:41+00:00</updated>
        <id>https://arnesonium.com/2015/02/prime-number-google-app-engine</id>
          <category term="cloud" />
        
          <category term="github" />
        
          <category term="golang" />
        
          <category term="google-cloud" />
        
          <category term="php" />
        
          <category term="plugin" />
        
          <category term="prime-numbers" />
        
          <category term="programming" />
        
          <category term="web-development" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/prime-number-google-app-engine/">&lt;p&gt;As I &lt;a href=&quot;http://arnesonium.com/2015/02/random-link-rodeo/&quot; title=&quot;Random Link Rodeo&quot;&gt;mentioned earlier this week&lt;/a&gt;, I’ve decided to learn the &lt;a href=&quot;http://golang.org/&quot; target=&quot;_blank&quot;&gt;Go programming language&lt;/a&gt;. I’ve also been very interested in Google App Engine, which lets you deploy applications to the cloud from a development sandbox. It’s like magic for web and mobile applications!
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Since I’m so fond of prime numbers, I thought I’d build a web service for calculating them. It does some other fun stuff, too, like figuring out if a number is happy. It also caches primes in the Google Cloud Datastore with some minimal statistics. If you’d like to see the source code for the prime number service, it’s &lt;a href=&quot;https://github.com/pymander/prime-json-service&quot; target=&quot;_blank&quot;&gt;available on GitHub&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The next thing I did was write the simplest of all WordPress plugins to query the service and return the latest prime number in the sequence. This all happens in a post using the [[nextprime]] shortcode. ((Including this information has the side-effect of revealing how much traffic this page gets.))&lt;/p&gt;

&lt;h1&gt;[nextprime]&lt;/h1&gt;

&lt;p&gt;You can also &lt;a href=&quot;http://sigma-crow-364.appspot.com/&quot; title=&quot;Prime Number Web App&quot; target=&quot;_blank&quot;&gt;visit the app itself&lt;/a&gt; and read about querying the service to get prime numbers for your own web page!&lt;/p&gt;

&lt;p&gt;Learning Go and writing for the Google App Engine has been really fun. I’m ready for a new challenge! If you have a web application in mind, &lt;a href=&quot;http://arnesonium.com/contact/&quot; title=&quot;Contact&quot;&gt;contact me and let’s figure out how to build it&lt;/a&gt;!&lt;/p&gt;</content>
      </entry>
    
      <entry>
        
        <title>Random Link Rodeo</title>
        <author>
          <name>Erik L. Arneson</name>
        </author>        
        <link href="https://arnesonium.com/2015/02/random-link-rodeo/" rel="alternate" type="text/html" title="Random Link Rodeo" />
        <updated>2015-02-17T16:43:32+00:00</updated>
        <id>https://arnesonium.com/2015/02/random-link-rodeo</id>
          <category term="golang" />
        
          <category term="pdx" />
        
          <category term="portland" />
        
          <category term="web-development" />
        
          <category term="wordpress" />
        <content type="html" xml:base="https://arnesonium.com/2015/02/random-link-rodeo/">&lt;p&gt;I’ve been working on a few projects, but nothing I can share publicly. However, I’ve also been out in the world of the Portland tech community, which has been excellent. If you haven’t heard of &lt;a href=&quot;http://calagator.org/&quot; target=&quot;_blank&quot;&gt;Calagator&lt;/a&gt; yet, go check it out.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Last week, I went to a meet-and-greet for developer evangelists from &lt;a href=&quot;https://cloud.google.com/&quot; target=&quot;_blank&quot;&gt;Google Cloud Platform&lt;/a&gt;. After talking to one of the Google devs, I was convinced to give &lt;a href=&quot;http://golang.org/&quot; title=&quot;The Go Language&quot; target=&quot;_blank&quot;&gt;Go&lt;/a&gt; a try. He told me that Go has type inference, and while I was dismayed to learn that it only has type inference on variable declarations, it still looks like a good language. I’m playing around with &lt;a href=&quot;http://sawsij.com/&quot; target=&quot;_blank&quot;&gt;sawsij&lt;/a&gt; and &lt;a href=&quot;https://cloud.google.com/appengine/&quot; target=&quot;_blank&quot;&gt;Google App Engine&lt;/a&gt; and should have something to share in a few weeks.&lt;/p&gt;

&lt;p&gt;Last night, I went to a &lt;a href=&quot;http://pdxwp.com/&quot; target=&quot;_blank&quot;&gt;PDX WordPress Meetup&lt;/a&gt;, where I saw Kronda Adair of &lt;a href=&quot;http://karveldigital.com/&quot; title=&quot;Karvel Digital&quot; target=&quot;_blank&quot;&gt;Karvel Digital&lt;/a&gt; give a presentation called “5 Common Website Owner Mistakes and How to Fix Them.” After the talk, there was some interesting talk about website optimization and the “noisy neighbor” problem in cloud computing.&lt;/p&gt;

&lt;p&gt;Next week, I’m looking forward to the &lt;a href=&quot;http://calagator.org/events/1250467737&quot; target=&quot;_blank&quot;&gt;PdxDevOps meeting&lt;/a&gt;, mostly because I’ve realized that this is what I do most of the time. When I build websites, I tend to handle everything from hosting and system administration through software development.&lt;/p&gt;

&lt;p&gt;I’m really impressed by how full and rich the Portland tech community is. So far I’ve met a lot of great people in it, and I look forward to meeting more.&lt;/p&gt;</content>
      </entry>
    
</feed>
