DONE Hello world (again) general@category1

A new try with a different css…

DONE Janet? Janet! janetgame-of-lifecode@category1

Do you like C but changed because you were tired of the low productivity, the annoying syntax and - oh my god! - Segmentation fault? Holy shit! Me too!

But then, a couple of years ago, a friend of mine showed me Janet. And I was from the get go hooked! It took me a while to create something in it, now I have something to show.

Why Janet?

Come on… google it

What have I done with it?

Well, I have this pet project that it is to create a Janet wrapper for ncurses. But that will deserve a post on its own. For now, I will show a game of life using the prototype version of the janet-ncurses.

  1. I created a repo for it:
  2. It is very simple to use it. The big bang file is the initial state of it. Play with it!
  3. Now you can run with janet, if you have installed it, make

DONE New year, new goals, more posting! lifehabitsblog@category1

A new year has come and hopefully it won’t be 2020 too again (although it is).

My plan is to post more often from now on, hence the monero qr code =]

DONE Moving averages beatifully janetcodemath@category1

So this is another post on the janet journey. My goal here was to create a simple moving average function in janet (maybe just as a functional programming lover).

The code

I created a repo named numja that I intend to put all mathy stuff there. And moving average fits that category.

The second step was to create a small script that would run with the new “lib”.

The result

Simple as the proposition is, simple the code and simple the result. I used the “lib”, and plotted with gnuplot and voila!

Figure 1: Moving average

Figure 1: Moving average

DONE Web view in mutt muttconfig@category1

I know for a fact that you, hypothetical reader, are a mutt user. And as such, you know how frustrating html emails can be. Recently I was having this particular problem to see Jira emails.

Behold the solution!

In the mailcap file:

text/html;      w3m -v -F -T text/html -dump %s;        copiousoutput

DONE Pomodoro with shell script codeshell-scriptlife@category1

By now, you must be asking yourself: “Oh my god, all you know is janet/functional programming?!”, to which my answer would be a resounding “Yes!”.

However, today I decided to step a little bit outside my comfort zone and make a little script to help me use pomodoro for productivity.

Like you, hypothetical reader, I use dwm with dmenu. With these you can easily create a pomodoro executable to work for you. I say easily because I have no experience with shell script and I made it happen.

Enjoy =]

DONE You don’t need browser to check if a website is up!

Well, the title is quite an obvious statement… You can use softwares such as restclient from emacs, curl and probably a gazillion others.

However, there is not another one made in janet, authored by me, made in the last month! I can guarantee it!

The Goal

Well, my goal here was to make a simple software that did one thing and well. That one thing is to check multiple urls if they are up and the status they would return.

The code

This is another one in the janet journey. I used a ncurses wrapper to create the tui. All you need is a url file with a name reference and the respective url to be checked. With just this, you are ready to use it.

What does it look like?

Like this!

DONE Artix vs NVIDIA linuxnvidiasolution@category1

What happened?

Today, when I turned my computer on to log in, X complained that could not connect…

Why did that happen?

On friday, I tried to solve a glitching issue on brave, and I found online that someone solved by changing some settings on the nvidia. This genius that speaks to you, hypothetical reader, tried to download nvidia-settings to find out that the solution was elsewhere. All I had to do was to disable hardware accelaration on brave://settings/system.


Well, to the debugging process.

Two things were off:

  1. the card was not being loaded, meaning that all the letters were huge and the screen was most definetly not optimized
  2. the message given when trying to load X: Number of screens does not match number of detected devices. And two devices were shown: nvidia and modesetting


After I recovered from a panick attack, I summoned my mate Umgeher for some help.

He helped me find that nvidia blacklisted my graphic driver nouveau. From this link I could figure out what file to remove to take nouveau out from the blacklist. Now, reboot!

After that, the screen went back to the regular resolution, however the X still did not connect. But something different from the previous situation is that an xorg.conf was created at /etc/X11/. From there all I had to do was to change the conf file on device from nvidia to modesetting (that was the other device from the list)

