<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title></title>
    <description>Trust me, Python will rule the world. And Emacs will guide it.</description>
    <link>pygopar.com/</link>
    <atom:link href="pygopar.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 27 Jan 2026 07:33:10 +0000</pubDate>
    <lastBuildDate>Tue, 27 Jan 2026 07:33:10 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Simple Language Agnostic Emacs IDE</title>
        <description>&lt;p&gt;A lot of people are jumping in the LSP ship for their all-purpose IDE, which is
fine but LSP has never been friendly to me. I always ended up having problems
with something. This led me to build a minimal but very helpful setup that will
work for many of the most used languages (Python/Javascript/Java/C++/etc).&lt;/p&gt;

&lt;p&gt;I wanted an IDE setup within emacs that didn’t involve LSP or any other server
because I kept running into problems and maintaining multiple servers for each
language is a hassle. After searching for a bit I came into the following
packages/libraries that have helped that transition to a simple but powerful IDE.&lt;/p&gt;

&lt;p&gt;Here they are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bbatsov/projectile&quot;&gt;Projectile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/jacktasia/dumb-jump&quot;&gt;Dumbjump&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/company-mode/company-mode&quot;&gt;Company Mode&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html&quot;&gt;GUD&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The reasoning for the following are below:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Projectile: This is a project management and navigation package. Think of it as
your sidebar view of files in a typical IDE plus the ability to run
commands on the entire project.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dumbjump: This is arguably the most essential feature, the ability to jump to
definition. This package is nicely well-written and works amazingly. Best of
all, works on all major languages and has no dependencies.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Company Mode: This is what I use for auto code completion. It’s not hooked up
to an engine but instead, it simply re-uses words that I’ve used throughout any
buffers I’ve opened. It’s a “smart” dumb auto-code completion. Works for my purpose&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GUD: Built-in debugger library in emacs. It comes with a few debuggers such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb&lt;/code&gt; which I’m constantly using. It will probably come with the debugger you
need. If not, then it might be worth checking out
https://github.com/realgud/realgud.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 02 Sep 2022 00:00:00 +0000</pubDate>
        <link>pygopar.com/simple-language-agnostic-emacs-ide</link>
        <guid isPermaLink="true">pygopar.com/simple-language-agnostic-emacs-ide</guid>
        
        
        <category>emacs</category>
        
      </item>
    
      <item>
        <title>How To Be A Kind Engineer</title>
        <description>&lt;p&gt;As I’ve worked in tech, I’ve come to appreciate when engineers are considerate of other engineers.
(If you’re a junior engineer reading this, I implore you to do all this and you will stand out)&lt;/p&gt;

&lt;p&gt;Here are a few things that in my mind, make an engineer “kind”:&lt;/p&gt;

&lt;h2 id=&quot;meaningful-git-messages&quot;&gt;Meaningful Git Messages&lt;/h2&gt;

&lt;p&gt;To me, a meaningful git message is something that has 2 (possibly 3 things).
Below is an example:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[BET-335] Implement caching on expensive user operations&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here are two things:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The message has the ticket ID (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[BET-335]&lt;/code&gt;) which you can refer to for more details on the work.
This can be for example the unique Jira slug of the ticket. &lt;strong&gt;Always include it&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A clear concise message that says what this commit contains and the purpose of the changes&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Not shown here, but in commit messages you are allowed to add extra text to describe more in detail
about the changes made.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For better guidance, read this which was my starting point: &lt;a href=&quot;https://chris.beams.io/posts/git-commit/&quot;&gt;https://chris.beams.io/posts/git-commit/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;to-the-point-messages&quot;&gt;To The Point Messages&lt;/h2&gt;

&lt;p&gt;One thing that I greatly dislike is when someone sends me a message via Slack with nothing relevant or missing information.
eg,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hey!&lt;/code&gt; (followed by more lines entered one by one)
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;page is not working&lt;/code&gt; (very vague, which page?)&lt;/p&gt;

&lt;p&gt;I’m pretty sure everyone has seen the examples above from someone in their company.
Not pretty nice, and greatly distracting if I’m in deep thought.&lt;/p&gt;

&lt;p&gt;Here’s how I approach it (still figuring out what I like best but here’s what I got so far):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Hey PERSON, I&apos;m working on JIRA-123 ticket and I&apos;ve ran into some roadblocks with the database.

Problem:
DB is not populating from fixtures

What I&apos;ve tried:
- Restarting DB
- Walking in circles
- Make a sacrafice to the gods

Ask:
Can we pair up once you are free or can you refer me to someone who might know the fix? thx!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is generally the format I go with, give everything in one go, with different sections and info.
I find it easier to read and would love for someone to send me messages like this. (No one has -_-)
Also, the Jira ticket is usually linked to the actual ticket for easy access.&lt;/p&gt;

