aboutsummaryrefslogtreecommitdiffstats
path: root/content_scripts/marks.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'content_scripts/marks.coffee')
-rw-r--r--content_scripts/marks.coffee124
1 files changed, 79 insertions, 45 deletions
diff --git a/content_scripts/marks.coffee b/content_scripts/marks.coffee
index 316ab951..067d05a8 100644
--- a/content_scripts/marks.coffee
+++ b/content_scripts/marks.coffee
@@ -1,45 +1,79 @@
-root = window.Marks = {}
-
-root.activateCreateMode = ->
- handlerStack.push keydown: (e) ->
- keyChar = KeyboardUtils.getKeyChar(event)
- return unless keyChar isnt ""
-
- if /[A-Z]/.test keyChar
- chrome.runtime.sendMessage {
- handler: 'createMark',
- markName: keyChar
- scrollX: window.scrollX,
- scrollY: window.scrollY
- }, -> HUD.showForDuration "Created global mark '#{keyChar}'", 1000
- else if /[a-z]/.test keyChar
- [baseLocation, sep, hash] = window.location.href.split '#'
- localStorage["vimiumMark|#{baseLocation}|#{keyChar}"] = JSON.stringify
- scrollX: window.scrollX,
- scrollY: window.scrollY
- HUD.showForDuration "Created local mark '#{keyChar}'", 1000
-
- @remove()
-
- false
-
-root.activateGotoMode = ->
- handlerStack.push keydown: (e) ->
- keyChar = KeyboardUtils.getKeyChar(event)
- return unless keyChar isnt ""
-
- if /[A-Z]/.test keyChar
- chrome.runtime.sendMessage
- handler: 'gotoMark'
- markName: keyChar
- else if /[a-z]/.test keyChar
- [baseLocation, sep, hash] = window.location.href.split '#'
- markString = localStorage["vimiumMark|#{baseLocation}|#{keyChar}"]
- if markString?
- mark = JSON.parse markString
- window.scrollTo mark.scrollX, mark.scrollY
- HUD.showForDuration "Jumped to local mark '#{keyChar}'", 1000
-
- @remove()
-
- false
+
+Marks =
+ previousPositionRegisters: [ "`", "'" ]
+ localRegisters: {}
+ mode: null
+
+ exit: (continuation = null) ->
+ @mode?.exit()
+ @mode = null
+ continuation?()
+
+ # This returns the key which is used for storing mark locations in localStorage.
+ getLocationKey: (keyChar) ->
+ "vimiumMark|#{window.location.href.split('#')[0]}|#{keyChar}"
+
+ getMarkString: ->
+ JSON.stringify scrollX: window.scrollX, scrollY: window.scrollY
+
+ setPreviousPosition: ->
+ markString = @getMarkString()
+ @localRegisters[reg] = markString for reg in @previousPositionRegisters
+
+ showMessage: (message, keyChar) ->
+ HUD.showForDuration "#{message} \"#{keyChar}\".", 1000
+
+ # If <Shift> is depressed, then it's a global mark, otherwise it's a local mark. This is consistent
+ # vim's [A-Z] for global marks and [a-z] for local marks. However, it also admits other non-Latin
+ # characters. The exceptions are "`" and "'", which are always considered local marks.
+ isGlobalMark: (event, keyChar) ->
+ event.shiftKey and keyChar not in @previousPositionRegisters
+
+ activateCreateMode: ->
+ @mode = new Mode
+ name: "create-mark"
+ indicator: "Create mark..."
+ exitOnEscape: true
+ suppressAllKeyboardEvents: true
+ keypress: (event) =>
+ keyChar = String.fromCharCode event.charCode
+ @exit =>
+ if @isGlobalMark event, keyChar
+ # We record the current scroll position, but only if this is the top frame within the tab.
+ # Otherwise, we'll fetch the scroll position of the top frame from the background page later.
+ [ scrollX, scrollY ] = [ window.scrollX, window.scrollY ] if DomUtils.isTopFrame()
+ chrome.runtime.sendMessage
+ handler: 'createMark'
+ markName: keyChar
+ scrollX: scrollX
+ scrollY: scrollY
+ , => @showMessage "Created global mark", keyChar
+ else
+ localStorage[@getLocationKey keyChar] = @getMarkString()
+ @showMessage "Created local mark", keyChar
+
+ activateGotoMode: (registryEntry) ->
+ @mode = new Mode
+ name: "goto-mark"
+ indicator: "Go to mark..."
+ exitOnEscape: true
+ suppressAllKeyboardEvents: true
+ keypress: (event) =>
+ @exit =>
+ keyChar = String.fromCharCode event.charCode
+ if @isGlobalMark event, keyChar
+ chrome.runtime.sendMessage
+ handler: 'gotoMark'
+ markName: keyChar
+ else
+ markString = @localRegisters[keyChar] ? localStorage[@getLocationKey keyChar]
+ if markString?
+ @setPreviousPosition()
+ position = JSON.parse markString
+ window.scrollTo position.scrollX, position.scrollY
+ @showMessage "Jumped to local mark", keyChar
+ else
+ @showMessage "Local mark not set", keyChar
+
+root = exports ? window
+root.Marks = Marks