lunes, 23 de diciembre de 2019

Do not delete tmux dead panes

I've been using tmux for about a year. tmux-fingers and the feature that I helped add of instant pasting was what triggered the move.

Even I can't exactly replicate my screen workflow in tmux, I'm more than happy with the tradeoff.

Here's a nice option I didn't know about tmux: "remain-on-exit"

By default, tmux (like screen) kills the panes (or frames, or windows, or however they are called) when the process inside them dies. And usually, that's what you want.

But there's a case when you probably don't want this: "parallell --tmux"

I use GNU parallel as much as I can. I find it an awesome tool. Very hacker friendly and composable with everything you're already doing.

So I was recently using it to build packages for multiple distros. The command was something like  "parallel ./ --tmux {} ::: alpine ubuntu".  But when the processes finish (both successfully or not), the pane disappears, and doesn't let you review and debug the outputs.

Setting "set-option -g remain-on-exit on" on tmux, leaves every pane opened for your inspection.

viernes, 6 de diciembre de 2019

Making "docker run ... bash" Remember

Here's a small docker+shell hack I've never seen around and feel it makes a difference if you're getting in and out different (but related) containers. Very hackish, but works surprisingly well! Don't try it at home or rely on anything from it for other tools, as it doesn't compose very well, but hey... it's free :)

It's shell monkeypatching, and some kind of command parsing that looks like tcl/lisp-y list munging. Enjoy!

miércoles, 4 de diciembre de 2019

Software Like Scrabble

I don't know where did I read this one but talking about how development is not linear, someone was comparing it with scrabble, where you could add words only connecting one letter, and be "ok", but if you really want to get the max scoring, you have to think of synergies (gasp), and symetries, and how to reuse components in multiple subsystems.

I don't remember the exact quote, but I like to think it as well. Although iterating is THE WAY, focus and review of greater goals help you reuse in non-obvious ways. I'm not sure if this goes against TDD, or some other methodology (but it really shouldn't)

lunes, 25 de noviembre de 2019

Git from the ground up

There's this recent amazing video about org-mode, that happens to use git internals as the topic of the org mode document. And I just remembered the Aha moments I got when I started grasping git internals.  Here's what made stuff click to me.


Also, seems like a very nice deep dive into git internals from its core ideas.  I haven't had the time to dig into those articles yet, but worth mentioning them.
And last but not least: A very plain but smart way to investigate git: . Kinda emacs' "c-h k", but for git.

sábado, 23 de noviembre de 2019

On the expressiveness of programming languages (and other stuff)

Here's this interesting talk about which features add expressivity to given languages, and which don't.  It's an interesting way of looking at this problem.

The pdf (and ps which is extended). It goes in the same fashion of operational semantics I love so much on the lisp culture. The same as in Baker's MetaCircular article that mentions many CL special operators that can be written already with the rest of CL and macros.

martes, 12 de noviembre de 2019

very proud of my history

So now that I'm transforming this blog in a twitter account (for my ~15 followers), I just wanted to mention that when I type 'pdf' in my firefox, the suggestions I get are the following:

And I'm extremely proud of that :)

lunes, 11 de noviembre de 2019

Some Forth Implementations

To finish up one of the geekiest weekends in the last months, I just wanted to point to a few Forth implementations, from where I learned some nice tricks (from both forth and the implementation languages)

- Bashforth/Perlforth
- Rubyforth
- Miniforth
- ItsyForth

I spent a lot of time grasping Bashforth, with its usage of some smart tricks that you don't usually see in bash scripts. Also, the fact that array indices are used as a sort of pointers makes total sense, but it wasn't obvious to me at first (I had to research a bit about "delcare"). Perlforth is done by the same guy, so it uses a similar approach.

Miniforth is Lua, and uses a different kind of implementation, and gets to bootstrap something forthish in 40 lines of lua.  Not bad :)

Rubyforth is the one I touched less, but looks like a variation of miniforth with more Forth compliance.

Now a quick bash quiz: What does it echo? AnswerHere

fun() {
        local var="local value of var"
        echo "$ref";
var="global var"
declare -n ref=var

Well, there are two more canonical forth implementations that is worth mentioning them here, because if you're gonna just look at one implementation, you should take these ones as more "de facto" implementations.
- pforth
- jonesforth

sábado, 9 de noviembre de 2019

J's awesome

So here are a couple of nice reads that, although they're not new, they somehow teached me something new today about J.

First one is this 9 minute video on the "i." integers monadic verb.  It's super simple. So simple I almost dismissed it as trivial. "Monadic verb that returns an array from 0 to the parameter you pass it", right? Well... There's more than meets they eye.  The trick is that for non-array programmers it's not obvious that the parameter can have many dimensions. And what zeroes mean? and negative numbers?

Next is this super nice interactive J demo.

And a classical: Loopless programming.

miércoles, 6 de noviembre de 2019

SICP and Hal Abelson

So I got recently hooked up to SICP again, and binge watching the 80's classes in HP.

Also, rereading parts of the book and feeling that magic again.

Starting from there, I've researched a bit more from the authors, and I've focused in Hal Abelson.

Usual links:

Emacsconf 2019!

Emacsconf last Saturday was a blast! I planned to attend for a couple of talks and ended up staying the whole day!

Quite interesting talks, made by passionate contributors, cutting BS to 0, and somehow the talks were broad enough to take something from each one of them.

Even digressions in the irc channels were also interesting. Of course, the tribe that joins a saturday on an irc channel and a video streaming of emacs stuff for 9 hours, we're more than ok to discuss about window managers, programming languages, and all sorts of emacsy geekyness not entirely related with the talks. There was a very good vibe there.

A couple of talks focused more on the meaning of emacs as an FSF flagship, and the political meaning of the project. Very important to note that in a gathering of emacsers. I sometimes forget that emacs is as much of a software artifact than a political statement.

Jitsi behaved ok for 70% of the time, but the first 30% was a bit worrisome.  Connection dropping and audio cutting was a bit frustrating. The organizers did a great job solving those (I can imagine the stress), and they had the "recorded lightning talks" card up their sleeve.  Kudos to them, and to JohnW who got most of the jitsi difficulties in his turn :/.  Luckily he was calm and patient enough to flyby those hiccups and the message went through ok.

Annnnd the closing keynote.  That one gave some food for thought...  Better html support, different implementation language (learning from Remacs?) different extension language, looking at vscode in depth, attracting contributors, bug reporting....

Thank you everyone involved in one way or another. Organizers, speakers and attendees.  I had a great Saturday :)

miércoles, 30 de octubre de 2019

Postgres 12 and a db course

Postgres 12 was recently released with some great features like concurrent reindex, jsonpath, and other stuff:  and are good general info pages for the new stuff there.

Then, this is a great course about databases. It is about the internals of databases: . Really cool (at least the first 4 lectures).

Another sql thingie:
Julia Evans has this select order of execution that also is quite helpful if you're learning SQL .

EDIT: An advanced db course from Pavlo (great, more courses!):

viernes, 18 de octubre de 2019

Updated interview questions

My new questions for interviews:

  • Tell me about 3 (tech?) talks you think are worth mentioning (you like them very much or you dislike them)
  • 3 books (technical or not)
  • Show me something in your Github, or github log (timeline matters)
  • Would you recommend me to read any code from a library? 
  • do you have any comments on the following code? Imagine it comes in a PR you are reviewing. 
  • name 3 famous computer scientists/programmers. Expand on why if you want.

miércoles, 25 de septiembre de 2019

Dark firefox even in "text" urls

I've been using dark reader for some time and I'm quite happy with it. Not a huge memory hog (just sometimes) and works pretty decently everywhere.

But I just discovered, where it tells how to darken also new tabs and urls with text mimetype

You just have to open about:config and set both browser.display.background_color and browser.display.foreground_color  to something that makes sense.

lunes, 9 de septiembre de 2019

set -e in bash subshell

Did you ever realize that even when you use `set -e` in a bash script, anything that happens inside a  $(subshell like that) won't be executed under the `set -e` umbrella?

Here are the 2 solutions we found. None feels very solid... but hey, it's bash, what did you expect?

- . Apparently traps work in this dynamic scope and they get access to the nesting level of the bash shell the code is called from. Kind of not unwinding the stack?

- .  running the subshell as a background task and immediately waiting for it, like a 1process forkjoin.  Nuts.

lunes, 2 de septiembre de 2019

Migrating from vim (proficent) to emacs

In HN's thread about 26.3 being released (Congrats!), there's this guy  explaining that being already quite confortable with vim, it's too much of a commitment to move to emacs.

I remember the frustration when coming to emacs from an advanced vimmer POV: no "yyp"? no ":%s/foo/bar"? imap? But here's what I answered him:

As this is not an overnight conversion and you are quite proficent with vim already, my advice is to:
- Get used to type "emacs file.txt" instead of "vim file.txt" in your console.
- Have a function in emacs that opens the current file in vim for those moments where you just want your trusted environment. Writing it by yourself is a good focused learning experience.
This way you'll decide (and balance) how much you want to learn every day, and little by little you'll find yourself using that function less and less.

And I think this goes very well with my other "bootstrap your emacs lisp learning".

It's the same approach to most of my development (and life) efforts.  It's a function of how bad do you need it, how fast do you want it, the compound interest of starting early, and how much it slows you down (or blocks you for doing other things).

miércoles, 21 de agosto de 2019

Taming zoom with ratpoison

If you use a manual tiling window manager (ratpoison), chances are zoom is misbehaving when you want to minimize it.

The minimized window steals the focus and you can't do anything while the window is minimized.

If the window is maximized you have to manually corner it somewhere (at least wasting 25% of your screen).

But! I found a way to use zoom while letting you work while you don't see the screen.

It's a tiny shellscript that pinpoints the Zoom full window, and then relegates it to a 1 pixel window on the top of the screen.  Very simple, but it works wonders for me.

miércoles, 7 de agosto de 2019

the simplest bookmark manager ever

So this is not even a bookmark manager with proper tags or anything.

It's just a stupid combination of shell tricks that compose into a quick memo browser.

I guess I'll keep reinventing program launchers and fuzzy finders till I die (first ratfinder version being from 2006)

jueves, 4 de julio de 2019

postgres indexes

I'm progressively more convinced PostgreSQL is my next "emacs", as in "a tool I'm addicted to and I'm determined to find out everything about it".

I'm starting with some of the internals, and some deep descriptions about its various types of indexes.  Those pages provided me a bunch of hours of reading and knowledge on postgres internals.

Also, this week I read somewhere that postgres was first written in Lisp! I guess it shows when you run EXPLAIN on a query. I just confirmed it for a fact. :)

miércoles, 3 de julio de 2019

who's next?

Queues is a pretty fascinating topic.


lunes, 1 de julio de 2019

What's dat?

I still don't know exactly, but it looks very interesting, in a similar spirit as Scuttlebutt:


martes, 4 de junio de 2019

TIU: git merge -Xpatience -Xignore-all-space

For better or worse, I'm becoming an expert on git merges.

Today I got to use (TodayIUsed) the special flags: "git merge -Xpatience -Xignore-all-space  mybranch".  And it makes a difference!

Trying imerge again was a bit of a failure due to one of the two branches behaving very bad (lots of churn in the same lines over and over, so it felt like a rebase).

jueves, 30 de mayo de 2019

jq accessing fields with dashes

Let's say you have a json like {"foo": {"bar-baz": true}}.  Dashes in the keys make it impossible to look for jq ''. you  look around and you read that you should use ["bar-baz"].   the thing is that you have to use that syntax everywhere in your query

solving lnav truncate files

lnav is an awesome tool for browsing logs.  I'm not sure what are most of the people doing with logs.... tail -f? grep?  anyway...

Sometimes log files get suddently truncated, and when you're doing development, you don't want lnav to be always refreshing itself with the current contents of the files.

just using a bit of unix magic, we can log our files with "lnav <(tail -F logs/access.log)". 

domingo, 12 de mayo de 2019

ncdu vs dired-du-mode

ncdu a very nice utility that does what you probably want to do when you do 'du -sh *'  repeatedly in different directories.

ncdu allows for navigating through the directory structure seeing sizes and disk usage percentages of files and subdirectories. Also, has vi-friendly keybindings.

Of course, there's a way to do a very similar thing in emacs, which is using `dired-du-mode`. Take a look at the "c-x c-h" keybind to toggle human friendly numbers, and m-x dired-du-count-size to aggregate the sizes of all marked files.

jueves, 9 de mayo de 2019

preview files/links without changing the focus

I realized today that there's a consistent way (although not very intuitive to me) to peek (preview) a destination of a clickable thing without opening it. 

It's "C-o".  Of course, it is very useful for browsing and exploring purposes.  Just try it in dired, occur, ibuffer, rg, and probably many more.

In most of those modes "o" "opens" a buffer on the destination and gives the focus to it, so I guess "C-o" makes sense, it's just I'm so used to hit RET that I never think of "C-o".

Anyway, I hope you find this one helpful

dashes-to-dashes goes "serverless"

jq is a known tool nowadays, with lots of uses everywhere in the industry. 

Today I just replaced dashes-to-dashes api that is hosted in heroku, (it is a single endpoint that did a json transformation) to a jq script that can live in a github, and travis can be the one that runs and self publishes itself, putting the json in the github page of the repo, so it's fast, statically served, and requires no heroku dinos to keep it running.

If something, I learnt about extracting keys from a hash in jq

viernes, 12 de abril de 2019

emacs 26.2 as a birthday present

Emacs 26.2 has been released in April 12th, matching my 36th birthday, 

Appart from this coincidence, it's the first emacs release that has any code of mine, which makes me extremely happy. I only contributed 2 tiny bugfixes, but nonetheless I'm very happy about it :D

jueves, 11 de abril de 2019

a gentle 1/8 screen popup

Found on (which has very good content), and reminded me of those "FREE BEER" banners

miércoles, 10 de abril de 2019

bypass zsh commands in bash

Here's a small trick I came out with, when trying to run some scripts that were thought for zsh in bash.

I use 'noglob' in many places, and sometimes they leak into my bash scripts, or are called from bash somehow.  As bash doesn't know about noglob, usual result is an error.

But! you can use this

cat <<-EOF >~/bin/noglob
#!/usr/bin/env bash

So a bypass file is called in case the command 'noglob' is not catched by the shell.

EDIT: Now I remember why the f I created this.

You know I'm a heavy user of zsh's global aliases. my aliases that contain pipes are always UPPERCASE, because it gives a hint that something strange is happening there, and I also see it entering the realm of pipes. 

The thing is that when pairing with others, if I write that when they are looking, people have no clue what's happening when I type that, and it's pretty unintuitive.  Also, as my zsh and bash share part of the history, if I reach some command that contains one of the magic aliases, I've to manually fix them by expanding by hand.

1st fix: magic expansions

