<?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: Thomas Alcala Schneider</title>
    <description>The latest articles on DEV Community by Thomas Alcala Schneider (@animo).</description>
    <link>https://dev.to/animo</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%2F162183%2F29c22a3a-802e-4083-9cd7-8bb5c8a39e17.jpeg</url>
      <title>DEV Community: Thomas Alcala Schneider</title>
      <link>https://dev.to/animo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/animo"/>
    <language>en</language>
    <item>
      <title>Fish-like Autosuggestion in Powershell</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Fri, 26 Mar 2021 00:23:15 +0000</pubDate>
      <link>https://dev.to/animo/fish-like-autosuggestion-in-powershell-21ec</link>
      <guid>https://dev.to/animo/fish-like-autosuggestion-in-powershell-21ec</guid>
      <description>&lt;p&gt;&lt;em&gt;For a year, working on Windows laptops has been nonoptional for me. I've been desperately trying to make my environment as close as it is on Mac OS, with the added challenge to do it without the Windows Subsystem for Linux (WSL). So this relies heavily on Powershell.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One thing I like from the &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;fish shell&lt;/a&gt; (and was reproduced in zsh by the &lt;a href="https://github.com/zsh-users/zsh-autosuggestions" rel="noopener noreferrer"&gt;zsh-autosuggestion plugin&lt;/a&gt;) is the autosuggestion feature.&lt;br&gt;&lt;br&gt;
It's that thing where when you start typing something and there is something that starts with the same letters in your history, it'll write it after the cursor in grayed colors. And it's awesome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asciinema.org/a/37390" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fasciinema.org%2Fa%2F37390.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Powershell, it´s called &lt;a href="https://devblogs.microsoft.com/powershell/announcing-psreadline-2-1-with-predictive-intellisense/" rel="noopener noreferrer"&gt;predictive IntelliSense&lt;/a&gt; in PSReadLine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Powershell 5.1 or higher&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, install ´PSReadLine´ version 2.1.0&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Install-Module PSReadLine -RequiredVersion 2.1.0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Then, initialize it with the command below
    ```


    Import-Module PSReadLine
    Set-PSReadLineOption -PredictionSource History


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

&lt;/div&gt;

&lt;p&gt;And there it is!&lt;/p&gt;

&lt;h2&gt;
  
  
  (Optional) Initialize it in your profile
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Check if you already have a profile&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Test-path $profile
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. If false, create one
    ```


    New-item –type file –force $profile


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If yes, edit it&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

notepad $profile
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Run this command and close your terminal
    ```


    Set-ExecutionPolicy RemoteSigned


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Update your profile file like in step 3, and add those lines to it&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource History
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
And that's it!

![Autosuggest in Powershell](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0yg202h1ju1o1cd4aeb.gif)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>powershell</category>
      <category>autosuggestion</category>
      <category>shell</category>
      <category>windows</category>
    </item>
    <item>
      <title>Translating My Resume (and any text file) with Rust</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Sun, 14 Mar 2021 19:57:02 +0000</pubDate>
      <link>https://dev.to/animo/translating-my-resume-and-any-text-file-with-rust-4h5e</link>
      <guid>https://dev.to/animo/translating-my-resume-and-any-text-file-with-rust-4h5e</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl; dr: this is about creating a CLI that uses Google Translate to translate a text file to a supported language. The code can be found &lt;a href="https://github.com/ThomasMarcel/rosette"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Something that sucks about moving to a country that doesn't care too much about the English language and look for a job there is that you have to translate your resume.&lt;/p&gt;

&lt;p&gt;So here I am with my well-written and tested resume in English, and have to spend hours  (a couple, at least) translating it to French. And French is my mother language too, I just moved around a bit, so a lot of different companies, that's why it's long to translate.&lt;/p&gt;

&lt;p&gt;And to be fair, it's even longer to write a CLI to do it for me 😅, even more so in a language that I am currently learning, and I still have to double-check and fix some errors... But I think it'll be helpful in the long run, I'll be able to translate my posts too.&lt;/p&gt;

&lt;p&gt;That the developer's paradox: we'd rather rebuild our blog with a crazy stack but have almost no posts in it. Develop in DRY mode that takes longer than actually repeat stuff (like this one). That reminds me of some funny quote from Parcs and Recs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iOZ1FRqs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5v4nx0nqj46qh1h4uyse.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iOZ1FRqs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5v4nx0nqj46qh1h4uyse.jpeg" alt="Ron Swanson on doing nothing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full disclosure: I am new to Rust, so the code at the end will not be optimal, and this is as much an exercise as it is a post.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;An API keyHere we are going to be using the Google Translate API, so you need to create an API key in the &lt;a href="https://console.cloud.google.com/apis/credentials"&gt;Google Cloud Platform (GCP) dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rust, cargo, etc: follow the &lt;a href="https://www.rust-lang.org/tools/install"&gt;installation instructions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Down to it!
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Project Creation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;$ cargo new rosette&lt;/code&gt;, this will create a directory called &lt;code&gt;rosette&lt;/code&gt; in your current folder&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;$ cargo run&lt;/code&gt; to test it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic Variables
&lt;/h2&gt;

&lt;p&gt;So we need to set the endpoint and get the &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt; from the environment variables. Here's how we get them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://translation.googleapis.com/language/translate/v2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GOOGLE_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Set up the GOOGLE_API_KEY environment variable first"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"endpoint: {:?}, args: {:?}, key: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;base_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&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;
  
  
  Dummy Call
&lt;/h2&gt;

&lt;p&gt;Now let's try doing a call to the API.&lt;br&gt;
A dummy call to that API with the &lt;code&gt;curl&lt;/code&gt; command line tool looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://translation.googleapis.com/language/translate/v2?key=&lt;/span&gt;&lt;span class="nv"&gt;$GOOGLE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;q=rust&amp;amp;source=en&amp;amp;target=fr"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are sending 3 parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;key&lt;/strong&gt;: the Google API key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;q&lt;/strong&gt;: the words to translate, here &lt;code&gt;rust&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;source&lt;/strong&gt;: the language of the words, here &lt;code&gt;en&lt;/code&gt; for English&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;target&lt;/strong&gt;: the target language to translate to, here &lt;code&gt;fr&lt;/code&gt; for French&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list of languages available can be found &lt;a href="https://cloud.google.com/translate/docs/languages"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The output is&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"translations"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"translatedText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rouiller"&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="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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Which isn't exact. &lt;code&gt;to rust&lt;/code&gt; == &lt;code&gt;rouiller&lt;/code&gt; (verb), &lt;code&gt;rust&lt;/code&gt; == &lt;code&gt;rouille&lt;/code&gt; (noun).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anyway...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let's do the same with Rust!&lt;/p&gt;

&lt;h2&gt;
  
  
  Call in Rust with Hardcoded Data
&lt;/h2&gt;

&lt;p&gt;First in &lt;code&gt;Cargo.toml&lt;/code&gt;, add the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="nn"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["derive"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;reqwest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"native-tls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cookies"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nn"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;["full"]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now the code in &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Translation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[serde(alias&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"translatedText"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;translated_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Translations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Translation&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="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Translations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Error&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;let&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://translation.googleapis.com/language/translate/v2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GOOGLE_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Set up the GOOGLE_API_KEY environment variable first"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"endpoint: {:?}, args: {:?}, key: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;base_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"rust"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fr"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;request_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{base}?key={key}&amp;amp;q={query}&amp;amp;source={source}&amp;amp;target={target}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c"&gt;// let request_url = format!("{base}?key={key}", base = base_endpoint, key = &amp;amp;api_key);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="nf"&gt;.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;request_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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;.send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;text_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;translations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;text_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&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;This works ok, now for the next steps:&lt;/p&gt;

&lt;h2&gt;
  
  
  Translate in a Function
&lt;/h2&gt;

&lt;p&gt;Let's put the code to translate in its own function below the &lt;code&gt;main&lt;/code&gt; function, so we can reuse it on every sentence of a file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&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;let&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://translation.googleapis.com/language/translate/v2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;request_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{base}?key={key}&amp;amp;q={query}&amp;amp;source={source}&amp;amp;target={target}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c"&gt;// let request_url = format!("{base}?key={key}", base = base_endpoint, key = &amp;amp;api_key);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="nf"&gt;.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;request_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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;.send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;text_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;translations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;text_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;translations&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;
  
  
  Take Arguments
&lt;/h2&gt;

&lt;p&gt;Now we'll take a file name, source and target languages as command arguments.&lt;br&gt;
Where we were getting arguments before, now we'll make sure that we have the exact number&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You need to pass a text file name, a source and a target language"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"args: {:?}, key: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used to build and run the app with &lt;code&gt;$ cargo run&lt;/code&gt;. Now to pass arguments, there's a trick. This is not needed when running the built app directly, but since we are running ir with cargo, we have to use &lt;code&gt;--&lt;/code&gt; to separate arguments for cargo and arguments for the app. So we do &lt;code&gt;$ cargo run -- file.txt fr en&lt;/code&gt; for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read Lines
&lt;/h2&gt;

&lt;p&gt;We'll create a &lt;code&gt;src/utils.rs&lt;/code&gt; file with a function to read lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BufRead&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;read_lines&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Lines&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BufReader&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Path&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&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="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;BufReader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.lines&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;And we have to import it at the top of our &lt;code&gt;src/main.rs&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;read_lines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Translate Lines
&lt;/h2&gt;

&lt;p&gt;Let's read the file, loop through the file and translate the lines one by one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_lines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;u{a0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsed_row&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;translation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;parsed_row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="py"&gt;.data.translations&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="py"&gt;.translated_text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;t2&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;translation&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So now we have this &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;read_lines&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Translation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[serde(alias&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"translatedText"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;translated_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Translations&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Translation&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="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Translations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GOOGLE_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Set up the GOOGLE_API_KEY environment variable first"&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="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;panic!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You need to pass a text file name, a source and a target language"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"args: {:?}, key: {:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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="c"&gt;// let translations = translate(query, source, target, &amp;amp;api_key);&lt;/span&gt;

    &lt;span class="c"&gt;// println!("{:?}", translations);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_lines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;parsed_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="nf"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;u{a0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="c"&gt;// println!("{}", parsed_row);&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;translation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;parsed_row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="py"&gt;.data.translations&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="py"&gt;.translated_text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;t2&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;translation&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&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;let&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://translation.googleapis.com/language/translate/v2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;request_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{base}?key={key}&amp;amp;q={query}&amp;amp;source={source}&amp;amp;target={target}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="nf"&gt;.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;request_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&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;.send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;text_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&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="n"&gt;translations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;text_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;translations&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;And the complete code can be found &lt;a href="https://github.com/ThomasMarcel/rosette"&gt;in this repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>translate</category>
      <category>learning</category>
      <category>resume</category>
    </item>
    <item>
      <title>Vim Configuration from Minimal to Complete</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Thu, 11 Mar 2021 17:57:25 +0000</pubDate>
      <link>https://dev.to/animo/vim-configuration-from-minimal-to-complete-5o9</link>
      <guid>https://dev.to/animo/vim-configuration-from-minimal-to-complete-5o9</guid>
      <description>&lt;p&gt;From a configuration that works on low-resource, restricted permissions environments, to a complete configuration...&lt;br&gt;&lt;br&gt;
And from almost scratch. Because I like to know what's in my &lt;code&gt;.vimrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL; DR the final vimrc and at the different steps is in &lt;a href="https://github.com/ThomasMarcel/vimrc" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;, with tags for each step.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vim rocks 🤘! And recent plugins can make it really great for coding, most notably using &lt;a href="https://github.com/neoclide/coc.nvim" rel="noopener noreferrer"&gt;Conquer of Completion&lt;/a&gt; with NodeJS, which has a bunch of extensions for a lot of languages using the Language Server Protocol.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this article, however, we'll assume to be working on a low resource computer, or limited in what can be installed, runtimes available, etc. So code completion, linting, quality without external runtimes!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'll use &lt;a href="https://github.com/ThomasMarcel/vimrc" rel="noopener noreferrer"&gt;this GitHub repository&lt;/a&gt; and tags for each step in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimal Configuration&lt;/li&gt;
&lt;li&gt;
Adding Plugins

&lt;ul&gt;
&lt;li&gt;Plugin Initialization&lt;/li&gt;
&lt;li&gt;General Developer Experience (DX) Plugins&lt;/li&gt;
&lt;li&gt;Linter and Fixer&lt;/li&gt;
&lt;li&gt;Language-specific configuration and plugins&lt;/li&gt;
&lt;li&gt;Linting configuration&lt;/li&gt;
&lt;li&gt;Language plugins&lt;/li&gt;
&lt;li&gt;Colors and Themes&lt;/li&gt;
&lt;li&gt;Extras&lt;/li&gt;
&lt;li&gt;Authoring&lt;/li&gt;
&lt;li&gt;More&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You can apply the diffs in this post by copying them in a file, let's say &lt;code&gt;example.patch&lt;/code&gt;, and apply them, as long as you have the same directory structure as in my GitHub repository, and run &lt;code&gt;$ git apply example.patch&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Minimal Configuration
&lt;/h1&gt;

&lt;p&gt;Let's create a minimal &lt;code&gt;.vimrc&lt;/code&gt; file with some basic configuration we need.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As a base, we'll take the content of Tim Pope's &lt;a href="https://github.com/tpope/vim-sensible" rel="noopener noreferrer"&gt;vim-sensible plugin&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now we have in &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.1.0/.vimrc" rel="noopener noreferrer"&gt;tag 0.1.0&lt;/a&gt; our minimal &lt;code&gt;.vimrc&lt;/code&gt; as recommended&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

" sensible.vim - Defaults everyone can agree on
" Maintainer:   Tim Pope &amp;lt;http://tpo.pe/&amp;gt;
" Version:      1.2

if exists('g:loaded_sensible') || &amp;amp;compatible
finish
else
let g:loaded_sensible = 'yes'
endif

if has('autocmd')
filetype plugin indent on
endif
if has('syntax') &amp;amp;&amp;amp; !exists('g:syntax_on')
syntax enable
endif

" Use :help 'option' to see the documentation for the given option.

set autoindent
set backspace=indent,eol,start
set complete-=i
set smarttab

set nrformats-=octal

if !has('nvim') &amp;amp;&amp;amp; &amp;amp;ttimeoutlen == -1
set ttimeout
set ttimeoutlen=100
endif

set incsearch
" Use &amp;lt;C-L&amp;gt; to clear the highlighting of :set hlsearch.
if maparg('&amp;lt;C-L&amp;gt;', 'n') ==# ''
nnoremap &amp;lt;silent&amp;gt; &amp;lt;C-L&amp;gt; :nohlsearch&amp;lt;C-R&amp;gt;=has('diff')?'&amp;lt;Bar&amp;gt;diffupdate':''&amp;lt;CR&amp;gt;&amp;lt;CR&amp;gt;&amp;lt;C-L&amp;gt;
endif

set laststatus=2
set ruler
set wildmenu

if !&amp;amp;scrolloff
set scrolloff=1
endif
if !&amp;amp;sidescrolloff
set sidescrolloff=5
endif
set display+=lastline

if &amp;amp;encoding ==# 'latin1' &amp;amp;&amp;amp; has('gui_running')
set encoding=utf-8
endif

if &amp;amp;listchars ==# 'eol:$'
set listchars=tab:&amp;gt;\ ,trail:-,extends:&amp;gt;,precedes:&amp;lt;,nbsp:+
endif

if v:version &amp;gt; 703 || v:version == 703 &amp;amp;&amp;amp; has("patch541")
set formatoptions+=j " Delete comment character when joining commented lines
endif

if has('path_extra')
setglobal tags-=./tags tags-=./tags; tags^=./tags;
endif

if &amp;amp;shell =~# 'fish$' &amp;amp;&amp;amp; (v:version &amp;lt; 704 || v:version == 704 &amp;amp;&amp;amp; !has('patch276'))
set shell=/usr/bin/env\ bash
endif

set autoread

if &amp;amp;history &amp;lt; 1000
set history=1000
endif
if &amp;amp;tabpagemax &amp;lt; 50
set tabpagemax=50
endif
if !empty(&amp;amp;viminfo)
set viminfo^=!
endif
set sessionoptions-=options
set viewoptions-=options

" Allow color schemes to do bright colors without forcing bold.
if &amp;amp;t_Co == 8 &amp;amp;&amp;amp; $TERM !~# '^Eterm'
set t_Co=16
endif

" Load matchit.vim, but only if the user hasn't installed a newer version.
if !exists('g:loaded_matchit') &amp;amp;&amp;amp; findfile('plugin/matchit.vim', &amp;amp;rtp) ==# ''
runtime! macros/matchit.vim
endif

if empty(mapcheck('&amp;lt;C-U&amp;gt;', 'i'))
inoremap &amp;lt;C-U&amp;gt; &amp;lt;C-G&amp;gt;u&amp;lt;C-U&amp;gt;
endif
if empty(mapcheck('&amp;lt;C-W&amp;gt;', 'i'))
inoremap &amp;lt;C-W&amp;gt; &amp;lt;C-G&amp;gt;u&amp;lt;C-W&amp;gt;
endif

" vim:set ft=vim et sw=2:
&lt;/code&gt;&lt;/pre&gt;


&lt;/li&gt;

&lt;/ul&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    - Note that we could have used this plugin as explained in the installation. But
      1. it makes for a great base
      1. We're trying to use the less possible plugins at the beginning, then build upon it
    - _Anecdote: the toolkit for ocaml developers does that same thing (only with an earlier version of the plugin) with `opam user-setup install`, and adds some ocaml related stuff below this plugin's code. You can check out the [vimrc generated by user-setup](https://github.com/ThomasMarcel/vimrc/blob/0.1.0-ocaml/.vimrc)_
- Now some options of my own blend or gotten from some good `.vimrc` around. Here's what I've added. Highlighting, tab settings, remap the leader key, and functions to know which OS we're using. Complete code in [the 0.2.0 tag](https://github.com/ThomasMarcel/vimrc/blob/0.2.0/.vimrc)
    ```diff


    diff --git a/.gitignore b/.gitignore
    new file mode 100644
    index 0000000..a01ee28
    --- /dev/null
    +++ b/.gitignore
    @@ -0,0 +1 @@
    +.*.swp
    diff --git a/.vimrc b/.vimrc
    index 0818853..302d55b 100644
    --- a/.vimrc
    +++ b/.vimrc
    @@ -1,3 +1,12 @@
    +" Modeline and Notes {
    +" vim: set sw=4 ts=4 sts=4 et tw=78 foldmarker={,} foldlevel=0 foldmethod=marker spell:
    +"
    +" @ThomasAlcala's vim configuration.
    +" }
    +"
    +"
    +set nocompatible
    +
    " sensible.vim - Defaults everyone can agree on
    " Maintainer:   Tim Pope &amp;lt;http://tpo.pe/&amp;gt;
    " Version:      1.2
    @@ -99,3 +108,41 @@ if empty(mapcheck('&amp;lt;C-W&amp;gt;', 'i'))
    endif

    " vim:set ft=vim et sw=2:
    +
    +" -----------
    +" Environment
    +" -----------
    +
    +" Encoding
    +set encoding=utf-8
    +set fileencoding=utf-8
    +set fileencodings=utf-8
    +set ttyfast
    +
    +" Tabs. May be overridden by autocmd rules
    +set tabstop=4
    +set softtabstop=0
    +set shiftwidth=4
    +set expandtab
    +
    +" Map leader to ,
    +let mapleader=','
    +
    +" Enable hidden buffers
    +set hidden
    +
    +" Searching
    +set hlsearch
    +set incsearch
    +set ignorecase
    +set smartcase
    +
    +silent function! OSX()
    +    return has('macunix')
    +endfunction
    +silent function! LINUX()
    +    return has('unix') &amp;amp;&amp;amp; !has('macunix') &amp;amp;&amp;amp; !has('win32unix')
    +endfunction
    +silent function! WINDOWS()
    +    return  (has('win32') || has('win64'))
    +endfunction


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;With that done, we now have autocompletion working with `ctrl+n` in insert mode.

And now some built in language support with omnifunc with `ctrl-x ctrl-o` (not very user-friendly), as in [the 0.2.1 tag](https://github.com/ThomasMarcel/vimrc/blob/0.2.1/.vimrc):

```diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --git a/.vimrc b/.vimrc
index 302d55b..77bfe70 100644
--- a/.vimrc
+++ b/.vimrc
@@ -146,3 +146,5 @@ endfunction
silent function! WINDOWS()
    return  (has('win32') || has('win64'))
endfunction
+
+set omnifunc=syntaxcomplete#Complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    _A trick for tab completion is to add a smart function like below, you can also find it in [the 0.2.2 tag](https://github.com/ThomasMarcel/vimrc/blob/0.2.2/.vimrc):_
    ```diff


    diff --git a/.vimrc b/.vimrc
    index 77bfe70..7f727b8 100644
    --- a/.vimrc
    +++ b/.vimrc
    @@ -148,3 +148,28 @@ silent function! WINDOWS()
    endfunction

    set omnifunc=syntaxcomplete#Complete
    +
    +" Smart mapping for tab completion
    +" https://vim.fandom.com/wiki/Smart_mapping_for_tab_completion
    +function! Smart_TabComplete()
    +  let line = getline('.')                         " current line
    +
    +  let substr = strpart(line, -1, col('.')+1)      " from the start of the current
    +                                                  " line to one character right
    +                                                  " of the cursor
    +  let substr = matchstr(substr, "[^ \t]*$")       " word till cursor
    +  if (strlen(substr)==0)                          " nothing to match on empty string
    +    return "\&amp;lt;tab&amp;gt;"
    +  endif
    +  let has_period = match(substr, '\.') != -1      " position of period, if any
    +  let has_slash = match(substr, '\/') != -1       " position of slash, if any
    +  if (!has_period &amp;amp;&amp;amp; !has_slash)
    +    return "\&amp;lt;C-X&amp;gt;\&amp;lt;C-P&amp;gt;"                         " existing text matching
    +  elseif ( has_slash )
    +    return "\&amp;lt;C-X&amp;gt;\&amp;lt;C-F&amp;gt;"                         " file matching
    +  else
    +    return "\&amp;lt;C-X&amp;gt;\&amp;lt;C-O&amp;gt;"                         " plugin matching
    +  endif
    +endfunction
    +
    +inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;__Check out `:help ins-completion` for a list of completion commands.__
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Adding Plugins
&lt;/h1&gt;

&lt;p&gt;With vim 7.4, there was some tuning to do to manage the runtime path, that's why there are a bunch of plugin managers out there, like the minimalistic, solid &lt;a href="https://github.com/tpope/vim-pathogen" rel="noopener noreferrer"&gt;vim-pathogen&lt;/a&gt; by Tim Pope (again!), &lt;a href="https://github.com/VundleVim/Vundle.vim" rel="noopener noreferrer"&gt;vundle&lt;/a&gt;, then asynchronous and fast &lt;a href="https://github.com/Shougo/dein.vim" rel="noopener noreferrer"&gt;dein&lt;/a&gt;, and my favorite &lt;a href="https://github.com/junegunn/Vim-Plug" rel="noopener noreferrer"&gt;Vim-Plug&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since vim 8, there's a &lt;code&gt;/pack/&lt;/code&gt; (think backslashes for Windows) directory in your vim files (&lt;code&gt;~/.vim/&lt;/code&gt; for linux and Mac OS, &lt;code&gt;~\vimfiles\&lt;/code&gt; for Windows) where you can clone, submodule, or simply copy plugins that will be loaded on vim startup.&lt;/p&gt;

&lt;p&gt;I'll demonstrate and put the code here using the package path and with &lt;a href="https://github.com/junegunn/Vim-Plug" rel="noopener noreferrer"&gt;Vim-Plug&lt;/a&gt;, but if you like another plugin manager, it's usually pretty simple to move from one to the other, they usually use the same pattern:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

call#open
  plugin '&amp;lt;plugin path&amp;gt;'
  plugin '&amp;lt;plugin path&amp;gt;'
  plugin '&amp;lt;plugin path&amp;gt;'
call#close


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;If you are not sure whether your vim supports packages, try typing &lt;code&gt;:echo has('packages')&lt;/code&gt; in vim, it should display &lt;code&gt;1&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I recommend using a plugin manager. I like Vim-Plug because of how fast it is to fetch things asynchronously, and the options to run an installation script that you won't have using the vendor thing. And pathogen for it's simplicity. On old OS with vim 7.4, maybe go for vim-pathogen.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugin Initialization
&lt;/h2&gt;

&lt;p&gt;Everything from here will be branched. So this is what the tags look like so far in &lt;a href="https://github.com/ThomasMarcel/vimrc" rel="noopener noreferrer"&gt;the repository&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%2Fuploads%2Farticles%2Fe1fgkunpqxcx4t4og5aj.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%2Fuploads%2Farticles%2Fe1fgkunpqxcx4t4og5aj.png" alt="vimrc 0.3.0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vim Packages
&lt;/h3&gt;

&lt;p&gt;Here's the initialization, I am also adding the scripts in the repository's bin folder. You can find the text in the &lt;code&gt;.vimrc&lt;/code&gt; file so far on &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.3.0/.vimrc" rel="noopener noreferrer"&gt;the 0.3.0 tag&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;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&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;/.vim/pack/bundle/start"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.vim/pack/bundle/start
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.vim/pack/bundle/start


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Vim-Plug
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install Vim-Plug using the instructions for your OS, following &lt;a href="https://github.com/junegunn/Vim-Plug#installation" rel="noopener noreferrer"&gt;the official instructions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Call and close plug in the &lt;code&gt;.vimrc&lt;/code&gt; file:
```diff
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;diff --git a/.vimrc b/.vimrc&lt;br&gt;
  index 7f727b8..143e7d2 100644&lt;br&gt;
  --- a/.vimrc&lt;br&gt;
  +++ b/.vimrc&lt;br&gt;
  @@ -173,3 +173,9 @@ function! Smart_TabComplete()&lt;br&gt;
  endfunction&lt;/p&gt;

&lt;p&gt;inoremap  =Smart_TabComplete()&lt;br&gt;
  +&lt;br&gt;
  +call plug#begin('~/.vim/plugged')&lt;br&gt;
  +&lt;br&gt;
  +" Put plugins here&lt;br&gt;
  +&lt;br&gt;
  +call plug#end()&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Find this content [the 0.3.0-plug tag](https://github.com/ThomasMarcel/vimrc/blob/0.3.0-plug/.vimrc).

## General Developer Experience (DX) Plugins

Now, let's add some cool DX plugins (let me know if I am missing some)

* [vim-sensible](https://github.com/tpope/vim-sensible) (we started our `.vimrc` file with that, so not mandatory, but like that it'll be up to do date)
* [mucomplete](https://github.com/lifepillar/vim-mucomplete) for code completion. Note that to use it properly, we need to remove the mapping for the tab key. And it is "better" than our omnifunc because it will check the language completion, then the tags, etc automatically in one command
* [vim-fugitive](https://github.com/tpope/vim-fugitive) git wrapper
* [vim-commentary](https://github.com/tpope/vim-commentary) comment stuff out
* [vim-surround](https://github.com/tpope/vim-surround) manipulate enclosing characters, tags, etc
* [vim-vinegar](https://github.com/tpope/vim-vinegar) to move around from buffer to netrw (vim's directory browser)
* [vim-sleuth](https://github.com/tpope/vim-sleuth) to set indentation
* [vim-obsession](https://github.com/tpope/vim-obsession) vim session autosave and other session-related things
* [delimitmate](https://github.com/raimondi/delimitmate) to automatically close quotes, etc
* [ctrlp.vim](https://github.com/ctrlpvim/ctrlp.vim) search for a file

### Vim Packages

I modified my script to clone repositories to not become very repetitive and commented out the tab key mapping to avoid conflict with mucomplete. Find the code in [the 0.4.0 tag](https://github.com/ThomasMarcel/vimrc/tree/0.4.0).

```diff


diff --git a/.vimrc b/.vimrc
index 7f727b8..65a4c7a 100644
--- a/.vimrc
+++ b/.vimrc
@@ -148,6 +148,7 @@ silent function! WINDOWS()
 endfunction

 set omnifunc=syntaxcomplete#Complete
+set spell

 " Smart mapping for tab completion
 " https://vim.fandom.com/wiki/Smart_mapping_for_tab_completion
@@ -172,4 +173,4 @@ function! Smart_TabComplete()
   endif
 endfunction

-inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
+" inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
diff --git a/bin/plugins.sh b/bin/plugins.sh
old mode 100644
new mode 100755
index 23d88c2..ab903ec
--- a/bin/plugins.sh
+++ b/bin/plugins.sh
@@ -6,4 +6,15 @@ fi

 cd ~/.vim/pack/bundle/start

-git clone --depth 1 https://github.com/lifepillar/vim-mucomplete.git
+git_plugins=( "tpope/vim-sensible" "lifepillar/vim-mucomplete" "tpope/vim-fugitive" "tpope/vim-commentary" "tpope/vim-surround" "tpope/vim-vinegar" "tpope/vim-sleuth" "tpope/vim-obsession" "raimondi/delimitmate" "ctrlpvim/ctrlp.vim" )
+
+for plugin in "${git_plugins[@]}"; do
+    folder=$(echo $plugin | cut -d'/' -f2)
+    if [ ! -d "$folder" ]; then
+        git clone --depth 1 "https://github.com/$plugin.git"
+    else
+        cd "$folder"
+        git fetch origin
+        cd ..
+    fi
+done


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Vim-Plug
&lt;/h3&gt;

&lt;p&gt;The results can be found in &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.4.0-plug/.vimrc" rel="noopener noreferrer"&gt;the 0.4.0-plug tag&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc
index 143e7d2..bcb980d 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc
&lt;/span&gt;&lt;span class="p"&gt;@@ -148,6 +148,7 @@&lt;/span&gt; silent function! WINDOWS()
 endfunction
&lt;span class="err"&gt;
&lt;/span&gt; set omnifunc=syntaxcomplete#Complete
&lt;span class="gi"&gt;+set spell
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; " Smart mapping for tab completion
 " https://vim.fandom.com/wiki/Smart_mapping_for_tab_completion
&lt;span class="p"&gt;@@ -172,10 +173,19 @@&lt;/span&gt; function! Smart_TabComplete()
   endif
 endfunction
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+" inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; call plug#begin('~/.vim/plugged')
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-" Put plugins here
&lt;/span&gt;&lt;span class="gi"&gt;+Plug 'tpope/vim-sensible'
+Plug 'lifepillar/vim-mucomplete'
+Plug 'tpope/vim-fugitive'
+Plug 'tpope/vim-commentary'
+Plug 'tpope/vim-surround'
+Plug 'tpope/vim-vinegar'
+Plug 'tpope/vim-sleuth'
+Plug 'tpope/vim-obsession'
+Plug 'raimondi/delimitmate'
+Plug 'ctrlpvim/ctrlp.vim'
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; call plug#end()
&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Linter and Fixer
&lt;/h2&gt;

&lt;p&gt;First let's get the package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dense-analysis/ale" rel="noopener noreferrer"&gt;ale&lt;/a&gt; is my favorite. Works really fine, is pretty fast and asynchronous, so not frustrating.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's a bit of configuration to do for the fixers. And you can optionally add &lt;code&gt;let g:ale_fix_on_save = 1&lt;/code&gt; to automatically fix on save.&lt;br&gt;&lt;br&gt;
We are also adding some general fixes for all file types: remove trailing lines and whitespaces.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc
index 65a4c7a..7711a6a 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc
&lt;/span&gt;&lt;span class="p"&gt;@@ -174,3 +174,9 @@&lt;/span&gt; function! Smart_TabComplete()
 endfunction
&lt;span class="err"&gt;
&lt;/span&gt; " inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
&lt;span class="gi"&gt;+
+let g:ale_fixers = {
+\   '*': ['remove_trailing_lines', 'trim_whitespace'],
+\}
+
+let g:ale_fix_on_save = 1
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Vim Packages
&lt;/h3&gt;

&lt;p&gt;Let's get the package (cf. &lt;a href="https://github.com/ThomasMarcel/vimrc/tree/0.5.0" rel="noopener noreferrer"&gt;tag 0.5.0&lt;/a&gt;).&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc
index 65a4c7a..7711a6a 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc
&lt;/span&gt;&lt;span class="p"&gt;@@ -174,3 +174,9 @@&lt;/span&gt; function! Smart_TabComplete()
 endfunction
&lt;span class="err"&gt;
&lt;/span&gt; " inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
&lt;span class="gi"&gt;+
+let g:ale_fixers = {
+\   '*': ['remove_trailing_lines', 'trim_whitespace'],
+\}
+
+let g:ale_fix_on_save = 1
&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/bin/plugins.sh b/bin/plugins.sh
index ab903ec..3b87ba4 100755
&lt;/span&gt;&lt;span class="gd"&gt;--- a/bin/plugins.sh
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/bin/plugins.sh
&lt;/span&gt;&lt;span class="p"&gt;@@ -8,6 +8,8 @@&lt;/span&gt; cd ~/.vim/pack/bundle/start
&lt;span class="err"&gt;
&lt;/span&gt; git_plugins=( "tpope/vim-sensible" "lifepillar/vim-mucomplete" "tpope/vim-fugitive" "tpope/vim-commentary" "tpope/vim-surround" "tpope/vim-vinegar" "tpope/vim-sleuth" "tpope/vim-obsession" "raimondi/delimitmate" "ctrlpvim/ctrlp.vim" )
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+linter_plugins=( "dense-analysis/ale" )
+
&lt;/span&gt; for plugin in "${git_plugins[@]}"; do
     folder=$(echo $plugin | cut -d'/' -f2)
     if [ ! -d "$folder" ]; then
&lt;span class="p"&gt;@@ -18,3 +20,14 @@&lt;/span&gt; for plugin in "${git_plugins[@]}"; do
         cd ..
     fi
 done
&lt;span class="gi"&gt;+
+for plugin in "${linter_plugins[@]}"; do
+    folder=$(echo $plugin | cut -d'/' -f2)
+    if [ ! -d "$folder" ]; then
+        git clone --depth 1 "https://github.com/$plugin.git"
+    else
+        cd "$folder"
+        git fetch origin
+        cd ..
+    fi
+done
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Vim-Plug
&lt;/h3&gt;

&lt;p&gt;Now we add the plugin with vim-plug, and the same bit of configuration as mentioned before. &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.5.0-plug/.vimrc" rel="noopener noreferrer"&gt;Tag 0.5.0-plug&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc
index bcb980d..109ec2f 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc
&lt;/span&gt;&lt;span class="p"&gt;@@ -188,4 +188,12 @@&lt;/span&gt; Plug 'tpope/vim-obsession'
 Plug 'raimondi/delimitmate'
 Plug 'ctrlpvim/ctrlp.vim'
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+Plug 'dense-analysis/ale'
+
&lt;/span&gt; call plug#end()
&lt;span class="gi"&gt;+
+let g:ale_fixers = {
+\   '*': ['remove_trailing_lines', 'trim_whitespace'],
+\}
+
+let g:ale_fix_on_save = 1
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Language-specific configuration and plugins
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Linting configuration
&lt;/h3&gt;

&lt;p&gt;Installed linters for your language of preference should work out of the box, and fixers too within the available commands, unless specified otherwise.&lt;/p&gt;

&lt;p&gt;To see what linters and fixers are available end enabled, open a file of the type you want, and write &lt;code&gt;:ALEInfo&lt;/code&gt;. At the top, you will see something like the following:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

 Current Filetype: rust
Available Linters: ['analyzer', 'cargo', 'rls', 'rustc']
  Enabled Linters: ['cargo', 'rls']
  Ignored Linters: []
 Suggested Fixers:
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'rustfmt' - Fix Rust files with Rustfmt.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.


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

&lt;/div&gt;

&lt;p&gt;And from this info, you can also see the output of the command, so if a linter or fixer isn't behaving like it should, check its output in &lt;code&gt;:ALEInfo&lt;/code&gt; and debug!&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.vimrc&lt;/code&gt; looks like this in tags &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.6.0/.vimrc" rel="noopener noreferrer"&gt;0.6.0&lt;/a&gt; and &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.6.0-plug/.vimrc" rel="noopener noreferrer"&gt;0.6.0-plug&lt;/a&gt;, respectively.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;  diff --git a/.vimrc b/.vimrc
&lt;span class="gh"&gt;index 7711a6a..9535a37 100644
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc
&lt;/span&gt;&lt;span class="p"&gt;@@ -64,7 +64,7 @@&lt;/span&gt; if &amp;amp;listchars ==# 'eol:$'
   set listchars=tab:&amp;gt;\ ,trail:-,extends:&amp;gt;,precedes:&amp;lt;,nbsp:+
 endif
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-if v:version &amp;gt; 703 || v:version == 703 &amp;amp;&amp;amp; has("patch541")
&lt;/span&gt;&lt;span class="gi"&gt;+if v:version &amp;gt; 703 || v:version == 703 &amp;amp;&amp;amp; has('patch541')
&lt;/span&gt;   set formatoptions+=j " Delete comment character when joining commented lines
 endif
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -96,7 +96,7 @@&lt;/span&gt; if &amp;amp;t_Co == 8 &amp;amp;&amp;amp; $TERM !~# '^Eterm'
 endif
&lt;span class="err"&gt;
&lt;/span&gt; " Load matchit.vim, but only if the user hasn't installed a newer version.
&lt;span class="gd"&gt;-if !exists('g:loaded_matchit') &amp;amp;&amp;amp; findfile('plugin/matchit.vim', &amp;amp;rtp) ==# ''
&lt;/span&gt;&lt;span class="gi"&gt;+if !exists('g:loaded_matchit') &amp;amp;&amp;amp; findfile('plugin/matchit.vim', &amp;amp;runtimepath) ==# ''
&lt;/span&gt;   runtime! macros/matchit.vim
 endif
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -175,8 +175,36 @@&lt;/span&gt; endfunction
&lt;span class="err"&gt;
&lt;/span&gt; " inoremap &amp;lt;tab&amp;gt; &amp;lt;c-r&amp;gt;=Smart_TabComplete()&amp;lt;CR&amp;gt;
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+augroup FiletypeGroup
+    autocmd!
+    au BufNewFile,BufRead *.jsx set filetype=javascript.jsx
+augroup END
+
+let g:ale_linter_aliases = {
+            \ 'jsx': ['css', 'javascript'],
+            \ 'vue': ['eslint', 'vls']
+            \}
+
+let g:ale_linters = {
+            \ 'jsx': ['stylelint', 'eslint'],
+            \ 'rust': ['analyzer', 'cargo', 'rls'],
+            \ 'vim': ['vint'],
+            \ 'zsh': ['shell', 'shellcheck'],
+            \}
+
&lt;/span&gt; let g:ale_fixers = {
&lt;span class="gd"&gt;-\   '*': ['remove_trailing_lines', 'trim_whitespace'],
-\}
&lt;/span&gt;&lt;span class="gi"&gt;+            \ '*': ['remove_trailing_lines', 'trim_whitespace'],
+            \ 'rust': ['rustfmt'],
+            \}
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; let g:ale_fix_on_save = 1
&lt;span class="gi"&gt;+
+let g:ale_sign_column_always = 1
+let g:ale_echo_msg_error_str = 'E'
+let g:ale_echo_msg_warning_str = 'W'
+let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
+let g:ale_lint_on_insert_leave = 0
+let g:ale_set_loclist = 1
+let g:ale_set_quickfix = 1
+let g:ale_open_list = 1
+let g:ale_list_window_size = 5
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;So mainly what was done here is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set &lt;code&gt;*.jsx&lt;/code&gt; files to type &lt;code&gt;javascript.jsx&lt;/code&gt;, easier to identify as javascript&lt;/li&gt;
&lt;li&gt;set aliases for jsx and vue files&lt;/li&gt;
&lt;li&gt;set specific linters instead of default ones for a few types&lt;/li&gt;
&lt;li&gt;same with fixers&lt;/li&gt;
&lt;li&gt;leave the "gutter" (1 character column on the left) that ale uses always open, so the buffer window isn't always tilting from left to right&lt;/li&gt;
&lt;li&gt;set the message format to know what type of message it is, and coming from which linter, as we can have several for one file type&lt;/li&gt;
&lt;li&gt;Open the quickfix window so it's easier to navigate warnings and errors, but not too big (in my opinion, the default 10 lines are obtrusive, especially in split views. 5 is fine)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Language plugins
&lt;/h3&gt;

