]> git.gir.st - VimFx.git/blob - extension/lib/hints-mode.coffee
Implement filtering hints by text and related changes
[VimFx.git] / extension / lib / hints-mode.coffee
1 ###
2 # Copyright Simon Lydell 2016.
3 #
4 # This file is part of VimFx.
5 #
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.
10 #
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.
15 #
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/>.
18 ###
19
20 # This file contains a few helper functions for Hints mode, that didn’t really
21 # fit in modes.coffee.
22
23 activateMatch = (vim, storage, match, matchedMarkers, callback) ->
24 {markerContainer} = storage
25
26 marker.markMatched(true) for marker in matchedMarkers
27
28 # Prevent `onLeave` cleanup if the callback enters another mode.
29 storage.skipOnLeaveCleanup = true
30 again = callback(matchedMarkers[0], storage.count, match.keyStr)
31 storage.skipOnLeaveCleanup = false
32
33 switchedMode = (vim.mode != 'hints')
34
35 if again and not switchedMode
36 storage.count -= 1
37 vim.window.setTimeout((->
38 marker.markMatched(false) for marker in matchedMarkers
39 updateVisualFeedback(vim, markerContainer, [])
40 return
41 ), vim.options['hints.matched_timeout'])
42 markerContainer.reset()
43
44 else
45 vim.window.setTimeout((->
46 # Don’t clean up if Hints mode has been re-entered before the
47 # timeout has passed.
48 cleanup(vim, storage) unless vim.mode == 'hints'
49 ), vim.options['hints.matched_timeout'])
50
51 unless switchedMode
52 storage.skipOnLeaveCleanup = true
53 vim._enterMode('normal')
54 storage.skipOnLeaveCleanup = false
55
56 cleanup = (vim, storage) ->
57 {markerContainer, matchText} = storage
58 markerContainer?.remove()
59 vim._run('clear_selection') if matchText and vim.mode != 'caret'
60 vim.hideNotification() if vim.options.notify_entered_keys
61 storage.clearInterval?()
62 for key of storage
63 storage[key] = null
64 return
65
66 getChar = (match, {markerContainer, matchText}) ->
67 {unmodifiedKey} = match
68 unmodifiedKey = unmodifiedKey.toLowerCase() unless matchText
69
70 isHintChar = switch
71 when not matchText
72 true
73 when unmodifiedKey.length == 1
74 markerContainer.isHintChar(unmodifiedKey)
75 else
76 false
77
78 char = if isHintChar then unmodifiedKey else match.rawKey
79 if char.length == 1
80 return {char, isHintChar}
81 else
82 return {char: null, isHintChar: false}
83
84 updateVisualFeedback = (vim, markerContainer, visibleMarkers) ->
85 if vim.options.notify_entered_keys
86 if markerContainer.enteredText == ''
87 vim.hideNotification()
88 else
89 vim.notify(markerContainer.enteredText)
90
91 elementIndices = visibleMarkers.map((marker) -> marker.wrapper.elementIndex)
92 strings = markerContainer.splitEnteredText()
93 vim._send('highlightMarkableElements', {elementIndices, strings})
94
95 module.exports = {
96 activateMatch
97 cleanup
98 getChar
99 updateVisualFeedback
100 }
Imprint / Impressum