<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Laura Viglioni</title>
    <description>The latest articles on DEV Community by Laura Viglioni (@viglioni).</description>
    <link>https://dev.to/viglioni</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F352493%2F15bf79c2-3a95-4961-b197-4380e22e8d5d.jpg</url>
      <title>DEV Community: Laura Viglioni</title>
      <link>https://dev.to/viglioni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viglioni"/>
    <language>en</language>
    <item>
      <title>Writing and Testing a stdin script with TypeScript</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Tue, 31 May 2022 02:59:39 +0000</pubDate>
      <link>https://dev.to/viglioni/writing-and-testing-a-stdin-script-with-typescript-57mb</link>
      <guid>https://dev.to/viglioni/writing-and-testing-a-stdin-script-with-typescript-57mb</guid>
      <description>&lt;p&gt;Hello there, folks, how are you?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6SmS4j3yjTzeRSosRv/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6SmS4j3yjTzeRSosRv/giphy.gif" width="420" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of my motivations for writing texts here in &lt;code&gt;dev.to&lt;/code&gt; is to compile information which took me a lot of effort to find in one place.&lt;/p&gt;

&lt;p&gt;So, one of these days I was writing a small application in TypeScript that used stdin from the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-node main.ts &amp;lt; input.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything went well until I had to test it. I spent more time than I'd like trying to find out how I would test this input. I tried a lot of different stuff that I saw on the internet but only one of them worked and this is the solution I'll present in this text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/FLznxjoxTdpCxtDmiu/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/FLznxjoxTdpCxtDmiu/giphy.gif" width="480" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0Iy9d5y9XvH2qfvi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0Iy9d5y9XvH2qfvi/giphy.gif" width="480" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, an example of a script in typescript that receives stdin line by line and terminates when an empty line is entered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:readline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;stdin&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Interface&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;SomeFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someFunction&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SomeFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="cm"&gt;/*
  * Do something with `line`
  */&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// doSomething(line)&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createInterface&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please insert the data.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// reads line by line and calls someFunction(rl)(line)&lt;/span&gt;
  &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;someFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check out the &lt;a href="https://nodejs.org/api/readline.html"&gt;readline docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing the project for testing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l0Iy3RS7F2jRheg48/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l0Iy3RS7F2jRheg48/giphy.gif" width="480" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The question is: how would we test our &lt;code&gt;main&lt;/code&gt; function that only calls our &lt;code&gt;someFunction&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;If we mock &lt;code&gt;readline&lt;/code&gt;, we wouldn't be testing our app, we need to mock the stdin to get a realistic simulation of what our program is doing.&lt;/p&gt;

&lt;p&gt;For that, we will use jest. In this particular project, these are my dependencies inside &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/core"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.16.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/preset-env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.16.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@babel/preset-typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.16.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^27.0.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.3.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"babel-jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^27.4.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^27.4.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mock-stdin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.3.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other config files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// jest.config.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;clearMocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;testMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/test/**/*.spec.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// babel.config.js&lt;/span&gt;
&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;presets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;current&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}],&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/preset-typescript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// tsconfig.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commonjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moduleResolution&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;removeComments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emitDecoratorMetadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;experimentalDecorators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allowSyntheticDefaultImports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ES2019&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ES2019&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sourceMap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outDir&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incremental&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esModuleInterop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./test/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exclude&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7bu4ZLGQTSBRJIBi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7bu4ZLGQTSBRJIBi/giphy.gif" width="480" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The package that does the trick is &lt;a href="https://www.npmjs.com/package/mock-stdin"&gt;mock-stdin&lt;/a&gt; and is very simple to use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. import the lib&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mockStdin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mock-stdin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// 2. start it &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stdin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mockStdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// 3. use it&lt;/span&gt;
&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// 4. end it&lt;/span&gt;
&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of a test for our &lt;code&gt;main&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;mockStdin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mock-stdin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../src/main&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// mock console.log&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;mockStdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c1"&gt;// just a helper function to start the application&lt;/span&gt;
  &lt;span class="c1"&gt;// and mock the input&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;execute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;stdin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mockStdin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when input is valid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// something&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// another thing&lt;/span&gt;

    &lt;span class="nx"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should print the correct output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// another describe blocks&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, folks, I hope this text helps you somehow!&lt;br&gt;
Bye bye &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/iFGvqsYOKrtT8gRzkG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/iFGvqsYOKrtT8gRzkG/giphy.gif" width="480" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use masks (yes!) and use emacs &lt;br&gt;
xoxo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;covidVaccines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;takeYourShot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7btMBGqquGTVJiF2/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7btMBGqquGTVJiF2/giphy.gif" width="480" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt; Cover photo: &lt;a href="https://unsplash.com/photos/elHKkgom1VU?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditShareLink"&gt;Photo by Sigmund&lt;/a&gt; &lt;/small&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>jest</category>
    </item>
    <item>
      <title>Creating Haskell notebooks with org-mode</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Sun, 05 Sep 2021 03:30:51 +0000</pubDate>
      <link>https://dev.to/viglioni/creating-haskell-notebooks-with-org-mode-4h7</link>
      <guid>https://dev.to/viglioni/creating-haskell-notebooks-with-org-mode-4h7</guid>
      <description>&lt;h3&gt;
  
  
  If you only knew the power of the Dark Side!
&lt;/h3&gt;

&lt;p&gt;Tools like &lt;a href="https://ipython.org/notebook.html" rel="noopener noreferrer"&gt;Jupyter Notebook&lt;/a&gt; are very well known and useful, although limited to a few languages. Wouldn't it be amazing to have this power to create notebooks with any other language?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F7guVjhMF9qBKE%2Fgiphy.gif%3Fcid%3Decf05e47q37qmzwrptf00no6pjyccaigplovdcpjplwdj59x%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F7guVjhMF9qBKE%2Fgiphy.gif%3Fcid%3Decf05e47q37qmzwrptf00no6pjyccaigplovdcpjplwdj59x%26rid%3Dgiphy.gif%26ct%3Dg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this text, we will focus on doing it with Haskell, although it is virtually possible to be done using any language.&lt;/p&gt;

&lt;p&gt;Emacs has a very powerful mode called &lt;a href="https://orgmode.org/" rel="noopener noreferrer"&gt;org-mode&lt;/a&gt;, I once wrote &lt;a href="https://dev.to/viglioni/installing-latex-themes-on-your-machine-emacs-org-mode-1k9e"&gt;a text&lt;/a&gt; about using it to write presentations with &lt;a href="https://ctan.org/pkg/beamer?lang=en" rel="noopener noreferrer"&gt;beamer&lt;/a&gt;. This same mode allows us to write code snippets (&lt;strong&gt;and execute them!&lt;/strong&gt;), which is helpful to write notes/documents/presentations and export them to several formats like pdf, HTML, markdown, LaTeX and more!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/1qOFYluebBg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FY9zXpUBsE0INO%2Fgiphy.gif%3Fcid%3D790b7611eda5c9355bae7673018d1b4da33d2ce80fac8628%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FY9zXpUBsE0INO%2Fgiphy.gif%3Fcid%3D790b7611eda5c9355bae7673018d1b4da33d2ce80fac8628%26rid%3Dgiphy.gif%26ct%3Dg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your Emacs will need some packages: &lt;code&gt;org&lt;/code&gt;, &lt;code&gt;org-babel&lt;/code&gt; and &lt;code&gt;haskell-mode&lt;/code&gt;. If you use &lt;a href="http://spacemacs.org" rel="noopener noreferrer"&gt;spacemacs&lt;/a&gt; it is enough to add these layers in your &lt;code&gt;.spacemacs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="c1"&gt;;; ...&lt;/span&gt;
     &lt;span class="nv"&gt;dotspacemacs-configuration-layers&lt;/span&gt;
      &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;org&lt;/span&gt;
         &lt;span class="nv"&gt;haskell&lt;/span&gt;
         &lt;span class="c1"&gt;;; ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, you must have &lt;a href="https://downloads.haskell.org/~ghc/" rel="noopener noreferrer"&gt;GHC&lt;/a&gt; on your machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improving what we already have
&lt;/h3&gt;

&lt;p&gt;It is important to note that once you have those packages installed, Emacs already knows how to execute Haskell blocks. The motivation of this text is to compile the learning I had these last few months of how to do it better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FNsIwMll0rhfgpdQlzn%2Fgiphy.gif%3Fcid%3D790b7611531ae5c75a90d7cb9149659570d5bd1efff6f41b%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FNsIwMll0rhfgpdQlzn%2Fgiphy.gif%3Fcid%3D790b7611531ae5c75a90d7cb9149659570d5bd1efff6f41b%26rid%3Dgiphy.gif%26ct%3Dg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run a code block is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    #+begin_src &amp;lt;language name&amp;gt;
      &amp;lt;code&amp;gt;
    #+end_src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and hit &lt;code&gt;C-c C-c&lt;/code&gt;. If your Emacs knows how to compile it, it will execute the code and put the result below your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing multiline Haskell code