globalias() {
   if [[ $LBUFFER =~ ' [A-Z0-9]+$' ]]; then
     zle _expand_alias
     zle expand-word
   zle self-insert

zle -N globalias

bindkey " " globalias

This expands the previous word if it's an alias, but I only want to expand the ones that are ALL CAPSLOCK. Because I have very nasty aliases I don't want to expand as I go. (This has extra an benefit of allowing expansions of "dynamic aliases", which I'll show in some other post)

With this, I end up with noglobs scattered around my history, and if for some reason I execute those in bash, it'll try to run `noglob http ....`.  Here is where  ~/bin/noglob works fine by just bypassing everything.

jueves, 14 de marzo de 2019

dark mode for slack on mobile

So apparently slack app provides a way for a dark mode.

miércoles, 6 de marzo de 2019

emms ftw

I never got into the Emacs MultiMedia System, but just read that it has support for streaming radios so I gave it a try. And you know what?  It's awesome.  I'm adding all the radios I have in my radios repo.

But you already knew that.

Only a few concepts/commands:
- m-x emms-streams RET
- m-x emms RET
- c-+ + + +
- m-x emms-add-dired RET

Enough to get by and start using it.

martes, 19 de febrero de 2019

FP vs OO talk

Here's a quite balanced talk about FP and OO that fits my view of the two paradigms. Give it a shot if you have 40mins on your commute or something.

jueves, 7 de febrero de 2019

TIL: paste -sd+

Following lectures, I found a neat trick I didn't know in the data wrangling chapter:

seq 100 | paste -sd+ | bc -l     # 5050

That's pretty nice.  I already had this usecase solved by an "addup" perl script that I stole years ago from Mark Jason Dominus' utils repo.

As a bonus, it reminds me the very similar trick to generate a regex that matches either of many words. That's part of my git pre-commit hook

Not exactly the same, but it also belongs to "Higher Order Shell"

miércoles, 30 de enero de 2019

inifinite history

This is a very nice hack combo that makes shell history really useful.

Add precmd to log the last command into a given ~/zsh_history.log file that will log EVERY command you ever type in the console. With some context like date, and $cwd.

rghist finds commands from any of you history files, allowing you to find many words in the same line but not necessarily one after the other. But necessarily in the same order.

rghist is 100% mine, and comes without guarantees. The precmd command has been sitting in my .zshrc for years. Not sure where I got it from, but the idea is very nice.

Given that rghist can plow through gzipped files, gzipping the log (with password), could be a nice improvement.

function rghist(){
  local str="$(echo ${(j:.*:)*})"
  rg --no-filename -v rghist ~/.zsh_history.log ~/.zhistory | rg "$str"      

function precmd {
  if [ "$(id -u)" -ne 0 ]; then
    echo "`/bin/date +%Y%m%d.%H%M.%S` `pwd` `history -1`" >> ${FULL_CMD_LOG};

so, rghist will join $*  with '.*', making it seamless to find for many words in the same line. For example, sometimes I wonder: "How was the command to run a bash inside a running docker, was it run? was it exec?", then I just "rghist docker bash" and get a list of examples of commands I've run in the past like that. It's dead easy, it's something like a grep with infinite memory, but having this ever growing scratchpad has immense value to me.

EDIT: rghist above tried to be an improved version from my original one(better color managemen). But it's failing to produce output in some cases (I suspect binary strings in file). Here's the older and more robust way.

function rghist() { 
  local str="$(echo ${(j:.*:)*})"
  rg --no-filename --color always "$str" ~/.zsh_history.log ~/.zhistory |
  rg -v rghist

martes, 22 de enero de 2019

Formatting JSON

Here's something you probably had to do at some point. You have some big json blob and you want to format it nicely.

I had done this in vim and honestly, it comes very very easy.  In vim, if you have a buffer (/tmp/foo.json) you want to reformat, and you have jq, the nicest way I've found is something like:

:r !jq %

This is really hard to beat, and I'm not sure you can be much faster in any other thing.

But I live inside emacs, and I when I have this need, until now, I was selecting the region, then `M-| jq .`  The problem is I always forget about m-|, and it's really annoying to type it anyway.

So I was about to create my elisp function that would reformat my json region, and before coding it, I timidly tried M-x json-form..  and yes, of course, json-reformat-region is already there (you can download it from melpa).  Job done.

Btw, if you use evil, you can also use ':r !jq /tmp/foo.json'.  For some reason, % doesn't work as a substitute for the current buffer-file-name, but at that point, I don't care much. :)

miércoles, 16 de enero de 2019

rubber docker

 Thousand different blogs and people rambling about docker, and whatnot, and years later of its boom, I slowly get the knowledge of wtf is docker and why it might be useful. 

I still think it's super complex and flexible, and that most people do not fully understand the nuances between the different situations you can get at with it.

Here I leave some links that in one way or another have made me "tick" something about docker.

One of the differences that were somehow harder to grasp was what exactly makes a container different than an image.

As of what I know today, a docker image has its read-only layers. A container that you spawn off this image will have a rw layer on top of that, and will point to the top layer of the image, that's why you can have 2 containers off the same image.

If you want to create an image out of a container (that means, start some image, fuck around manually as much as you want, and then store it to a runnable image), you can use docker commit.

Another option to create an image out of another image is to create a dockerfile and make that dockerfile start FROM the initial image. Then, in the dockerfile you fuck around, and after that you'll have an image where you can spawn off many containers.

The image doesn't have any state. You build it and that's it.  A container, apart from the filesystem itself is a bunch of processes that are running, and a network setting, and mounted volumes.

You can start a container from an image with different network settings, or exposed ports. That belongs to the container dimension.  And containers can be in multitude of states. halt,run,stop,pause,....

Another weird thing is what does it mean to run a command in a container.  If you have a container running, you can use 'docker exec' and you'll run a command inside that container. no new container will be created, and if this command changes some internal state, or creates a file, it will create a file in that already existing container.  If instead, you 'docker run', you should pass an image name, not a container name, and if the command you run is stateless, and just does something to the outer world (run migrations), you can run it either with run or with exec inside an already running container (if you have one)

docker dilema

martes, 15 de enero de 2019

tmux session navigation tells us that c-b ) and c-b ( lets us cycle through different "sessions". And I'm afraid that's pretty cool, and in fact I can import that to ratpoison and move through the different workspaces with c-t ) and c-t (.

I guess that's pretty basic tmux, but I found it very nice and I'm already using it to swing between my work session and the "slacks" session (using slack-term)

lunes, 14 de enero de 2019

Postgres compression of jsonb

Postgres supports JSON data since loong time ago, but until jsonb (9.4) all solutions were somewhat limited in features.  Jsonb gives you most of what a document storage engine would give you, but...  what about performance? and space efficiency? Unfortunately I don't have real answers to those questions, but I've started doing some research, and for now, here's a nice takeaway:

First of all you should be aware of "\dt+", which gives us the size of a table and "\d+" which describes a table. The "+" suffix adds more info to the descriptions.

CREATE TABLE foo AS SELECT '{"f":true}'::jsonb FROM generate_series(1,1e6);
CREATE TABLE bar AS SELECT '{"f":true}'::text FROM generate_series(1,1e6);
\dt+ foo;
\dt+ bar;  

We see that the text field takes about half of the size of the jsonb. So if you don't need json features in a field (you're only archiving data that happens to be json), think twice when giving it the jsonb type.

Jsonb is TOAST-able, but will probably be toasted  (and compressed) when it's bigger than a page, so don't count on that if you're jsons are <4kb .="" p="">


So, don't think spacewise it comes for free. If you're concerned about space, there's a big impact on the size of the table.

domingo, 13 de enero de 2019

docker run top & docker exec

Here's how I test docker things:

docker container run -t ubuntu top

Then you have this top window  that shows only a single process.

In a different terminal you can then do things like "docker container exec 123456789abcdef sleep 10", and see it in the top window. It's a stupid thing, but I need instant feedback to solidify my knowledge of what's happening where.

jueves, 10 de enero de 2019

Remapping Keys "Up to Eleven"

Remapping keys on your linux is a "normal" thing to do amongst hardcore vim or emacs users.

The most standard hack is to remap CapsLock to Escape or to Ctrl.

And with emacs' key-chord and key-seq plugins, you can have really fancy combos to do the most obvious save-buffer, m-x, switch-to-buffer...

But I just discovered (via this reddit thread) that there's this "xcape" thing that allows you to bind keys to different keycodes depending on whether a key is pressed and released on its own or it's pressed as a modifier key along with other keys.

Here's how to "Remap left and right shift, when pressed alone, to left and right parens on keyup": xcape -t 250 -e "Shift\_L=parenleft;Shift\_R=parenright" &

That's super cool. And the readme of the project has some hardcore hacks for even more crazy conditional remappings.

As a side note, but kinda related, here's a great recent article about all kinds of glue (and duct tape) for X windows. And here's another awesome post about wizardy linux usages. The guy uses dmenu as an interface to a barebones plumber and gave me an idea to improve on my home made plumber (be smart and let you trim down witn dmenu when there are multiple options)

miércoles, 9 de enero de 2019

docker-compose, multiple yml files and environment variables

Did you know that docker-compose can merge multiple yml files into one? it seems like a very cool way to override configs and have something like a linear composability.

Just for fun, try

And do a few tests using

  • docker-compose -f docker-compose.yml config
  • docker-compose -f docker-compose.yml -f docker-compose-over.yml config
  • FOO=1 docker-compose -f docker-compose.yml config
  • FOO=1 docker-compose -f docker-compose.yml -f docker-compose-over.yml config
  • docker-compose -f docker-compose.yml up
  • docker-compose -f docker-compose.yml -f docker-compose-over.yml up
  • FOO=1 docker-compose -f docker-compose.yml up
  • FOO=1 docker-compose -f docker-compose.yml -f docker-compose-over.yml up

In addition to this, you can use the .env file to add defaults to the variables, and you can take a look at a special .override.yml suffix in Plenty of ways to configure, reconfigure, and override variables. The difficult part is to make it understandable at all for the next guy touching your setups.

Also, in your app, you can have defaults for the env variables (docker will set them to empty strings if you don't set a value for them).

Also, remember that "docker-compose run" and "docker-compose exec" accept -e to set environment variables. I still haven't tried all the possibilities with those to see exactly what do they overwrite and what is fixed.