Postgres’ psql meta command
\d stands for display or describe.
h/t Jack Christensen
Postgres’ psql meta command
\d stands for display or describe.
h/t Jack Christensen
I’m currently working on an app that forwards logging around to various locations on the Linux server. It’s a bit tricky for me to figure out where any action I take in the browser is being logged. I need those logs!
A nice way to figure out where the logging is happening is to narrow it down to one directory (say,
ls that directory, ordering by most recently updated. The items at the top of the list have been recently updated, and thus probably contain valuable loggings!
$ ls -lt
I’m throwing on the
-l flag for more detail. If there are lot of logs, filter it down with
$ ls -lt | head
Thanks for the idea, Kori!
This is a companion to my previous post about inline HTML styles. If you want to put your images inline in your HTML, GNU coreutils provides the
Here’s me running it in Vim command mode, sending the output right to my current line:
:.! base64 -w 0 public/images/bg.gif
-w 0 disables line wrapping, which I don’t want for inline images. Prefix this string with
"data:image/<MIME TYPE>;base64," and you’re good to go.
I like my exceptional pages (404, 500, 503) to rely as little as possible on the webserver to render in the browser. A nice tool to support this is CSS Used for Chrome.
CSS Used adds a panel to DevTools that reports which CSS classes from external stylesheets are being used on your page. You can then paste these styles inside a
style tag and remove stylesheet references in your HTML. I iterate on this by opening the HTML file in my browser outside of my project repo; when all the styles are loading, I’ve removed the stylesheet dependency.
Today while doing some sleuthing, I learned about the
host “is a simple utility for performing DNS lookups.” It helped me connect a series of domains to their respective AWS EC2 servers, without a visit to the domain registrar.
$ host jakeworth.com jakeworth.com has address 188.8.131.52 jakeworth.com mail is handled by 10 mailstore1.secureserver.net. jakeworth.com mail is handled by 0 smtp.secureserver.net.
UUID’s (universally unique identifiers) are really handy. I use them for all sorts of things, like key props in a React map, and I like to have them easily accessible when writing code.
Today I wrote two Vim mappings to support this workflow. I can shell out to Ruby and use
" Insert a UUID with Ruby nnoremap ruid :read !ruby -e "require 'securerandom'; p SecureRandom.uuid"<cr>
uuid library. I did not have to install
uuid, it was already available to me.
" Insert a UUID with JS nnoremap juid :read !node -e "var uuid = require('uuid'); console.log(uuid.v4())"<cr>
includes, and in Ruby, it’s
include (with a question mark). Each language does not care what I meant.
includes. Ruby does not, so it is
I cooked up this Heroku/subshell command today, and I like it:
$ psql $(heroku config:get DATABASE_URL)
This will connect me to the primary PostgreSQL database for my Heroku application in the psql client. Now I’m ready to query!
NOTE: why not
$ heroku pg:psql? I’m not sure. I think Heroku was reporting status issues today, and I wanted to bypass any infrastructure I could.
I’m managing two Firefoxes on my laptop: one for work and one for after work. A feature that supports this well is Firefox profiles. Visit them in Firefox by typing
about:profiles into the browser bar.
These work like Chrome People— separate sessions, histories, bookmarks, etc. I have styled the two browsers a little differently so I can quickly tell them apart.
I used to use Incognito/Private Windows for this setup, but those aren’t great for long-running browser sessions, because when you close or crash the browser, anything you’ve done in that browser is gone. Profiles give me the isolation I need with some persistence, too.
Planning to use Zoom for something other than a meeting, like a reading or musical performance, that would benefit from room noise and a softer audio experience? If so, read on!
Zoom has several default audio features in place to make your business calls sound great. We don’t want those features in place in a performance setting. Jettison them by enabling ‘original sound’ under advanced audio settings:
All you need to do from here is turn on your best (quality and/or position) microphone option. For me, that’s my display audio.
h/t Suzanne Erin
Something I’ve learned pairing with Chris Erin is to checkout code you don’t want in patches. Here’s the command:
$ git checkout --patch
git add --patch command many developers know, this puts you an interactive workflow where you can decide how to handle each chunk, or patch, of your changes. It works opposite of
git add --patch, in that
y means check out the patch (abandon the changes), and
n means keep the changes.
This is a great flow to go through before trying to commit code; use it to get rid of debugger statements, pseudocode, unwanted autoformatter changes, etc.
I really love the Dark Reader Browser plugin (h/t Chris Erin). It turns most websites into a dark mode that is really easy on my eyes. However, some sites just don’t look right in dark mode. Luckily, the plugin can be toggled on and off with
ALT + SHIFT + D on Firefox and Chrome. I use it a couple of times a day on websites I encounter on the internet.
Bonus: Here’s an example of this plugin in action, that is very meta.
There are lot of tutorials about Git. One that is built right into Git is the ‘everyday help’. Print this help with:
$ git help everyday
The output is a series of must-know commands for a variety of roles in a technical organization: individual developer (standalone), individual developer (participant), integrators, and admins.
Pick a lane and go! 🏁
Git has one feature that I find irksome; you have to be in the directory with the Git repository to run commands against it.
…Or do you?
Git provides the
-C flag for this scenario. Follow it with a directory name, and Git will execute your command as if it was run from
$ git -C ~/tilex status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: lib/tilex_web/templates/layout/app.html.eex no changes added to commit (use "git add" and/or "git commit -a")
I’ve been doing an experiment lately that requires reading and searching lots of logs in Tmux. Something that makes this harder is that we collect a deep history there. Sometimes I’ll ‘find’ a query I’ve been looking for 😀, only to realize it is hours or days old ️😐.
clear-history has been our solution. Running this command on an already cleared Tmux pane clears your history for that pane; you can’t scroll up or search the previous output.
We’re doing this enough that I put this alias in our terminal dotfiles.
alias tc='clear; tmux clear-history; clear'
tmux clear-history is the CLI version of the Tmux meta command
This week Chris Erin taught me a technique that has changed my testing game: Vim mark your current Ruby test with
When writing TDD-style code in a test-crazy language like Ruby, I tend to follow a predictable workflow: create a test, watch it fail, bounce around the code making changes, and run/edit the test again. This loop can repeat for hours on a complex feature.
There are many ways you could navigate back to your test from elsewhere; a very efficient method is to mark it in Vim with
mA. Like any mark, you can return to it with
`A. Why ‘A’? Capitalized marks are file marks and are valid between files. With this command, you can mindlessly jump back to your test from anywhere in the jumplist stack.
This week, we discovered an interesting feature: when the target branch for PR is deleted, GitHub closes (permanently, from what I can tell) the PR. To observe this in action:
Delete your branches carefully; doing so could unintentionally close one or more PRs.
Today I learned that the
git-diff command accepts a
<path> argument. I used this knowledge to construct a command that runs only the RSpec test files on my branch that differ from master.
(other-branch)$ git diff master --name-only spec | xargs rspec
This is handy on a big test suite; when you can’t run every test, make sure you run the ones that you have changed.
man git-diff for more info.
I use Mac Notes a lot during pairing and brainstorming. It works, and it’s right there on the Mac!
One issue I’ve had is that the default text size on Mac Notes is unreadably small on a big monitor or iMac. I always end up creating a note, then bumping the text size with
Of course, there’s a better way. Set the default font size in preferences.
I’ve been hacking on TIL to optimize our site for Safari Reader mode. A lot of this is black box, because Apple doesn’t have easy-to-find documentation about how the feature works.
One thing that seems to matter is a class called
byline for your author information, and an HTML tag
time for the publication date. Here’s an example, borrowed from this site:
<p class="byline"> <%= name %> <time datetime="<%= inserted_at %>"> <%= inserted_at %> </time> </p>
It gives us relevant reader information, shown here in Safari:
Here’s the PR:
When writing HTML, make sure that your meta
charset tag is in the first 1024 bytes on the page.
<meta>element declaring the encoding must be inside the
<head>element and within the first 1024 bytes of the HTML as some browsers only look at those bytes before choosing an encoding.
What does this mean practically? Keep this tag near the top of your document, and use a website validator like https://validator.w3.org to check your tag placement.
script tag in your HTML annotated with
script tag, when omitted, is
Delete that code and go green 💚.
Today I became familiar with the Git configuration
interactive.singleKey. In the Hashrocket dotfiles this is enabled by default, and I’m not sure how common it is out in the wild. To quote the docs:
In interactive commands, allow the user to provide one-letter input with a single key (i.e., without hitting enter).
git add --patch to be very powerful by enabling a quick vote up or down on a patch with a single keystroke.
Make sure you have the Perl module
Term::ReadKey installed; it is a dependency.
To repeat your last Vim command mode command, use the
After doing this once, continue to call the command with
@@. A use case would be continuing to expand a pane in increments of two via
This is a follow up to PayPal Transaction Pages aren’t Linkable. We figured out a way to build this feature!
When you process a PayPal transaction with the SDK (i.e. as a seller), you get a token that could be considered a transaction ID. It is something like a primary key on an object that is the parent to several other transactions: the seller’s transaction, any currency conversions, etc.
With this ID in hand, you can link to the seller’s dashboard and see a summary of this parent transaction. It’s not a documented feature, so the link could be broken at any time.
Thanks for sticking with me, PayPal support.
I spent some time this week trying to create a link directly to a PayPal Merchant transaction show page. This is the page you’d see as a merchant when somebody has paid you via PayPal.
These pages use the transaction’s ID as a lookup, so I’d need the know that ID in order to dynamically create the link. After some Googling, reading GitHub issues, and finally the source code of my PayPal SDK of choice, I’d like to report: PayPal does not expose this ID in the normal course of business.
To quote my PayPal caseworker:
“While there are ways of retrieving the Transaction ID… you will not be able to link directly to the PayPal transaction details page, for security. The only way that your buyers can view the transaction details page is by accessing PayPal themselves, logging in with their credentials, and navigating to the Activity.”
I hope this spares another developer from the same rabbit-hole I just emerged from. Sometimes things with technology don’t work. 🤷♀️
Edit: we figured it out!
Today I encountered the following syntax (observed in Ruby 2.7):
SpecialError = Class.new(StandardError)
What’s going on here?
According to the Class docs,
Class.new takes a superclass as an argument, creating an anonymous unnamed class. So this could be written as:
class SpecialError < StandardError end
We’d lose the anonymity of the
SpecialError class, but in the first example, we are assigning it to a Pascal-cased variable name anyway.
I think the first syntax would make sense when the code looks just like this example: a simple class that inherits some behavior, where the name is needed only in the scope where the class is declared.
Some of my repos have a lot of branches, and a command I discovered this week sorts them by the most recent committer date:
$ git branch --sort=-committerdate * new-branch not-so-new-branch super-old-branch
- reverses the order, putting the most-recently updated branch at the top, rather than the bottom, of my output. That’s more intuitive to me, but it certainly works in reverse.
Have you been editing the code in your bundle’s Ruby gems, adding
puts, debuggers, deleting code, etc. And now you want to restore your bundle to its pristine state?
$ bundle pristine
This “restores installed gems to their pristine condition”. See
man bundle-pristine for more info.
At RubyConf 2019, I learned that social media hashtags are more easily read by screen readers if they are capitalized. So #rubyconf is more accessible when written as #RubyConf, because the screen reader can more easily make sense of the word breaks. Keep this in mind when posting and designing marketing campaigns.
I saw #rubyfriends and #rubyconf migrate to #RubyFriends and #RubyConf at the conference in realtime as this idea spread.
h/t Coraline Ada Ehmke
HAML uses meaningful whitespace identation, so in general, multiline code doesn’t fly. The prevailing wisdom is that ‘it’s better to put that Ruby code into a helper’ rather than support multiline blocks. But what if I really want to?
Here’s an example of a multiline HAML block using pipes.
= link_to( | 'someplace', | some_path, | class: 'someclass'
The pipe character preceded by whitespace signifies a multiline block. Make sure you don’t end your final line with a pipe; this can break your templating.
Your Tmux working directory is the root directory of the session. You can figure out what it is by opening a new window or pane in your session. The directory you start in is your working directory.
Sometimes it’s not the best directory for the type of project you’re developing. For instance, it could be set to the root directory of an umbrella app, when you’re working exclusively in one of the subdirectories.
Reset it with the
$ tmux attach-session -t my_session -c ~/my_project
Services that render fenced code blocks tend to remove whitespace. They’ll display these two code blocks the same way, trimming the blank lines from the second example.
GitHub does this, as does Deckset. Deckset also adjusts your code’s font size based on how many lines are in the block, which means these two code blocks would have different font sizes on their slides. Sometimes I don’t want that to happen, like when building a series of slides that fill in different pieces of an example and should look consistent.
I cheat this feature putting a non-breaking space on the last line. On Mac, I can do this with
OPTION + SPACE. I can see the character in Vim (‘
+’), but it’s invisible on the slide, and it prevents Deckset from collapsing the line it’s on, forcing the code block to the length I choose.
This is my 400th TIL! 🎉
I’ll file this under ‘Vim is endlessly composable’. Today I learned that Vim tags can be used to define a range in visual mode. Here’s how you’d fold your code between two Vim tags.
Go to the first tag. If you marked it
1, here’s how you’d do that:
Enter visual mode and extend to your second tag
Enter command mode and fold the range:
Which automatically extends to:
I use this in big markdown files to hide all but the thing I’m currently working on. Enjoy.
I use Vim’s
:sort all the time. If I can’t have a more meaningful algorithm than alphabetical, at least my lists are in some kind of order.
This function comes in surprisingly useful while writing GitHub-style checkbox lists.
- [x] Check mail - [ ] Play guitar - [x] Write TIL
Sorting this list alphabeticaly puts the undone items at the top.
- [ ] Play guitar - [x] Check mail - [x] Write TIL
Reverse the order (in classic Vim style) with a bang:
Pull request openers on GitHub can request a review from a GitHub user, or a team that has at least read-access to the repository. In the screenshot below, deploying the ‘Ninjas’ to review this PR is effectively the same as requesting a review from each ninja on the team. If they have notifications for such things, they’ll be notified, and they’ll see a banner on the PR’s show page requesting their input on the change.
This is a handy way to request a lot of reviews at once.
I’ve owned a WASD keyboard for a while but totally forgot about the DIP switches on the bottom. What’s a DIP switch? From Wikipedia:
A DIP switch is a manual electric switch that is packaged with others in a group in a standard dual in-line package (DIP). The term may refer to each individual switch, or to the unit as a whole. This type of switch is designed to be used on a printed circuit board along with other electronic components and is commonly used to customize the behavior of an electronic device for specific situations.
On a WASD V2 87-key, these switches let you enable Mac mode (switch command and option), swap caps lock with CTRL, activate function commands, and more. These can be set in the OS or via different applications, but setting them at the hardware level is very convenient.
Vim’s quickfix buffer is a place I spend a lot of time. Iterating through it can be done in a couple of ways:
:cprevious :cnext :cfirst :clast
:cp :cn :cfir :cla
vim-unimpaired has some nice mappings to help.
[q :cprevious ]q :cnext [Q :cfirst ]Q :clast
]q we’re flying through those results.
I change the keys on my mechanical keyboards often. Sometimes I’m upgrading from stock, or trying an experiment, or just pursuing a look. It’s a reality of being really into keyboards.
Something I’ve learned along the way: removing all your old caps at once is a bad idea. When you do this, you have to figure out where every key goes. Some keycaps have a code on the underside telling you the row it belongs to, most do not. I end up pulling up my Mac virtual keyboard, or looking at another keyboard, to sort it out.
A better techique: take the new keys and line them up in the correct order for each row. Some keycaps ship in separate rows, making this easy. If that’s the case, slide each row out of its shrinkwrap like a sleeve of Thin Mints.
Then, change one row at a time. Remove all the keycaps in one row, and then put all the new ones in place. This is fast, foolproof, and if you get interrupted in between rows, you still have a functioning keyboard.
This is a command I am continually a huge fan of. Here’s one way to open a new Tmux window, from Tmux command mode:
:new-window <program> <arguments>
My practical example from today:
:new-window psql my_database
This opens a new Tmux window
psql with the arguments supplied, connecting me to
my_database. When I terminate database connection, the window closes. For web development, this is a great way to quickly connect to a program, run some commands, then close the connection and cleanup the Tmux session.
Today I learned a new Vim command,
:cope. The headline for this command is that it “open[s] a window to show the current list of errors”. The side benefit is that if you already have quickfix window in your buffers, like you would after greping the codebase, it will open or reopen that quickfix buffer.
:help :copen for more info.
When I make a Vim horizontal split, the two panes are evenly sized. I then often use
:resize n to make one pane larger or smaller. To restore the panes to their evenly sized split, use
<vim-leader> =. In the Hashrocket dotfiles, this translates to
CTRL + W =.
CodeSandbox autoformats your code on save by default, which I find very valuable. Sometimes, when debugging an issue or experimenting with a code style, I don’t actually want autoformatting to occur.
This can be disabled under ‘Preferences’ -> ‘Settings’ -> ‘User Settings’ -> ‘Format On Save’. Make sure to turn it back on when you’re done experimenting.
When doing puts-driven-development in Elixir,
IO.inspect/2 are very useful. These functions return their items unchanged, allowing us to spy on a value in our Elixir code.
I’m a fan of the
:label option, which decorates our output with a label, making it easier to understand.
def channel_name_split(channel) do channel.name |> IO.inspect(label: "channel name before") |> String.split("") |> IO.inspect(label: "channel name after") end
And here’s the output in our server log:
channel name before: "workflow" channel name after: ["", "w", "o", "r", "k", "f", "l", "o", "w", ""]
h IO.inspect in IEX for more info.
Set usually include an array as the argument:
const arraySet = new Set([1, 2, 3, 4, 5]);
Set constructor also accepts a string, splitting it into a set for you:
const text = 'India'; const stringSet = new Set(text); // Set ['I', 'n', 'd', 'i', 'a']
Enjoy those extra keystrokes!
To debug your VSCode installation, use the verbose flag:
$ code --verbose
Lots of interesting output to explore!
The iTerm2 terminal includes a transparency feature; enable it in settings:
Once enabled, you can toggle transparency on and off with
CMD + u.
Here’s my transparent iTerm, with a very important Wikipedia page below.
Today I learned that GitHub has allows you to insert a one-line suggestion while conducting a pull request review. Click on the button circled in red, and you’ll get a
suggestion fenced code block, as shown.
Inside the code block is the current code; replace it with your proposed change. GitHub will present your suggestion in a nice diff format.
When the pull requester views your suggestion, they can accept the change with one click. Efficient!
Multiple-lines are not yet supported, according to this GitHub blog post it is a frequently requested feature.
h/t Jed and Raelyn