&lt;/h3&gt;

&lt;p&gt;The default way that &lt;code&gt;org-babel&lt;/code&gt; compiles your code is using &lt;code&gt;GHCi&lt;/code&gt;, so if you have to write a multiline code, then you need to do it as if we were inside a &lt;code&gt;GHCi&lt;/code&gt; buffer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;-- a very verbose way to sum a sequence of numbers:  &lt;/span&gt;
    &lt;span class="n"&gt;sumInts&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="n"&gt;sumInts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
        &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
        &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sumInts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sumInts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;         
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="kt"&gt;Prelude&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;i.e.&lt;/em&gt; we need to put the multiline part of the code inside &lt;code&gt;:{ :}&lt;/code&gt; and what we want to be on the output on the last line. Also, it is important to note that, since it is running inside a &lt;code&gt;GHCi&lt;/code&gt;, we will only see the result of the last call. &lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;GHCi&lt;/code&gt; commands like &lt;code&gt;:set -XDataKinds&lt;/code&gt; too :))&lt;/p&gt;

&lt;p&gt;You may be asking yourself what is that &lt;code&gt;:exports both&lt;/code&gt;. As I said earlier, we can export this &lt;code&gt;org&lt;/code&gt; file to several formats. The &lt;code&gt;:exports&lt;/code&gt; tag defines if we want to export the code, result, both or none. You can check out the other tags &lt;a href="https://orgmode.org/manual/Using-Header-Arguments.html#Using-Header-Arguments" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fun fact&lt;/strong&gt;: GitHub understands &lt;code&gt;org&lt;/code&gt; files without any manual export. You can use &lt;code&gt;org&lt;/code&gt; files to READMEs, or even to post &lt;a href="https://github.com/Viglioni/lang-studies/blob/main/learn-you-a-haskell/chapter-11.org" rel="noopener noreferrer"&gt;your notebooks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fx2Vx409.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fx2Vx409.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting the output
&lt;/h3&gt;

&lt;p&gt;As you may have noticed in the excerpt above, the output has a &lt;code&gt;Prelude&amp;gt;&lt;/code&gt; "prefix", and it might get bigger if you import other libs or executes multiline blocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Monad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="kt"&gt;Prelude&lt;/span&gt; &lt;span class="kt"&gt;Control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Monad&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt; &lt;span class="kt"&gt;Control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Monad&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt; &lt;span class="kt"&gt;Control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Monad&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Prelude&lt;/span&gt; &lt;span class="kt"&gt;Control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Monad&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;57&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FcrnWnvD4kWUAAAAC%2Fannoyed-annoying.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FcrnWnvD4kWUAAAAC%2Fannoyed-annoying.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can avoid that with the &lt;code&gt;:post&lt;/code&gt; tag. This tag executes a function, of your choice, with the output of your code block as input. To get that, we will use... Yes, another code block :D&lt;/p&gt;

&lt;p&gt;At the beginning of your code, add these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="o"&gt;#+&lt;/span&gt;&lt;span class="nv"&gt;name:&lt;/span&gt; &lt;span class="nv"&gt;org-babel-haskell-formatter&lt;/span&gt;
    &lt;span class="o"&gt;#+&lt;/span&gt;&lt;span class="nv"&gt;begin_src&lt;/span&gt; &lt;span class="nv"&gt;emacs-lisp&lt;/span&gt; &lt;span class="ss"&gt;:var&lt;/span&gt; &lt;span class="nv"&gt;strr=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="ss"&gt;:exports&lt;/span&gt; &lt;span class="nv"&gt;code&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;replace-regexp-in-string&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;rx&lt;/span&gt; &lt;span class="nv"&gt;line-start&lt;/span&gt;
                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;| alphanumeric blank "." "|&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="nb"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;")))
               "" (format "&lt;/span&gt;&lt;span class="nv"&gt;%s&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;strr&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="o"&gt;#+&lt;/span&gt;&lt;span class="nv"&gt;end_src&lt;/span&gt;      
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt; &lt;a href="https://github.com/Viglioni/laurisp/blob/main/config/org-mode-extra-configs.org" rel="noopener noreferrer"&gt;This is the file I use to store this func in my repo&lt;/a&gt; &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;For now on, on your Haskell code blocks, you add the &lt;code&gt;#+name:&lt;/code&gt; you gave to that code block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; #+begin_src haskell :exports both :post org-babel-haskell-formatter(*this*)
  &amp;lt;code&amp;gt;
 #+end_src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;e.g.&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;57&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;73&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  You might be asking yourself right now:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Will you always have to write this template on the &lt;code&gt;#+begin_src&lt;/code&gt;?
&lt;/h5&gt;

&lt;p&gt;Unfortunately, yes. My recommendation is to create a snippet to generate this Haskell block code or to create some helper function that does that for you.&lt;/p&gt;

&lt;h5&gt;
  
  
  Will you have to define the formatter function on every org file?
&lt;/h5&gt;

&lt;p&gt;No! :D&lt;/p&gt;

&lt;p&gt;You can add to your config files an org file with that function definition and import it on your Emacs initiation using the &lt;code&gt;org-babel-lob-ingest&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with-eval-after-load&lt;/span&gt; &lt;span class="s"&gt;"org"&lt;/span&gt;
      &lt;span class="c1"&gt;;; load extra configs to org mode&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;org-babel-lob-ingest&lt;/span&gt; &lt;span class="s"&gt;"~/path/to/org-config-file.org"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if you add a relative path (&lt;code&gt;./org-config-file.org&lt;/code&gt;) it might fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  A wild awesome feature appears!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FdwxrfKboa0YAAAAC%2Fdarth-vader.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FdwxrfKboa0YAAAAC%2Fdarth-vader.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the coolest stuff about using &lt;code&gt;org&lt;/code&gt; to write code snippets, even if you will not execute them, is that you can use specific modes while writing your snippet! &lt;/p&gt;

&lt;p&gt;With the cursor inside the &lt;code&gt;#+begin_src&lt;/code&gt; block, call a function &lt;code&gt;org-edit-special&lt;/code&gt; (&lt;code&gt;, '&lt;/code&gt; on spacemacs default binding), then Emacs will open a new buffer with your language mode. To exit it, hit &lt;code&gt;C-c '&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using external Haskell libs with Stack
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FvjlozeBNuwEAAAAC%2Five-been-looking-forward-to-this-dooku.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2FvjlozeBNuwEAAAAC%2Five-been-looking-forward-to-this-dooku.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one was the trickiest to me, mostly because I'm not very familiar with the &lt;a href="https://docs.haskellstack.org/en/stable/" rel="noopener noreferrer"&gt;stack&lt;/a&gt; ecosystem. Maybe this is not the best way of doing it, but this is the way that I achieved it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Stack&lt;/code&gt; has a global project by default, you can check it out on &lt;code&gt;~/.stack/global-project&lt;/code&gt;. Inside this directory, create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nv"&gt;$ &lt;/span&gt;stack new org-haskell new-template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On &lt;code&gt;~/.stack/global-project/stack.yaml&lt;/code&gt; add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;            &lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;org-haskell&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, all the libs you have imported on your &lt;code&gt;.stack/global-project/org-haskell/packages.yaml&lt;/code&gt; will be available on &lt;code&gt;stack ghci&lt;/code&gt;. For &lt;code&gt;org-babel&lt;/code&gt; to use it instead of regular &lt;code&gt;GHCi&lt;/code&gt;, set this variable on your configs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;haskell-process-type&lt;/span&gt; &lt;span class="ss"&gt;'stack-ghci&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Know the power of the Dark Side!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FxTiIzIhgJ6ZrY3cZeo%2Fgiphy.gif%3Fcid%3D790b76119c80a5db5863d2363f1ec9e44c75267bf50b1f35%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FxTiIzIhgJ6ZrY3cZeo%2Fgiphy.gif%3Fcid%3D790b76119c80a5db5863d2363f1ec9e44c75267bf50b1f35%26rid%3Dgiphy.gif%26ct%3Dg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I do hope this is helpful for you.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;org-mode&lt;/code&gt; is a &lt;strong&gt;very&lt;/strong&gt; powerful tool, I do recommend that you know it and use it!&lt;/p&gt;

&lt;p&gt;Stay safe, use masks (even if you already got your shots!) and use Emacs&lt;br&gt;
xoxo&lt;/p&gt;

&lt;p&gt;&lt;small&gt; &lt;a href="https://www.reddit.com/r/emacs/comments/lf2cfm/just_in_case_yall_were_looking_for_some_new/" rel="noopener noreferrer"&gt;The header picture&lt;/a&gt; &lt;/small&gt;&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>haskell</category>
      <category>org</category>
      <category>notebook</category>
    </item>
    <item>
      <title>Emacs as SQL client with LSP</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Mon, 22 Mar 2021 00:54:40 +0000</pubDate>
      <link>https://dev.to/viglioni/emacs-as-sql-client-with-lsp-143l</link>
      <guid>https://dev.to/viglioni/emacs-as-sql-client-with-lsp-143l</guid>
      <description>&lt;p&gt;Hello there!&lt;/p&gt;

&lt;p&gt;In this post, I show you how I configured my Emacs to be used as a SQL client using the &lt;a href="https://langserver.org/" rel="noopener noreferrer"&gt;LSP - Language Server Protocol&lt;/a&gt; :)&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/D97vDu_BhwA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;small&gt; yes I'm a light-moder now, you can judge me &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;If this is not your first time here, you probably know that I'm a &lt;a href=""&gt;Spacemacs&lt;/a&gt; user, so it will be the focus of this tutorial, although with small adaptations you will be able to use on another "Emacs distro" or vanilla Emacs :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Third party installs
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F74%2F76%2Fd9%2F7476d96990bc2c3d97a23493246107c3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.pinimg.com%2Foriginals%2F74%2F76%2Fd9%2F7476d96990bc2c3d97a23493246107c3.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to install the LSP support, the SQL linter and the SQL formatter, to do that we first need to install &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;Go&lt;/a&gt; and &lt;a href="https://www.ruby-lang.org/en/" rel="noopener noreferrer"&gt;Ruby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In macOS, you can do that by:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;ruby
brew &lt;span class="nb"&gt;install &lt;/span&gt;go


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You need to export gopath on your &lt;code&gt;.bashrc&lt;/code&gt; or similar, in my case I use &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;Oh My Zsh&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# add this line to your rc file&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/go/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="$HOME/go/bin:$PATH"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .zshrc 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we install the &lt;code&gt;SQLS&lt;/code&gt;, &lt;code&gt;sqlint&lt;/code&gt; and &lt;code&gt;sqlfmt&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