&lt;p&gt;For some guidance, and ideas on messaging etiquette read this: &lt;a href=&quot;https://slack.com/intl/en-gb/blog/collaboration/etiquette-tips-in-slack&quot;&gt;https://slack.com/intl/en-gb/blog/collaboration/etiquette-tips-in-slack&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;always-lintformat-before-push&quot;&gt;Always lint/format before push&lt;/h2&gt;

&lt;p&gt;I’m surprised when I see commits/PRs failing because they didn’t pass the linter/formatter check.
This can be easily avoided if we all ran our linters before committing (git hooks anyone?)
These tools are here to make it more readable/easier to digest when reviewing.&lt;/p&gt;

&lt;p&gt;Also, if you have something like GitHub that comments wherever linter/formatter violations occurred in your PR,
then it gets really hard to review with a wall of linter errors in the way&lt;/p&gt;

&lt;h2 id=&quot;document-your-own-pr&quot;&gt;Document your own PR&lt;/h2&gt;

&lt;p&gt;When creating a PR, please:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Properly describe what your changes are doing (Write as much as you need)&lt;/li&gt;
  &lt;li&gt;Link to the Bug tracker issue&lt;/li&gt;
  &lt;li&gt;How to test your changes (if applicable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For your PR code, please take your time to review and:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Ask any questions you have, don’t wait for someone to point them out or hope they don’t catch it&lt;/p&gt;

    &lt;p&gt;If you were unsure about the changes you made (eg not sure if calling expensive func or something is a good idea)
then please comment about asking for feedback. Don’t expect someone to catch and start a conversation, or even worse
your changes go out to production and break something, all because you didn’t take the initiative.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Highlight any relevant parts of a file&lt;/p&gt;

    &lt;p&gt;Sometimes we have ‘noise’ in PRs such as indentation changes which mask the real purpose of the changes.
When this happens I usually comment at the top of the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A lot of noise due to indentation changes, please see comments inside file for relevant changes&lt;/code&gt;
Then I go to each of my actual changes and say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;relevant bit, doing x,y z here&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;document-your-and-someone-elses-code&quot;&gt;Document your (and someone else’s) code&lt;/h2&gt;

&lt;p&gt;When a codebase grows to a certain size, it’s hard to maintain, especially with all the due dates and what not’s.
Cause of that, I’ve come to love/hate a few things but for now, I’ll mainly talk about comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Love them when they are right.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hate them when they are missing, or even worse, when they have the wrong information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks to this, I always try to make sure I document anything I’m working on that isn’t obvious at first glance.
&lt;strong&gt;And to update wrong or missing comments.&lt;/strong&gt;
I’ve been bitten before by being too trusting at what a piece of code does from just reading the comments,
and then I’m stuck wondering why it’s not working. Please comment on your code, and update any outdated ones that you see in the wild.
Other devs and I will thank you in spirit.&lt;/p&gt;

&lt;h2 id=&quot;be-considerate&quot;&gt;Be considerate&lt;/h2&gt;
&lt;p&gt;Everyone should strive to be kind.&lt;/p&gt;
</description>
        <pubDate>Thu, 18 Nov 2021 00:00:00 +0000</pubDate>
        <link>pygopar.com/how-to-be-a-kind-engineer</link>
        <guid isPermaLink="true">pygopar.com/how-to-be-a-kind-engineer</guid>
        
        
        <category>engineering</category>
        
      </item>
    
      <item>
        <title>Creating new columns in Org agenda</title>
        <description>&lt;p&gt;Whenever viewing the Org agenda, you can add new “columns” to the view with the help of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org-agenda-prefix-format&lt;/code&gt; variable.
If you do a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C-h v org-agenda-prefix-format&lt;/code&gt; in emacs, you should get a nice description of what it does and how to use it.&lt;/p&gt;

&lt;p&gt;Here is an example on how to extend it&lt;/p&gt;

&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;;; Originally from here: https://stackoverflow.com/a/59001859/2178312&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/get-schedule-or-deadline-if-available&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;Return an calendar emoji if current item doens&apos;t have a schedule or deadline.
  Otherwise return an empty string.&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;scheduled&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;org-get-scheduled-time&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;org-get-deadline-time&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;scheduled&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;deadline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;   &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;org-agenda-prefix-format&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;agenda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; %i %-12:c%?-12t% s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;todo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; %i %-10:c %-5e %(gopar/get-schedule-or-deadline-if-available)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; %i %-12:c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;search&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; %i %-12:c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In a nutshell, if I have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TODO&lt;/code&gt; item that doesn’t have a schedule or deadline, then I’ll add a display a simple calendar emoji, otherwise I’ll just leave some space (To emulate it being empty, otherwise the spacing gets out of sync)&lt;/p&gt;

&lt;p&gt;I also made it so that it displays the effort.&lt;/p&gt;

&lt;p&gt;Heres a screenshot of how it looks (I use a black/white theme):
&lt;img src=&quot;/assets/images/posts/org_column.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, I have 2 thigs that don’t have a schedule/deadline and 2 of them show the estimated time it would take to complete them.&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Apr 2021 00:00:00 +0000</pubDate>
        <link>pygopar.com/creating-new-columns-in-org-agenda</link>
        <guid isPermaLink="true">pygopar.com/creating-new-columns-in-org-agenda</guid>
        
        
        <category>emacs</category>
        
      </item>
    
      <item>
        <title>Combining react-hook-form with Draft-JS WYSIWYG</title>
        <description>&lt;p&gt;We use &lt;a href=&quot;https://react-hook-form.com/&quot;&gt;react-hook-form&lt;/a&gt; at work, and we needed to integrate it with the &lt;a href=&quot;https://jpuri.github.io/react-draft-wysiwyg/#/&quot;&gt;React Draft WYSIWYG&lt;/a&gt; editor. Ended up creating something like this (which requires another small 3rd party lib &lt;a href=&quot;https://github.com/jpuri/draftjs-to-html&quot;&gt;draft-to-html&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
import React from &apos;react&apos;;
import PropTypes from &apos;prop-types&apos;;
import { Controller } from &apos;react-hook-form/dist/index.ie11&apos;;
import { Editor } from &apos;react-draft-wysiwyg&apos;;
import draftToHtml from &apos;draftjs-to-html&apos;;
import &apos;react-draft-wysiwyg/dist/react-draft-wysiwyg.css&apos;;

/**
 * Given an html string.
 * Return an `EditorState` object that is used for the Rich Editor Text Box.
 *
 */

export const getEditorState = (name) =&amp;gt; {
  const { contentBlocks, entityMap } = htmlToDraft(name || &apos;&apos;);
  const contentState = ContentState.createFromBlockArray(contentBlocks, entityMap);
  return EditorState.createWithContent(contentState);
};

const EMPTY_VALUE_TO_PACIFY_WARNINGS = &apos;&apos;;

/**
 * Component that provides basic Rich Text Editor.
 */
const RichEditor = ({ name, onUpdate }) =&amp;gt; (
  &amp;lt;Controller
    name={name}
    defaultValue={EMPTY_VALUE_TO_PACIFY_WARNINGS}
    render={({ onChange, value }) =&amp;gt; {
      let defaultEditorState;
      if (defaultValue || value) {
        defaultEditorState = getEditorState(defaultValue || value);
      }

      const onInternalChange = (currentContentState) =&amp;gt; {
        const html = draftToHtml(currentContentState);
        onChange(html);
        if (onUpdate) onUpdate(html);
      };

      const toolbar = {
        options: [&apos;inline&apos;, &apos;blockType&apos;, &apos;list&apos;],
        inline: {
          inDropdown: false,
          className: undefined,
          component: undefined,
          dropdownClassName: undefined,
          options: [&apos;bold&apos;, &apos;italic&apos;, &apos;underline&apos;, &apos;strikethrough&apos;],
        },
        blockType: {
          inDropdown: true,
          options: [&apos;Normal&apos;, &apos;H1&apos;, &apos;H2&apos;, &apos;H3&apos;, &apos;H4&apos;, &apos;H5&apos;, &apos;H6&apos;],
        },
        list: {
          inDrodown: false,
          options: [&apos;unordered&apos;, &apos;ordered&apos;],
        },
      }

      const editorStyle = { border: &apos;1px solid #565c65&apos;, height: &apos;10rem&apos; }

      return (
        &amp;lt;Editor
          tabIndex=&quot;0&quot;
          spellCheck
          defaultEditorState={defaultEditorState}
          onChange={onInternalChange}
          editorStyle={editorStyle}
          toolbar={toolbar}
        /&amp;gt;
      );
    }}
  /&amp;gt;
);

RichEditor.propTypes = {
  name: PropTypes.string.isRequired,
  onUpdate: PropTypes.func,
};

RichEditor.defaultProps = {
  onUpdate: undefined,
};

export default RichEditor;

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

&lt;p&gt;This works nicely and we use it in within FormContext (that is part of react-hook-form).&lt;/p&gt;

&lt;p&gt;That’s pretty much it.&lt;/p&gt;
</description>
        <pubDate>Sat, 10 Apr 2021 00:00:00 +0000</pubDate>
        <link>pygopar.com/combining-react-hook-form-with-draft-js-wysiwyg</link>
        <guid isPermaLink="true">pygopar.com/combining-react-hook-form-with-draft-js-wysiwyg</guid>
        
        
        <category>javascript</category>
        
      </item>
    
      <item>
        <title>Extending Eshell Git Prompt To Provide Virtualenv Info</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/images/posts/eshell-venv.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There’s a package that customizes your eshell prompt, it’s called &lt;a href=&quot;https://github.com/xuchunyang/eshell-git-prompt&quot;&gt;eshell-git-prompt&lt;/a&gt;. Its pretty awesome except it doesn’t show
which virtualenv I’m in, which is a big no no for me. So I ended up creating a different prompt from one of the provided ones in the package.&lt;/p&gt;

&lt;p&gt;Before I show the code, it’s important to know that I’m using &lt;a href=&quot;https://github.com/porterjamesj/virtualenvwrapper.el&quot;&gt;virtualenvwrapper&lt;/a&gt; to know which virtualenv I’m currently in, therefore a dependency.&lt;/p&gt;

&lt;p&gt;Here’s basically what I added to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;powerline&lt;/code&gt; prompt theme&lt;/p&gt;
&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;venv-current-name&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;venv-current-name&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;#5B3758&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;#5B3758&quot;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Small snippet to inject :)&lt;/p&gt;

&lt;p&gt;Anyways, here’s how it all looks together:&lt;/p&gt;
&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;;;; An extension of &apos;powerline&apos; theme from `eshell-git-prompt`&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defmacro&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;Add face PROPERTIES to STR.&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;indent&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;propertize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;face&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;,@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;read-only&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;rear-nonsticky&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;read-only&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-powerline-venv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\xe0b0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;branch&lt;/span&gt;            &lt;span class=&quot;s&quot;&gt;&quot;\xe0a0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;detached&lt;/span&gt;          &lt;span class=&quot;s&quot;&gt;&quot;\x27a6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cross&lt;/span&gt;             &lt;span class=&quot;s&quot;&gt;&quot;\x2718&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dir&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;propertize&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-exit-success-p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cross&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-powerline-dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;ss&quot;&gt;&apos;face&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;read-only&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt--git-root-dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git-face&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt--collect-status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-not-clean-face&lt;/span&gt;
                    &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-clean-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-branch-name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt--branch-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;propertize&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;-if-let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;branch-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-branch-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;branch&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;branch-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;detached&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt--commit-short-sha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;ss&quot;&gt;&apos;face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git-face&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;read-only&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;;; This is the actuall important stuff, everthing else is the same&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;venv-current-name&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;venv-current-name&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;#5B3758&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;#5B3758&quot;&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dir&lt;/span&gt;
                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;
                   &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                   &lt;span class=&quot;ss&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                 &lt;span class=&quot;nv&quot;&gt;git&lt;/span&gt;
                 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;
                   &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;git-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dir&lt;/span&gt;
               &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;
                 &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\n&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;segment-separator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;ss&quot;&gt;:foreground&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;face-background&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-powerline-dir-face&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;propertize&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;$&quot;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;invisible&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;read-only&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with-read-only-face&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defconst&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-powerline-venv-regexp&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;^[^$\n]*\\\$ &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;provide&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;powerline-with-venv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;I put this somewhere in my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.emacs.d&lt;/code&gt; directory and load up it via&lt;/p&gt;

&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;use-package&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;powerline-with-venv&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:ensure&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:after&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;;; This is a dependency&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:load-path&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;lisp/themes/powerline-with-venv&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;;; path to where I saved the file&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:config&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;;; Allow me to add this to the possible eshell prompt selections&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-to-list&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;eshell-git-prompt-themes&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;powerline-plus&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-powerline-venv&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-powerline-regexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;;; Automatically set this as the default theme to use&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-git-prompt-use-theme&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;powerline-plus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It was pretty simple to do, honestly the longest time was to decided what color to use as the virtualenv part.&lt;/p&gt;
</description>
        <pubDate>Thu, 17 Dec 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/extending-eshell-git-prompt-to-provide-virtualenv-info</link>
        <guid isPermaLink="true">pygopar.com/extending-eshell-git-prompt-to-provide-virtualenv-info</guid>
        
        
        <category>emacs</category>
        
        <category>eshell</category>
        
      </item>
    
      <item>
        <title>Making Eshell tell jokes</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/images/posts/eshell-joke.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Whenever you start eshell, there is a banner that welcomes you. I decided I didn’t like having the same message everytime so I hooked up eshell to query some apis to return a joke on eshell startup.
Before I show how to do that, you need to understand that eshell loads up modules (list of modules are in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eshell-modules-list&lt;/code&gt;), and in that list there is a module called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eshell-banner&lt;/code&gt;  which is
in charge of displaying the banner on startup (who would of guessed). With that in mind, we can do the following:&lt;/p&gt;

&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;use-package&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;em-banner&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:defer&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:ensure&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:custom&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eshell-banner-message&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;funcall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-jokes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-jokes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: I am using &lt;a href=&quot;https://github.com/jwiegley/use-package&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use-package&lt;/code&gt;&lt;/a&gt; but same functionality should be available with the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval-after-load&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What I’m doing above is setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eshell-banner-message&lt;/code&gt; (which can be any s-exp) to a function that returns a string (the joke).
The function itself is randomly selecting an element from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gopar/request-jokes&lt;/code&gt; (which we will define in moment), once it has selected an element, it will call it (all the elements in the list are functions)&lt;/p&gt;

&lt;p&gt;Here is how I’m defining the variables and how I’m querying the apis&lt;/p&gt;

&lt;div class=&quot;language-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;use-package&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:defer&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:ensure&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:commands&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:custom&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request-timeout&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request-message-level&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request-log-level&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:init&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-chuck-norris-joke&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;Return a chuck norris joke&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;assoc-default&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request-response-data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;
                                                           &lt;span class=&quot;s&quot;&gt;&quot;https://api.chucknorris.io/jokes/random&quot;&lt;/span&gt;
                                                           &lt;span class=&quot;ss&quot;&gt;:parser&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;json-read&lt;/span&gt;
                                                           &lt;span class=&quot;ss&quot;&gt;:headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Accept&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                                                           &lt;span class=&quot;ss&quot;&gt;:sync&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-dad-joke&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;Return a dad joke&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;concat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;assoc-default&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;joke&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request-response-data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;request&lt;/span&gt;
                                                          &lt;span class=&quot;s&quot;&gt;&quot;https://icanhazdadjoke.com/&quot;&lt;/span&gt;
                                                          &lt;span class=&quot;ss&quot;&gt;:parser&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;json-read&lt;/span&gt;
                                                          &lt;span class=&quot;ss&quot;&gt;:headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Accept&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                                                          &lt;span class=&quot;ss&quot;&gt;:sync&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\n\n&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-jokes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gopar/request-chuck-norris-joke&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;gopar/request-dad-joke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First thing to notice is that I am using &lt;a href=&quot;https://github.com/tkf/emacs-request&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt;&lt;/a&gt; which allows me to effortlessly make network requests \o/
Next, you can see I have 2 functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gopar/request-dad-joke&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gopar/request-chuck-norris-joke&lt;/code&gt;) that return a joke from their apis, and am storing both
those functions in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gopar/request-jokes&lt;/code&gt; (which is what eshell banner is using).&lt;/p&gt;

&lt;p&gt;One thing to notice is that I am using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sync&lt;/code&gt; parameter in the request call.
When using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sync&lt;/code&gt;, the network call is synchronous which means that emacs will be unresponsive until the network call finishes. To me this isn’t a problem since I’ve set the timeout to half a second (It’s never taken more than that for me)&lt;/p&gt;

&lt;p&gt;Lastly, I’m not doing any error handling. So if something blows up when doing a network call, eshell will break and you’ll have to close it and call it again. Haven’t had a need to implement it, but if you’re up to it, you can add that in :)&lt;/p&gt;
</description>
        <pubDate>Sat, 28 Nov 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/making-eshell-tell-jokes</link>
        <guid isPermaLink="true">pygopar.com/making-eshell-tell-jokes</guid>
        
        
        <category>emacs</category>
        
        <category>eshell</category>
        
      </item>
    
      <item>
        <title>Eshell CD tricks</title>
        <description>&lt;p&gt;Eshell’s built in command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; has a pretty nice feature,
