viernes, 21 de diciembre de 2018

TIL: search-whitespace-regexp

Here's another little dwim emacs' feature that I didn't know it existed and I just noticed today when it didn't dwim'ed.

When searching for a string "foo     bar", multiple whitespaces are ignored, and strings with one whitespace between the 2 words is detected as a match anyway.

Here are some ways to fix it, or bypass it in a particular occasion.

miércoles, 19 de diciembre de 2018

A strange case of quoting shell vars

cat << ${FOO:-"{}"}

You got that? evaluate it in your shell. Now Put it into a file and try to "sh".  You're going to see the funny {"}.   Go figure...

  1. sh doesn't understand about nested {} inside {}
  2. Take into account that bash or zsh do, so none of this applies there, you have to test it on pure sh.
  3. ${FOO:-"{} is what gets interpreted as part of the variable
  4. as $FOO is not defined, '"{' should be outputted,
  5. leaving the final "{"}
  6. But nope. Because quotes inside a variable expansion do not pass through
  7. So the final {"}
  8. Bonus points for this not happening in bash
  9. More bonus points for this being inside a makefile that calls the file as $(SHELL) And different platforms use different $(SHELL) by default.
  10. Mine (ubuntu) uses /bin/sh (which is linked to /bin/dash), others might use busybox, and MacOS uses something that does not do any of the above (zsh?)

martes, 18 de diciembre de 2018

Linux extended file attributes

I just discovered a couple of nice linux commands that seem to be quite orthogonal and suckless, and that probably allow for all sorts of nice tricks.

Extended attributes are like the -rwxrwxrwx but allow for more subtle meanings.

On the one hand we have chattr, which allows to add about 10 different attributes to files and directories with a very specific meaning:
  • a - append only
  • c - compressed
  • d - no dump
  • e - extent format
  • i - immutable
  • j - data journaling
  • s - secure deletion
  • t - no tail-merging
  • u - undeletable
  • A - no atime updates
  • D - synchronous directory updates
  • S - synchronous updates
  • T - top of directory hierarchy

On the other hand, we have the command 'attr' (not nstalled by default in ubuntu, but it's just one apt-get away).

This one serves as a kind of general tag:value system for files and directories.  It feels like it's a feature that can be overused to extremes to create not only tagging systems but acls (there's already getfacl), complex permissions or just hide info in this kind of "plists" scoped by file.

miércoles, 12 de diciembre de 2018

3 basic org agenda tips for the fundamentally forgetful

I've been trying to use org mode for the last 5 years, and the system always fails in one way or another.

  • When I have too many types of templates, I doubt which template should I use.
  • When I set for too many tags, I forget about them (and I dont' know how to search for them anyway), so I don't use them.
  • When I use datetree for org-capture definitions, I never know where to find the things and end up using c-s. Multiple reasons here:
    • There's some missbehaving on the change of a month. Not sure how to fix it but it messes up my trees.
    • If  entries are supposed to be refiled anyway to their "final" topic, no need to keep a structural context when capturing.
  • Having 2 different capture one beginning with TODO and the other not.

Any of these mean total failure unless you're already a very well organized person and can hold the system.  And they lead to not using org consistently, which leads to not using it efficiently, which means it's useless.

But lately I seem to have found something that kinda works.

#1. Use 1 template

So, only 1 capture template.

   ("t" "Todo" entry (file+headline "~/org/" "Tasks")
    "* %^{title} \n  SCHEDULED:%t\n  %?\n %i\n  %a\nAdded: %U")

This creates a plain entry sequentially under "* Tasks".  You know that "up" means before, and "down" means after. If you ever start using refile or tags properly, then I guess you'll add them to the mesh, but for now, leave it like this.

#2. Schedule everything to not miss it

Schedule everything. Get used to use scheduling.  Although being incapable of using org mode in a decent way, I've read its whole manual (more than once). And I know there's a bunch of different timestamps that mean different things. DEADLINE, SCHEDULED, <active timestamps> and [inactive timestamps].  

Usual advice is to use active timestamps for things that will happen anyway, no matter what (birthdays?, new years,..). Inactive is for "meta" logging of when you created the entry, or a date you want to be clickable, but not visible in the agenda.  DEADLINE and SCHEDULE also have their own subtle meanings.

I just want something that appears in front of me when I press 'c-c a a' (for a given date), and if I think it's not relevant anymore, I'd have to have a way to say "ok, do not bother me anymore with that".

So with SCHEDULED, it works, and if the day passes and you haven't done anything about it, it carries over to next day, so you will end up doing something about it (or having a huge overdue list).

So yeah. 'c-c c-s' all (most) of your entries.

#3. ] == reflog

So I created a couple of items in a trance, and after 10 minutes I'm like: "ok, let's review those items"....  And I realize I forgot to add a schedule date (usually I schedule for the same day if I want to review later).

Old me would blame himself for not being organized enough, and go through the huge, trying to grep for the year-month (if we had the datetree), or was it month-year? who knows.  Going over many different datetrees for supposed different topics. most of them half forgotten.

The trick here is a magic unknown keybinding on your agenda view: ']'.  What it does is it displays the inactive timestamps in your agenda, as if they were active.

And as we added the '%U' pattern in the single org-capture template, we know all our items will have an inactive timestamp of its creation. So you can see it as a reflog you can use to see your activity in "diary mode".

lunes, 10 de diciembre de 2018

bash and python pills

So you know bash sucks, but it's the best we have to do process orchestration and pipes and all that kind of stuff.

Here are a few lists of knowledge pills that are kind of related.

  • You are writing bash, and there's clearly a list of things (patterns) you do over and over. Here's a list of some common things
  • You have some shellscripts but some depend on linux/bsd programs and you'd like to make them pure bash. Or you're just the curious type that wants to know "what would this look in pure bash".
  •  Until you realize you should start moving all your bash crap to something different. What about python?
  • Python is great, but it's not without wtfs.

sábado, 8 de diciembre de 2018

Dark themes for the browser

If you're spending many hours a day at your computer, chances are the white background of the average web site causes some visual stress to you (that's why we use low contrast themes in our editors and terminals.)

Changing css styles of websites you visit can be done with userstyles (custom css's loaded by your browser), but until now, all plugins I've found to manage them sucked in one way or another. Here's my experience:

The most successful strategy I had until 2 days ago was using stylus with one of its "Global dark style", but the problem with those generic themes is that some pages go very wrong with them, and then you have to manually disable them for those sites, and maybe find an ad-hoc dark style for them.

That was the case with Slack, HackerNews, Reddit, Github (which are 80% of my browsing anyway).

But this week I discovered Dark Reader, and I'm so happy with it I can't believe it.

Just give it a try. It just works.

EDIT: I'm noticing added load and lag when loading some pages, but for now it's nothing that outweights the benefits, so for now, it stays

jueves, 29 de noviembre de 2018

prefer duplication over the wrong abstraction


  1. Programmer A sees duplication.
  2. Programmer A extracts duplication and gives it a name.
    This creates a new abstraction. It could be a new method, or perhaps even a new class.
  3. Programmer A replaces the duplication with the new abstraction.
    Ah, the code is perfect. Programmer A trots happily away.
  4. Time passes.
  5. A new requirement appears for which the current abstraction is almost perfect.
  6. Programmer B gets tasked to implement this requirement.
    Programmer B feels honor-bound to retain the existing abstraction, but since isn't exactly the same for every case, they alter the code to take a parameter, and then add logic to conditionally do the right thing based on the value of that parameter.
    What was once a universal abstraction now behaves differently for different cases.
  7. Another new requirement arrives.
    Programmer X.
    Another additional parameter.
    Another new conditional.
    Loop until code becomes incomprehensible.
  8. You appear in the story about here, and your life takes a dramatic turn for the worse

martes, 27 de noviembre de 2018

Book: Amusing Ourselves to Death

You've read 1984, you've read "A Brave New World", you've read "The Information" (you should), you've read McLuhan, and you want more connections between those, Amusing Ourselves to Death. It's like a missing (darker) chapter from "The Information", or an update to "A Brave New World".

Filled with data, and very up to date (being written in 1986).  I'd love to see an extension to it talking about the nonsense of information flood and "And now ... this" we're in now.  Neil Postman hints at gamification without naming it and speaks with great clarity about the continuous amusement we're in nowadays. Slot machines aren't mentioned in the book, but the fact that now we know many successful platforms/services/soma base engagement on the same algorithms than slot machines makes the book scary when looking at both directions from when it was written. Both as constataion of facts and premonitory.

Here's a very nice review about it, (funnily enough with nice pictures to help the reader)

lunes, 26 de noviembre de 2018

A Philosophy of Software Design

I finished "A Philosophy of Software Design" by John Ousterhout (creator of tcl):

The book contains some tips and tricks to keep complexity low, and some concerns against some mainstream trends (agile, short methods, etc..). 

I was expecting a bit more, given that the trigger for me was this review []  that already covered 90% of the value of the book.  

The author did a talk ( which covers also many of the good points.

Overall the book is a nice conversation starter. It's packed with good advices but it feels a bit short and sometimes simplistic. Maybe it's removing complexity even in the tips, so keeping it "obvious" is part of the magic. 

I'm still deciding if it's meta-genius.

viernes, 23 de noviembre de 2018

overlapping screens

I recently bought a screen, and funnily enough, this shiny new thing is not sufficiently tall to be placed just behind my laptop screen without overlapping.

The bottom centimeter of the screen is behind the laptop screen.

And this is a huge problem because emacs' minibuffer is what is hidden.

But luckily, ratpoison has this option called "padding".

set padding 0 0 0 50

Maybe it's clearer with a picture.

So this is my stupid trick of the day.

Yes, books would work too.

jueves, 8 de noviembre de 2018

Regex madness

I'm a big fan of regexes, the problems they solve, and the problems they create. It reminds me of Perl :p

Lately I've encountered a couple of very twisted uses of them worth a post.

First of all is a very nasty way of using the regex engine as a sintactic transformer that ends up validating arithmetic operations. Totally nuts.

Second one is a kind of "sed for power users". It's about internals of sed at a user level (as strange as it seems).

After reading drregex post I started hunting for that Abigail's slides on how to solve sudoku using regexes.

And here is Brian d Foy explaining how to parse json with a single regex.

Last one is my metaII bootstrapping parser. A single regex to bootstrap the metacompiler. I guess it also counts as crazyish.

martes, 6 de noviembre de 2018

e{vil,macs} macros

Macros are a powerful tool. I personally prefer vim-style macros although they're less powerful than emacs'(as I don't usually need anything on the surplus of emacs' macros features, I'm good with that).

Here's something I noticed today when using evil macros.

In vim, when you record a macro, you do it specifying a register where you want it to be stored. And registers are used for both copying/pasting text and storing macros (it stores the keypresses, so it's all text!).

On the other hand, a nice thing about emacs macros is that you can fine tune a macro in a very user-friendly way with kmacro-edit-macro.
Evil macros are a kind of hybrid between the two, and stored in an evil register and also as an emacs macro, so kmacro-edit-macro will give you the last macro you created, even if you created it with evil. The "problem" is that it doesn't update the evil register, so once the macro is defined for the first time, both macros (emacs kmacro and the evil register) are completely detached, and modifying one, does not modify the other.

I guess this is the right thing to do, because entangling one with the other could have many unexpected effects.

Along this experimentation, It's worth noting that editing the macro "the vim way" works great. kudos to evil devs again.

 So given we have stored the evil macro in register 'q':

  1. "qp to paste the register q. 
  2. edit the line - select the characters of the macro. 
  3. "qy 
  4. @q

lunes, 29 de octubre de 2018

so this is where the slack notification sound could come from

Nearly 1 year after finding out where old msn notification sound came from, I just was listening to this St Germain song that has something similar for slack notifications. Not sure it's the exact same sound, but it could very well be. At least, It took me half of the song to realize noone was pinging me in slack....

sábado, 27 de octubre de 2018

Some Lua articles

So at my job we're heavy Lua(jit) users. I've always liked Lua since I discovered it a few years ago.

It has a scheme-y feeling to it (with paredit unfriendly syntax, unfortunately). So here's a new article that has been recently published in the ACM. And some other paper from 2011. And another very nice paper that shows how lua can be used in different programming styles. Like the old "Implementation of Lua 5.0" or the lpeg one (you search that link yourself), Lua maintainers have a very concise style of designing and writing. Both code and papers. I always enjoy them.

viernes, 26 de octubre de 2018

jueves, 11 de octubre de 2018

staging hunks without magit

So there's magit that allows you to stage hunks as if you were doing "git add -p".  And I love it, but sometimes magit feels like too much, and it's slower than using vc.

I've been using git-gutter for some time, and I think there's a nice potential for staging hunks with it.

(use-package git-gutter
  :ensure t
  :config (global-git-gutter-mode t)
  :bind ("C-x v s" .  git-gutter:stage-hunk)
  ("C-x v n" .  git-gutter:next-hunk)
  ("C-x v p" .  git-gutter:previous-hunk))

With these configs (I'm using use-package), you can navigate through hunks with c-x v n/p (I'm basing the keybinds on vc "c-x v" ones) and stage them with "c-x v s". 

I'm pretty happy with those, only missing the ability of staging several hunks at once within a region.

viernes, 5 de octubre de 2018

kill-ring-max is a thing

So I recently discovered the variable `kill-ring-max', that dictates the size of the kill-ring, meaning when items on the kill-ring will be discarded.  Its original value is 60, and for some reason I still had it set to the default.

It's strange that I hadn't seen it mentioned before (at least, enough times to pay attention to it,) so let's try to increase the awareness of this very useful variable.

If you use helm-show-kill-ring, or something that allows you to search through kill-ring, having a bigger kill-ring might allow you to recover s"lost" work.

martes, 11 de septiembre de 2018

The Algernon Argument

From Here:
That intelligence (g) in healthy people is nearly impossible to improve is clear from the failure of psychology to provide any such method. But why intelligence would be so constant is not as clear: many other cognitive abilities are improvable (like working memory), so why not intelligence?

domingo, 12 de agosto de 2018

Adopting org-gcal.el

I just wanted to announce that I recently adopted org-gcal.

This great emacs mode imports google calendar events to your org files, and has some support for exporting events to your google calendars.

The author went missing in action for more than a year, and there were some nasty bugs in master that made the initial experience quite disappointing. Most of the bugs had Pull Requests opened, but still pending to be merged. So I decided to adopt the package to give it some love, and since last week, the melpa link points to my repo instead of @myuhe's.

Big props to the original author and also the many users of the module that helped with the migration.

If you use org-gcal, my recommendation is to update the package, and it will only improve your experience. There's an ongoing big refactoring that uses oauth2.el to manage all the tokens and oauth, but it still have issues that I haven't figured out how to solve in an elegant way.
Of course, if you have suggestions (or even better, code) for org-gcal, please direct them to .

miércoles, 25 de julio de 2018

meta git-tip-of-the-day

curl |
     jq 'map([.title, .tip] | join(" --> ")) | join("\n")' -j | 
     shuf -n1

jueves, 28 de junio de 2018

TIL: dabbrev-expand in zsh

So just by chance I found that M-/ does a kind of dabbrev-expand in zsh.

And it took me a few seconds to realize that shouldn't happen in that context.

Or should it?

What's for sure is this is one of the coolest things you'll learn today about zsh.

domingo, 24 de junio de 2018

emacs-like browsing in firefox and chrome

In this post we'll see how to make ctrl-n work as "next-line" in chrome, firefox, or any other app in your linux box.

Browsing is my only daily computing activity I can't do inside emacs. There are browser extensions that make your browser behave like vim or emacs to a certain extent, which is very useful but they don't give a complete experience to the user (often because of limitations in the browse extension system).

Bear in mind that myself being an evil user and heavy hjkl fan, my configs use j and k sometimes to mean down and up.


Long time ago, there was conkeror. which gave a very emacsy browsing experience, but after the whole change on browser extensions, conkeror is a feasible option anymore.  The same happened to keysnail. There were also some nifty hacks using mozrepl, which are long gone now.


The plugin is originally thought to give vim-like experience to chrome/firefox, but there's no reason you can't add shortcuts like "m-<" for "beginning-of-buffer" command.

Here's my config. Custom mappings:

Btw, pay attention to c-j and c-k. that's basically to be able to use j and k somehow in sites that override them (github, gmail). Also, note that we have a custom mapping for c-n and another for c-p, but unfortunately they do not work because those shortcuts are catched by the browser application before it arrives to the plugin.


This should be in your ~/.config/gtk-3.0/settings.ini :
With this you're allowing basic movements in address bar, search boxes, and input forms and text areas.


Yep, this is the tricky one. Both firefox and chrome take over ctrl-n, so you can't remap them and they always open a new window. Same happens with c-p showing the printing dialog. The trick then is to take over it ourselves going at Window manager level :).

In my case, I'm using ratpoison wm, so some of the commands used here won't work in your window manager, but you can find your way around using xdotool Look at this link for more info.

So we need 3 things:
  • - A way to guess which window is active (ratpoison -c "info") 
  • - A way to capture a keystroke (ratpoison's "definekey top" ) 
  • - A way to send an arbitrary keystroke to the active window. (ratpoison's "meta")
With these 3 capabilities, easy peasy:
It's dead simple, but I didn't write this till this week, and it's already made a huge difference in removing friction using firefox for me.


If you write long texts in text areas, you probably want to check atomic-chrome with ghost-text.

Also, mooz, the author of keysnail is now working in a generalized solution for what I just explained for C-n, using python (and requires root privileges) called xkeysnail. It appears to be very powerful and super customizable. Also, windowmanager agnostic, so you should probably give xkeysnail a try.

Also, /u/attrigh suggests giving next browser a try. Written in Common Lisp, built using webkit, and with a much richer experience than all those hacks put together.  I haven't tried it yet, but it's worth looking at in the near future.

sábado, 12 de mayo de 2018

Lisp recent threads

Lately, some articles on Lisp appeared in my usual websites.

Here's a HN thread where you can see the usual lispers enlightening other people about why Common Lisp is a very special beast.  DR Christian Shafmeister (CLASP) gives masterclasses in every post. Don't miss any :). There's some mention to those charts, where lisp shows as one of the both fastest and cheapest languages (after the ones that are specifically built to be superfast or efficient, while being more flexible than both)

Beautiful Racket, another hn post about the book.

Cloe lang. Apparently a heavily concurrent lisp.

extramaze, is built with racket, and the post shows some tricks used there.

Some CL macros?

Insightful post about starting a project in CL (going from repl to a project). Specially cool comment on tooling.

And as a bonus, RMS talking about his story with lisps. Very nice read also

I think I miss CL ... (...said while installing sbcl....)

bitmasking basic readings

So lately I've been exposed to using bitmasking for several tasks, and it's a cool and niche enough topic so that I delved a bit into it.

Appart from datastructures that depend on bit indexing like persistent datastructures, bit trees, bloom/cuckoo filters or others,  there's the concept of "plain" bit masking to optimize bookkeeping of a set of numbers (they can be indices of an array) in one big number.

Here are some examples of them:

martes, 8 de mayo de 2018

an advanced jq slideshow

So I found this advanced slideshow about jq (a tool you wanna have in your toolbox), and felt like sharing it here.

domingo, 6 de mayo de 2018

TIL elisp has iterators

So I was reading the Gnu/Emacs mail list and saw this thread where there's some good discussion about destructively modifying a recursive structure (as every structure, right?) in elisp.

All proposed solutions have something worth reading and understanding, but there's one that caught my attention. It uses cl-loop and generators. Yep, like python's ones, but in elisp.

I didn't even know that elisp had this magic in loop (as CL doesn't have it, and you have to make iterators yourself as closures called in `for' clauses.

So yep, the code is (as usual) only elisp and ready to be explored (and be enlightened with).  pcase and CPS used in real world. Also, nice to see in the end of the file where it wrestles itself into elisp itself and into emacs (even it adds syntax highlight for it).

Very good Sunday afternoon read (I just don't understand everything on it yet...)

Thanks to Daniel Colascione again for providing inspiring gems one more time :)

lunes, 30 de abril de 2018

bootstrap your emacs lisp learning

So every now and then there's someone asking in /r/emacs about learning elisp. And I always answer with the same solution that I'm now posting here to avoid copypasting the whole thing every time.

In an attempt to give bootstrapped solution, t-shirt sized, and that is both a fish,  a fishing lesson and a fishing rod, this is what I came with.
  • Type c-h k c-h k and read.
  • Type c-h k c-h f and read.
  • With the previous tools, try to understand the following:
    (defun foo ()
        (insert ";")))
    (global-set-key (kbd "C-c ;") 'foo)
  • Select the whole snippet and type m-x eval-region.
  • Type c-c ; .
  • Try to understand what just happened.

jueves, 26 de abril de 2018

It's like copy-paste, but reversed

So browsing this reddit thread I felt again like when I discovered the "undo in selection".

So you can mark a point in an emacs buffer as the destination of all your future inserts, copys and pastes.  And of course, this comes by default, because why not :).

domingo, 1 de abril de 2018


Cloudflare announcing their dns, and me reading this text about what and why of dns.

EDIT: more stuff on dns appearing in hn

miércoles, 28 de marzo de 2018

nice, no-bullshit, senior docs

So I've been reviewing some old documents and blogs and found some new ones.

Things that just make sense, that are full of common sense, and ask for common sense.

- Antirez's youtube channel. Very mamma mia.
- Norvig's lisp style book
- Joel on software. Worth every word
- Patterns and antipatterns of APL.
- The Art of Unix Programming. ESR.
- Patterns of software. Dick Gabriel's one, not the GoF's one.
- Some HN thread with good links about system dynamics.
- Christopher Alexander a city is not a tree 

miércoles, 21 de marzo de 2018

TIL: no more git clone

I knew about suffix aliases but usually don't need them because my launchers already use xdo-open. But I came out with this, and feel that it has a twist:
alias -s git="git clone"
It makes github links more copypasteable.

domingo, 18 de marzo de 2018

fixing indentation of lua (busted) in emacs. A nasty hack

In general, indentation is not an issue in emacs.

But there are some exceptions.  For example, in Lua, one of the de facto testing libraries is busted, which tries to mimick rspec in many aspects.

A typical busted test looks like this:
Lua mode tends to indent code in a very lisp-y way (which I personally like) by aligning parameters to the same function using as a "starting point" the offset of the first parameter.  In this case, there's also an opened function that gets indented in addition to that base column.
This is unacceptable in most codebases, so I had to write some hack for those particular cases.

As the indentation code for lua-mode is quite complex and this is an exception to the general rule, I wrote this very ugly hack, that seems to solve my problem at hand.
As with all defadvice uses, it looks like a hack because it is a big ugly hack, but at least it lets me deal with it, and move on with my tasks without manually reindenting stuff.

Another +1 for emacs hackability :)

domingo, 25 de febrero de 2018

SF emacs meetup

This week I attended an emacs meetup in SF just by pure chance. I was browsing /r/emacs and there was a comment about the meetup. I found about it just the day before the event.

Being the first time I'm in San Francisco, and the fact that I'll be around just for a couple of weeks (for my new job), it makes it even more surprising that  I was able to go.

We were about 15 people, most from the bay area, and I think myself I was the only foreigner. The meetup topic was "a few of our favourite emacs modes", which unlocked the possibility to talk about helm-dash (not that it's my favourite mode, but is the one I wrote (and I also find it quite helpful)).

So I volunteered and gave a really quick intro to helm-dash.

Others talked about evil, magit, pynt, multiple-cursors (that was nuts!), git-timemachine, use-package, and probably some more that I already forgot.

My discoveries were:

- evil can easily create new text objects.
- learn to use multiple cursors (although I prefer vim's substitutions, mc work better for multiline "macros", and give you more visual feedback than emacs macros)
- pynt and emacs-ipython-notebook . If I ever do python again, I should remember that.
- use-package has more options that one usually thinks. RTFM
- ggtags is worth looking at if your language is not supported by etags/ctags.
- hydra red/blue modes.

Lots of fun during a couple of hours talking about tooling and worfklows with random techies.See you next time I'm around.

sábado, 27 de enero de 2018

2 ways to anchor a regex in elisp

This one I just learnt reading a PR in the melpa repo.

Usually we use ^ and $ to match the beginning and end of the line when dealing with regular expressions.

But, the same way we have \A and \z in ruby , in elisp manual: elisp regex backslash explains there is \` and \'  (that would be written \\` and \\' inside your regex string) to anchor the regex match to the beginning and end of the string or buffer. While $ matches end of the line, so "hello$" will match "hello\ngoodbye", while "hello\\'" will not.

jueves, 25 de enero de 2018

make vlc fit fullscreen window

It's an annoying thing but I was already getting used to it: VLC scales its window strangely (using ratpoison window manager), and I always have to split and 'unsplit' the frame it's in, so it adapts its proportions to the enclosing frame.

But here is the solution: 

Try this...(note: this was written using VLC 2.0.5, but it should also apply to 2.0.7)

  1. In VLC, click ToolsPreferences
  2. In the bottom left, for "Show Settings", click Simple (it might already be selected).
  3. At the top left, make sure "Interface" is selected (it should be).
  4. On the right side, for "Look & Feel", uncheck...
    • [ ] Resize interface to video size may also wanna check (or it might already be checked)...
    • [■] Integrate video in interface
  5. Click Save
  6. Manually re-size the VLC window to the size you want.
  7. Close VLC to commit the pref change & window resize.
  8. Run VLC, play some files & report if that's what you want.

It might be useful to my future self, and as I'm not sure where vlc saves its config, I might have to redo it in my future installs. (FYI, the config is saved in ~/.config/vlc/vlcrc, and the info is there, so just carry that file with your dotfiles and you should be fine).