DONE A first (not bad) emacs experience emacsconfig@category1

Well, not for me. I have been using emacs for almost a decade now and I have used bad configs and good ones. In the past few years that I am feeling more comfortable with lisp, I have been enjoying to tweak the configuration more and more.

My girlfriend has recently come to the good side of workplace and could drop Windows and its tools. In this new world, she tried to go into the Linux and emacs was something that I was more than eager to show her!

The problem

Well, emacs has quite of an interesting learning curve source

and I totally agree with it! So I created what it could be a first step to use it.

What is FirstEmacs?

What I looked for was a way to drop the two most troublesome keys in emacs (in my opinion) and its consequences. Which are Ctrl+x, Ctrl+c and Ctrl+v for cutting, copying and pasting. And emacs has most of its hotkeys attached to Ctrl+x and Ctrl+c.

It took me some time, but then I found wakib-keys. Which was pretty much the solution I was looking for. Basically, remaps the standart Ctrl+x and Ctrl+c to Ctrl+e and Ctrl+d.

Last note

Writing this assured the usefulness in the notation C-c and C-x for Ctrl-c and Ctrl-x (and so on) =].

DONE Divide and Conquer to optimality! optimizationalgorithmmipcode@category1

This week I made a pretty cool achievement for the paper on the wall that says that I am an applied mathematician. This week, I developed a branch and bound to solve a mixed integer linear problem.

Yeah… so?

Well, hipothetical reader, if you asked me that, I would say that you are not familiar with the power of integer programming. This kind of technique is pretty useful in the industry, in an area called operational research.

To make it simple, it is intended to help the user make better decisions. In other words, it is inside the prescription area inside artificial intelligence (more on this later!).

Ok… tell me more… (I think)

Let’s think of an example. Let’s say you have to find the best route from point A to point B, and for the sake of the example, you do not want google to track you down, so you cannot use google.maps =].

In this case, integer programming can help you! Why? Because you have to make the decisions of where to turn and when.

Ok, the problem passed the first test. The second test is a lot more techinical. You have to be able to model this problem only with linear equations. Putting aside what is the modelling per se, you might be wondering: “Why must it be linear? Nothing in the world follows a linear curve!”. To which my answer would be: “Correct, hypothetical reader! But you gain something pretty cool by forcing it to be linear. The solution you find is guaranteed to be optimal! In the worst case, I can tell you how better the solution could be, if not optimal!”

And now, I will give you some time to think about this. I am telling you there is an algorithm that with few conditions (one might be hard one), you can have the best kind o quality measure one can think of. The final solution is n percent worse than the best one.

Ok… I’m kind of sold. But what does Branch and Bound have to do with this?

Well, branch and bound is the go to algorithm framework solvers use to find this measure of quality I mentioned earlier. And I made one in clojure! I had to solve a small problem and I could not find a decent package similar to pulp in python (which is very sad, if I may say so).

Nice, but I don’t need to find a route…

Glad you mentioned this! That’s the beauty of it. Branch and Bound is a framework in which, if you can mathematically model the problem, you can solve a bunch of kind of problems:

  • Find the best location to build a station (fire fighters, restaurants, telecomunication towers, etc…)
  • Find the best way to load a truck (or any container for this matter).
  • Best way to plan your production

and others. Here you can find a bunch of applications! =]

DONE Going Hugo for framework! blog@category1

So, the time has come! I also started using Hugo for my blog framework. Previously, I was using org-static-blog for my framework and honestly I was pretty happy about it.

But things changed when I wanted to make a second website. org-static-blog is pretty neat to work inside emacs, however to use on a second project there is a lot of setup to do. Facing that problem and knowing about Hugo and ox-hugo, it was a no brainer.

Now, the final equation is:

(= "<3" (+ 'ox-hugo 'hugo 'emacs))

The other project

The other website I mentioned earlier is this one. Maybe I will post some insights I had while doing this (and a proper marketing for it hehe).

DONE Managing dependencies in clojure clojureleincode

Today I was having a hard time to load a nice lib for managing excel files ( I was having some weird problems at loading them in cider (btw, if you don’t use it, start now!).

I gave some search into it, and lein has a nice feature to handle dependencies. The command that saved me this time was:

lein deps :tree

It gave me a quick report on what was strange with the dependencies. Some examples:

1Possibly confusing dependencies found:
2[metosin/compojure-api "2.0.0-alpha30"] -> [com.fasterxml.jackson.datatype/jackson-datatype-joda "2.9.8"] -> [joda-time "2.7"]
3 overrides
4[midje "1.9.9"] -> [clj-time "0.15.1" :exclusions [org.clojure/clojure]] -> [joda-time "2.10"]
6Consider using these exclusions:
7[midje "1.9.9" :exclusions [joda-time]]
Possibly confusing dependencies found:
[metosin/compojure-api "2.0.0-alpha30"] -> [com.fasterxml.jackson.datatype/jackson-datatype-joda "2.9.8"] -> [joda-time "2.7"]
[midje "1.9.9"] -> [clj-time "0.15.1" :exclusions [org.clojure/clojure]] -> [joda-time "2.10"]

Consider using these exclusions:
[midje "1.9.9" :exclusions [joda-time]]

DONE Patching your way to contribution! gitversion

Hypothetical reader, I know what you are thinking. You have some interesting projects, but I am not sure to engage on those because on source hut there is no way to make a pull request (at least, I have never found to the day of this writing).

Well, this make a nice oportunity to learn about patch in git! So, the magical command I use

git format-patch -x

where x is the number of commits that I did or

git format-patch branch-name

where branch-name is what you expect =] (source).

A nice recommendation by Umgeher is as follows. It will give some information per line, like who wrote the commit or put the tag, for instance. To do so, make a little tweak on ~/.gitconfig:

annotate = yes
forceSignAnnotated = true

DONE Remap your keyboard! config

Why? Well, because as an emacs user, you are probably tired of your pinky trip to ctrl in order to do the “chords”.

I would assume, hypothetical reader, that you have already tried changing caps for ctrl. Well that’s nice, however, let me introduce you the better idea (giving credit where is due, thanks for this Umgeher!).

It is a lot more comfortable and an easier transition to change shift->ctrl and caps->shift. The muscle memory for shift stays the same and ctrl is in a much more comfortable position. Here is xmodmap script to arrange that:

! making shift ctrl and caps shift

remove Lock = Caps_Lock
remove Shift = Shift_L
remove Control = Control_L
keysym Caps_Lock = Shift_L
keysym Shift_L = Control_L
keysym Control_L = Control_L
add Lock = Caps_Lock
add Shift = Shift_L
add Control = Control_L
  • To run it, put the script in a file your-remap-name, and run it with
xmodmap your-remap-name
  • If you like it, you can put on your .xsession, so whenever you start the graphics on your user, this awesome change is already made.

DONE All praise stash git

Today I figured a pretty cool git command. Up to this day, sometimes I get a bit disorganized with the branches, and git stash came to save the day (or at least some working stamina).

Here is the procedure:

“Oh no! I forgot to change the branch before making changes”

git stash save "name of the mistake"

Now, moving to the correct branch

git checkout the-correct-branch

Recover the modifications

git stash pop

And, a nice command:

git stash list

DONE Searching for packages in openbsd openbsd

Finally! I am using openbsd! It is quite interesting but somethings are different. I will need to post somethings to help me remember =]

Starting by package search:

pkg_info -aPqQ package | sort

where package is what you are looking for. Thanks for the tip Umgeher!

DONE Meetings in openbsd openbsdtools

Ok… I have been using a little bit more OpenBSD, and I was having some issues to use it during calls. After some research and experimentation, I have thought a way to make it happen! So it was born lets-meet!

It is simply a toggle to enable/disable microphone and camera. Enjoy!

DONE Extract infos from a pdf! codeshell-scriptclojure

Hypothetical reader, I bet you always wanted to extract the text from a pdf file. Sure there are a few big tech options but let me appeal to your minimalistic side: pdfminer! This is a simple jar that extracts the text from the pdf into a huge string.

What is this good for you might ask. Well, you can extract the code payment from an invoice. How? There you go: invoice =]

