]> git.gir.st - VimFx.git/blob - extension/packages/commands.coffee
Merge branch 'master' into develop
[VimFx.git] / extension / packages / commands.coffee
1 { classes: Cc, interfaces: Ci, utils: Cu } = Components
2
3 utils = require 'utils'
4 hints = require 'hints'
5 help = require 'help'
6 find = require 'find'
7
8 { getPref
9 , setPref
10 , getFirefoxPref } = require 'prefs'
11
12 # Opens developer toolbar (Default shotrcut: Shift-F2)
13 command_dev = (vim) ->
14 if chromeWindow = utils.getRootWindow vim.window
15 chromeWindow.DeveloperToolbar.show(true)
16
17 # Focus the Address Bar
18 command_o = (vim) ->
19 if chromeWindow = utils.getRootWindow vim.window
20 chromeWindow.focusAndSelectUrlBar()
21
22 # Navigate to the address that is currently stored in the system clipboard
23 command_p = (vim) ->
24 url = utils.readFromClipboard(vim.window)
25 postData = null
26 if not utils.isURL(url) and submission = utils.browserSearchSubmission url
27 url = submission.uri.spec
28 postData = submission.postData
29
30 if chromeWindow = utils.getRootWindow vim.window
31 chromeWindow.gBrowser.loadURIWithFlags url, null, null, null, postData
32
33 # Open new tab and navigate to the address that is currently stored in the system clipboard
34 command_P = (vim) ->
35 url = utils.readFromClipboard(vim.window)
36 postData = null
37 if not utils.isURL(url) and submission = utils.browserSearchSubmission url
38 url = submission.uri.spec
39 postData = submission.postData
40
41 if chromeWindow = utils.getRootWindow vim.window
42 chromeWindow.gBrowser.selectedTab = chromeWindow.gBrowser.addTab url, null, null, postData, null, false
43
44 # Open new tab and focus the address bar
45 command_t = (vim) ->
46 if chromeWindow = utils.getRootWindow vim.window
47 if gBrowser = chromeWindow.gBrowser
48 # Get the default url for the new tab
49 newtab_url = getFirefoxPref 'browser.newtab.url'
50 gBrowser.selectedTab = gBrowser.addTab newtab_url
51 # Focus the address bar
52 chromeWindow.focusAndSelectUrlBar()
53
54 # Copy current URL to the clipboard
55 command_yf = (vim) ->
56 markers = hints.injectHints vim.window.document
57 if markers?.length > 0
58 # This callback will be called with the selected marker as argument
59 cb = (marker) ->
60 if url = marker.element.href
61 utils.writeToClipboard vim.window, url
62
63 vim.enterHintsMode(markers, cb)
64
65 # Copy current URL to the clipboard
66 command_yy = (vim) ->
67 utils.writeToClipboard vim.window, vim.window.location.toString()
68
69 # Reload the page, possibly from cache
70 command_r = (vim) ->
71 vim.window.location.reload(false)
72
73 # Reload the page from the server
74 command_R = (vim) ->
75 vim.window.location.reload(true)
76
77 # Reload the page, possibly from cache
78 command_ar = (vim) ->
79 if rootWindow = utils.getRootWindow vim.window
80 if tabs = rootWindow.gBrowser.tabContainer
81 for i in [0...tabs.itemCount]
82 window = tabs.getItemAtIndex(i).linkedBrowser.contentWindow
83 window.location.reload(false)
84
85 # Reload the page from the server
86 command_aR = (vim) ->
87 if rootWindow = utils.getRootWindow vim.window
88 if tabs = rootWindow.gBrowser.tabContainer
89 for i in [0...tabs.itemCount]
90 window = tabs.getItemAtIndex(i).linkedBrowser.contentWindow
91 window.location.reload(true)
92
93 # Scroll to the top of the page
94 command_gg = (vim) ->
95 vim.window.scrollTo(0, 0)
96
97 # Scroll to the bottom of the page
98 command_G = (vim) ->
99 if document = vim.window.document
100 # Workaround the pages where body isn't the scrollable element.
101 # In this case we try to scroll 100k pixels
102 vim.window.scrollTo(0, Math.max(document.body.scrollHeight, 100000))
103
104 # Scroll down a bit
105 command_j_ce = (vim) ->
106 utils.smoothScroll vim.window, 0, (getPref 'scroll_step'), getPref 'scroll_time'
107
108 # Scroll up a bit
109 command_k_cy = (vim) ->
110 utils.smoothScroll vim.window, 0, -(getPref 'scroll_step'), getPref 'scroll_time'
111
112 # Scroll left a bit
113 command_h = (vim) ->
114 utils.smoothScroll vim.window, -(getPref 'scroll_step'), 0, getPref 'scroll_time'
115
116 # Scroll right a bit
117 command_l = (vim) ->
118 utils.smoothScroll vim.window, (getPref 'scroll_step'), 0, getPref 'scroll_time'
119
120 # Scroll down half a page
121 command_d = (vim) ->
122 utils.smoothScroll vim.window, 0, vim.window.innerHeight / 2, getPref 'scroll_time'
123
124 # Scroll up half a page
125 command_u = (vim) ->
126 utils.smoothScroll vim.window, 0, -vim.window.innerHeight / 2, getPref 'scroll_time'
127
128 # Scroll down full a page
129 command_cf = (vim) ->
130 step = (vim.window.innerHeight - (getPref 'scroll_step'))
131 utils.smoothScroll vim.window, 0, step, getPref 'scroll_time'
132
133 # Scroll up full a page
134 command_cb = (vim) ->
135 step = - (vim.window.innerHeight - (getPref 'scroll_step'))
136 utils.smoothScroll vim.window, 0, step, getPref 'scroll_time'
137
138 # Activate previous tab
139 command_J_gT = (vim) ->
140 if rootWindow = utils.getRootWindow vim.window
141 rootWindow.gBrowser.tabContainer.advanceSelectedTab(-1, true);
142
143 # Activate next tab
144 command_K_gt = (vim) ->
145 if rootWindow = utils.getRootWindow vim.window
146 rootWindow.gBrowser.tabContainer.advanceSelectedTab(1, true);
147
148 command_gh = (vim) ->
149 homepage_url = getFirefoxPref 'browser.startup.homepage'
150 vim.window.location.assign homepage_url
151
152 # Go to the first tab
153 command_gH_g0 = (vim) ->
154 if rootWindow = utils.getRootWindow vim.window
155 rootWindow.gBrowser.tabContainer.selectedIndex = 0;
156
157 # Go to the last tab
158 command_gL_g$ = (vim) ->
159 if rootWindow = utils.getRootWindow vim.window
160 itemCount = rootWindow.gBrowser.tabContainer.itemCount;
161 rootWindow.gBrowser.tabContainer.selectedIndex = itemCount - 1;
162
163 # Go back in history
164 command_H = (vim) ->
165 vim.window.history.back()
166
167 # Go forward in history
168 command_L = (vim) ->
169 vim.window.history.forward()
170
171 # Close current tab
172 command_x = (vim) ->
173 if rootWindow = utils.getRootWindow vim.window
174 unless rootWindow.gBrowser.selectedTab.pinned
175 rootWindow.gBrowser.removeCurrentTab()
176
177 # Restore last closed tab
178 command_X = (vim) ->
179 if rootWindow = utils.getRootWindow vim.window
180 ss = utils.getSessionStore()
181 if ss and ss.getClosedTabCount(rootWindow) > 0
182 ss.undoCloseTab rootWindow, 0
183
184 # Follow links with hint markers
185 command_f = (vim) ->
186 if document = vim.window.document
187 markers = hints.injectHints document
188 if markers?.length > 0
189 # This callback will be called with the selected marker as argument
190 cb = (marker) ->
191 marker.element.focus()
192 utils.simulateClick marker.element
193
194 vim.enterHintsMode markers, cb
195
196 # Follow links in a new Tab with hint markers
197 command_F = (vim) ->
198 markers = hints.injectHints vim.window.document
199 if markers?.length > 0
200 # This callback will be called with the selected marker as argument
201 cb = (marker) ->
202 marker.element.focus()
203 utils.simulateClick marker.element, { metaKey: true, ctrlKey: true }
204
205 vim.enterHintsMode markers, cb
206
207 # Move current tab to the left
208 command_cJ = (vim) ->
209 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
210 if tab = gBrowser.selectedTab
211 index = gBrowser.tabContainer.selectedIndex
212 total = gBrowser.tabContainer.itemCount
213
214 # `total` is added to deal with negative offset
215 gBrowser.moveTabTo tab, (total + index - 1) % total
216
217 # Move current tab to the right
218 command_cK = (vim) ->
219 if gBrowser = utils.getRootWindow(vim.window)?.gBrowser
220 if tab = gBrowser.selectedTab
221 index = gBrowser.tabContainer.selectedIndex
222 total = gBrowser.tabContainer.itemCount
223
224 gBrowser.moveTabTo tab, (index + 1) % total
225
226 # Display the Help Dialog
227 command_help = (vim) ->
228 help.injectHelp vim.window.document, commandsHelp
229
230 # Switch into find mode
231 command_find = (vim) ->
232 vim.enterFindMode()
233 vim.findStr = ""
234
235 find.injectFind vim.window.document
236
237 # Search for the last pattern
238 command_n = (vim) ->
239 if vim.findStr.length > 0
240 if not find.find vim.window, vim.findStr, false
241 find.flashFind vim.window.document, "#{ vim.findStr } (Not Found)"
242
243 # Search for the last pattern backwards
244 command_N = (vim) ->
245 if vim.findStr.length > 0
246 if not find.find vim.window, vim.findStr, true
247 find.flashFind vim.window.document, "#{ vim.findStr } (Not Found)"
248
249 # Close the Help dialog and cancel the pending hint marker action
250 command_Esc = (vim) ->
251 # Blur active element if it's editable. Other elements
252 # aren't blurred - we don't want to interfere with
253 # the browser too much
254 activeElement = vim.window.document.activeElement
255 if utils.isElementEditable activeElement
256 activeElement.blur()
257
258 #Remove Find input
259 find.removeFind vim.window.document
260
261 # Remove hints
262 hints.removeHints vim.window.document
263
264 # Hide help dialog
265 help.removeHelp vim.window.document
266
267 # Finally enter normal mode
268 vim.enterNormalMode()
269
270 if not getPref('leave_dt_on_esc')
271 if chromeWindow = utils.getRootWindow vim.window
272 chromeWindow.DeveloperToolbar.hide()
273
274 commandGroups =
275 'urls':
276 'o': [ command_o, _('help_command_o') ]
277 'p': [ command_p, _('help_command_p') ]
278 'P': [ command_P, _('help_command_P') ]
279 'y,f': [ command_yf, _('help_command_yf') ]
280 'y,y': [ command_yy, _('help_command_yy') ]
281 'r': [ command_r, _('help_command_r') ]
282 'R': [ command_R, _('help_command_R') ]
283 'a,r': [ command_ar, _('help_command_ar') ]
284 'a,R': [ command_aR, _('help_command_aR') ]
285 'nav':
286 'g,g': [ command_gg , _('help_command_gg') ]
287 'G': [ command_G, _('help_command_G') ]
288 'j|c-e': [ command_j_ce, _('help_command_j_ce') ]
289 'k|c-y': [ command_k_cy, _('help_command_k_cy') ]
290 'h': [ command_h, _('help_command_h') ]
291 'l': [ command_l , _('help_command_l') ]
292 # Can't use c-u/c-d because c-u is widely used for viewing sources
293 'd': [ command_d, _('help_command_d') ]
294 'u': [ command_u, _('help_command_u') ]
295 'c-f': [ command_cf, _('help_command_cf') ]
296 'c-b': [ command_cb, _('help_command_cb') ]
297 'tabs':
298 't': [ command_t, _('help_command_t') ]
299 'J|g,T': [ command_J_gT, _('help_command_J_gT') ]
300 'K|g,t': [ command_K_gt, _('help_command_K_gt') ]
301 'c-J': [ command_cJ, _('help_command_cJ') ]
302 'c-K': [ command_cK, _('help_command_cK') ]
303 'g,h': [ command_gh, _('help_command_gh') ]
304 "g,H|g,\^": [ command_gH_g0, _('help_command_gH_g0') ]
305 'g,L|g,$': [ command_gL_g$, _('help_command_gL_g$') ]
306 'x': [ command_x, _('help_command_x') ]
307 'X': [ command_X, _('help_command_X') ]
308 'browse':
309 'f': [ command_f, _('help_command_f') ]
310 'F': [ command_F, _('help_command_F') ]
311 'H': [ command_H, _('help_command_H') ]
312 'L': [ command_L, _('help_command_L') ]
313 'misc':
314 # `.` is added to find command mapping to hack around Russian keyboard layout
315 '\.|/': [ command_find, _('help_command_find') ]
316 'n': [ command_n, _('help_command_n') ]
317 'N': [ command_N, _('help_command_N') ]
318 # `>` is added to help command mapping to hack around Russian keyboard layout
319 # See key-utils.coffee for more info
320 '?|>': [ command_help, _('help_command_help') ]
321 'Esc': [ command_Esc, _('help_command_Esc') ]
322 ':': [ command_dev, _('help_command_dev') ]
323
324 # Merge groups and split command pipes into individual commands
325 commands = do (commandGroups) ->
326 newCommands = {}
327 for group, commandsList of commandGroups
328 for keys, command of commandsList
329 for key in keys.split '|'
330 newCommands[key] = command[0]
331
332 return newCommands
333
334 # Extract the help text from the commands preserving groups formation
335 commandsHelp = do (commandGroups) ->
336 helpStrings = {}
337 for group, commandsList of commandGroups
338 helpGroup = {}
339 for keys, command of commandsList
340 helpGroup[keys] = command[1]
341
342 helpStrings[group] = helpGroup
343 return helpStrings
344
345 # Called in hints mode. Will process the char, update and hide/show markers
346 hintCharHandler = (vim, keyStr, charCode) ->
347 if keyStr and charCode > 0
348 # Get char and escape it to avoid problems with String.search
349 key = regexpEscape keyStr
350
351 # First do a pre match - count how many markers will match with the new character entered
352 if vim.markers.reduce ((v, marker) -> v or marker.willMatch key), false
353 for marker in vim.markers
354 marker.matchHintChar key
355
356 if marker.isMatched()
357 vim.cb marker
358 hints.removeHints vim.window.document
359 vim.enterNormalMode()
360 break
361
362 # Called in find mode. Will process charCode, update find, or close the
363 findCharHandler = (vim, keyStr, charCode) ->
364 backwards = false
365
366 toNormalMode = ->
367 find.removeFind vim.window.document
368 vim.enterNormalMode()
369
370 if keyStr and keyStr.match(/.*Return/)
371 return toNormalMode()
372 else if keyStr == 'Backspace'
373 # Delete last available character from the query string
374 if vim.findStr.length > 0
375 vim.findStr = vim.findStr.substr(0, vim.findStr.length - 1)
376 # Leave Find Mode the query string is already empty
377 else
378 return toNormalMode()
379 else if charCode > 0
380 vim.findStr += String.fromCharCode(charCode)
381 else
382 return
383
384 # Update the interface string
385
386 # Clear selection to avoid jumping between matching search results
387 vim.window.getSelection().removeAllRanges()
388
389 # Search only if the query string isn't emply.
390 # Otherwise it will pop up Find dialog
391 if find.find vim.window, vim.findStr, backwards
392 find.setFindStr vim.window.document, vim.findStr
393 else
394 find.setFindStr vim.window.document, "#{ vim.findStr } (Not Found)"
395
396
397 exports.hintCharHandler = hintCharHandler
398 exports.findCharHandler = findCharHandler
399 exports.commands = commands
400 exports.commandsHelp = commandsHelp
Imprint / Impressum