&lt;p&gt;For better syntax highlighting and other functions, sometimes the default language support offered by vim out of the box is subpar or non-existent. In that case, there are several options to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://vimawesome.com/" rel="noopener noreferrer"&gt;VimAwesome&lt;/a&gt;, look in the language menu, there are a lot of tags. you can check out the plugins by language&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sheerun/vim-polyglot#language-packs" rel="noopener noreferrer"&gt;vim-polyglot&lt;/a&gt; offers support for a lot of different languages with their own official and/or community plugins. Look at &lt;a href="https://github.com/sheerun/vim-polyglot#language-packs" rel="noopener noreferrer"&gt;the language pack list&lt;/a&gt; to see if the programming language you want is in the list (it probably is). And it loads them on demand, so it's not slowing down vim performances&lt;/li&gt;
&lt;li&gt;Language packs. So here, you have to look for them one by one, depending on the languages you use. Sometimes, the official website or official organization in GitHub or such offers a plugin, like &lt;a href="https://www.rust-lang.org/tools" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; or &lt;a href="https://rescript-lang.org/docs/manual/latest/editor-plugins" rel="noopener noreferrer"&gt;Rescript&lt;/a&gt;. Sometimes you will have to search for "javascript vim" or something, and check out the results. The &lt;a href="https://github.com/sheerun/vim-polyglot#language-packs" rel="noopener noreferrer"&gt;vim-polyglot language package list&lt;/a&gt; is also a good starting point to search for a specific language&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Colors and Themes
&lt;/h2&gt;