gem &lt;span class="nb"&gt;install &lt;/span&gt;sqlint
go get github.com/lighttiger2505/sqls
wget &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; - https://github.com/mjibson/sqlfmt/releases/download/v0.4.0/sqlfmt_0.4.0_darwin_amd64.tar.gz | &lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xpvzf&lt;/span&gt; - &lt;span class="nt"&gt;--directory&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/go/bin"&lt;/span&gt;
&lt;span class="c"&gt;# for other distros you can check out the releases&lt;/span&gt;
&lt;span class="c"&gt;# here: https://github.com/mjibson/sqlfmt/releases&lt;/span&gt;
&lt;span class="c"&gt;# remember to extract the files to your go path&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point if you &lt;code&gt;ls&lt;/code&gt; your &lt;code&gt;go/bin&lt;/code&gt; you should see this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/go/bin                                               
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; sqlfmt sqls


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And, of course, install &lt;code&gt;mysql&lt;/code&gt; and &lt;code&gt;psql&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;mysql
brew &lt;span class="nb"&gt;install &lt;/span&gt;libpq
brew &lt;span class="nb"&gt;link&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt; libpq


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Emacs installs
&lt;/h1&gt;

&lt;p&gt;For Spacemacs users, you must add to you &lt;code&gt;dotspacemacs-configuration-layers&lt;/code&gt; the lsp and the SQL layers:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;;; ...&lt;/span&gt;
  &lt;span class="nv"&gt;dotspacemacs-configuration-layers&lt;/span&gt;
    &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;;; ...&lt;/span&gt;
      &lt;span class="nv"&gt;lsp&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql&lt;/span&gt; &lt;span class="ss"&gt;:variables&lt;/span&gt;
           &lt;span class="nv"&gt;sql-backend&lt;/span&gt; &lt;span class="ss"&gt;'lsp&lt;/span&gt;
           &lt;span class="nv"&gt;lsp-sqls-workspace-config-path&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;;; ...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Obs.:&lt;/p&gt;

&lt;p&gt;I will explain the &lt;code&gt;lsp-sqls-workspace-config-path&lt;/code&gt; later on this text.&lt;/p&gt;

&lt;p&gt;This will work on the most recent branch of Spacemacs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For non-spacemacs users&lt;/strong&gt;, you must install &lt;code&gt;sql&lt;/code&gt; and &lt;code&gt;sql-indent&lt;/code&gt; and of course the &lt;code&gt;lsp&lt;/code&gt;, &lt;a href="https://www.emacswiki.org/emacs/SqlMode" rel="noopener noreferrer"&gt;this link might be of your interest&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final configs
&lt;/h1&gt;

&lt;p&gt;Well, now we must configure our emacs, &lt;em&gt;i.e.&lt;/em&gt; add our databases to some variables inside emacs.&lt;/p&gt;

&lt;p&gt;Your LSP will try to reach a config file on your root or project, to avoid that we set the &lt;code&gt;lsp-sqls-workspace-config-path&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;, so we can configure it on &lt;code&gt;elisp&lt;/code&gt; only, but if you prefer you can do it as &lt;br&gt;
&lt;a href="https://develop.spacemacs.org/layers/+lang/sql/README.html#external-dependencies" rel="noopener noreferrer"&gt;this doc exemplifies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have two variables now to deal: &lt;code&gt;lsp-sqls-connections&lt;/code&gt; and &lt;code&gt;sql-connection-alist&lt;/code&gt;. The first one is to give access to LSP to your db, the second to your emacs.&lt;/p&gt;

&lt;p&gt;They have the following shape:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;lsp-sqls-connections&lt;/span&gt;
    &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nv"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dataSourceName&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"yyoncho:local@tcp(localhost:3306)/foo"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"postgresql"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dataSourceName&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"host=127.0.0.1 port=5432 user=yyoncho password=local dbname=sammy sslmode=disable"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;small&gt; &lt;a href="https://emacs-lsp.github.io/lsp-mode/page/lsp-sqls/" rel="noopener noreferrer"&gt;font&lt;/a&gt; &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;sql-connection-alist&lt;/span&gt;
      &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;pool-a&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-product&lt;/span&gt; &lt;span class="ss"&gt;'mysql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-server&lt;/span&gt; &lt;span class="s"&gt;"1.2.3.4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-user&lt;/span&gt; &lt;span class="s"&gt;"me"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-password&lt;/span&gt; &lt;span class="s"&gt;"mypassword"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-database&lt;/span&gt; &lt;span class="s"&gt;"thedb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-port&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;small&gt; &lt;a href="https://stackoverflow.com/questions/5734965/how-can-i-get-emacs-sql-mode-to-use-the-mysql-config-file-my-cnf" rel="noopener noreferrer"&gt;font&lt;/a&gt; &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Buuuuut there are some issues. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2Fb902b70c387295173375fc54f22b5d0f%2Ftenor.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2Fb902b70c387295173375fc54f22b5d0f%2Ftenor.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might have noticed that the form of &lt;code&gt;dataSourceName&lt;/code&gt; is different if you are using &lt;code&gt;mysql&lt;/code&gt; or &lt;code&gt;postgres&lt;/code&gt; and there is a strange issue that emacs always asks for password on &lt;code&gt;postgres&lt;/code&gt; databases even when you pass it to &lt;code&gt;sql-connection-alist&lt;/code&gt;, the solution is to pass the full uri to the database variable.&lt;/p&gt;

&lt;p&gt;But don't worry, I've got your back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2FiGHbjYrUftITS%2Fgiphy.gif%3Fcid%3D82a1493b2j6tz0v1kvq81a6nxqezcjo96f8cknfug16e4ygu%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2FiGHbjYrUftITS%2Fgiphy.gif%3Fcid%3D82a1493b2j6tz0v1kvq81a6nxqezcjo96f8cknfug16e4ygu%26rid%3Dgiphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Macros making your life easier
&lt;/h1&gt;

