Today I Learned

A Hashrocket project

133 posts about #workflow

Open Newest Email with Gmail

Part of my Gmail workflow includes hotkeys. I’d recommend them to anyone who wants to use their email more efficiently.

My current favorite command is gio, or gi (show inbox), combined with o (open focused message), which defaults to the newest message. gio lets me open my newest email without a mouse, faster than you can say ‘unsubscribe’.

Combine this with Vim motions (j and k) and you’re off to the races. 🏁

Access Unsupported Resolutions With RDM On Mac

If you visit the Display Settings for your Mac, you’ll find that you only have a handful of screen resolution options. For standard use, you’ll get by with these. If you need a specific, unsupported resolution you’ll need help from a 3rd party tool. There are many options out there. RDM is a free and open-source option.

Once you have it installed and have given it Accessibility permissions, open the menu from your top toolbar and select the resolution you are looking for.

I use RDM to adjust my screen resolution to 1280x720 for optimal screencasting.

🔍 Using NSArray with CONTAINS NSPredicates

NSPredicate’s predicateWithFormat method takes a va_list of arguments, so it’s not possible to pass an array to your format string. But, the same result can be achieved by combining multiple NSPredicates together using an NSCompoundPredicate:

Given a space-separated array of search words:

NSArray<NSString*> *words = [@"my search terms" componentsSeparatedByString:@" "];

You can combine them by first creating multiple predicates:

NSMutableArray<NSPredicate *> *predicates = [NSMutableArray new];
for (NSString *word in words) {
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"attribute CONTAINS[cd] %@", word];
  [predicates addObject:predicate];
}

And finally create one NSPredicate via NSCompoundPredicate

NSPredicate *finalPredicate =
        [NSCompoundPredicate andPredicateWithSubpredicates:predicates];

Copy Some Data From The Chrome Console

Sometimes you have some data that you are playing around with in the console, something you logged from an API response. You then want to share it, so you try to copy the whole thing into your system copy buffer. There are a couple hacky ways of doing this, but Chrome supports a really smooth way.

Use the copy function.

characters
> (8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
copy(characters[1])

My system copy buffer now contains the entire object that makes up the second entry in that list. I can then paste it into Slack or wherever.

source

Open Slack's Keyboard Shortcuts Reference Panel

Slack has a ton of keyboard shortcuts, but you might only be familiar with some of the more obvious ones. When I started using Slack, I quickly discovered that Cmd+} and Cmd+{ allow you to navigate forward and backward through your different Slack workspaces.

But there is a whole world of Slack keyboard shortcuts that I didn’t know about. By hitting Cmd+/ a Keyboard Shortcuts reference panel will be toggled open. This lists all of the keyboard shortcuts you didn’t know you needed.

Gesture To View All Windows Of Current Mac App

I use a Mac as my primary development machine. When working on a web application, I often end up with a couple Chrome windows open and sometimes even a couple terminal windows open. I generally use the Cmd+~ key binding to toggle through them. This can occasionally get confusing though. To get the fuller picture, I can get a birds-eye view of all windows for the current app using a track pad gesture.

Swiping down with three fingers on the track pad will provide a zoomed out view of all windows. Click on the window you care about to view that or swipe back up with three fingers to dismiss it.

source

Enable Keyboard Shortcuts In Gmail

In these modern times of asynchronous communication and paperless receipts, a person’s email inbox can get mighty full. Keeping that influx of emails at bay is a challenge. If you’d like to start unburying yourself and get on the path to inbox zero — Gmail’s keyboard shortcuts can help.

Keyboard shortcuts are not enabled by default, so you’ll need to turn them on in settings. Click the gear icon, select Settings and then scroll down under the General tab until you find the Keyboard shortcuts section. Select the Keyboard shortcuts on radio button and then Save changes.

You’ll now have access to a variety of shortcuts, such as using the j and k keys to move up and down the list of emails in your inbox. Find the one you want and hit o to open it up.

Keep exploring — there is a whole world of keyboard shortcuts out there.

h/t Jake Worth

Gmail 'o'

In my quest to learn all the Gmail hotkeys, today I learned ‘o’.

‘o’ opens the focused email in your inbox. Combine this with ‘gi’ (go to inbox) and Vim-style JK (down/up throught the inbox list), and you’re cruising. 🏁

Hotkeys must be enabled in your settings.

Change the Mac Screenshots Dir

If you like a clean virtual desktop, then placing all screenshots on the Desktop can be incredibly messy.

To change the desktop location:

> defaults write com.apple.screencapture location ~/Desktop/Screenshots

Let’s say you configured this to a weird directoy and you want remember where you are saving screenshots, you can read that configuration.

> defaults read com.apple.screencapture location
~/Desktop/Screenshots

ProxyJump: simplest way to ssh with a jump host

Ever need to jump your ssh through an intermediate host? You may be familiar with using netcat like this in your ~/.ssh/config:

Host jumpy
  ProxyCommand ssh -q jump-host nc destination-host %p

ProxyCommand runs on our local machine. The command must open a tcp connection that ssh may then use for the session. Here we shell into our jump-host, connecting the file descriptors to nc, which will forward all data to destination-host on %p, the port you provided to -p on the cli.

Clear as mud, no?

Another slightly more readable way to achieve this is with -W

Host jumpy
  ProxyCommand ssh -W destination-host jump-host

This works the same way as the nc version, but now we are using ssh’s internal implementation of nc. So one less dependency on the jump host.

But behold, the most legit and legible version of jumping hosts:

Host jumpy
  Hostname destination-host
  ProxyJump jump-host

So same thing, but now the words say what it does.

When you get lost remember that .ssh/config has it’s own man page:

$ man ssh_config

Thanks Dillon!

Duplicate The Current Tab In Chrome

Sometimes when viewing a page in Chrome, you realize you want to keep that page open but also go back to the previous page to view something else. An easy way of achieving this is to duplicate the current tab and then go back.

To duplicate the current tab hit Cmd+Enter while the focus is on the URL bar.

If the URL bar is not in focus, then first hit Cmd+L to focus followed by Cmd+Enter.

Start Zoom on Mute 📣

We’ve been using Zoom for a while now, and it’s proving to be an excellent video conferencing tool.

One setting I recommend enabling is ‘Always mute microphone when joining meeting’, under the ‘Audio’ settings. I’ve been using it for a week and love it. Pausing work in an open office to join a conference call can be a messy affair, and this setting helps me control how I enter the conversation (silently).

Shell parameter expansion

Shells can perform variable expansion, this is really useful for default argument variables in shell functions.

Here is a simple example of assigning a variable from an argument or defaulting to running a different shell command:

clog() {
  log_date=${1-`date +%Y-%m-%d`}
  git log --after="$log_date 00:00" --before="$log_date 23:59"
}

This allows me to write

clog to default to today’s date or

clog 2018-10-02 to look at the logs from yesterday

The date in the example clog 2018-10-02 would come through as $1 in the function, so ${1-`date`} means run this shell command if there is no $1.

*references:

https://www.tldp.org/LDP/abs/html/parameter-substitution.html#USAGEMESSAGE

Select a Square With Mac Preview

Lately I’ve been taking screenshots of code and my terminal. They seem to look the best when they’re square; that shape translates better to a variety of project management tools and social media platforms.

Mac Preview lets you select part of an image down to the pixel for cropping, and I have found selecting a perfect square very difficult. The solution? Select with SHIFT + click to force a square-shaped selection. ⌘ + K to crop.

🔲

Enable Breadcrumbs For VS Code 1.26 Release

The latest release of Code (Version 1.26) brings about a lot of exciting new features — including file breadcrumbs at the top of each file editor view.

Breadcrumbs feature in action

By default this feature is not enabled. You can enable it from User Settings (Cmd+Shift+P, ‘User Settings’). From the User Settings view, you can search for breadcrumbs and you’ll see the following item:

  "breadcrumbs.enabled": false,

Use the pencil to override it to true and you’ll have that trail of breadcrumbs waiting for you.

Two ways to access emojis in Windows 10

Include an emoji via keyboard shortcut while typing in Windows 10 by using the Windows key together with the period key. Windows key + semicolon is also a valid shortcut.

No keyboard handy? In the right-hand part of the taskbar, there is a small keyboard icon. If that is not visible, you can enable it by right-clicking on the taskbar.

Clicking this taskbar icon enables the touch keyboard, which includes a smiley key that takes you to to the emoji list.

Now, you can express yourself. 🤠

Add The VSCode CLI To Your Path

Visual Studio Code has a command line tool that can do a bunch of things. Perhaps the most common is opening up the current directory from the command line.

First, you need to add code to your path. This can be done from within Code itself.

Hit Cmd+Shift+p to pop open the command palette. Then start typing Shell Command ... until the Shell Command: Install "code" command in shell PATH option appears. Select this and Code will add code to your path.

Try code . to open the current directory or run code --help for more details on what’s available.

Log Into Windows 10 Without A Keyboard

Sometimes you might need to log into a Windows machine without a keyboard. A damaged keyboard, non-functioning ports for connecting an external keyboard, or a faulty keyboard driver could put you in this predicament.

Windows 10 includes an accessibility menu called ‘Ease of Access’, located in the lower righthand corner of the screen. This menu includes an on-screen keyboard. Use it to log in when your keyboard doesn’t work.

Ease of Access

Disable Swipe Navigation For A Specific App On Mac

Mac’s touch pad has a bunch of handy swipe gestures, including swiping two fingers to the left or the right to navigate backward or forward. This particular gesture can be globally enabled and disabled. I find it useful for most apps and a pain in a few apps, such as Google Chrome.

From the terminal we can disable it for a specific app (like Google Chrome):

$ defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool FALSE

Restart the target application, in my case Chrome. The left and right swipe navigation will no longer be triggered.

source

Hide all other windows on #macOS

Sometimes your desktop gets cluttered with windows of different running applications which makes it difficult to concetrate on the task at hand.

This can also come in handing when sharing your screen or presenting.

Fortunately macOS offers some shortcuts to remediate this common problem:

⌘+h - hide current window

⌘+⌥+h - hide all other windows

⌃+⌘+f - toggle full screen mode

Import A Github Project Into CodeSandbox

A really fancy feature that CodeSandbox offers is the ability to import a Github project. If you go to the Create Sandbox page, you’ll see some options including Import from Github. From there, paste in the URL to a public github repository and a matter of seconds your entire project will be synced into a new CodeSandbox project.

I recently did this with a create-react-app project and CodeSandbox even knew how to recognize that it was a CRA app so that it could run and display it in the web view.

Set A Window To Its Default Zoom Level In Mac OS X

Often when showing my screen to someone else or connecting to a project, I have to adjust the zoom level of my current window by hitting Cmd + a bunch of times. Once I am done I usually do some guess work to get the screen size back to what I am used to, hitting Cmd - a couple times.

There is an easier way.

Hitting Cmd 0 will return the window back to its default zoom level.

h/t Jake Worth

🆙 Update macOS from cli

Opening the App Store and navigating to the update tab and clicking and confirming the update buttons is just too many steps for me.

macOS has a cli to the software update process:

$ /usr/sbin/softwareupdate

With some fancy arguments I can update everything in one command:

$ sudo softwareupdate -ia

the -ia flag means install all the available updates.

Shell into a stopped docker container

If you are experiencing an error trying to run your docker container then maybe you need to do some debugging inside of the docker container. But how do you shell into a container if you can’t even start it?

docker run -it --rm --name newname myimage:latest bash

This takes your image and starts a new container, running bash and allowing you to examine your container.

-it allows you to attach a terminal.

--rm will clean this container up when you are done with it.

--name <something> is the name you give your new container.

Selecting DOM Elements Faster Than Ever In Chrome

Selecting and inspecting DOM elements: you’ve done it many times before. Whether you right click the element and select Inspect (which isn’t always all that accurate) or you use the DevTools’ inspect tool with highlight-assist, it takes a couple clicks to get there.

There is a faster way.

Hit Cmd-Shift-C.

Chrome DevTools will be expanded open if it isn’t already and your mouse pointer will be put in inspect mode with the highlight-assist. Find your DOM element, give it a click, and start inspecting!

Easier Access To Network Throttling Controls

In Simulating Various Network Connection Speeds, I showed how to change between various simulated connection speeds from the Network tab in Chrome devtools. Unfortunately, the Connection Speed dropdown is crowded out by a number of other controls in the Network tab. As a result, unless that tab is expanded pretty wide, you won’t be able to get at it. I’ve found myself sliding the devtools wider and narrower over and over while testing things with throttling.

There is another, easier place to access throttling.

The console drawer gives us access to a number of additional tabs of controls. Add the Network connections tab for easier access.

Show All Pivotal Stories With Blockers

Within the past year Pivotal Tracker added a feature that allows you to mark stories with blockers. These are visual indicators with a description that are used to show a particular story is blocked, that is, it cannot be completed until something else is taken care of.

In order to maintain the health of the project, it is good to triage these blocked stories from time to time. The best way to identify all of the blocked stories is to filter them into their own column.

Enter is:blocked into the search bar to show all of the blocked stories.

Toggle Between Terminals In VSCode

VSCode allows you to have multiple terminal tabs, but you have to manually switch between them with a drop down. For me, that is a lot of mouse action. I’d prefer to have a keyboard shortcut that allows me to switch between them. Fortunately, there are commands for going to the next and previous terminal which can be attached to keybindings.

Try adding the following two entries to your keybindings.json file:

[
  { "key": "cmd+shift+k", "command": "workbench.action.terminal.focusNext" },
  { "key": "cmd+shift+j", "command": "workbench.action.terminal.focusPrevious" },
]

Save the file and then start toggling between your different VSCode terminals.

source

Firefox DevTools Vim Mode

I’ve been using Firefox more and more lately, and keep discovering new features with the devtools. One of the most handy when trying to edit css or html is vim mode.

To enable vim mode in the devtools, first to to your about:config page:

Change the devtools.editor.keymap setting to vim and you get all your familiar editing functionality.

List Tmux Keys

Want to see all the mapped shortcuts for your Tmux session? Try this, assuming a Tmux leader of <CRTL-Z>:

<CTRL-Z> ?

This produces a list like the following:

bind-key    -T prefix       :                 command-prompt
bind-key    -T prefix       ;                 last-pane
bind-key    -T prefix       =                 choose-buffer
bind-key    -T prefix       ?                 list-keys
bind-key    -T prefix       D                 choose-client

Cursor Pagination with graphql

When a graphql object has a plural type, each object of the collection from that plural type will have a cursor associated with it. This cursor is generally a base64 encoded unique identifier referencing the search, the object and the place of that object amongst all objects in the collection.

Ask for the cursor as a property when iterating over a collection.

  query {
    User(login: 'jbranchaud') {
      repositories(first: 100) {
        edges {
          node {
            cursor
            name
          }
        }
      }
    }
  }

The above query will return a cursor for each repo.

Get the last cursor of that collection with pageInfo.endCursor:

  query {
    User(login: 'jbranchaud') {
      repositories(first: 100) {
        pageInfo {
          endCursor
          hasNextPage
        }
        edges {
          node {
            name
          }
        }
      }
    }
  }

The endCursor will look like:

Y3Vyc29yOnYyOpHOBK0NoA==

Use this cursor to obtain the next 100 repos with the after property.

  query {
    User(login: 'jbranchaud') {
      repositories(first: 100, after: "Y3Vyc29yOnYyOpHOBK0NoA==") {
        pageInfo {
          endCursor
          hasNextPage
        }
        edges {
          node {
            name
          }
        }
      }
    }
  }