&lt;p&gt;Now there's a saying in French that goes like "Des goûts et des couleurs, on ne discute pas". Literal translation being "of tastes and colors, we don't discuss".&lt;/p&gt;

&lt;p&gt;So here I'll just drop a basic configuration, one plugin I like, to easily switch between themes, and a bunch of themes I like.&lt;br&gt;&lt;br&gt;
Mostly dark. Cuz most developers have some common traits with vampires. Like hating the light, not living the healthiest of lives. Some hate garlic, I guess. And now (03/06/2021) we can't cross seas, but that's valid for most of the human condition, not only vampires and developers. And developires.&lt;/p&gt;

&lt;p&gt;Let's take an example with the famous &lt;a href="https://github.com/lifepillar/vim-solarized8" rel="noopener noreferrer"&gt;solarized8 color theme&lt;/a&gt;.&lt;br&gt;
Basically, we get the plugin, set the &lt;code&gt;colorscheme&lt;/code&gt; variable, background tone (light/dark).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Optional: for a GUI, we can add a font. Mine is Dank Mono. It's not free, but there are a lot of cool free fonts too. Check out &lt;a href="https://devfonts.gafi.dev/" rel="noopener noreferrer"&gt;Dev Fonts&lt;/a&gt; to see which one lookgs good.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can find a list of popular color schemes at &lt;a href="https://vimawesome.com/?q=tag:color-scheme" rel="noopener noreferrer"&gt;VimAwesome&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vim Packages
&lt;/h3&gt;

&lt;p&gt;You can see the results in &lt;a href="https://github.com/ThomasMarcel/vimrc" rel="noopener noreferrer"&gt;tag 0.7.0&lt;/a&gt; for the install script, &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.8.0/.vimrc" rel="noopener noreferrer"&gt;tag 0.8.0&lt;/a&gt; for the &lt;code&gt;.vimrc&lt;/code&gt;.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc&lt;br&gt;
index 9535a37..373d076 100644&lt;br&gt;
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc&lt;br&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc&lt;br&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -148,7 +148,7 @@&lt;/span&gt; silent function! WINDOWS()&lt;br&gt;
 endfunction&lt;br&gt;
&lt;span class="err"&gt;&lt;br&gt;
&lt;/span&gt; set omnifunc=syntaxcomplete#Complete&lt;br&gt;
&lt;span class="gd"&gt;-set spell&lt;br&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+" set spell&lt;br&gt;
&lt;/span&gt;&lt;span class="err"&gt;&lt;br&gt;
&lt;/span&gt; " Smart mapping for tab completion&lt;br&gt;
 " &lt;a href="https://vim.fandom.com/wiki/Smart_mapping_for_tab_completion" rel="noopener noreferrer"&gt;https://vim.fandom.com/wiki/Smart_mapping_for_tab_completion&lt;/a&gt;&lt;br&gt;
&lt;span class="p"&gt;@@ -208,3 +208,15 @@&lt;/span&gt; let g:ale_set_loclist = 1&lt;br&gt;
 let g:ale_set_quickfix = 1&lt;br&gt;
 let g:ale_open_list = 1&lt;br&gt;
 let g:ale_list_window_size = 5&lt;br&gt;
&lt;span class="gi"&gt;+&lt;br&gt;
+set background=dark&lt;br&gt;
+colorscheme solarized8&lt;br&gt;
+if has('gui_running')