which is keeping track of the directories visited and being able to jump to a directory
matching the directory stack history.&lt;/p&gt;

&lt;p&gt;You can see the directory stack via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$ cd =&lt;/code&gt; and then either choose a number or directory to jump to
(eg &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd =foo&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd -3&lt;/code&gt;) both will jump to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; directory&lt;/p&gt;

&lt;p&gt;eg:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
0: /Users/gopar
1: /Users/gopar/.emacs.d
2: /Users/gopar/projs
3: /Users/gopar/.emacs.d/org/work
5: /Users/gopar
6: /Users/gopar/.emacs.d/org
7: /Users/gopar/foo
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;foo &lt;span class=&quot;c&quot;&gt;# cd&apos;s into directory foo&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-7&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# also cd&apos;s into foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;Another cool thing that it has is that you don’t have to type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd path/dir&lt;/code&gt; but simply &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path/dir&lt;/code&gt; in the prompt to cd into that directory. This works by checking if the input is a path, if not then fallback to using it as a command.&lt;/p&gt;

&lt;p&gt;Eshells CD command is a pretty simple easy convinient tool :)&lt;/p&gt;
</description>
        <pubDate>Fri, 27 Nov 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/eshell-cd-tricks</link>
        <guid isPermaLink="true">pygopar.com/eshell-cd-tricks</guid>
        
        
        <category>emacs</category>
        
        <category>eshell</category>
        
      </item>
    
      <item>
        <title>Book Review: Don&apos;t Make Me Think (Revisited)</title>
        <description>&lt;p&gt;I decided to pick up &lt;a href=&quot;https://amzn.to/3lCh6SD&quot;&gt;Don’t Make Me Think (Revisited)&lt;/a&gt; to learn more about UI/UX since I’m not that familiar with that topic. And well here is my review:&lt;/p&gt;

