Skip to content

Instantly share code, notes, and snippets.

@louwers
Created May 8, 2022 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louwers/04a48bcde0bc3fa0910934a0d356c829 to your computer and use it in GitHub Desktop.
Save louwers/04a48bcde0bc3fa0910934a0d356c829 to your computer and use it in GitHub Desktop.
#!/usr/bin/node
var path = require('path');
const { exit } = require("process");
const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);
var filename = path.basename(__filename);
// As can be seen when you run
// gsettings list-keys org.gnome.shell.keybindings
// you can only map switch-to-application-1 until switch-to-application-9
const MAX_FAVORITE_APPS_KEYBINDS = 9;
function usage() {
console.error("This script can be used to set GNOME keybinds for your favorite apps.\n");
console.error("usage:")
console.error(` ${filename} [--1 APP_NAME] [--2 APP_NAME] [--3 APP_NAME] ...\n`);
console.error("example:")
console.error(` ${filename} --6 firefox.desktop`);
console.error(`This will bind Super+1 to Firefox if it is one of the first ${MAX_FAVORITE_APPS_KEYBINDS} favorite apps.`)
exit(1);
}
function error(errorMessage) {
console.error(errorMessage);
exit(1);
}
function parseArgs() {
let readingNumber = true;
let num = 0;
const parsedArgs = {};
if (process.argv.length <= 2) usage();
for (let arg of process.argv.slice(2)) {
if (readingNumber) {
if (!arg.startsWith("--")) usage();
num = parseInt(arg.slice(2));
if (typeof num !== 'number') usage();
if (num <= 0 || num > MAX_FAVORITE_APPS_KEYBINDS) error(`Only --1 until --${MAX_FAVORITE_APPS_KEYBINDS} are supported.`);
} else {
parsedArgs[num] = arg;
}
readingNumber = !readingNumber;
}
if (!readingNumber) usage();
return parsedArgs;
}
async function readFavoriteApps() {
const { stdout, stderr } = await exec("gsettings get org.gnome.shell favorite-apps");
if (stderr) {
error("Failed to read favorite apps with gsettings. Make sure it is installed.");
}
try {
const gsJson = stdout.replace(/'/g, '"');
const jsonArr = JSON.parse(gsJson);
if (!Array.isArray(jsonArr))
throw new Error("Parsed result from gsettings is not an array.");
return jsonArr.slice(0, MAX_FAVORITE_APPS_KEYBINDS);
} catch(e) {
error(`Faild to parse output from gsettings: ${e}.`);
}
}
function checkParsedArgs(parsedArgs, favoriteApps) {
const favoriteAppsSet = new Set(favoriteApps);
for (const num in parsedArgs) {
if (!favoriteAppsSet.has(parsedArgs[num]))
error(`Trying to set keybind with number ${num} to '${parsedArgs[num]}', ` +
`but this is not a favorite app in range 1-10. Available apps are:\n${favoriteApps.join('\n')}`);
}
}
async function setKeybindFavoriteApp(appName, keybindNum, favoriteApps) {
const appIdx = favoriteApps.findIndex(favApp => appName === favApp);
if (appIdx === -1) error(`'${appName}' is not a favorite app`);
const { stderr } = await exec(`gsettings set org.gnome.shell.keybindings switch-to-application-${appIdx + 1} "['<Super>${keybindNum}']"`);
if (stderr) {
error(`Something went wrong while setting favorite app keybind for '${appName}': ${stderr}`);
}
}
(async function() {
const favoriteApps = await readFavoriteApps();
const parsedArgs = parseArgs();
checkParsedArgs(parsedArgs, favoriteApps);
for (let num in parsedArgs) {
await setKeybindFavoriteApp(parsedArgs[num], num, favoriteApps);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment