-
Notifications
You must be signed in to change notification settings - Fork 175
Custom Commands
Please share useful custom commands here!
See documentation/config-file.md for how to use this.
Tip: Here’s a way to find how many built-in Firefox commands are implemented:
-
Go to about:config and make sure that
devtools.chrome.enabled
is set totrue
. -
Open the browser console.
-
Run the following code:
Array.map(document.querySelectorAll('command'), command => `${command.id}: ${command.getAttribute('oncommand')}`).join('\n')
That prints a list of command names and the code they use.
let {commands} = vimfx.modes.normal
vimfx.addCommand({
name: 'tab_new_and_focus_search_bar',
description: 'Open new tab and focus Search Bar',
category: 'tabs',
order: commands.tab_new.order + 1,
}, args => {
commands.tab_new.run(args)
commands.focus_search_bar.run(args)
})
vimfx.addCommand({
name: 'zoom_in',
description: 'Zoom in',
}, ({vim}) => {
vim.window.FullZoom.enlarge()
})
You can also replace enlarge
with reduce
to zoom out, and with reset
to reset to 100%.
vimfx.addCommand({
name: 'bookmark_page',
description: 'Bookmark page',
}, ({vim}) => {
let {window} = vim
window.PlacesCommandHook.bookmarkCurrentPage(true, window.PlacesUtils.bookmarksMenuFolderId)
})
The above is equivalent to the Firefox default shortcut <c-d>
.
let {commands} = vimfx.modes.normal
vimfx.addCommand({
name: 'search_bookmarks',
description: 'Search bookmarks',
category: 'location',
order: commands.focus_location_bar.order + 1,
}, (args) => {
commands.focus_location_bar.run(args)
args.vim.window.gURLBar.value = '* '
})
You may also want to read more about handy location bar features.
vimfx.addCommand({
name: 'goto_downloads',
description: 'Downloads',
}, ({vim}) => {
vim.window.gBrowser.loadURI('about:downloads')
})
Replace loadURI
with loadOneTab
to open in a new tab instead.
Here are some URLs you might find interesting (they should be self-explanatory):
about:downloads
about:preferences
about:addons
Like about:
pages? Go to about:about
to list them all!
vimfx.addCommand({
name: 'search_selected_text',
description: 'Search for the selected text'
}, ({vim}) => {
let {messageManager} = vim.window.gBrowser.selectedBrowser
let callback = ({data: {selection}}) => {
vimfx.send(vim, 'getSelection', null, selection => {
let inTab = true // Change to `false` if you’d like to search in current tab.
vim.window.BrowserSearch.loadSearch(selection, inTab)
})
})
frame.js:
vimfx.listen('getSelection', (data, callback) => {
let selection = content.getSelection().toString()
callback(selection)
})
vimfx.addCommand({
name: 'web_console',
description: 'Web console',
}, ({vim}) => {
vim.window.gDevToolsBrowser.selectToolCommand(vim.window.gBrowser, 'webconsole')
})
The above is equivalent to the Firefox default shortcut <c-K>
. Alternatively, you can use the following to toggle the developer tools instead:
vim.window.gDevToolsBrowser.toggleToolboxCommand(vim.window.gBrowser)
This command moves the current tab before tab number count.
vimfx.addCommand({
name: 'tab_move_to_index',
description: 'Move tab to index',
category: 'tabs',
order: commands.tab_move_forward.order + 1,
}, ({vim, count}) => {
if (count === undefined) {
vim.notify('Provide a count')
return
}
let {window} = vim
window.setTimeout(() => {
let {selectedTab} = window.gBrowser
if (selectedTab.pinned) {
vim.notify('Run from a non-pinned tab')
return
}
let newPosition = window.gBrowser._numPinnedTabs + count - 1
window.gBrowser.moveTabTo(selectedTab, newPosition)
}, 0)
})
Tip: Add the following to custom styling to make it easier to work out which number to type. It turns the tab close buttons into numbers until you hover the tab:
#TabsToolbar {
counter-reset: tabs-counter;
}
.tab-close-button:not([pinned]) {
visibility: hidden;
display: block;
color: inherit;
counter-increment: tabs-counter;
&::before {
content: counter(tabs-counter);
visibility: visible;
font-weight: normal;
font-style: normal;
}
}
let {commands} = vimfx.modes.normal
vimfx.addCommand({
name: 'tab_close_to_start',
description: 'Close tabs to the left',
category: 'tabs',
order: commands.tab_close_to_end.order + 1,
}, ({vim}) => {
let {gBrowser} = vim.window
Array.slice(gBrowser.tabs, gBrowser._numPinnedTabs, gBrowser.selectedTab._tPos)
.forEach(tab => gBrowser.removeTab(tab))
})
Click the NoScript button
vimfx.addCommand({
name: 'noscript_click_toolbar_button',
description: 'NoScript',
}, ({vim}) => {
vim.window.document.getElementById('noscript-tbb').click()
})
const {classes: Cc, interfaces: Ci} = Components
const mpv_path = '/usr/bin/mpv'
const mpv_options = '--video-unscaled=yes --ytdl-raw-options=format=best'
vimfx.addCommand({
name: 'play_with_mpv',
description: 'Play the focused link with MPV'
}, ({vim}) => {
vimfx.send(vim, 'getCurrentHref', null, url => {
let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile)
file.initWithPath(mpv_path)
let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess)
process.init(file)
let args = mpv_options.split(' ')
if (url.includes('youtube.com')) {
// Parse url params to an object like:
// {"v":"g04s2u30NfQ","index":"3","list":"PL58H4uS5fMRzmMC_SfMelnCoHgB8COa5r"}
let qs = (function(a) {
if (a == '') return {}
let b = {}
for (let i = 0; i < a.length; ++i) {
let p = a[i].split('=', 2)
if (p.length == 1) {
b[p[0]] = ''
} else {
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' '))
}
}
return b
})(url.substr(1).split('&'))
if (qs['list'] && qs['index']) {
// Example args: ['--video-unscaled=yes', '--ytdl-raw-options=format=best']
// So check for ytdl-raw-options.
let ytdlRawOptionsIndex = -1
for (let i = 0; i < args.length; i++) {
if (args[i].includes('ytdl-raw-options')) {
ytdlRawOptionsIndex = i
break
}
}
if (ytdlRawOptionsIndex > -1) {
args[ytdlRawOptionsIndex] += `,yes-playlist=,playlist-start=${qs['index']}`
} else {
args.push(`--ytdl-raw-options=yes-playlist=,playlist-start=${qs['index']}`)
}
}
}
args.push(url)
// process.run(false, args, args.length)
process.runAsync(args, args.length)
})
})
frame.js:
vimfx.listen('getCurrentHref', (data, callback) => {
let {href} = content.document.activeElement
callback(href)
})
Sorry for hairy code :)