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