DONE Let the charge come back, thinkpad… thinkpadhardware

So, I have a thinkpad x270 which is pretty good. However, for the past few months, I was having a lot of trouble to charge it. There was a single position and mood for it work charge normally.

Well, no more! Let’s face the challenge of fixing it by myself. First things first, diagnosis:

Since the computer was charging, there was a specific position to work and, probably most important, the charger was loose when connected… There you go, probably there is a problem with the dc jack. Let’s get a new one.

Apparently, it is good practice to shut down the internal battery… This is done in the BIOS.

Now, I need to open the damn thing. Looking around the web, I saw that to open the x270, you need plastic ply to “unclick”. Damn… these are the worse… Let’s try Umgeher’s suggestion… a guitar pick…

Well, after not 20 minutes… I managed to open the thing, with more strength necessary than expected. But the result was kind of a relieve. My old jack was actually broken.

After changing, closing it, and turning it on with the cable, et voila, battery charging!

DONE pomodoro is now its own thing! codeshell-scriptlifetools

I started using my pomodoro script again, and made few improvements. Also, I separated in its own repository.

DONE Bookmark unix-style! shell-scripttools

Hypothetical user, do you use any bookmark system? What? Only on firefox? Why am I calling it “system”?

Well, you don’t need to use bookmark only for webpages and restricted to the browser. A little bit of rofi and shell script, and there you go: bmark!

DONE Mutt’s glasses for html email mutt

Mutt is awesome but html email not so much… well, let me give you a possible solution: create a hotkey (F) to open html email in your favorite browser.

macro attach F \
    <enter-command>unset wait_key<enter>\
    <shell-escape>rm -f /tmp/mutt-attach<enter>\
    <shell-escape>$BROWSER /tmp/mutt-attach &<enter>\

DONE Uploading in firefox vs OpenBSD openbsdfirefox

I had some issues adapting to some security features in OpenBSD, for example, to have videoconferences (let’s meet). Another interesting problem I had was that I could not upload files from firefox.

To fix that, all I had to do was enter on this “page”: about:config and change this setting to the specified path that I wanted dom.input.fallbackUploadDir.

There you go, now you can upload files from this directory on your firefox.

DONE Fix incanters core.view in dwm clojureciderdwm

Now, let’s face it. dwm is awesome. But sometimes, it needs adjustments. If you are using incanter and cannot see a plot with core.view function in a cider enviroment, all you have to do is export this variable into your enviroment before firing up cider.


DONE Data science with clojure clojureds

Hypothetical reader, you must be asking yourself:

“Why not use python? There are a gazillion libraries and methods already prepared to go! So… why?”

I will tell you one reason in this post! One small disclaimer though, I will not discuss performance here, only convenience ;]

Actually, the point I will make is theoretically valid for any lisp dialect. But I have found a pretty nice project with a solid library in clojure, so here we go.

Some basics…

(If you are already familiar with thread macros (-> and/or ->>) you can skip to So what?)

I will assume that you, hypothetical reader, have some knowledge in lisp. At least the basics, ie, understand how to declare and call functions and not afraid of parenthesis (not too much, at least).

Having said that, maybe I will need to explain a little bit of the thread macro (aka, ->). The why will be clearer later. So…

What is the thread macro?

Well, if you have used pipes (|) in the command line, you are already familiarized with the concept. Now all it takes is to see how it happens in a lisp context.

Let’s say you have a unix command that is something like this:

cat textfile1.txt textfile2.txt | grep "a string"

What this is doing is pretty much giving to grep, the result of the first cat command. Something like:

cat textfile1.txt textfile2.txt | grep "a string" ~result~
	  |                                             ^
	  |                                             |
	  ------------------  result  -------------------

