2 This is part of the VimFx documentation.
3 Copyright Simon Lydell 2015.
4 See the file README.md for copying conditions.
9 VimFx can be configured using a configuration file. This should be done by users
12 - prefer to configure things using text files.
13 - would like to add custom commands.
14 - would like to set [special options].
15 - would like to make site-specific customizations.
17 Look at the [Share your config file] wiki page for inspiration.
19 [special options]: options.md#special-options
20 [Share your config file]: https://github.com/akhodakivskiy/VimFx/wiki/Share-your-config-file
25 The config file is written in JavaScript and is actually a regular Firefox
26 add-on, that makes use of VimFx’s [public API].
33 1. Create a directory for your config file to live in. Actually, there will be
34 _three_ files that will live in it.
36 2. Create an [install.rdf] file in your directory. Inside that file there is an
37 extension ID; take note of it.
39 3. Create a [bootstrap.js] and a [vimfx.js] file in your directory.
41 4. Find the `extensions/` directory in your [profile directory].
43 5. In the extensions directory, do one of the following:
45 - Move your config file directory into it, renamed as the extension ID.
47 - Create a plain text file named as the extension ID with the absolute path
48 to your config file directory inside it. You might want to read the
49 documentation about such [proxy files].
51 - Create a symlink named as the extension ID pointing to your config file
56 7. Open the [browser console]. If you copied the [bootstrap.js] and [vimfx.js]
57 templates below, you should see a greeting and an inspection of VimFx’s
60 Any time you make changes to any of your add-on files you need to restart
61 Firefox to make the changes take effect.
63 Now you might want to read about the [public API] or look at the [Custom
66 [install.rdf]: #installrdf
67 [bootstrap.js]: #bootstrapjs
69 [profile directory]: https://support.mozilla.org/en-US/kb/profiles-where-firefox-stores-user-data
70 [proxy files]: https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment#Firefox_extension_proxy_file
71 [browser console]: https://developer.mozilla.org/en-US/docs/Tools/Browser_Console
72 [Custom Commands]: https://github.com/akhodakivskiy/VimFx/wiki/Custom-Commands
77 This file tells Firefox that this is an add-on and provides some information
78 about it. You’ll probably look at this once and not touch it again.
80 Here is a boilerplate that you can copy without changing anything (unless you
84 <?xml version="1.0" encoding="utf-8"?>
85 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
86 xmlns:em="http://www.mozilla.org/2004/em-rdf#">
87 <Description about="urn:mozilla:install-manifest">
89 <!-- Edit from here ... -->
90 <em:name>VimFx-custom</em:name>
91 <em:id>VimFx-custom@vimfx.org</em:id>
92 <em:version>1</em:version>
93 <!-- ... to here (if you feel like it). -->
95 <em:bootstrap>true</em:bootstrap>
96 <em:multiprocessCompatible>true</em:multiprocessCompatible>
98 <em:targetApplication>
100 <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
101 <em:minVersion>38</em:minVersion>
102 <em:maxVersion>*</em:maxVersion>
104 </em:targetApplication>
109 You might also want to read the [install.rdf documentation].
111 [install.rdf documentation]: https://developer.mozilla.org/en-US/Add-ons/Install_Manifests
116 This file starts up your add-on. Just like [install.rdf], you’ll probably look
117 at this once and not touch it again.
119 Here is a boilerplate that you can copy as is. All it does is loading VimFx’s
120 public API, as well as some very commonly used Firefox APIs, and passing those
124 let {classes: Cc, interfaces: Ci, utils: Cu} = Components
126 Cu.import('resource://gre/modules/Services.jsm')
127 Cu.import('resource://gre/modules/devtools/Console.jsm')
128 let apiPref = 'extensions.VimFx.api_url'
129 let apiUrl = Services.prefs.getComplexValue(apiPref, Ci.nsISupportsString).data
130 Cu.import(apiUrl, {}).getAPI(vimfx => {
131 let path = __SCRIPT_URI_SPEC__.replace('bootstrap.js', 'vimfx.js')
132 let scope = {Cc, Ci, Cu, vimfx}
133 Services.scriptloader.loadSubScript(path, scope, 'UTF-8')
136 function shutdown() {}
137 function install() {}
138 function uninstall() {}
144 This is the actual config file, written in JavaScript.
147 console.log('Hello, world! This is vimfx:', vimfx)
151 ## Custom commands that access web page content
153 If you plan to add custom commands that need to access web page content, you
154 have to add two more files and make an adjustment to bootstrap.js.
156 ### bootstrap.js adjustment
158 In bootstrap.js there is one function called `startup` and one called
159 `shutdown`. At the end of the `startup` function, add the following:
162 Cc['@mozilla.org/globalmessagemanager;1']
163 .getService(Ci.nsIMessageListenerManager)
164 .loadFrameScript('chrome://vimfx-custom/content/frame.js', true)
167 Inside the `shutdown` function, add the following:
170 Cc['@mozilla.org/globalmessagemanager;1']
171 .getService(Ci.nsIMessageListenerManager)
172 .removeDelayedFrameScript('chrome://vimfx-custom/content/frame.js')
175 That will load a so called “frame script,” named [frame.js] in our case, and
176 unload it when your add-on shuts down.
182 In order for Firefox to be able to find [frame.js], you need to add a file
183 called `chrome.manifest` with the following contents:
186 content vimfx-custom ./
193 Finally you of course need to add the file frame.js itself. Add any code that
194 needs access web page content inside this file.
198 Here’s a typical pattern used in custom commands that communicate with a frame
202 let {messageManager} = vim.window.gBrowser.selectedBrowser
203 let callback = ({data: {selection}}) => {
204 messageManager.removeMessageListener('VimFx-custom:selection', callback)
205 console.log('Currently selected text:', selection)
207 messageManager.addMessageListener('VimFx-custom:selection', callback)
208 messageManager.sendAsyncMessage('VimFx-custom:getSelection', {exampleValue: 1337})
211 And here’s some accompaning frame script code:
214 addMessageListener('VimFx-custom:getSelection', ({data: {exampleValue}}) => {
215 console.log('exampleValue should be 5:', exampleValue)
216 let selection = content.getSelection().toString()
217 sendAsyncMessage('VimFx-custom:selection', {selection})