2 # Copyright Simon Lydell 2016.
4 # This file is part of VimFx.
6 # VimFx is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # VimFx is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
20 # This file contains a few helper functions for Hints mode, that didn’t really
21 # fit in modes.coffee.
23 activateMatch = (vim, storage, match, matchedMarkers, callback) ->
24 {markerContainer} = storage
26 marker.markMatched(true) for marker in matchedMarkers
28 [largestMatchedMarker] = matchedMarkers
29 .sort((a, b) -> b.wrapper.shape.area - a.wrapper.shape.area)
31 # Prevent `onLeave` cleanup if the callback enters another mode.
32 storage.skipOnLeaveCleanup = true
33 again = callback(largestMatchedMarker, storage.count, match.keyStr)
34 storage.skipOnLeaveCleanup = false
36 switchedMode = (vim.mode != 'hints')
38 if again and not switchedMode
40 vim.window.setTimeout((->
41 marker.markMatched(false) for marker in matchedMarkers
42 updateVisualFeedback(vim, markerContainer, [])
44 ), vim.options['hints.matched_timeout'])
45 markerContainer.reset()
48 vim.window.setTimeout((->
49 # Don’t clean up if Hints mode has been re-entered before the
51 unless vim.mode == 'hints'
52 # Don’t blur frames (in `utils.clearSelectionDeep`) in case the callback
53 # has focused something in a frame.
54 cleanup(vim, storage, {blur: false})
55 ), vim.options['hints.matched_timeout'])
58 storage.skipOnLeaveCleanup = true
59 vim._enterMode('normal')
60 storage.skipOnLeaveCleanup = false
62 cleanup = (vim, storage, options = {}) ->
63 {markerContainer, matchText} = storage
64 markerContainer?.remove()
65 vim._run('clear_selection', options) if matchText and vim.mode != 'caret'
66 if vim.options.notify_entered_keys and
67 markerContainer.enteredText == vim._state.lastNotification
68 vim.hideNotification()
69 storage.clearInterval?()
74 getChar = (match, {markerContainer, matchText}) ->
75 {unmodifiedKey} = match
80 when unmodifiedKey.length == 1
81 markerContainer.isHintChar(unmodifiedKey)
85 char = if isHintChar then unmodifiedKey else match.rawKey
87 return {char, isHintChar}
89 return {char: null, isHintChar: false}
91 updateVisualFeedback = (vim, markerContainer, visibleMarkers) ->
92 hasEnteredText = (markerContainer.enteredText != '')
94 if vim.options.notify_entered_keys
96 vim._notifyPersistent(markerContainer.enteredText)
98 vim.hideNotification()
100 elements = visibleMarkers.map((marker) ->
102 elementIndex: marker.wrapper.elementIndex
103 selectAll: marker.highlighted and hasEnteredText
106 strings = markerContainer.splitEnteredText()
107 vim._send('highlightMarkableElements', {elements, strings})
109 isMatched = (visibleMarkers, {enteredHint}) ->
110 isUnique = (new Set(visibleMarkers.map((marker) -> marker.hint)).size == 1)
112 return {byText: true, byHint: (enteredHint == visibleMarkers[0].hint)}
114 return {byText: false, byHint: false}