&lt;p&gt;What if we could do this?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-add-mysql-db&lt;/span&gt;
 &lt;span class="nv"&gt;your-db-name&lt;/span&gt;
 &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;
 &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;
 &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="s"&gt;"dbhost"&lt;/span&gt;
 &lt;span class="ss"&gt;:database&lt;/span&gt; &lt;span class="s"&gt;"dbname"&lt;/span&gt;
 &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="s"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-add-postgress-db&lt;/span&gt;
 &lt;span class="nv"&gt;your-db-name&lt;/span&gt;
 &lt;span class="ss"&gt;:port&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;
 &lt;span class="ss"&gt;:user&lt;/span&gt; &lt;span class="s"&gt;"username"&lt;/span&gt;
 &lt;span class="ss"&gt;:host&lt;/span&gt; &lt;span class="s"&gt;"dbhost"&lt;/span&gt;
 &lt;span class="ss"&gt;:database&lt;/span&gt; &lt;span class="s"&gt;"dbname"&lt;/span&gt;
 &lt;span class="ss"&gt;:password&lt;/span&gt; &lt;span class="s"&gt;"mysql"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add these next functions and macros to your emacs config and you will be able to do that ;D&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;any-nil?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&amp;amp;rest&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;and&lt;/span&gt; &lt;span class="o"&gt;,@&lt;/span&gt;&lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;throw-if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;condition&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;error-description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;"if condition is true, thrown an error"&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;error-description&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Variables related to sql configs&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;lsp-sqls-connections&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;sql-connection-alist&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;format-postgres-sqls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"host=%s port=%s user=%s password=%s dbname=%s"&lt;/span&gt;
          &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;format-mysql-sqls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"%s:%s@tcp(%s:%s)/%s"&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;format-postgres-uri&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"postgresql://%s:%s@%s:%s/%s"&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;add-to-sqls-connections&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;db-type&lt;/span&gt; &lt;span class="nv"&gt;data-src-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'lsp-sqls-connections&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="ss"&gt;'driver&lt;/span&gt; &lt;span class="nv"&gt;db-type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="ss"&gt;'dataSourceName&lt;/span&gt; &lt;span class="nv"&gt;data-src-name&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;add-to-sql-conection-alist&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;db-type&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'sql-connection-alist&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-product&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;db-type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-user&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-server&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-port&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-password&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="ss"&gt;'sql-database&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;sql-add-postgres-db&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;rest&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;"Adds a mysql database to emacs and lsp
   This macro expects a name to the database and a p-list of parameters
   :port, :user, :password, :database, :host
   The only optional is :port, its default value is 5432
   e.g.:
   (sql-add-postgres-db
        my-db-name ;; notice that there are no quotes here
        :port 1234
        :user \"username\"
        :host \"my-host\"
        :database \"my-db\"
        :password \"mypassword\")"&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:host&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:database&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;throw-if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;any-nil?&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="s"&gt;"there are info missing!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;full-uri&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format-postgres-uri&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;data-src-name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format-postgres-sqls&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-sqls-connections&lt;/span&gt; &lt;span class="s"&gt;"postgresql"&lt;/span&gt; &lt;span class="nv"&gt;data-src-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-sql-conection-alist&lt;/span&gt; &lt;span class="ss"&gt;'postgres&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;full-uri&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;;;###autoload&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;sql-add-mysql-db&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;rest&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;"Adds a mysql database to emacs and lsp
   This macro expects a name to the database and a p-list of parameters
   :port, :user, :password, :database, :host
   The only optional is :port, its default value is 3306
   e.g.:
   (sql-add-mysql-db
        my-db-name ;; notice that there are no quotes here
        :port 1234
        :user \"username\"
        :host \"my-host\"
        :database \"my-db\"
        :password \"mypassword\")"&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:host&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;db-info&lt;/span&gt; &lt;span class="ss"&gt;:database&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;throw-if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;any-nil?&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="s"&gt;"there are info missing!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-sqls-connections&lt;/span&gt; &lt;span class="s"&gt;"mysql"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format-mysql-sqls&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-sql-conection-alist&lt;/span&gt; &lt;span class="ss"&gt;'mysql&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="o"&gt;```&lt;/span&gt;

&lt;span class="nv"&gt;Those&lt;/span&gt; &lt;span class="nv"&gt;are&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;[elisp&lt;/span&gt; &lt;span class="nv"&gt;repo]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;https://github.com/Viglioni/laurisp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;And&lt;/span&gt; &lt;span class="nv"&gt;that&lt;/span&gt;&lt;span class="ss"&gt;'s&lt;/span&gt; &lt;span class="nv"&gt;it!&lt;/span&gt;
&lt;span class="nv"&gt;With&lt;/span&gt; &lt;span class="nv"&gt;all&lt;/span&gt; &lt;span class="nv"&gt;these&lt;/span&gt; &lt;span class="nv"&gt;configs&lt;/span&gt; &lt;span class="nv"&gt;you&lt;/span&gt; &lt;span class="nv"&gt;can&lt;/span&gt; &lt;span class="nv"&gt;now&lt;/span&gt; &lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;your&lt;/span&gt; &lt;span class="nv"&gt;Emacs&lt;/span&gt; &lt;span class="nv"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;SQL&lt;/span&gt; &lt;span class="nv"&gt;client&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;linter,&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;backend&lt;/span&gt; &lt;span class="nb"&gt;and&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nb"&gt;formatter&lt;/span&gt; &lt;span class="err"&gt;:))&lt;/span&gt;

&lt;span class="nv"&gt;Stay&lt;/span&gt; &lt;span class="nv"&gt;safe,&lt;/span&gt; &lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;masks&lt;/span&gt; &lt;span class="nb"&gt;and&lt;/span&gt; &lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="nv"&gt;Emacs&lt;/span&gt;
&lt;span class="nv"&gt;xoxo&lt;/span&gt;

&lt;span class="nv"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="nv"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://i.imgur.com/HL9QRRz.gif"&lt;/span&gt;&lt;span class="nv"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nv"&gt;edits&lt;/span&gt;
&lt;span class="nb"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;there&lt;/span&gt; &lt;span class="nv"&gt;was&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nb"&gt;error&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;sql-add-postgres-db&lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;```&lt;/span&gt;&lt;span class="nv"&gt;lisp&lt;/span&gt;
&lt;span class="c1"&gt;;; wrong&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;data-src-name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format-postgres-uri&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;;; correct&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;data-src-name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;format-postgres-sqls&lt;/span&gt; &lt;span class="nv"&gt;host&lt;/span&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;```&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>sql</category>
      <category>emacs</category>
      <category>lsp</category>
      <category>database</category>
    </item>
    <item>
      <title>Mocking dependencies with Jest + TypeScript</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Sat, 23 Jan 2021 02:49:49 +0000</pubDate>
      <link>https://dev.to/viglioni/mocking-dependencies-with-jest-typescript-12im</link>
      <guid>https://dev.to/viglioni/mocking-dependencies-with-jest-typescript-12im</guid>
      <description>&lt;p&gt;Once I've heard a phrase that was something like &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Pure applications can only heat machines&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And well... It that is true. In real life, some parts of our application need to have contact with the external world, to be impure, and testing them might be tricky.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a href="https://www.braveclojure.com/functional-programming/#Pure_Functions__What_and_Why" rel="noopener noreferrer"&gt;wait, what are (im)pure functions and side effects?&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2Ff51320411362b0c51166a3b0932eb73f%2Ftenor.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.tenor.com%2Fimages%2Ff51320411362b0c51166a3b0932eb73f%2Ftenor.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Context
&lt;/h1&gt;

&lt;p&gt;One common use is setting up &lt;a href="https://launchdarkly.com/features/feature-flags/" rel="noopener noreferrer"&gt;feature flags&lt;/a&gt; for your application. Imagine you have the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myInpureFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFlag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flagName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this aplication is flagged&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;this application is not flagged&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you need to test it, after all, you must guarantee your feature flag is behaving as you expected in your project. The problem is: we need to mock this &lt;code&gt;getFlag&lt;/code&gt; function and what happens when its value changes. &lt;/p&gt;

&lt;p&gt;Well... What is the problem, then?&lt;/p&gt;

&lt;p&gt;The usual way of mocking functions/modules are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.spec.ts&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getFlag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// or false or any other value&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we have two contexts to cover with tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.spec.ts&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when feature flag is on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...})&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when feature flag is off&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we need to change the &lt;code&gt;getFlag&lt;/code&gt; mock.&lt;/p&gt;

&lt;p&gt;In JavaScript, we can implement solutions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.spec.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when feature flag is on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getFlag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using &lt;code&gt;mockImplementation&lt;/code&gt; but none of these is allowed in TypeScript. &lt;/p&gt;

&lt;p&gt;I've been across similar solutions like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.spec.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when feature flag is on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFlag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But TypeScript won't allow this either.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT9DPtspqPm33VRnTa/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT9DPtspqPm33VRnTa/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;There is a way.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you ever head the tragedy of &lt;strong&gt;&lt;em&gt;Type Assertion&lt;/em&gt;&lt;/strong&gt; the wise?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l3diT8stVH9qImalO/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l3diT8stVH9qImalO/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a very intuitive solution, in my opinion, but once you see it, is easy to understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file.spec.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getFlag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-lib/flags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;when feature flag is on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getFlag&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValueOnce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asserting our name &lt;code&gt;getFlag&lt;/code&gt; to &lt;code&gt;jest.Mock&lt;/code&gt; type will allow us to use jest mock functions like &lt;code&gt;mockReturnValueOnce&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In this case, any test inside this &lt;code&gt;describe&lt;/code&gt; will use the &lt;code&gt;true&lt;/code&gt; value from our mock, I think putting it inside a &lt;code&gt;beforeEach&lt;/code&gt; block gives us more control and readability of what is happening, but you can put it inside an &lt;code&gt;it&lt;/code&gt; block too. &lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;mockReturnValueOnce&lt;/code&gt; instead of mocking implementation or return is a good practice because its changes will not affect any other test, be &lt;strong&gt;very careful with tests' side effects&lt;/strong&gt;, they can lead you to trouble finding why sometimes your tests' suits pass and sometimes don't.&lt;/p&gt;

&lt;p&gt;Well,&lt;/p&gt;

&lt;p&gt;I do hope this is useful to you :)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/VZCFpF6sUyoG6l5SrY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/VZCFpF6sUyoG6l5SrY/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Be safe, stay home, use masks and use Emacs (&lt;em&gt;even though this is not an Emacs text haha&lt;/em&gt;)&lt;br&gt;
Xoxo&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>jest</category>
      <category>testing</category>
    </item>
    <item>
      <title>Installing LaTeX themes on your machine/Emacs org-mode</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Thu, 21 Jan 2021 01:18:44 +0000</pubDate>
      <link>https://dev.to/viglioni/installing-latex-themes-on-your-machine-emacs-org-mode-1k9e</link>
      <guid>https://dev.to/viglioni/installing-latex-themes-on-your-machine-emacs-org-mode-1k9e</guid>
      <description>&lt;p&gt;For those who need to write academic presentations, it is very common to make use of LaTeX. If you majored computer science you have probably seen a lecture like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcdszcwif1couvql0c3w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcdszcwif1couvql0c3w4.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fits6k79h8ggv6ai7usw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fits6k79h8ggv6ai7usw9.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of these presentations are created with &lt;a href="https://ctan.org/pkg/beamer?lang=en" rel="noopener noreferrer"&gt;beamer&lt;/a&gt; and its &lt;a href="https://deic-web.uab.cat/~iblanes/beamer_gallery/index_by_theme.html" rel="noopener noreferrer"&gt;default themes&lt;/a&gt;, although beamer is very handy, these themes are a little bit old-fashioned. We can use modern custom themes like &lt;a href="https://github.com/matze/mtheme" rel="noopener noreferrer"&gt;metropolis&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxya3tlh5mdcg2hncn3e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxya3tlh5mdcg2hncn3e7.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  My org-mode code
&lt;/h1&gt;

&lt;p&gt;I use &lt;a href="https://orgmode.org/" rel="noopener noreferrer"&gt;org-mode&lt;/a&gt; to do most of my writing, that includes presentations, articles, personal notes etc. &lt;code&gt;Org-mode&lt;/code&gt; can interpret LaTeX (and code blocks of a wide range of languages), but talking about &lt;code&gt;org-mode&lt;/code&gt; is not the point of this text... (&lt;em&gt;or is it?&lt;/em&gt; 👀)&lt;/p&gt;

&lt;p&gt;The presentation example above was created with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#+options: H:3 email:nil tex:t toc:t
#+title: Any Computer Science Class
#+date: \today
#+author: Laura Viglioni
#+language: en
#+creator: Emacs 27.1 (Org mode 9.4)
#+startup: beamer
#+LaTeX_CLASS: beamer
#+LaTeX_CLASS_OPTIONS: [bigger]
#+beamer_theme: Copenhagen


* Graph theory
** Nodes and vertices
*** 
** BFS 
*** 
** DFS
*** 
* Algorithm Complexity
** Big O notation
*** 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiling that (&lt;code&gt;M-x org-beamer-export-to-pdf&lt;/code&gt; or &lt;code&gt;C-c C-e l P&lt;/code&gt;) will generate the first pdf shown in this text. &lt;code&gt;Org-mode&lt;/code&gt; convert this to a LaTeX file and compiles it, in this example it the &lt;code&gt;.tex&lt;/code&gt; generated is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="c"&gt;% Created 2021-01-20 Wed 21:22&lt;/span&gt;
&lt;span class="c"&gt;% Intended LaTeX compiler: pdflatex&lt;/span&gt;
&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="na"&gt;[bigger]&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;beamer&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="na"&gt;[utf8]&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;inputenc&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="na"&gt;[T1]&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;fontenc&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;graphicx&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;grffile&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;longtable&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;wrapfig&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;rotating&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="na"&gt;[normalem]&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;ulem&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;amsmath&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;textcomp&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;amssymb&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;capt-of&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;hyperref&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\usetheme&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Copenhagen&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\author&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Laura Viglioni&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\date&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\today&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\title&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Any Computer Science Class&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\hypersetup&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 pdfauthor=&lt;span class="p"&gt;{&lt;/span&gt;Laura Viglioni&lt;span class="p"&gt;}&lt;/span&gt;,
 pdftitle=&lt;span class="p"&gt;{&lt;/span&gt;Any Computer Science Class&lt;span class="p"&gt;}&lt;/span&gt;,
 pdfkeywords=&lt;span class="p"&gt;{}&lt;/span&gt;,
 pdfsubject=&lt;span class="p"&gt;{}&lt;/span&gt;,
 pdfcreator=&lt;span class="p"&gt;{&lt;/span&gt;Emacs 27.1 (Org mode 9.4)&lt;span class="p"&gt;}&lt;/span&gt;, 
 pdflang=&lt;span class="p"&gt;{&lt;/span&gt;Portuguese&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="nt"&gt;\begin{document}&lt;/span&gt;

&lt;span class="k"&gt;\maketitle&lt;/span&gt;
&lt;span class="nt"&gt;\begin{frame}&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Outline&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\tableofcontents&lt;/span&gt;
&lt;span class="nt"&gt;\end{frame}&lt;/span&gt;

&lt;span class="k"&gt;\section&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Graph theory&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:org391ab7d&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\subsection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Nodes and vertices&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:org334895a&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;\begin{frame}&lt;/span&gt;[label=&lt;span class="p"&gt;{&lt;/span&gt;sec:org5882936&lt;span class="p"&gt;}&lt;/span&gt;]&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;\end{frame}&lt;/span&gt;

&lt;span class="k"&gt;\subsection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;BFS&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:orge68a1c6&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;\begin{frame}&lt;/span&gt;[label=&lt;span class="p"&gt;{&lt;/span&gt;sec:orgba23b2e&lt;span class="p"&gt;}&lt;/span&gt;]&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;\end{frame}&lt;/span&gt;

&lt;span class="k"&gt;\subsection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;DFS&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:orgc3fd777&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;\begin{frame}&lt;/span&gt;[label=&lt;span class="p"&gt;{&lt;/span&gt;sec:orgf5f342e&lt;span class="p"&gt;}&lt;/span&gt;]&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;\end{frame}&lt;/span&gt;

&lt;span class="k"&gt;\section&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Algorithm Complexity&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:org5501e0f&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\subsection&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Big O notation&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\label&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;sec:orgbe99555&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;\begin{frame}&lt;/span&gt;[label=&lt;span class="p"&gt;{&lt;/span&gt;sec:orgb18e2bf&lt;span class="p"&gt;}&lt;/span&gt;]&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;\end{frame}&lt;/span&gt;
&lt;span class="nt"&gt;\end{document}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;sup&gt; &lt;em&gt;woa... a little bit verbose compared to org, huh&lt;/em&gt; 👀&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;But the most important lines for this text are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#+beamer_theme: Copenhagen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or &lt;br&gt;
&lt;sup&gt; &lt;em&gt;aren't you convinced to use org at this point?&lt;/em&gt; 😨&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="k"&gt;\usetheme&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;Copenhagen&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to use custom themes, as we can read on &lt;a href="https://github.com/matze/mtheme/blob/master/README.md" rel="noopener noreferrer"&gt;metropolis documentation&lt;/a&gt;, we must compile the project and put the &lt;code&gt;.sty&lt;/code&gt; files in the same directory as our &lt;code&gt;.tex&lt;/code&gt; or &lt;code&gt;.org&lt;/code&gt; that is calling the theme and change it from &lt;code&gt;Copenhagen&lt;/code&gt; to &lt;code&gt;metropolis&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But how to install themes on your system and use them without copying and pasting the &lt;code&gt;.sty&lt;/code&gt; files every time?&lt;/p&gt;

&lt;h1&gt;
  
  
  Installing LaTeX themes to your machine/Emacs
&lt;/h1&gt;

&lt;p&gt;First, you need to know where your system (or Emacs) looks for LaTeX files, including the styles (&lt;code&gt;.sty&lt;/code&gt;) ones. The easiest way I know is using the command &lt;a href="https://linux.die.net/man/1/kpsewhich" rel="noopener noreferrer"&gt;kpsewhich&lt;/a&gt; － &lt;em&gt;if you are a mac user, it comes in MacTex package :)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kpsewhich &lt;span class="nt"&gt;-var-value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;TEXMFHOME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case it returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/Users/laura.viglioni/spacemacs/Library/texmf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you must create this dir, if it doesn't exist, and paste the &lt;code&gt;.sty&lt;/code&gt; files in there and that's it, as simple as that :)&lt;/p&gt;

&lt;p&gt;I hope this might be useful to you :)&lt;/p&gt;

&lt;p&gt;Be safe, use masks and use Emacs&lt;br&gt;
Xoxo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/7yojoQtevjOCI/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/7yojoQtevjOCI/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS.: If you want to know more about &lt;code&gt;org-mode&lt;/code&gt;, checkout these videos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=34zODp_lhqg&amp;amp;t=1153s" rel="noopener noreferrer"&gt;Org Mode Basics In Doom Emacs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Ea_-TaEGa7Y&amp;amp;ab_channel=DistroTube" rel="noopener noreferrer"&gt;Boost Productivity With Emacs, Org Mode and Org Agenda&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>latex</category>
      <category>emacs</category>
      <category>orgmode</category>
      <category>beamer</category>
    </item>
    <item>
      <title>How to use CMD as a leader key on Spacemacs</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Sun, 17 Jan 2021 01:34:55 +0000</pubDate>
      <link>https://dev.to/viglioni/how-to-use-cmd-as-a-leader-key-on-spacemacs-3281</link>
      <guid>https://dev.to/viglioni/how-to-use-cmd-as-a-leader-key-on-spacemacs-3281</guid>
      <description>&lt;p&gt;Okay... Maybe the title was a little bit of a clickbait, although it is indeed possible to do that, there is a price...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT9IgDk29h0Vye0jAs/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT9IgDk29h0Vye0jAs/giphy.gif" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The problem
&lt;/h1&gt;

&lt;p&gt;In Spacemacs or Emacs, in general, is not possible to bind commands or anything to a &lt;strong&gt;modifier key&lt;/strong&gt; alone like &lt;em&gt;meta&lt;/em&gt;, &lt;em&gt;control&lt;/em&gt;, &lt;em&gt;super&lt;/em&gt;, &lt;em&gt;shift&lt;/em&gt;, &lt;em&gt;command (macOS)&lt;/em&gt; etc and sometimes is very useful to bind that one button you barely use to some important functionality.&lt;/p&gt;

&lt;p&gt;In my case I use Spacemacs, there are two very important commands I use a lot:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;M-m&lt;/code&gt;: the leader key, i.e., the key that opens the default spacemacs menu, &lt;code&gt;SPC&lt;/code&gt; if you use... the &lt;em&gt;evil mode&lt;/em&gt; urgh... &lt;br&gt;
And&lt;br&gt;
&lt;code&gt;C-M-m&lt;/code&gt; or &lt;code&gt;M-m m&lt;/code&gt;: the major mode leader key, that opens the major mode menu, in &lt;em&gt;evil mode&lt;/em&gt; the default binding is &lt;code&gt;,&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can't normally bind these functionalities to modifier keys, you can bind &lt;code&gt;M-[something]&lt;/code&gt;, but not &lt;code&gt;M-&lt;/code&gt; alone, but there is a way around...&lt;/p&gt;
&lt;h1&gt;
  
  
  The trick
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o75271dzgbEbQKFe8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o75271dzgbEbQKFe8/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some hours suffering from this problem, I've come to a solution I've found &lt;a href="https://emacs.stackexchange.com/questions/21892/bind-a-modifier-key-like-right-shift-to-a-command"&gt;here&lt;/a&gt;. If you can't bind something to a modifier key, change that key so it will not be a modifier key anymore...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l3vR84p7VZfRSx8kg/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l3vR84p7VZfRSx8kg/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can bind in your system that key, in my case, &lt;code&gt;right-cmd&lt;/code&gt; and &lt;code&gt;right-option&lt;/code&gt;, to unused keys like &lt;code&gt;f19&lt;/code&gt; and &lt;code&gt;f17&lt;/code&gt;. You can do it with software like &lt;a href="https://wiki.archlinux.org/index.php/xmodmap"&gt;xmodmap for GNU/Linux&lt;/a&gt; or &lt;a href="https://pqrs.org/osx/karabiner/"&gt;karabiner for macOS&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Example with Karabiner
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7TscSTTi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/badkygvq54lbs58kzqxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7TscSTTi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/badkygvq54lbs58kzqxt.png" alt="Karabiner print" width="880" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've switched my &lt;code&gt;right-cmd&lt;/code&gt; and &lt;code&gt;right-option&lt;/code&gt; to &lt;code&gt;f19&lt;/code&gt; and &lt;code&gt;f17&lt;/code&gt;. It's not the point of this text, but I &lt;strong&gt;really&lt;/strong&gt; recommend that anyone who codes to switch &lt;code&gt;capslock&lt;/code&gt; with &lt;code&gt;control&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my &lt;code&gt;.spacemacs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;dotspacemacs/init&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;;; ...&lt;/span&gt;
  &lt;span class="nv"&gt;dotspacemacs-emacs-leader-key&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;f19&amp;gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;;; ...&lt;/span&gt;
  &lt;span class="nv"&gt;dotspacemacs-major-mode-emacs-leader-key&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;f17&amp;gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;;; ...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can access these two menus with one key :)&lt;/p&gt;

&lt;h4&gt;
  
  
  The leader key:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_roaKsUT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z78oyeneetoiy1tym57c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_roaKsUT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z78oyeneetoiy1tym57c.png" alt="leader key example" width="880" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The major mode leader key, in this case in &lt;code&gt;org-mode&lt;/code&gt;:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AFZWdpbK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rxtzzb9kpymh0ezf8zy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AFZWdpbK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rxtzzb9kpymh0ezf8zy4.png" alt="major mode leader key example" width="880" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One might say that in &lt;em&gt;evil mode&lt;/em&gt; I'd have access to those menus in one key but you have to leave editing mode to do that, so it would cost you more than one key to achieve that.&lt;/p&gt;

&lt;h1&gt;
  
  
  The price
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l4KhTT9w5LlsOWxVu/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4KhTT9w5LlsOWxVu/giphy.gif" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only problem with this trick is that while in Emacs or not, you've lost those keys on your keyboard, or at least if you don't add any new binds using those &lt;code&gt;f17&lt;/code&gt; or &lt;code&gt;f19&lt;/code&gt; keys.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;These changes improved a lot my life while I'm coding, what used to take me three keys to do I do in just one, and these are two of my most used shortcuts, it is not called &lt;em&gt;leader key&lt;/em&gt; for nothing... haha.&lt;/p&gt;

&lt;p&gt;I hope that it can help some of you as well :)&lt;/p&gt;

&lt;p&gt;Be safe, use masks and use Emacs&lt;br&gt;
Xoxo &lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;a href="https://www.pexels.com/photo/close-up-photo-of-vintage-typewriter-1425146/"&gt;Credits for the header picture&lt;/a&gt;&lt;/small&gt;&lt;br&gt;
&lt;small&gt; The gifs here are from &lt;a href="https://en.wikipedia.org/wiki/Lucifer_(TV_series)"&gt;Lucifer TV series&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>emacs</category>
    </item>
    <item>
      <title>How I set up my emacs for TypeScript + React</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Sun, 11 Oct 2020 20:32:51 +0000</pubDate>
      <link>https://dev.to/viglioni/how-i-set-up-my-emacs-for-typescript-3eeh</link>
      <guid>https://dev.to/viglioni/how-i-set-up-my-emacs-for-typescript-3eeh</guid>
      <description>&lt;h1&gt;
  
  
  What exactly is my point here?
&lt;/h1&gt;

&lt;p&gt;I recently knew typescript and with it, some joy and some tears. For a very long time, I've been working with React and using an emacs mode called &lt;a href="https://github.com/felipeochoa/rjsx-mode" rel="noopener noreferrer"&gt;rjsx-mode&lt;/a&gt; and I always loved it, I think this is a mode so good I use it even with regular JavaScript files.&lt;/p&gt;

&lt;p&gt;Then I started with TypeScript and I was both amazed and saddened by it. For regular TS files, &lt;code&gt;.ts&lt;/code&gt; it was amazing. The spacemacs &lt;a href="https://develop.spacemacs.org/layers/+lang/typescript/README.html" rel="noopener noreferrer"&gt;typescript-mode&lt;/a&gt; was even better than &lt;code&gt;rjsx-mode&lt;/code&gt;, all the types are shown perfectly in the bottom bar, autocomplete, auto-import... Everything. And thanks to &lt;a href="https://github.com/ananthakumaran/tide" rel="noopener noreferrer"&gt;tide&lt;/a&gt;. The sad part is: there is no &lt;code&gt;tsx-mode&lt;/code&gt;, to write our &lt;code&gt;.tsx&lt;/code&gt; files, we have to use &lt;a href="http://web-mode.org/" rel="noopener noreferrer"&gt;web-mode&lt;/a&gt;. Don't get me wrong, this is a great mode, but &lt;code&gt;React + Typescript&lt;/code&gt; were not the goals back then.&lt;/p&gt;

&lt;p&gt;My point here is to put the best parts of all three modes in all of them!&lt;/p&gt;

&lt;p&gt;This text might be a little long, but I hope it will help :)&lt;/p&gt;

&lt;p&gt;Here my configs in practice:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Q29ZhIYe6iY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An important point here: I use nowadays &lt;a href="https://www.spacemacs.org/" rel="noopener noreferrer"&gt;spacemacs&lt;/a&gt; and part of my code examples here will be in its way of doing things, but there is no magic, spacemacs is just emacs with some already written extra lisp (haha). You will be able to do it in your other emacs. But I &lt;strong&gt;really&lt;/strong&gt; recommend you to start with spacemacs, especially if you are new to emacs. Changed my life, but this is a theme for another text.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Let's get started
&lt;/h1&gt;

&lt;p&gt;You must have some modes installed. If you are using spacemacs most of them will be installed automatically when you install the layers. Those packages are:&lt;br&gt;
&lt;code&gt;rjsx-mode&lt;/code&gt;, &lt;code&gt;typescript-mode&lt;/code&gt;, &lt;code&gt;web-mode&lt;/code&gt;, &lt;code&gt;tide&lt;/code&gt;, &lt;code&gt;company&lt;/code&gt;, &lt;code&gt;yasnippet&lt;/code&gt;, &lt;code&gt;prettier-js&lt;/code&gt; (sorry if I forgot to list some pkg here)&lt;/p&gt;

&lt;p&gt;Or in a simpler way, on your &lt;code&gt;.spacemacs&lt;/code&gt; file add these layers on &lt;code&gt;dotspacemacs-configuration-layers&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;dotspacemacs/layers&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;;; ... &lt;/span&gt;
  &lt;span class="nv"&gt;dotspacemacs-configuration-layers&lt;/span&gt;
   &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="nv"&gt;html&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;typescript&lt;/span&gt; &lt;span class="ss"&gt;:variables&lt;/span&gt;
                 &lt;span class="nv"&gt;javascript-backend&lt;/span&gt; &lt;span class="ss"&gt;'tide&lt;/span&gt;
                 &lt;span class="nv"&gt;typescript-fmt-tool&lt;/span&gt; &lt;span class="ss"&gt;'prettier&lt;/span&gt;
                 &lt;span class="nv"&gt;typescript-linter&lt;/span&gt; &lt;span class="ss"&gt;'eslint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;javascript&lt;/span&gt; &lt;span class="ss"&gt;:variables&lt;/span&gt;
                 &lt;span class="nv"&gt;javascript-backend&lt;/span&gt; &lt;span class="ss"&gt;'tide&lt;/span&gt;
                 &lt;span class="nv"&gt;javascript-fmt-tool&lt;/span&gt; &lt;span class="ss"&gt;'prettier&lt;/span&gt;
                 &lt;span class="nv"&gt;node-add-modules-path&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="c1"&gt;;; ...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;see &lt;a href="https://develop.spacemacs.org/layers/+lang/typescript/README.html" rel="noopener noreferrer"&gt;typescript layer&lt;/a&gt;, &lt;a href="https://develop.spacemacs.org/layers/+lang/javascript/README.html" rel="noopener noreferrer"&gt;javascript layer&lt;/a&gt;, &lt;a href="https://develop.spacemacs.org/layers/+lang/html/README.html#prettier" rel="noopener noreferrer"&gt;html layer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and on &lt;code&gt;dotspacemacs-additional-packages&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="c1"&gt;;; ...&lt;/span&gt;
 &lt;span class="nv"&gt;dotspacemacs-additional-packages&lt;/span&gt;
   &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="nv"&gt;rjsx-mode&lt;/span&gt;
     &lt;span class="nv"&gt;yasnippet-snippets&lt;/span&gt;
     &lt;span class="nv"&gt;prettier-js&lt;/span&gt;
     &lt;span class="c1"&gt;;; ...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Some of these imports require you to install third-party libs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm i &lt;span class="nt"&gt;-g&lt;/span&gt; tern prettier


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you are not using spacemacs, you must to require each package on your &lt;code&gt;.emacs&lt;/code&gt; file. All the GitHub pages of these modes have clear instructions for the installation :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Applying &lt;code&gt;tide&lt;/code&gt; to &lt;code&gt;rjsx&lt;/code&gt; and &lt;code&gt;web&lt;/code&gt; modes
&lt;/h1&gt;

&lt;p&gt;The basics configs are done, we have all the three modes installed and working, what now? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ananthakumaran/tide" rel="noopener noreferrer"&gt;Tide&lt;/a&gt; is a great mode that does a lot of magic for you, I'd recommend you to read its README. It runs automatically on &lt;code&gt;typescript-mode&lt;/code&gt; and it would be great to use it on your other &lt;code&gt;js/ts&lt;/code&gt; modes.&lt;/p&gt;

&lt;p&gt;I have all my config files separated and import them in &lt;code&gt;dotspacemacs/user-config&lt;/code&gt;, but you can put all these extra configs directly on this section or on your &lt;code&gt;.emacs&lt;/code&gt; file if you're not using spacemacs.&lt;/p&gt;

&lt;p&gt;First, we define a tide function config, later apply it on all those modes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;dotspacemacs/user-config&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="c1"&gt;;; ...&lt;/span&gt;
 &lt;span class="c1"&gt;;; tide def func:&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;tide-setup-hook&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tide-setup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;eldoc-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tide-hl-identifier-mode&lt;/span&gt; &lt;span class="mi"&gt;+1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;web-mode-enable-auto-quoting&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;web-mode-markup-indent-offset&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;web-mode-code-indent-offset&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;web-mode-attr-indent-offset&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;web-mode-attr-value-indent-offset&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;lsp-eslint-server-command&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"node"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;getenv&lt;/span&gt; &lt;span class="s"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"/var/src/vscode-eslint/server/out/eslintServer.js"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"--stdio"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-local-variable&lt;/span&gt; &lt;span class="ss"&gt;'company-backends&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;company-tide&lt;/span&gt; &lt;span class="nv"&gt;company-files&lt;/span&gt; &lt;span class="ss"&gt;:with&lt;/span&gt; &lt;span class="nv"&gt;company-yasnippet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-dabbrev-code&lt;/span&gt; &lt;span class="nv"&gt;company-dabbrev&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; hooks&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'before-save-hook&lt;/span&gt; &lt;span class="ss"&gt;'tide-format-before-save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;;; use rjsx-mode for .js* files except json and use tide with rjsx&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'auto-mode-alist&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\.js.*$"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;rjsx-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'auto-mode-alist&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\.json$"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;json-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'rjsx-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'tide-setup-hook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;;; web-mode extra config&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'web-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'tide-setup-hook&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;pcase&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-extension&lt;/span&gt; &lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tsx"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;'tide-setup-hook&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;my-web-mode-hook&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;flycheck-add-mode&lt;/span&gt; &lt;span class="ss"&gt;'typescript-tslint&lt;/span&gt; &lt;span class="ss"&gt;'web-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'web-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'company-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'web-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'prettier-js-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'web-mode-hook&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;turn-on-smartparens-mode&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="c1"&gt;;; ...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;These last lines add our tide setup for &lt;code&gt;.tsx&lt;/code&gt; files and some other sub-modules that already exists in the other two modes.&lt;/p&gt;

&lt;p&gt;Also, I recommend using these modes globally:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="c1"&gt;;; yasnippet&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;yas-global-mode&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; flycheck&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-flycheck-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'after-init-hook&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;global-flycheck-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; company-mode &lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-company-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Using &lt;code&gt;rjsx&lt;/code&gt; snippets on all three modes
&lt;/h1&gt;

&lt;p&gt;The one thing &lt;code&gt;rjsx-mode&lt;/code&gt; has better than the other two modes is its snippets, so let's use it everywhere :)&lt;/p&gt;

&lt;p&gt;There are two ways here, the first you can find on your &lt;code&gt;.emacs.d&lt;/code&gt; where is the default dir for snippets configs (on spacemacs is &lt;code&gt;.emacs.d/layers/+completion/auto-completion/local/snippets/&lt;/code&gt;), the second is define your own:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'yas-snippet-dirs&lt;/span&gt; &lt;span class="s"&gt;"~/path/to/your/dir"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;;; notice that this add-to-list must be called before this:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;yas-global-mode&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The procedure here is very simple: inside your snippet dir, create a dir with the mode name, i.e. &lt;code&gt;web-mode/&lt;/code&gt; and inside it create a file called &lt;code&gt;.yas-parents&lt;/code&gt; with the mode names you want to "steal" the snippets. In our case:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;snippets-dir/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;web-mode/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.yas-parents&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;typescript-mode/&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.yas-parents&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;/blockquote&gt;

&lt;p&gt;On my own configs:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftuqkk04dwiktgsjsgyb0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftuqkk04dwiktgsjsgyb0.png" alt="Picture of these dirs in a tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add these lines to the files:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;typescript-mode/.yas-parents&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

rjsx-mode


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;web-mode/.yas-parents&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

rjsx-mode
prog-mode
js-mode


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Last but not least
&lt;/h1&gt;

&lt;p&gt;With all these configs you're now able to auto-import, format/import on saving, check types, check definitions... Everything :)&lt;/p&gt;

&lt;p&gt;But I'd like to recommend you another package called &lt;a href="http://wikemacs.org/wiki/Paredit-mode" rel="noopener noreferrer"&gt;paredit&lt;/a&gt;: it is a lib for lisp languages (if you are coding in any lisp family this package should be mandatory!) but once you get the shortcuts, you want to use them in every language, it is possible with this function call:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sp-use-paredit-bindings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I also use &lt;a href="https://github.com/jaypei/emacs-neotree" rel="noopener noreferrer"&gt;neotree&lt;/a&gt; with &lt;a href="https://github.com/domtronn/all-the-icons.el" rel="noopener noreferrer"&gt;all-the-icons&lt;/a&gt; to create my sidebar. Since this text is already too long, I will write about this specific config another day :)&lt;/p&gt;

&lt;p&gt;And &lt;a href="https://emacsredux.com/blog/2014/08/25/a-peek-at-emacs-24-dot-4-prettify-symbols-mode/#:~:text=Emacs%2024.4%20ships%20with%20a,would%20replace%20several%20ascii%20characters" rel="noopener noreferrer"&gt;prettify symbols&lt;/a&gt; too!&lt;/p&gt;

&lt;p&gt;I really hope you liked it and I hope this to be useful to you on your emacs journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Viglioni/spacemacs" rel="noopener noreferrer"&gt;This&lt;/a&gt; is my spacemacs config repo, all my lisps are in &lt;code&gt;laurisp/&lt;/code&gt; (haha) dir.&lt;/p&gt;

&lt;p&gt;Be safe, use masks, stay home, use emacs.&lt;br&gt;
xoxo&lt;/p&gt;

&lt;p&gt;edit: &lt;em&gt;I've found today some strange behaviour of &lt;code&gt;import-js&lt;/code&gt; so I removed it from this tutorial. I'll try using tide for organizing imports on save, if I'm successful I update it here :)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>emacs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Using URL as a global state - React Hook</title>
      <dc:creator>Laura Viglioni</dc:creator>
      <pubDate>Tue, 07 Apr 2020 02:51:31 +0000</pubDate>
      <link>https://dev.to/viglioni/using-url-as-a-global-state-react-hook-25l3</link>
      <guid>https://dev.to/viglioni/using-url-as-a-global-state-react-hook-25l3</guid>
      <description>&lt;p&gt;Sometimes in small applications using some state manager like Redux can be a little pain in the *, with this post I hope to help with a less spartan way to achieve this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tPC2qQkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tkalftqv79ldlfhlarpb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tPC2qQkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tkalftqv79ldlfhlarpb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this litle POC we will use ReactJS, NextJS and &lt;a href="https://dog.ceo/dog-api/"&gt;Dog Ceo Api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main purpose of this solution is to avoid creating a state in a parent component and keep passing it and its setter as props to the children components.&lt;/p&gt;

&lt;p&gt;In this example we have two components: a &lt;code&gt;Home&lt;/code&gt; in &lt;code&gt;pages/index/index.js&lt;/code&gt; and some buttons in &lt;code&gt;pages/components/breed-buttons&lt;/code&gt;. &lt;br&gt;
&lt;em&gt;You can checkout full code at my &lt;a href="https://github.com/Viglioni/global-state-example"&gt;github page&lt;/a&gt; and see it running &lt;a href="https://global-state-example.herokuapp.com/"&gt;here&lt;/a&gt; :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lTGnwtnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3xge8bhecd373crhupv8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lTGnwtnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3xge8bhecd373crhupv8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;Home&lt;/code&gt; component have a state called &lt;em&gt;breed&lt;/em&gt; with "random" as its default value and this component makes an API call to get a random picture of a dog. Usually we would do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Home = () =&amp;gt; {
    const [breed, setBreed] = useState("random")
    /* api call */
    /* display pic */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;BreedButtons&lt;/code&gt; component is a simple &lt;code&gt;div&lt;/code&gt; with some buttons with breed names that when clicked set our breed state with its respective breed value. For this to be possible, we must pass &lt;code&gt;breed&lt;/code&gt; and &lt;code&gt;setBreed&lt;/code&gt; as props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Home = () =&amp;gt; {
    const [breed, setBreed] = useState("random")
    /* api call */
    &amp;lt;BreedButtons breed={breed} setBreed={setBreed}/&amp;gt;
    /* display pic */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now just &lt;em&gt;picture&lt;/em&gt; the scene when &lt;code&gt;Home&lt;/code&gt; has a lot of children that might read or write this state. And you have more states. It might get messy.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;helpers/hooks.js&lt;/code&gt; you will find this React Hook:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AdIpCvlO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9l8k0o8mt3mdcsx1ygrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AdIpCvlO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9l8k0o8mt3mdcsx1ygrg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(obs.: if you do not know &lt;code&gt;pathOr&lt;/code&gt; you should checkout &lt;a href="https://ramdajs.com/docs/#pathOr"&gt;ramda&lt;/a&gt;, it is an amazing functional lib!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This function gets two parameters: first the name of this state and second the initial value. For instance, in our problem we want a state called &lt;em&gt;breed&lt;/em&gt; with default value &lt;em&gt;random&lt;/em&gt;. The use is very similar to React's &lt;code&gt;useState&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [breed, setBreed] = useRouterAsState("breed", "random")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our hook will check if our URL has already some value for the state "breed", for instance &lt;code&gt;https://global-state-example.herokuapp.com/?breed=husky&lt;/code&gt;, if yes it will set the state to "husky" or whatever it is placed after the equal sign, if not to our default value "random".&lt;/p&gt;

&lt;p&gt;Whenever we change the state in any component, &lt;em&gt;i.e.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setBreed("dalmatian")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the &lt;code&gt;next router&lt;/code&gt; will change in URL to &lt;code&gt;/?breed=dalmatian&lt;/code&gt; and &lt;strong&gt;all&lt;/strong&gt; components the used our &lt;code&gt;useRouteAsState&lt;/code&gt; will automatically update its value. If we have more states in our URL it will change only the "breed" state. That is why you name the state in &lt;code&gt;useRouteAsState&lt;/code&gt; first parameter.&lt;/p&gt;

&lt;p&gt;This is what our &lt;code&gt;Home&lt;/code&gt; looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qa0wPtSG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6nqlquoibu6wu4j9akih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qa0wPtSG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6nqlquoibu6wu4j9akih.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;where &lt;code&gt;getDog&lt;/code&gt; is a syntax sugar for our API call in &lt;code&gt;helpers/api.js&lt;/code&gt;. Our &lt;code&gt;BreedButtons&lt;/code&gt; component contains the buttons that actually change our state and it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1nmYg3FB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iv4njfbyijthxxyik0vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1nmYg3FB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iv4njfbyijthxxyik0vg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course our approach has &lt;strong&gt;a lot&lt;/strong&gt; of limitations such as: it simply does not make sense for some states to be in URL like &lt;em&gt;loading&lt;/em&gt; or &lt;em&gt;data&lt;/em&gt;, but it is very usefull to states like pagination, dark-mode etc. &lt;br&gt;
Be careful, it might get messy if more than one component tries to change the state at the same time, so &lt;strong&gt;you must use it very carefully when thinking about &lt;a href="https://en.wikipedia.org/wiki/Concurrency_(computer_science)"&gt;concurrency&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;On the other hand, more than just being &lt;em&gt;handy&lt;/em&gt; not to have to pass the same state and setter to a lot of children, grandchildren again and again, the state in URL has a &lt;strong&gt;huge&lt;/strong&gt; advantage of not losing context when the page is reloaded or when you hit back button - in mobile web development this behaviour is &lt;strong&gt;fundamental&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another important point: sometimes you don't want to give the power of manually setting a state to the user just typing in the URL, specially if some of the states are being used in an API call. For this problem we have a partial solution.&lt;/p&gt;

&lt;p&gt;If you check our &lt;code&gt;pages/encoded/&lt;/code&gt; code you will see that the components are very similar to our &lt;code&gt;pages/index&lt;/code&gt; ones, except that our hook is imported from &lt;code&gt;helpers/encoded-state.js&lt;/code&gt;. The code is a little bit longer so I won't print it here, but the main difference is instead of our URL be something like &lt;code&gt;?breed=labrador&lt;/code&gt; it will be &lt;code&gt;?c3RhdGVz=eyJicmVlZCI6ImxhYnJhZG9yIn0%253D&lt;/code&gt;. It is a Base64 encoding of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;state: {
    breed: "labrador"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user will be able to decode it, but it is a little bit safer than just let the state in plain text.&lt;/p&gt;

&lt;p&gt;A last but not least point: you might have noticed that in our &lt;code&gt;useRouteAsState&lt;/code&gt; we have a third parameter called &lt;code&gt;r&lt;/code&gt;. In some older versions of &lt;code&gt;NextJS&lt;/code&gt; the &lt;code&gt;useRouter&lt;/code&gt; native hook does not work, so you must import &lt;code&gt;withRouter&lt;/code&gt; from &lt;code&gt;next/router&lt;/code&gt; and wrap your component using it, for example: &lt;code&gt;export default withRouter(Home)&lt;/code&gt; with that you will receive a prop called &lt;code&gt;router&lt;/code&gt; in &lt;code&gt;Home&lt;/code&gt; component that is our third paramter.&lt;/p&gt;

&lt;p&gt;I really hope you find this little trick useful. Any doubts or sugestions you can call me on my twitter account &lt;a href="https://twitter.com/ViglioniLaura"&gt;twitter.com/viglionilaura&lt;/a&gt; :)&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
