Skip to content

Instantly share code, notes, and snippets.

@paulera
Last active March 4, 2026 14:30
Show Gist options
  • Select an option

  • Save paulera/72da90b173da8a400824dd8205e95e85 to your computer and use it in GitHub Desktop.

Select an option

Save paulera/72da90b173da8a400824dd8205e95e85 to your computer and use it in GitHub Desktop.
Tampermonkey script that shows Gmail keyboard shortcuts for easier navigation
// ==UserScript==
// @name Gmail Shortcut Hints
// @namespace gmail-shortcut-hints
// @version 2.0.1
// @author Paulo Amaral
// @description Shows Gmail keyboard shortcuts for easier navigation. Coded with ChatGPT assistance.
// @match https://mail.google.com/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const SHORTCUTS = {
"Archive": "e",
"Delete": "#",
"Reply": "r",
"Reply all": "a",
"Forward": "f",
"Mark as read": "Shift+i",
"Mark as unread": "Shift+u",
"Report spam": "!",
"Snooze": "b",
"Move to": "v",
"Older": "j",
"Newer": "k",
"Back to Inbox": "gi",
"Add to Tasks": "Shift+t",
"Back to Inbox": "gi",
"Add to Tasks": "Shift+t",
"More email options": "."
};
const FLAG = "data-shortcut-injected";
function normalizeLabel(label) {
return label.replace(/\.$/, '').trim();
}
function injectShortcut_old(button, shortcut) {
if (button.hasAttribute(FLAG)) return;
// Force vertical stacking without breaking layout
button.style.display = "flex";
button.style.flexDirection = "column";
button.style.alignItems = "center";
button.style.justifyContent = "center";
const hint = document.createElement("div");
hint.textContent = shortcut;
hint.style.fontSize = "12px";
hint.style.color = "#8a8a8a";
hint.style.marginTop = "2px";
hint.style.lineHeight = "1";
hint.style.pointerEvents = "none";
hint.style.userSelect = "none";
button.appendChild(hint);
button.setAttribute(FLAG, "true");
}
function injectShortcut(button, shortcut) {
if (button.hasAttribute(FLAG)) return;
// Preserve existing layout but stack visually
button.style.display = "inline-flex";
button.style.flexDirection = "column";
button.style.alignItems = "center";
button.style.justifyContent = "center";
const hint = document.createElement("div");
hint.textContent = shortcut;
hint.style.fontSize = "12px";
hint.style.color = "#909090";
hint.style.marginTop = "1px";
hint.style.lineHeight = "1";
hint.style.pointerEvents = "none";
hint.style.userSelect = "none";
hint.style.fontWeight = "500";
hint.style.letterSpacing = "0.2px";
button.appendChild(hint);
button.setAttribute(FLAG, "true");
}
function scan() {
const buttons = document.querySelectorAll('div[role="button"][aria-label]');
buttons.forEach(button => {
const label = normalizeLabel(button.getAttribute("aria-label"));
if (SHORTCUTS[label]) {
injectShortcut(button, SHORTCUTS[label]);
}
});
}
function observe() {
const observer = new MutationObserver(() => {
scan();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
function init() {
scan();
observe();
}
window.addEventListener("load", () => {
setTimeout(init, 1200);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment