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