Configuration (v3) - johnste/finicky GitHub Wiki
Table of Contents
- General options
- Matching urls
- Selecting a browser
- Rewriting urls
- Parameters
- Example configuration
- Finicky API Specification
General options
module.exports = {
defaultBrowser: "Google Chrome",
options: {
// Hide the finicky icon from the top bar. Default: false
hideIcon: false,
// Check for update on startup. Default: true
checkForUpdate: true,
// Change the internal list of url shortener services. Default: undefined
urlShorteners: (list) => [...list, "custom.urlshortener.com"],
// Log every request with basic information to console. Default: false
logRequests: false
},
};
The default list of short url providers can be found here. Finicky uses this list to resolve urls to the intended destination before running them through the rule system.
Matching urls
module.exports = {
defaultBrowser: "Google Chrome",
rewrite: [
{
match: "example.org/*",
url: "http://example.com",
},
],
handlers: [
{
match: "apple.com/*",
browser: "Safari",
},
],
};
Examples
A handler or url rewrite always needs a matcher to match the incoming url. There are a couple of different ways to match a url:
// Only matches that exact url
match: "http://example.com/path?query"
// Matches anything the Regular Expression matches
match: /^https?:\/\/example\.com/.*$/
// A function that accepts some arguments.
match: ({ url }) => url.host === "example.com"
// Or, an array with any combination of the above
match: ["https://example.com", /^http:\/\/example.(org|com)\/.*/]
The full parameter description for functions is available here
Selecting a browser
module.exports = {
defaultBrowser: "Safari",
handlers: [
{
match: ({ url }) => url.host.endsWith("example.org"),
browser: "Firefox",
},
],
};
1. Browser (or app) as a string:
// Name
browser: "Google Chrome"
// Bundle identifier (useful when the app name isn't unique)
browser: "com.google.Chrome"
// Path to application. Useful when both name and bundle id aren't unique
browser: "/Applications/Firefox.app"
Finicky will try detect automatically if what was entered was a name, a bundle id or a path name. If you don't know what bundle id to use, see this wiki entry
2. You can define more options with a browser object.
If you want to force the string type you can supply it in a browser object:
browser: {
name: "Google Chrome",
appType: "appName" // Force name type. "appName", "bundleId" or "appPath",
openInBackground: true // or false, force opening the browser in the background
}
From Finicky 3.2, you can specify a profile to activate when using Chrome, Brave, Edge or Vivaldi as your browser.
{
match: "example.com/*",
browser: {
name: "Google Chrome",
profile: "Default",
}
},
{
match: "example.org/*",
browser: {
name: "Google Chrome",
profile: "Profile 1",
}
}
The profile name you supply to Finicky must match the folder name of the profile. For Chrome, the folders are located at ~/Library/Application Support/Google/Chrome. Folder names are called "Profile 1", "Profile 2", etc.
You can list the profiles with there names via following shell snippet:
for profile in ~/Library/Application\ Support/Google/Chrome/Profile*; do
echo "$profile: $(jq .profile.name "$profile/Preferences")"
done
⚠️ Please note ⚠️ If you supply a folder name of a profile that does not exist, e.g. "Avocado", Chrome and Brave will create a new profile using that folder name. This appears to work pretty well, but I would advise against this since there is a risk corrupt your Chrome configuration. In the future, I want to add some verification to avoid this possibility, so it might stop working.
3. A browser function that returns either a browser string or object
browser: ({ url }) => url.host === "example.com" ? "Google Chrome" : "Firefox"
browser: ({ urlString }) => {
name: "Google Chrome",
openInBackground: urlString.includes("facebook")
}
Rewriting urls
If you want to change the incoming url in any way, you can do that in a couple of different ways.
module.exports = {
defaultBrowser: "Safari",
rewrite: [
{
match: ({ url }) => url.host.endsWith("example.org"),
url: "https://gitlab.com",
},
],
};
The url property can either be:
// A string for the a completely new url
url: "http://example.com?something=else"
// A URL Object
url: {
"host": "example.com",
"protocol": "https"
}
// A function that returns either a url string or a url object
url: ({ url }) => {
return {
...url,
protocol: "https"
}
}
Parameters
Matcher, browser and url function callback all accept the same options object as the only argument. Below is the full object including a description of the parts.
// Options object:
// Available as the first parameter when using match, browser or url functions.
{
"urlString": "http://username:[email protected]:3000/pathname/?search=test#hash", // The full URL string
"url": { // The URL parsed into parts
"username": "username",
"host": "example.com",
"protocol": "http",
"pathname": "/pathname/",
"search": "search=test",
"password": "password",
"port": 3000,
"hash": "hash"
},
"opener": {
"pid": 1337,
"path": "/Users/user/Applications/Example.app",
"bundleId": "com.example.app",
"name": "Example app"
},
"keys": { // DEPRECATED, replaced by finicky.getKeys – Status of modifier keys on keyboard.
"control": false,
"function": false,
"shift": false,
"option": false,
"command": false,
"capsLock": false
},
"sourceBundleIdentifier": "net.kassett.finicky", // DEPRECATED, use opener.bundleId instead
"sourceProcessPath": "/Applications/Finicky.app" // DEPRECATED, use opener.path instead
}
Example configuration
module.exports = {
defaultBrowser: "Google Chrome",
options: {
// Hide the finicky icon from the top bar
hideIcon: true
},
handlers: [
{
// Open any link clicked in Slack in Safari
match: ({ opener }) =>
opener.bundleId === "com.tinyspeck.slackmacgap",
browser: "Safari"
},
{
// You can get the path of the process that triggered Finicky (EXPERIMENTAL)
match: ({ opener }) =>
opener.path && opener.path.startsWith("/Applications/Slack.app"),
browser: "Firefox"
},
{
match: ["http://zombo.com"],
browser: {
name: "Google Chrome Canary",
// Force opening the link in the background
openInBackground: true
}
},
{
match: finicky.matchHostnames(["example.com"]),
// Opens the first running browsers in the list. If none are running, the first one will be started.
browser: ["Google Chrome", "Safari", "Firefox"]
},
{
match: ["http://example.com"],
// Don't open any browser for this url, effectively blocking it
browser: null
},
{
// Open links in Safari when the option key is pressed
// Valid keys are: shift, option, command, control, capsLock, and function.
// Please note that control usually opens a tooltip menu instead of visiting a link
match: () => finicky.getKeys().option,
browser: "Safari"
}
]
};
API specification
finicky.log(message: string)
Logs a string to the finicky console
module.exports = {
defaultBrowser: "Google Chrome",
handlers: [{
match: ({ url, urlString }) => {
finicky.log("Received URL " + urlString);
return url.host === "apple.com";
}
browser: "Safari"
}]
}
finicky.notify(title: string, subtitle: string)
Display a notification
module.exports = {
defaultBrowser: "Google Chrome",
handlers: [{
match: ({ url, urlString }) => {
finicky.notify("Received URL", urlString);
return url.host === "apple.com";
}
browser: "Safari"
}]
}
finicky.getBattery() => { isCharging: bool, isPluggedIn: bool, chargePercentage: number }
Get the battery status.
module.exports = {
// Use Safari as default when battery is low
defaultBrowser: () => finicky.getBattery().chargePercentage < 50 ? "Safari" : "Google Chrome",
}
finicky.getKeys() => { key: bool }
Get the pressed status of keyboard modifier keys. Available keys are "control", "function", "shift", "option", "command", "capsLock"
if (finicky.getKeys().command) {
finicky.log("Command is pressed")
}
finicky.getSystemInfo() => { localizedName: string, name: string }
Get system information
finicky.getSystemInfo() // returns {"localizedName":"John’s Mac mini","name":"Johns-Mac-mini.local"}
finicky.matchHostnames(matchers: string | RegExp | (string | RegExp)[]) => bool
Utility function to make it easier to match on the domain/hostnames part
module.exports = {
defaultBrowser: "Google Chrome",
handlers: [{
match: finicky.matchHostnames(["apple.com", /example\.(com|org|net)/]),
browser: "Safari"
}]
}