&lt;h3 id=&quot;pros&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Author makes it easy to follow and read&lt;/li&gt;
  &lt;li&gt;Not technical so anyone can learn what he’s teaching.&lt;/li&gt;
  &lt;li&gt;Shows best practices and how to not make silly common mistakes.&lt;/li&gt;
  &lt;li&gt;Good examples on how to do useability testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;The mobile part is outdated (It was released in 2013) but you get the idea/points he’s making from the previous chapters&lt;/li&gt;
  &lt;li&gt;Wouldn’t recommend to someone who has UI/UX background since this seems like it’s only giving a high level over view in the subject.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;overall&quot;&gt;Overall&lt;/h3&gt;

&lt;p&gt;The book is under 200 pages and would &lt;em&gt;strongly&lt;/em&gt; recommend it for anyone wanting to learn more about UI/UX, or just in general on how the structure of websites came to be.
It’s amazing that the things he goes through are pretty simple, but thats the point, simple is best.&lt;/p&gt;
</description>
        <pubDate>Sat, 10 Oct 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/book-review-dont-make-me-think-revisited</link>
        <guid isPermaLink="true">pygopar.com/book-review-dont-make-me-think-revisited</guid>
        
        
        <category>bookreview</category>
        
        <category>design</category>
        
      </item>
    
      <item>
        <title>Google App Engine&apos;s `DistributionNotFound: google-cloud-ndb`</title>
        <description>&lt;p&gt;When following Google’s migration guide for GAE 2.7 to GAE 3.7, they mention to start using their &lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python/migrate-to-python3/migrate-to-cloud-ndb&quot;&gt;new ndb client &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;google-cloud-ndb&lt;/code&gt;&lt;/a&gt;. This is straighforward until we ran into the following problem:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Traceback (most recent call last):
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py&quot;, line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py&quot;, line 311, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py&quot;, line 85, in LoadObject
    obj = __import__(path[0])
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/third_party/setuptools-0.6c11/pkg_resources.py&quot;, line 311, in get_distribution
    if isinstance(dist,Requirement): dist = get_provider(dist)
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/third_party/setuptools-0.6c11/pkg_resources.py&quot;, line 197, in get_provider
    return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/third_party/setuptools-0.6c11/pkg_resources.py&quot;, line 666, in require
    needed = self.resolve(parse_requirements(requirements))
  File &quot;/base/alloc/tmpfs/dynamic_runtimes/python27g/python27/python27_lib/versions/third_party/setuptools-0.6c11/pkg_resources.py&quot;, line 565, in resolve
    raise DistributionNotFound(req)  # XXX put more info here