The concept of thread macros is the same. The result of the function will go to the next one. Let’s take a look this simple example:

(-> (+ 2 2)
    (/ 8))

The idea is that everything inside the macro -> will generate a result and give it to the next function as a parameter. In other words the flow of the snippet above is:

(-> 4
    (/ 8))


(-> (/ 4 8)) ;; which is the same as (/ 4 8), therefore 0.5

Ok, but what is the difference of -> and ->>?

Very simple! -> will give the result of every function as the first parameter and ->> will give as the last parameter. Take a look:

(->> (+ 2 2)
     (/ 8)) ;; which is the same as (/ 8 4), therefore 2

So what?

Let me introduce you to scicloj ml! This library has some pretty cool features for dealing with tabular dataset. Actually, it is what you would expect if you are familiar with pandas or pyspark, but with lisp!

If you have done some hard work with pandas (or pyspark), you may have noticed that the nature of OOP does no good for the readability of the code. In order to transform your dataframe you would have to dot everything and try indent nicely in order to get some readability.

For example, lets assume we have a dataframe like this:

Shutter IslandMartin Scorsese294.82010
Kill Bill Vol.1Quentin Tarantino180.92003
The DepartedMartin Scorsese291.52006
Once Upon a Time in HollywoodQuentin Tarantino377.62019
The Wolf of Wall StreetMartin Scorsese406.92013

Given this dataset, let’s assume we would like to see which director has the highest box office after 2010. There are some ways of doing this, but one way would be:

  1. Filter the data frame to have only the valid information
  2. Use a group by in order to aggregate the values of box office per director
  3. Order the dataframe per box office aggregated

Well, to do so in python, assuming that the variable would be df for the dataframe above, it would go something like

df # the small movie dataframe above

df[df.Year > 2010].groupby('Director').agg({'Box-Office':'sum'}).sort_values(by=['Box-Office'])

# or maybe with a good (?) identation
df[df.Year > 2010].groupby('Director').\

Now, I am not saying it is bad, but it is not ideal either. Let me show something similar in a lisp enviroment. In this case clojure’s scicloj:

(use :as ml)

df ;; let's say this is the dataframe

(-> df
    (ml/select-rows #(> (:Year %) 2010))
    (ml/group-by :Director)
    (ml/aggregate (fn [ds] #(reduce + (get ds :Box-Office))))
    (ml/order-by [:Box-Office]))

I won’t go in details how each line works but, honestly, only understanding that the thread macro (->) is there to transform your data one line at time, it is enough to make the lisp version more readable to the three steps mentioned earlier.

If you consider this point biased since I am a huge lisp fan, no problem, consider this my first plea to make data science doable in other languages (specially lisp) rather than only python or R.


Quick note: A very good source to play with scicloj ml for me was this link with examples.

Quick note 2: Scicloj has a page with bunch of nice tools for data in clojure: scicloj resources. You are welcome!

DONE Zoom vs OpenBSD openbsdtools

I do not mind saying it again, OpenBSD is pretty cool, however it does has its quirks. Recently, I had a fairly important meeting in Zoom in which I would make an presentation and I did not make it because I could not enter the room. All it appeared to me was and enternal “Joining” and the endless MS circle spinning.

So, let’s fix it shall we?

Apparently, in order to make Zoom work, one must have wasm enabled in your system. By the way, this is what I would call a bloated piece of software… it only is a videoconference software… geez…

Anyway, I digress. So, OpenBSD disables wasm by default for security reasons. So, what one can do is: enables wasm, go to your conference and at the end disables it.

And I give you sadzoom! You will notice that I use chromium to enter the conference. I do that because with chromium because outside of the box it allows screen share. Why sadzoom? Because you are probably sad to use zoom as I am…

One last thing, remember to use let’s-meet to enable cam and mic =]

DONE neomutt <3 notmuch mutt

This is a tale of stubbornness. I’ve heard about notmuch, quite sometimes and yet, I did not use it. I was bit confused reading the docs but then I read this:

Notmuch does not modify or delete your mails. This is one of the main design principles of Notmuch.

That gave me some nerves to try this on! And it is worth it!

To put it simply, notmuch is a indexer of all your emails and make search annoyingly easy. Once you go with the basics

notmuch new

A search can be done as simply as

notmuch search boardgames

notmuch will use xapian search engine to look for your emails that contain boardgames. More impressively, it can look for any kind of filter: from:, to:, cc: and so on. You can also search with tags:

notmuch search tag:bills

Now, you might wonder, how did it tag bills? Well, it did not. You must do it, like this:

notmuch tag +bills - from:*@somebilldomain*

On the right side, it used the search functionality to find all mails that satisfied the condition after -. You can also use logical expressions:

notmuch tag +boardgames +general - from:*@*boardgamestore1* or from:*@*boardgamestore2*

Now, let’s address the elephant in the room. Why bother with all this? Well, because you use neomutt =]

With neomutt, you can create mailboxes (named virtual-mailboxes) to organize your emails.

set nm_default_uri="notmuch:///path/to/mails/"
set virtual_spoolfile=yes
virtual-mailboxes "inbox" "notmuch://?query=tag:inbox"
virtual-mailboxes "boardgames" "notmuch://?query=tag:boardgames"
virtual-mailboxes "bills" "notmuch://?query=tag:bills"

What is left to use this snippet is to tag inbox:

notmuch tag +inbox - to:youremail@domain and not tag:general

This way you won’t get duplicated in your inbox, and everything you tag with general, won’t show in your inbox. Anyway, that’s what I am doing for now. But honestly, you can go crazy with it. Because notmuch is a command line, you can have an insane control over your emails. Good stuff!

Just do not forget to put it in you sync script:

mbsync -a
notmuch new
notmuch tag +boardgames - from:*@*boardgamestore1* or from:*@*boardgamestore2*
# and so on...

DONE NEOmutt with html glasses mutt

In this post I created a macro to open those annoying html e-mails with your favorite browser. Well, with neomutt I did not manage it to make it work so I went on a different approach. Arguably, a more elegant.

So, (neo)mutt has the mailcap file which is a file that tells (neo)mutt how to open a file tipe from it.

So if I write in the mailcap file this:

text/html;      w3m -v -F -T text/html -dump %s;        copiousoutput

it tells (neo)mutt that any text/html file should be opened with w3m with these arguments and copiousoutput will tell to open in the internal pager (this can set to be an external pager, however my default is internal).

So, what I did was add another rule for text/html, and create a macro to go for it. In other words

mailcap file

text/html; firefox %s;
text/html;      w3m -v -F -T text/html -dump %s;        copiousoutput

muttrc file

macro index,pager F "<view-attachments><search>html<enter><view-mailcap><exit>"

DONE tmux colors tmux

I am starting to explore tmux and emacsclient -t. But it is annoying that emacs gui and in the tmux terminal was being colored differently. The solution?

set -g default-terminal "tmux-256color"

DONE Erlang? Erlang! erlangopenbsd

Let’s dive into some new language programming. Functional of course… Erlang!

In Openbsd, did some tweaks into the installation process…

~> doas pkg_add erlang rebar
~> ln -s /usr/local/bin/erl<version> ~/bin/erl # my personal bin directory
~> ln -s /usr/local/bin/rebar<version> ~/bin/rebar

It was not so obvious for me but it seems that rebar is to erlang like leiningen is to clojure. And as such, you can initialize your project quite easily

rebar new umbrella prj-name

Also your first time?

A bit more on rebar

You can see all templates and understand them better with

rebar new help

Now what?

Well, now with the template one can really program in Emacs. I am currently using erlang mode from this instruction. However, my load path was a bit different.

(setq load-path (cons  "/usr/local/lib/erlang<version>/lib/tools-<tools version>/emacs"
(setq erlang-root-dir "/usr/local/erlang<version>")
(setq exec-path (cons "/usr/local/erlang<version>/bin" exec-path))
(require 'erlang-start)

Once that is fired up, in the *app*.erl file, C-c C-k to compile (quite ciderish… very comfy).


If in doubt with rebar

rebar help <command that clouds your mind>

If in doubt with erlang:

DONE Finally, a whatsapp tui! tuiwhatsapp

Ok, finally I have found a (half) solution to the whatsapp web problem. The problem being the “web” part of it… I don’t like having the browser open just to text chat. So for some time I have been looking for a text user interface solution to this.

In other words, a less RAM intensive little piece of software. The important key part for this solution is matterbridge. It is a piece of software that connects two chat enviroments that you have.

Effectively the only ones that I use are: email and whatsapp. Since this is not a viable bridging, I created a local IRC server to ensure that my chat does not go to a third party server.

Ok, now I can tell you all the softwares I used:

  1. matterbridge
  2. ergo (irc local server)
  3. weechat (but can be any irc client)

Here is an example of the matterbridge configuration for this kind of setup.

Here is the configuration of the ergo. It was the default when I cloned it

Now, start all with a script like this one.

There you go. A simple solution to an annoying problem. But it is a half solution because matterbridge only supports groups. Well, for now this is what I have. Enjoy =]

DONE Emacs? No, emacsclient! emacsterminal

This is a shoutout for all of you who are tired of waiting emacs to load on startup or annoyed to feel forced to leave an instance open.

emacsclient can save you from that. All you have to do is to leave an daemon open. Don’t use (server-start) because that will force you to have an GUI or terminal open at all time. The solution? A command.

On your terminal (or .xsession file):

emacs --daemon

After that, you can invoke emacs GUI with emacsclient -c and emacsclient -t to open directly in the terminal. The colors probably will not match, so you can take a look here =].

Now, to make life a little bit better, you can create alias/binary

alias emt='emacsclient -t'
emacsclient -c -F '((font . "Hack 12"))'

The latter I use as a binary in $PATH to be invoked with rofi or as a shortcut in the dwm.

Thanks Pedro for the post idea hehe.

gpg expiration

to get the list of keys

~> gpg -k
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   rsa4096 2022-01-18 [SC] [expired: 2024-01-18]
uid           [ expired] lucas moreira <>

then, to change expiration


and to change the subkey as well

> key 1
> expire

DONE Integration test in a good way codetools

This is another tale of redemption… I really enjoy minimalistic solutions and yet, I was not using for integration tests…

So, as everything that needs a start, what was the problem? For some time, I have been thinking about integration tests. What I am calling integration here means a way to test an API that goes through other APIs.

The non minimal

I tried a few approaches. One was to create a “fake” data structure that would represent the return of one API but that proved to be very difficult to insert in my coding routine.

Another approach was to use a http request client. The one I used the most was restclient mode in emacs. Which is pretty good. Here is an example of a GET request from the README:

# XML is supported - highlight, pretty-print

With the mode, you have some shortcuts and can have a bunch of requests in a single file. It is pretty cool actually. The problem? it is not very good in the automation front… I did not find an easy way to run all these requests.

Well, what is the solution? Thinking minimal. Like, really minimal. I mean curl minimal.

Now, what is the problem with curl? It is tedious to make it work if you are not used to it. You have a lot of the control of how the request should be made…

Save this. We will come back to it.

The minimal

Why is it a solution, then? Because you made your request with a command line, it is very easy to automate with a script, such as a shell script.

For instance, you can create an “integration” test script like so:

# testing with 10
curl -X GET

# a test with json post
curl -X POST --json @path-to-json-file


Pretty simple if you ask me. Now, after a commit or when you feel like it, it is one command away.

Remember the problem? Well, I wonder if it really is. More control over it means that you are fully aware of what is going on. Meaning, you have a better understanding of the process. You have to study more? Sure, however I would argue it is the extra mile that could make you a better coder.

I am leaving giving my thanks to ’erica and umgeher for this small realization. Cheers!

/comments ~lucasemmoreira/