&lt;ul&gt;
&lt;li&gt; if has('gui_gtk2')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; elseif has('gui_macvim')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; elseif has('gui_win32')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; endif
+endif
&lt;/li&gt;
&lt;/ul&gt;&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/bin/plugins.sh b/bin/plugins.sh
index 3b87ba4..38b9e9c 100755
&lt;/span&gt;&lt;span class="gd"&gt;--- a/bin/plugins.sh
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/bin/plugins.sh
&lt;/span&gt;&lt;span class="p"&gt;@@ -10,6 +10,8 @@&lt;/span&gt; git_plugins=( "tpope/vim-sensible" "lifepillar/vim-mucomplete" "tpope/vim-fugiti
&lt;span class="err"&gt;
&lt;/span&gt; linter_plugins=( "dense-analysis/ale" )
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+color_plugins=( "lifepillar/vim-solarized8" )
+
&lt;/span&gt; for plugin in "${git_plugins[@]}"; do
 folder=$(echo $plugin | cut -d'/' -f2)
 if [ ! -d "$folder" ]; then
&lt;span class="p"&gt;@@ -31,3 +33,14 @@&lt;/span&gt; for plugin in "${linter_plugins[@]}"; do
     cd ..
 fi
done
&lt;span class="gi"&gt;+
+for plugin in "${color_plugins[@]}"; do
&lt;li&gt;   folder=$(echo $plugin | cut -d'/' -f2)&lt;/li&gt;
&lt;li&gt;   if [ ! -d "$folder" ]; then&lt;/li&gt;
&lt;li&gt;       git clone --depth 1 "&lt;a href="https://github.com/$plugin.git" rel="noopener noreferrer"&gt;https://github.com/$plugin.git&lt;/a&gt;"&lt;/li&gt;
&lt;li&gt;   else&lt;/li&gt;
&lt;li&gt;       cd "$folder"&lt;/li&gt;
&lt;li&gt;       git fetch origin&lt;/li&gt;
&lt;li&gt;       cd ..&lt;/li&gt;
&lt;li&gt;   fi
+done
&lt;/li&gt;&lt;/span&gt;&lt;span class="err"&gt;


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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Vim-Plug&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/ThomasMarcel/vimrc/blob/0.8.0-plug/.vimrc" rel="noopener noreferrer"&gt;tag 0.8.0-plug&lt;/a&gt; adds the colorscheme in the &lt;code&gt;vim-plug&lt;/code&gt; branch.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gh"&gt;diff --git a/.vimrc b/.vimrc&lt;br&gt;
index 2844774..e3843a2 100644&lt;br&gt;
&lt;/span&gt;&lt;span class="gd"&gt;--- a/.vimrc&lt;br&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/.vimrc&lt;br&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -190,6 +190,8 @@&lt;/span&gt; Plug 'ctrlpvim/ctrlp.vim'&lt;br&gt;
&lt;span class="err"&gt;&lt;br&gt;
&lt;/span&gt; Plug 'dense-analysis/ale'&lt;br&gt;
&lt;span class="err"&gt;&lt;br&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+Plug 'lifepillar/vim-solarized8'&lt;br&gt;
+&lt;br&gt;
&lt;/span&gt; call plug#end()&lt;br&gt;
&lt;span class="err"&gt;&lt;br&gt;
&lt;/span&gt; augroup FiletypeGroup&lt;br&gt;
&lt;span class="p"&gt;@@ -226,3 +228,15 @@&lt;/span&gt; let g:ale_set_loclist = 1&lt;br&gt;
 let g:ale_set_quickfix = 1&lt;br&gt;
 let g:ale_open_list = 1&lt;br&gt;
 let g:ale_list_window_size = 5&lt;br&gt;
&lt;span class="gi"&gt;+&lt;br&gt;
+set background=dark&lt;br&gt;
+colorscheme solarized8&lt;br&gt;
+if has('gui_running')

&lt;ul&gt;
&lt;li&gt; if has('gui_gtk2')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; elseif has('gui_macvim')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; elseif has('gui_win32')&lt;/li&gt;
&lt;li&gt;   set guifont=Dank\ Mono\ Regular:h12&lt;/li&gt;
&lt;li&gt; endif
+endif
&lt;/li&gt;
&lt;/ul&gt;&lt;/span&gt;&lt;span class="err"&gt;


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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Extras&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;So now we have a pretty decent configuration. But there are still some plugins that are good to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/vim-easy-align" rel="noopener noreferrer"&gt;vim-seasy-align&lt;/a&gt; easily align things&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mg979/vim-visual-multi" rel="noopener noreferrer"&gt;vim-visual-multi&lt;/a&gt; for multi selectors&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/goyo.vim" rel="noopener noreferrer"&gt;goyo.vim&lt;/a&gt; distraction-free mode&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/limelight.vim" rel="noopener noreferrer"&gt;limelight.vim&lt;/a&gt; focus on current paragraph, dim the rest (cool with goyo)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/itchyny/lightline.vim" rel="noopener noreferrer"&gt;lightline.vim&lt;/a&gt; status bar&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ryanoasis/vim-devicons" rel="noopener noreferrer"&gt;devicons&lt;/a&gt; file, scm icons&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mhinz/vim-startify" rel="noopener noreferrer"&gt;startify&lt;/a&gt; cool vim startup page, with recent files and a quote&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pechorin/any-jump.vim" rel="noopener noreferrer"&gt;any-jump.vim&lt;/a&gt; jump to definition&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/machakann/vim-highlightedyank" rel="noopener noreferrer"&gt;vim-highlightedyank&lt;/a&gt; to highlight the yaked text for a sec&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/reedes/vim-thematic" rel="noopener noreferrer"&gt;vim-thematic&lt;/a&gt; to switch between themes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/airblade/vim-gitgutter" rel="noopener noreferrer"&gt;vim-gitgutter&lt;/a&gt; to display git information in the "gutter"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/SirVer/ultisnips" rel="noopener noreferrer"&gt;ultisnips&lt;/a&gt; vim snippets engine&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/honza/vim-snippets" rel="noopener noreferrer"&gt;vim-snippets&lt;/a&gt; actual snippets&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authoring
&lt;/h3&gt;

&lt;p&gt;I've written &lt;a href="https://dev.to/animo/authoring-with-vim-46e"&gt;an article abouth authoring with vim&lt;/a&gt;, all the plugins for completion and spelling, and some goodies.&lt;/p&gt;

&lt;h2&gt;
  
  
  More
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Visit &lt;a href="https://vimawesome.com/" rel="noopener noreferrer"&gt;VimAwesome&lt;/a&gt; for a list of popular vim plugins&lt;/p&gt;

&lt;h3&gt;
  
  
  Dotfiles and vimrc generators
&lt;/h3&gt;

&lt;p&gt;There are several dotfiles from developers that you can find on GitHub. And there's &lt;a href="https://vim-bootstrap.com/" rel="noopener noreferrer"&gt;Vim Bootstrap&lt;/a&gt; and other &lt;code&gt;.vimrc&lt;/code&gt; generators.&lt;/p&gt;

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

&lt;p&gt;I hope this will help you. This is also part of a thought process that I went through to cleanup my own &lt;code&gt;.vimrc&lt;/code&gt;, and know it better.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.vimrc&lt;/code&gt; at that point is located in &lt;a href="https://github.com/ThomasMarcel/vimrc/tree/1.0.0" rel="noopener noreferrer"&gt;tag 1.0.0&lt;/a&gt; and &lt;a href="https://github.com/ThomasMarcel/vimrc/tree/1.0.0-plug" rel="noopener noreferrer"&gt;1.0.0-plug&lt;/a&gt;. I will write separate posts for the programming languages I use.&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%2Fuploads%2Farticles%2Ff1v9sl5d01z7w8cr3dlq.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%2Fuploads%2Farticles%2Ff1v9sl5d01z7w8cr3dlq.png" alt="vimrc 1.0.0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And note so self: write smaller articles but more often 😅.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vim</category>
      <category>editor</category>
      <category>lsp</category>
      <category>tools</category>
    </item>
    <item>
      <title>Convert an Express NodeJS App From JavaScript to TypeScript</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Sat, 18 Jul 2020 15:42:21 +0000</pubDate>
      <link>https://dev.to/animo/convert-an-express-nodejs-app-from-javascript-to-typescript-302l</link>
      <guid>https://dev.to/animo/convert-an-express-nodejs-app-from-javascript-to-typescript-302l</guid>
      <description>&lt;p&gt;Hi! 🖖  &lt;/p&gt;

&lt;p&gt;Today, I'll walk us through moving an Express NodeJS app from JavaScript&lt;br&gt;
to TypeScript.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; TypeScript offers type safety "on demand", most of the code&lt;br&gt;
won't break if you move your app from one to the other, and then, you&lt;br&gt;
can add the safety where it is important.&lt;/p&gt;
&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;We are going to start from a &lt;a href="https://github.com/ThomasMarcel/express-app-example/tree/javascript"&gt;fork of Kent C. Dodds' Express example for&lt;br&gt;
mid-large&lt;br&gt;
apps&lt;/a&gt;.&lt;br&gt;
I made a branch called &lt;code&gt;javascript&lt;/code&gt; as a starter.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Nothing is lost, nothing is created, everything is transformed
&lt;/h3&gt;

&lt;p&gt;Let's change the extension of all our app's js files to ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ find . -type f -name '*.js' | grep -v node_modules | grep -v babelrc | while read line; do name=$(echo $line | sed 's/\.js$/.ts/'); mv $line $name; done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;We find all js files, ignore node_modules and babelrc, and rename them&lt;br&gt;
to ts.&lt;/em&gt;  &lt;/p&gt;
&lt;h3&gt;
  
  
  Adding TypeScript
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Let's add the dependencies
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add typescript --dev
$ yarn add concurrently @types/express --dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And in &lt;code&gt;package.json&lt;/code&gt;, we add more scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "start": "node .",
    "build": "babel --delete-dir-on-start --out-dir dist --copy-files --ignore \"**/__tests__/**,**/__mocks__/**\" --no-copy-ignored src",
    "start:dev": "nodemon dist/index.js",
    "build:dev": "tsc --watch --preserveWatchOutput",
    "dev": "concurrently \"npm:build:dev\" \"npm:start:dev\""
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Init the config
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn tsc --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can copy &lt;a href="https://raw.githubusercontent.com/ThomasMarcel/express-app-example/main/tsconfig.json"&gt;my &lt;code&gt;tsconfig.json&lt;/code&gt;&lt;/a&gt;, I mainly added an output dire and small things like that.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the TypeScript compiler, crash and burn
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn tsc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, this breaks. Now let's fix the issues&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixing a File
&lt;/h3&gt;

&lt;p&gt;Let's start with a small file: &lt;code&gt;src/index.ts&lt;/code&gt;. It returns an error that&lt;br&gt;
seems straightforward, but is representative of how TypeScript can be&lt;br&gt;
annoying with little things.  &lt;/p&gt;

&lt;p&gt;Here is the content of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import logger from 'loglevel'
import {startServer} from './start'

const isTest = process.env.NODE_ENV === 'test'
const logLevel = process.env.LOG_LEVEL || (isTest ? 'warn' : 'info')

logger.setLevel(logLevel)

startServer()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/index.ts:7:17 - error TS2345: Argument of type 'string' is not&lt;br&gt;
assignable to parameter of type 'LogLevelDesc'.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So here, we can see that &lt;code&gt;logger.setLevel()&lt;/code&gt; is used to set the log&lt;br&gt;
level, taking a &lt;code&gt;logLevel&lt;/code&gt; variable. And it is going to be a string from&lt;br&gt;
the &lt;code&gt;LOG_LEVEL&lt;/code&gt; environment variable if defined, else based on the&lt;br&gt;
&lt;code&gt;NODE_ENV&lt;/code&gt; variable, it will be a string: 'warn' or 'info'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HOWEVER&lt;/strong&gt;, this crashes now, because in TypeScript, &lt;code&gt;setLevel()&lt;/code&gt; takes&lt;br&gt;
a &lt;code&gt;LogLevelDesc&lt;/code&gt; type, which is essentially an integer with a fancy type&lt;br&gt;
name.&lt;/p&gt;

&lt;p&gt;Common libraries have types well documented, toplevel not really. So&lt;br&gt;
I had to look at examples in the &lt;code&gt;node_modules&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;$ grep -rHin setlevel node_modules | less

node_modules/loglevel/test/node-integration.js:11:
log.setLevel(log.levels.TRACE);
node_modules/loglevel/test/node-integration.js:12:
log.setLevel(log.levels.DEBUG);
node_modules/loglevel/test/node-integration.js:13:
log.setLevel(log.levels.INFO);
node_modules/loglevel/test/node-integration.js:14:
log.setLevel(log.levels.WARN);
node_modules/loglevel/test/node-integration.js:15:
log.setLevel(log.levels.ERROR);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... So here we have some usage, for us it is going to be&lt;br&gt;
&lt;code&gt;logger.levels.INFO&lt;/code&gt;, etc, so we replace &lt;code&gt;"warn"&lt;/code&gt; and &lt;code&gt;"info"&lt;/code&gt; in &lt;code&gt;const&lt;br&gt;
logLevel = process.env.LOG_LEVEL || (isTest ? 'warn' : 'info')&lt;/code&gt; by&lt;br&gt;
&lt;code&gt;logger.levels.WARN&lt;/code&gt; and &lt;code&gt;logger.levels.INFO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It's still not enough, because &lt;code&gt;process.env.LOG_LEVEL&lt;/code&gt; is still&lt;br&gt;
potentially there, and it's going to be a string. So I had to write&lt;br&gt;
a function to convert the string and cast it in a &lt;code&gt;LogLevelDesc&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 convertLogLevel: (logLevel: string | undefined) =&amp;gt; logger.LogLevelDesc = (
  logLevel: string | undefined,
) =&amp;gt; {
  switch (logLevel) {
    case "1":
    case "error":
      return logger.levels.ERROR;
    case "2":
    case "warn":
      return logger.levels.WARN;
    default:
      return logger.levels.INFO;
  }
};

const isTest = process.env.NODE_ENV === "test";
const logLevel: logger.LogLevelDesc = convertLogLevel(process.env.LOG_LEVEL) ||
  (isTest ? logger.levels.WARN : logger.levels.INFO);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the first line, I had to specifically write the type&lt;br&gt;
of the function &lt;code&gt;(logLevel: string | undefined) =&amp;gt; logger.LogLevelDesc&lt;/code&gt;&lt;br&gt;
(a function signature is &lt;code&gt;(param1: type, param2: type, ...) =&amp;gt;&lt;br&gt;
returnType&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I strongly recommend that you use a linter for your editor, so you can&lt;br&gt;
see type errors while writing the code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that this file is fixed, let's try another one with Express code so&lt;br&gt;
we see how this works for bigger, better documented libraries,&lt;/p&gt;
&lt;h3&gt;
  
  
  Fixing an Express Route File
&lt;/h3&gt;

&lt;p&gt;Now let's fix &lt;code&gt;src/routes/math.ts&lt;/code&gt;. There is a problem with implicit&lt;br&gt;
&lt;code&gt;any&lt;/code&gt; type for req, res, etc. This can be solved by defining an explicit&lt;br&gt;
type &lt;code&gt;any for those&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;async function add(req: any, res: any) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Types for request and stuff aren't safe and more of adding another&lt;br&gt;
headache than a solution. I prefer creating a type for the query&lt;br&gt;
parameters, this is more useful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type MathQuery = {
  a: number;
  b: number;
  c: number;
};

async function add(req: any, res: any) {
  const mathQuery = req.query as MathQuery;
  const sum = Number(mathQuery.a) + Number(mathQuery.c);
  res.send(sum.toString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here, we cast &lt;code&gt;req.query&lt;/code&gt; as MathQuery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some Battles You Can't Win
&lt;/h3&gt;

&lt;p&gt;We've seen well done transition to TypeScript, this latest compromise,&lt;br&gt;
now we'll see a case where it is too painful to fix the code so we&lt;br&gt;
ignore it.&lt;/p&gt;

&lt;p&gt;I am a partisan of using TypeScript when it is useful, and try to use&lt;br&gt;
the type system the most possible, to avoid errors at runtime.&lt;/p&gt;

&lt;p&gt;That said, there are times when it is just too exhausting, painful and&lt;br&gt;
a waste of time to use.  Here for example, the &lt;code&gt;src/start.ts&lt;/code&gt; file is&lt;br&gt;
a good example. Kent has wrapped the &lt;code&gt;startServer&lt;/code&gt; and middleware&lt;br&gt;
functions in promises with no type, no real return, just a resolution.&lt;br&gt;
And I'm sure he knows what he's doing a lot better than me.&lt;/p&gt;

&lt;p&gt;There is no way to match this signature without overriding or modifying&lt;br&gt;
the node type definitions, so in that case when we know it's working,&lt;br&gt;
it's faster and probably best just to ignore the type verification.&lt;/p&gt;

&lt;p&gt;Simply add &lt;code&gt;// @ts-nocheck&lt;/code&gt; at the top of the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  We've done it again! 🎉
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ThomasMarcel/express-app-example"&gt;The final code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>express</category>
    </item>
    <item>
      <title>Deno Version Management</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Tue, 07 Jul 2020 21:09:58 +0000</pubDate>
      <link>https://dev.to/animo/deno-version-management-3o70</link>
      <guid>https://dev.to/animo/deno-version-management-3o70</guid>
      <description>&lt;p&gt;&lt;em&gt;Logo © &lt;a href="https://twitter.com/SamipPoudel3"&gt;Samip Poudel&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Deno is really nice! Version managers are nice too, they offer a way to have several versions of a runtime, dependencies installed at a user level, without breaking system runtime if any.&lt;/p&gt;

&lt;p&gt;Here we will use one version manager to install the Deno runtime 😀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lexicon
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deno
&lt;/h3&gt;

&lt;p&gt;Deno is a JavaScript/TypeScript runtime that can replace NodeJS, with&lt;br&gt;
the aim to be more secure.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deno Runtime Installation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Standard Installation
&lt;/h3&gt;

&lt;p&gt;There are a bunch of scripts to install the Deno runtime in &lt;a href="https://deno.land/manual/getting_started/installation"&gt;the&lt;br&gt;
official&lt;br&gt;
documentation&lt;/a&gt;,&lt;br&gt;
depending on your operating system. Deno is written in Rust, so you can&lt;br&gt;
also install it with cargo, the Rust package manager.&lt;/p&gt;
&lt;h3&gt;
  
  
  dvm
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The real topic of this post!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;dvm (Deno Version Manager) is a version manager inspired by&lt;br&gt;
&lt;a href="https://github.com/Schniz/fnm"&gt;fnm&lt;/a&gt;, a fast NodeJS version manager.  &lt;/p&gt;
&lt;h4&gt;
  
  
  Installation
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;You can get it from the &lt;a href="https://github.com/imbsky/dvm/releases"&gt;GitHub release&lt;br&gt;
page&lt;/a&gt; or with opam if you work&lt;br&gt;
with OCaml, it is written in OCaml.&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam pin add dvm https://github.com/imbsky/dvm.git 
$ opam install dvm
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;For Windows, your best bet is probably the OPAM approach, or WSL.&lt;/strong&gt;  &lt;/p&gt;
&lt;h4&gt;
  
  
  Initialization
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;It is not as mature as fnm, so what you have to do next is:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install a Deno runtime&lt;br&gt;&lt;br&gt;
&lt;code&gt;$ dvm install 1.1.3&lt;/code&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the Deno runtime&lt;br&gt;&lt;br&gt;
&lt;code&gt;$ dvm use 1.1.3&lt;/code&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the Deno runtime to your PATH&lt;br&gt;&lt;br&gt;
Add this line to your shell rc: &lt;code&gt;export PATH="$HOME/.dvm/current:$PATH"&lt;/code&gt;  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Test the Runtime
&lt;/h4&gt;

&lt;p&gt;Deno hosts an example file with a single line console log in it. You can&lt;br&gt;
test your runtime with it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ deno run https://deno.land/std/examples/welcome.ts  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  This is it! 🎊
&lt;/h2&gt;

</description>
      <category>deno</category>
      <category>node</category>
      <category>javascript</category>
      <category>runtime</category>
    </item>
    <item>
      <title>Emojis in Svelte 3 🤘</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Wed, 01 Jul 2020 08:03:25 +0000</pubDate>
      <link>https://dev.to/animo/emojis-in-svelte-3-2829</link>
      <guid>https://dev.to/animo/emojis-in-svelte-3-2829</guid>
      <description>&lt;p&gt;Hey!&lt;/p&gt;

&lt;p&gt;So today, let's make an emoji component in Svelte 3. It's fairly simple. Our objective is to be able to write something like below, and it'll show the emoji. We also want to be careful that the accessibility attributes are there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Emoji symbol="👋" label="Hi!" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start by writing our &lt;code&gt;Emoji&lt;/code&gt; component, and call it &lt;code&gt;Emoji.svelte&lt;/code&gt;, with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  export let label;
  export let symbol;
&amp;lt;/script&amp;gt;

&amp;lt;style&amp;gt;
&amp;lt;/style&amp;gt;

&amp;lt;span
  className="emoji"
  role="img"
  aria-label={label ? label : ""}
  aria-hidden={label ? "false" : "true"}
&amp;gt;
{symbol}
&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component will be a span&lt;/li&gt;
&lt;li&gt;It has a symbol and a label attribute, so it's a11y-compliant&lt;/li&gt;
&lt;li&gt;The aria is hidden if there's no label (but you should always put one)&lt;/li&gt;
&lt;li&gt;The symbol is the actual emoji, and will be displayed as a child/inner HTML of the span&lt;/li&gt;
&lt;li&gt;Inside the script tag, we make the label and symbol variables available&lt;/li&gt;
&lt;li&gt;I am leaving a style tag, so you can add CSS in there if you want&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is it! I You just have to import the component like so, in another component's script tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  import Emoji from '../components/Emoji.svelte';
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... Then use the &lt;code&gt;Emoji&lt;/code&gt; tag as described in the first code block, and that's it!&lt;/p&gt;

&lt;p&gt;You still have to copy/paste the emoji character from somewhere and insert it in the &lt;code&gt;symbol&lt;/code&gt; attribute of the &lt;code&gt;Emoji&lt;/code&gt; tag. If you are on Mac OS, I recommend the lightweight &lt;a href="https://github.com/jaredly/qmoji"&gt;qmoji&lt;/a&gt; by Jared Forsyth, but there's a bunch of those emoji apps for any OS.&lt;/p&gt;

&lt;p&gt;Talk to y'all soon!&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>a11y</category>
      <category>emoji</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Authoring with Vim</title>
      <dc:creator>Thomas Alcala Schneider</dc:creator>
      <pubDate>Wed, 01 Jul 2020 07:41:43 +0000</pubDate>
      <link>https://dev.to/animo/authoring-with-vim-46e</link>
      <guid>https://dev.to/animo/authoring-with-vim-46e</guid>
      <description>&lt;p&gt;&lt;strong&gt;The REAL writing, not &lt;em&gt;code&lt;/em&gt; writing 😆.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post reflects only the thoughts of its author, Thomas Alcala.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you don't know vim, I recommend trying &lt;a href="https://vim-adventures.com/"&gt;Vim&lt;br&gt;
Adventures&lt;/a&gt;, a game-like vim tutorial.&lt;/em&gt;  &lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It was already the case before with tools like WordPress, but with the surge of headless CMS, serverless platforms, JAMstack, Wix, writing and&lt;br&gt;
publishing your own blog is easier than ever.  &lt;/p&gt;

&lt;p&gt;There's a lot of value in browser editors too (the famous WYSIWYG, What&lt;br&gt;
You See Is What You Get) that let users click text formatting buttons,&lt;br&gt;
and the HTML code is generated for them. No need to learn web design,&lt;br&gt;
and with browser plugins like the Grammarly plugin, you also get the&lt;br&gt;
spelling,  grammar corrections you'd get in office software.  &lt;/p&gt;

&lt;p&gt;So you ask &lt;strong&gt;"is there a reason to try and write with vim?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vim is not the most beginner-friendly editor, so this is mostly for&lt;br&gt;
people already familiar with vim, but the answer is &lt;em&gt;&lt;strong&gt;YES!&lt;/strong&gt;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Let's try to get some cool writing features, to prove it!  &lt;/p&gt;
&lt;h2&gt;
  
  
  Requisites
&lt;/h2&gt;

&lt;p&gt;As you may know, the vim configuration is located in &lt;code&gt;~/.vimrc&lt;/code&gt;.&lt;br&gt;
Technically, you can call &lt;code&gt;vi -u /path/to/some/other/vimrc&lt;/code&gt; to use&lt;br&gt;
another configuration file, so it should be possible to use different&lt;br&gt;
configurations for code and writing. I prefer to maintain only one file, so I use a plugin manager for vim.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/junegunn/vim-plug"&gt;vim-plug&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://golang.org/dl/"&gt;Go&lt;/a&gt; for some plugins
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Formatting
&lt;/h2&gt;

&lt;p&gt;For text formatting, I use&lt;br&gt;
&lt;a href="https://github.com/reedes/vim-pencil"&gt;vim-pencil&lt;/a&gt;. It automatically&lt;br&gt;
breaks lines in Markdown files, hides formatting code, etc. It helps&lt;br&gt;
keeping the paragraphs clean.&lt;br&gt;&lt;br&gt;
I use the basic implementation with no configuration, the only trick&lt;br&gt;
I made is with vim-plug to conditionally import it, so it doesn't break&lt;br&gt;
lines and stuff when I write code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plug 'reedes/vim-pencil', { 'for': ['text', 'notes', 'markdown', 'mkd'] }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spell Check
&lt;/h2&gt;

&lt;p&gt;For spell checking, I use another excellent plugin by reedes:&lt;br&gt;
&lt;a href="https://github.com/reedes/vim-lexical"&gt;vim-lexical&lt;/a&gt;. You can also&lt;br&gt;
configure a dictionary and a thesaurus, for completion, for technical&lt;br&gt;
terms, etc. Very powerful.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Quality Assurance
&lt;/h2&gt;

&lt;p&gt;Last but not least, by reedes, there's a plugin for writing quality,&lt;br&gt;
called &lt;a href="https://github.com/reedes/vim-wordy"&gt;vim-wordy&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;It's got a bunch of dictionary rings for the English language, and you&lt;br&gt;
can switch between them. For example, it detects  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;redundant words&lt;/li&gt;
&lt;li&gt;jargon&lt;/li&gt;
&lt;li&gt;problematic terms&lt;/li&gt;
&lt;li&gt;lazy or passive voice&lt;/li&gt;
&lt;li&gt;manipulative (weasel) language&lt;/li&gt;
&lt;li&gt;colloquialisms and idioms&lt;/li&gt;
&lt;li&gt;etc... &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll run it for fun after a first draft of this post, this should be&lt;br&gt;
somewhat of an eye opener 😆.&lt;/p&gt;
&lt;h2&gt;
  
  
  Completion
&lt;/h2&gt;

&lt;p&gt;Completion is kind of done by the lexical plugin, this is more about&lt;br&gt;
&lt;strong&gt;&lt;em&gt;prediction&lt;/em&gt; of the next word&lt;/strong&gt; in a sentence!&lt;/p&gt;

&lt;p&gt;Would you like an example?  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M13rmpiS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/uploads/prediction.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M13rmpiS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/uploads/prediction.gif" alt="Text prediction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a non-native English speaker like me, this is very useful, most of&lt;br&gt;
all for some idiomatic expressions.  &lt;/p&gt;

&lt;p&gt;This is done by combining some data, scripts and vim plugins:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the data from
&lt;a href="https://github.com/high-moctane/nextword-data/releases"&gt;the nextword dataset release page&lt;/a&gt;, there's a small and a large dataset, pick the one you like&lt;/li&gt;
&lt;li&gt;Define an environment variable in your shell for the dataset location
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export NEXTWORD_DATA_PATH=/path/to/nextword-data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Get the nextword script (you must have installed Go before, as
mentioned in the prerequisites)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get -u github.com/high-moctane/nextword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Install
&lt;a href="https://github.com/high-moctane/asyncomplete-nextword.vim"&gt;asyncomplete-nextword&lt;/a&gt;, that means adding the &lt;code&gt;asyncomplete&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt; vim plugins too, it's all in the plugin installation instructions
Here I use the same trick as for the pencil plugin, and write
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Plug 'high-moctane/asyncomplete-nextword.vim', { 'for': ['text', 'notes', 'markdown', 'mkd'] }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;in my &lt;code&gt;.vimrc&lt;/code&gt; file, so this plugin doesn't try to complete code&lt;br&gt;
   with grammarily correct words  &lt;/p&gt;
&lt;h2&gt;
  
  
  Emojis
&lt;/h2&gt;

&lt;p&gt;With very technical or outlandish posts, like one trying to sell writing&lt;br&gt;
 blog posts with vim, it's almost mandatory to put&lt;br&gt;
some emojis to lighten the tone. I use a couple of plugins for that:&lt;br&gt;
&lt;a href="https://github.com/junegunn/vim-emoji"&gt;vim-emoji&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://github.com/prabirshrestha/asyncomplete-emoji.vim"&gt;asyncomplete-emoji&lt;/a&gt;, that takes advantage of the asyncomplete plugin already installed in the completion segment of this post.  &lt;/p&gt;

&lt;p&gt;The asyncomplete plugin autocompletes stuff starting with colon, like&lt;br&gt;
&lt;code&gt;:thumbsup:&lt;/code&gt;, then I mapped a &lt;code&gt;vim-emoji&lt;/code&gt; command in my &lt;code&gt;.vimrc&lt;/code&gt; file that uses &lt;code&gt;sed&lt;/code&gt; to translate all emojis&lt;br&gt;
to unicode 👍!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nnoremap &amp;lt;Leader&amp;gt;e :s/:\([^:]\+\):/\=emoji#for(submatch(1), submatch(0))/g&amp;lt;CR&amp;gt;  
nnoremap &amp;lt;Leader&amp;gt;E :%s/:\([^:]\+\):/\=emoji#for(submatch(1), submatch(0))/g&amp;lt;CR&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now, &lt;code&gt;&amp;lt;Leader&amp;gt;&lt;/code&gt; (comma &lt;code&gt;,&lt;/code&gt; in my configuration) + &lt;code&gt;e&lt;/code&gt; rewrites all&lt;br&gt;
&lt;code&gt;:emoji:&lt;/code&gt; to their symbol, lowercase &lt;code&gt;e&lt;/code&gt; for the current line, uppercase&lt;br&gt;
for the whole buffer.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Distraction-free Mode
&lt;/h2&gt;

&lt;p&gt;I also use &lt;a href="https://github.com/junegunn/goyo.vim"&gt;goyo.vim&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://github.com/junegunn/limelight.vim"&gt;limelight.vim&lt;/a&gt;, even though&lt;br&gt;
it may be even more distracting until you get used to it! 😆  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bpEpjiF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/uploads/goyo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bpEpjiF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/v1/uploads/goyo.gif" alt="Goyo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;Not for vim but for screen recording and making gifs out of videos, I&lt;br&gt;
use:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simplescreenrecorder to record the screen or part of it
&lt;/li&gt;
&lt;li&gt;ffmpeg to make a gif out of the mkv video
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i ~/Videos/simplescreenrecorder-2020-03-29_19.22.57.mkv -r 15 -vf scale=720:-1 uploads/goyo.gif  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Turns out it's not completely crazy to author stuff in vim! 😉&lt;/p&gt;

</description>
      <category>vim</category>
      <category>editor</category>
      <category>author</category>
      <category>authoring</category>
    </item>
  </channel>
</rss>