DistributionNotFound: google-cloud-ndb&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At first it seems like the system didn’t install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;google-cloud-ndb&lt;/code&gt; correctly, but the &lt;strong&gt;real problem&lt;/strong&gt; is with the version of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuptools&lt;/code&gt; that our instance was using, which as you can see from the traceback is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuptools-0.6c11&lt;/code&gt;. If you look at the Googles list of &lt;a href=&quot;https://cloud.google.com/appengine/docs/standard/python/tools/built-in-libraries-27&quot;&gt;supported 3rd party libs, that version is deprecated&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The fix should be easy, update your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.yaml&lt;/code&gt; to use the latest &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuptools&lt;/code&gt; (as of this writing its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;36.6.0&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;...
libraries:
- name: setuptools
  version: 36.6.0 # You can also use `latest`
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately for us, the problem still persisted and we kept seeing in our logs that we were still using the old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuptools&lt;/code&gt;. After more debugging, we realized that another dependency we had in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.yaml&lt;/code&gt; was requiring the old version. My senior pointed out that if you look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;google/appengine/api/appinfo.py&lt;/code&gt; inside Google’s SDK, you’ll see the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;REQUIRED_LIBRARIES = {
    (&apos;django&apos;, &apos;1.11&apos;): [(&apos;pytz&apos;, &apos;2017.2&apos;)],
    (&apos;flask&apos;, &apos;0.12&apos;): [(&apos;click&apos;, &apos;6.6&apos;), (&apos;itsdangerous&apos;, &apos;0.24&apos;),
                        (&apos;jinja2&apos;, &apos;2.6&apos;), (&apos;werkzeug&apos;, &apos;0.11.10&apos;)],
    (&apos;jinja2&apos;, &apos;2.6&apos;): [(&apos;markupsafe&apos;, &apos;0.15&apos;), (&apos;setuptools&apos;, &apos;0.6c11&apos;)],
    (&apos;jinja2&apos;, &apos;latest&apos;): [(&apos;markupsafe&apos;, &apos;latest&apos;), (&apos;setuptools&apos;, &apos;latest&apos;)],
    (&apos;matplotlib&apos;, &apos;1.2.0&apos;): [(&apos;numpy&apos;, &apos;1.6.1&apos;)],
    (&apos;matplotlib&apos;, &apos;latest&apos;): [(&apos;numpy&apos;, &apos;latest&apos;)],
    (&apos;protobuf&apos;, &apos;3.0.0&apos;): [(&apos;six&apos;, &apos;latest&apos;)],
    (&apos;protobuf&apos;, &apos;latest&apos;): [(&apos;six&apos;, &apos;latest&apos;)],
    (&apos;grpcio&apos;, &apos;1.0.0&apos;): [(&apos;protobuf&apos;, &apos;3.0.0&apos;), (&apos;enum&apos;, &apos;0.9.23&apos;),
                          (&apos;futures&apos;, &apos;3.0.5&apos;), (&apos;six&apos;, &apos;latest&apos;),
                          (&apos;setuptools&apos;, &apos;36.6.0&apos;)],
    (&apos;grpcio&apos;, &apos;latest&apos;): [(&apos;protobuf&apos;, &apos;latest&apos;), (&apos;enum&apos;, &apos;latest&apos;),
                           (&apos;futures&apos;, &apos;latest&apos;), (&apos;six&apos;, &apos;latest&apos;),
                           (&apos;setuptools&apos;, &apos;latest&apos;)]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We were using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jinja2 2.6&lt;/code&gt; which required the deprecated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setuptools&lt;/code&gt;. We decided to remove &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jinja2&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.yaml&lt;/code&gt; and vendor it with the rest of the external 3rd party libraries. After that, the issue was fixed!&lt;/p&gt;
</description>
        <pubDate>Mon, 03 Aug 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/google-app-engines-distribution-not-found-google-cloud-ndb</link>
        <guid isPermaLink="true">pygopar.com/google-app-engines-distribution-not-found-google-cloud-ndb</guid>
        
        
        <category>python</category>
        
      </item>
    
      <item>
        <title>How I Stay Productive</title>
        <description>&lt;p&gt;I’ve been playing with tools and methods on how to make myself stay productive.&lt;/p&gt;

&lt;p&gt;I’ve noticed that being physically present at work doesn’t make me productive at all, so I started playing with tools and methods
to see if I can change this, and long story short, it has.&lt;/p&gt;

&lt;p&gt;This is a quick rundown on tools and explanations on why I use them and what/how they work.&lt;/p&gt;

&lt;p&gt;One thing before I start is that I greatly &lt;strong&gt;dislike&lt;/strong&gt; moving my hand from the keyboard to the mouse, and back and forth.
So most of these help with that.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://orgmode.org/&quot;&gt;Org Mode&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;This is an &lt;em&gt;amazing&lt;/em&gt; free tool. It helps with organizing almost anything and everything. Todos, calendar/agenda, spread sheets, literate programming, etc.
  Highly customizeable in almost every way and runs inside of GNU Emacs which is an editor that I also mention in this list.
  Another good alternative is a tool called &lt;a href=&quot;https://www.notion.so/&quot;&gt;Notion&lt;/a&gt;,it’s been gaining a lot of popularity but I lost interest since
  I can’t control everything from the keyboard. Also, the free version can be very limiting if you end up going pretty deep in the rabbit hole.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://vimium.github.io/&quot;&gt;Vimium&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;A free browser plugin that lets you use VIM keybindings to navigate. Pretty slick. \o/
  I believe it’s only available in Chrome/Firefox, but if you’re like me and &lt;strong&gt;dislike&lt;/strong&gt; using the mouse to move, then this will be a life saver.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.asianefficiency.com/motivation/pomodoro-technique-ultimate-guide/&quot;&gt;Pomodoro&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;A technique to help you stay focus on work. It works wonders.
  Here’s the basic breakdown&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Work for 25 mins&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Take a 5 min break&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Work for 25 mins&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Take a 5 min break&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Work for 25 mins&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Take a 5 mins break&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Work for 25 mins&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Take a 20 min break&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Repeat all the steps&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;The thing that you &lt;strong&gt;must&lt;/strong&gt; understand is that this is 25 mins of &lt;strong&gt;pure&lt;/strong&gt; work, no distractions, no checking phone, social media, etc.
  And once the 25 mins are up, you must stop working and take a break. Otherwise you’re losing the reason as to why you’re doing Pomodoro.&lt;/p&gt;

    &lt;p&gt;Make sure that in the breaks you’re doing something that relaxes you or helps you get something else done.
  For example, I sometimes read a book, wash the dishes, do a quick exercise, etc, but once the break is over I get back to work.
  Staying strict on yourself is key to making this work.&lt;/p&gt;

    &lt;p&gt;I found it difficult at first but then it started to become easier and easier. So just stick to it \o/&lt;/p&gt;

    &lt;p&gt;Also, all of these numbers can be changed (eg, work for 30 mins and take 10 mins break) to make it work for you.
  I find it that the default numbers work for me and sometimes, I work an extra minute or two after the 25 mins are up just to wrap up.
  If I realize that I’m spending more than 3 mins extra on the task, I stop and take the break.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.gnu.org/software/emacs/&quot;&gt;Emacs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;An editor that’s pretty customizable and can nearly do anything and everything. The only editor I use for programming.&lt;/p&gt;

    &lt;p&gt;Although, it should be mentioned that it takes a while to learn since it’s primarily keyboard driven,
  of course you can use the mouse to move around but I’ve found that not many people do that.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://ianyh.com/amethyst/&quot;&gt;Amethys&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;A tiling Window Manager (WM) for Mac.&lt;/p&gt;

    &lt;p&gt;When I was in Linux I went nuts with finding the perfect tiling manager and ultimately settled for &lt;a href=&quot;https://stumpwm.github.io/&quot;&gt;stumpwm&lt;/a&gt;.
  If you’ve never heard of a window manager, it basically lets you controls all your windows and lets you decided what to with them via keystrokes.
  Pretty neat!&lt;/p&gt;

    &lt;p&gt;Sadly there the closest I found to that was Amethys, which works well but it just doens’t feel the same. Anyhow, if you’ve never
  tried Window Managers, I’d highly suggest checking one out.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.asianefficiency.com/podcast/288-12-week-year/&quot;&gt;12 Week Year&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;A method of actually achieving your yearly goals.&lt;/p&gt;

    &lt;p&gt;I’m no expert in this topic since I just started using it, but checking out the link above will go more into depth, but I’ll do a quick breakdown
  from what I understand.&lt;/p&gt;

    &lt;p&gt;You break up your year into 12 weeks. In those 12 weeks, you focus on achieving some type of goal (learning guitar, get fit, create a company, etc)
  and track your progress throughout the 12 week year. The point is, that if you have a year to do something, you’ll likely procrastinate and forget about it,
  but if you know it’s just around the corner, you’ll be more motivated.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Listening/Watching in 2X Speed&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;This isn’t really a tool but something that never occurred to me.&lt;/p&gt;

    &lt;p&gt;If you simple speed up a video/audio 2X, you’ll be able to consume the content faster and not loose any information while doing so.
  It takes a bit of practice to listen/watch things in 2X but once you’re there you can pretty much take on information much faster/quicker.
  Some people even do 3X which is a little insane for me.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Save Everything To Calendar&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;If you’re anything like me, then you probably forget things pretty frequently which is annoying.
  Especially if you have to do something, now I’ve gotten to the habit of saving everything and I mean everything to my calendar,
  no matter how small. This has helped a lot in realizing and prioritizing things no matter what they are.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pen and Paper for problem solving&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;I never believed this worked, but actually writing problems when I’m stuck has helped me clear my mind and find the solution faster than usual.
  There really isn’t anything else I can add to this but to simply just try it, even if you were like me not believing it worked.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, I’m still learning how to be more productive/efficient. Some of the ways I go about learning new things is by listening to podcasts.
A podcast I really like is &lt;a href=&quot;https://www.asianefficiency.com/podcast/&quot;&gt;The Productivity Show&lt;/a&gt; which where I’ve learned quite a bit of things
and I hope it’ll help you as well.&lt;/p&gt;
</description>
        <pubDate>Sun, 29 Mar 2020 00:00:00 +0000</pubDate>
        <link>pygopar.com/how-i-stay-productive</link>
        <guid isPermaLink="true">pygopar.com/how-i-stay-productive</guid>
        
        
        <category>productivity</category>
        
      </item>
    
  </channel>
</rss>
