]> git.gir.st - VimFx.git/blob - extension/lib/hints-mode.coffee
Change license to MIT
[VimFx.git] / extension / lib / hints-mode.coffee
1 # This file contains a few helper functions for Hints mode, that didn’t really
2 # fit in modes.coffee.
3
4 activateMatch = (vim, storage, match, matchedMarkers, callback) ->
5 {markerContainer} = storage
6
7 marker.markMatched(true) for marker in matchedMarkers
8
9 [largestMatchedMarker] = matchedMarkers
10 .sort((a, b) -> b.wrapper.shape.area - a.wrapper.shape.area)
11
12 # Prevent `onLeave` cleanup if the callback enters another mode.
13 storage.skipOnLeaveCleanup = true
14 again = callback(largestMatchedMarker, storage.count, match.keyStr)
15 storage.skipOnLeaveCleanup = false
16
17 switchedMode = (vim.mode != 'hints')
18
19 if again and not switchedMode
20 storage.count -= 1
21 vim.window.setTimeout((->
22 marker.markMatched(false) for marker in matchedMarkers
23 updateVisualFeedback(vim, markerContainer, [])
24 return
25 ), vim.options['hints.matched_timeout'])
26 markerContainer.reset()
27
28 else
29 vim.window.setTimeout((->
30 # Don’t clean up if Hints mode has been re-entered before the
31 # timeout has passed.
32 unless vim.mode == 'hints'
33 # Don’t blur frames (in `utils.clearSelectionDeep`) in case the callback
34 # has focused something in a frame.
35 cleanup(vim, storage, {blur: false})
36 ), vim.options['hints.matched_timeout'])
37
38 unless switchedMode
39 storage.skipOnLeaveCleanup = true
40 vim._enterMode('normal')
41 storage.skipOnLeaveCleanup = false
42
43 cleanup = (vim, storage, options = {}) ->
44 {markerContainer, matchText} = storage
45 markerContainer?.remove()
46 vim._run('clear_selection', options) if matchText and vim.mode != 'caret'
47 if vim.options.notify_entered_keys and
48 markerContainer.enteredText == vim._state.lastNotification
49 vim.hideNotification()
50 storage.clearInterval?()
51 for key of storage
52 storage[key] = null
53 return
54
55 getChar = (match, {markerContainer, matchText}) ->
56 {unmodifiedKey} = match
57
58 isHintChar = switch
59 when not matchText
60 true
61 when unmodifiedKey.length == 1
62 markerContainer.isHintChar(unmodifiedKey)
63 else
64 false
65
66 char = if isHintChar then unmodifiedKey else match.rawKey
67 if char.length == 1
68 return {char, isHintChar}
69 else
70 return {char: null, isHintChar: false}
71
72 updateVisualFeedback = (vim, markerContainer, visibleMarkers) ->
73 hasEnteredText = (markerContainer.enteredText != '')
74
75 if vim.options.notify_entered_keys
76 if hasEnteredText
77 vim._notifyPersistent(markerContainer.enteredText)
78 else
79 vim.hideNotification()
80
81 elements = visibleMarkers.map((marker) ->
82 return {
83 elementIndex: marker.wrapper.elementIndex
84 selectAll: marker.highlighted and hasEnteredText
85 }
86 )
87 strings = markerContainer.splitEnteredText()
88 vim._send('highlightMarkableElements', {elements, strings})
89
90 isMatched = (visibleMarkers, {enteredHint}) ->
91 isUnique = (new Set(visibleMarkers.map((marker) -> marker.hint)).size == 1)
92 if isUnique
93 return {byText: true, byHint: (enteredHint == visibleMarkers[0].hint)}
94 else
95 return {byText: false, byHint: false}
96
97 module.exports = {
98 activateMatch
99 cleanup
100 getChar
101 updateVisualFeedback
102 isMatched
103 }
Imprint / Impressum