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