1 | // Scintilla source code edit control |
2 | /** @file KeyMap.cxx |
3 | ** Defines a mapping between keystrokes and commands. |
4 | **/ |
5 | // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | |
8 | #include <cstdlib> |
9 | |
10 | #include <stdexcept> |
11 | #include <string_view> |
12 | #include <vector> |
13 | #include <map> |
14 | #include <optional> |
15 | #include <memory> |
16 | |
17 | #include "ScintillaTypes.h" |
18 | #include "ScintillaMessages.h" |
19 | |
20 | #include "Debugging.h" |
21 | |
22 | #include "KeyMap.h" |
23 | |
24 | using namespace Scintilla; |
25 | using namespace Scintilla::Internal; |
26 | |
27 | KeyMap::KeyMap() { |
28 | for (int i = 0; static_cast<int>(MapDefault[i].key); i++) { |
29 | AssignCmdKey(MapDefault[i].key, |
30 | MapDefault[i].modifiers, |
31 | MapDefault[i].msg); |
32 | } |
33 | } |
34 | |
35 | void KeyMap::Clear() noexcept { |
36 | kmap.clear(); |
37 | } |
38 | |
39 | void KeyMap::AssignCmdKey(Keys key, KeyMod modifiers, Message msg) { |
40 | kmap[KeyModifiers(key, modifiers)] = msg; |
41 | } |
42 | |
43 | Message KeyMap::Find(Keys key, KeyMod modifiers) const { |
44 | std::map<KeyModifiers, Message>::const_iterator it = kmap.find(KeyModifiers(key, modifiers)); |
45 | return (it == kmap.end()) ? static_cast<Message>(0) : it->second; |
46 | } |
47 | |
48 | const std::map<KeyModifiers, Message> &KeyMap::GetKeyMap() const noexcept { |
49 | return kmap; |
50 | } |
51 | |
52 | #if PLAT_GTK_MACOSX |
53 | #define OS_X_KEYS 1 |
54 | #else |
55 | #define OS_X_KEYS 0 |
56 | #endif |
57 | |
58 | // Define a modifier that is exactly Ctrl key on all platforms |
59 | // Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META |
60 | #if OS_X_KEYS |
61 | #define SCI_CTRL_META SCI_META |
62 | #define SCI_SCTRL_META (SCI_META | SCI_SHIFT) |
63 | #else |
64 | #define SCI_CTRL_META SCI_CTRL |
65 | #define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT) |
66 | #endif |
67 | |
68 | namespace { |
69 | |
70 | constexpr Keys Key(char ch) noexcept { |
71 | return static_cast<Keys>(ch); |
72 | } |
73 | |
74 | } |
75 | |
76 | const KeyToCommand KeyMap::MapDefault[] = { |
77 | |
78 | #if OS_X_KEYS |
79 | {Keys::Down, SCI_CTRL, Message::DocumentEnd}, |
80 | {Keys::Down, SCI_CSHIFT, Message::DocumentEndExtend}, |
81 | {Keys::Up, SCI_CTRL, Message::DocumentStart}, |
82 | {Keys::Up, SCI_CSHIFT, Message::DocumentStartExtend}, |
83 | {Keys::Left, SCI_CTRL, Message::VCHome}, |
84 | {Keys::Left, SCI_CSHIFT, Message::VCHomeExtend}, |
85 | {Keys::Right, SCI_CTRL, Message::LineEnd}, |
86 | {Keys::Right, SCI_CSHIFT, Message::LineEndExtend}, |
87 | #endif |
88 | |
89 | {Keys::Down, SCI_NORM, Message::LineDown}, |
90 | {Keys::Down, SCI_SHIFT, Message::LineDownExtend}, |
91 | {Keys::Down, SCI_CTRL_META, Message::LineScrollDown}, |
92 | {Keys::Down, SCI_ASHIFT, Message::LineDownRectExtend}, |
93 | {Keys::Up, SCI_NORM, Message::LineUp}, |
94 | {Keys::Up, SCI_SHIFT, Message::LineUpExtend}, |
95 | {Keys::Up, SCI_CTRL_META, Message::LineScrollUp}, |
96 | {Keys::Up, SCI_ASHIFT, Message::LineUpRectExtend}, |
97 | {Key('['), SCI_CTRL, Message::ParaUp}, |
98 | {Key('['), SCI_CSHIFT, Message::ParaUpExtend}, |
99 | {Key(']'), SCI_CTRL, Message::ParaDown}, |
100 | {Key(']'), SCI_CSHIFT, Message::ParaDownExtend}, |
101 | {Keys::Left, SCI_NORM, Message::CharLeft}, |
102 | {Keys::Left, SCI_SHIFT, Message::CharLeftExtend}, |
103 | {Keys::Left, SCI_CTRL_META, Message::WordLeft}, |
104 | {Keys::Left, SCI_SCTRL_META, Message::WordLeftExtend}, |
105 | {Keys::Left, SCI_ASHIFT, Message::CharLeftRectExtend}, |
106 | {Keys::Right, SCI_NORM, Message::CharRight}, |
107 | {Keys::Right, SCI_SHIFT, Message::CharRightExtend}, |
108 | {Keys::Right, SCI_CTRL_META, Message::WordRight}, |
109 | {Keys::Right, SCI_SCTRL_META, Message::WordRightExtend}, |
110 | {Keys::Right, SCI_ASHIFT, Message::CharRightRectExtend}, |
111 | {Key('/'), SCI_CTRL, Message::WordPartLeft}, |
112 | {Key('/'), SCI_CSHIFT, Message::WordPartLeftExtend}, |
113 | {Key('\\'), SCI_CTRL, Message::WordPartRight}, |
114 | {Key('\\'), SCI_CSHIFT, Message::WordPartRightExtend}, |
115 | {Keys::Home, SCI_NORM, Message::VCHome}, |
116 | {Keys::Home, SCI_SHIFT, Message::VCHomeExtend}, |
117 | {Keys::Home, SCI_CTRL, Message::DocumentStart}, |
118 | {Keys::Home, SCI_CSHIFT, Message::DocumentStartExtend}, |
119 | {Keys::Home, SCI_ALT, Message::HomeDisplay}, |
120 | {Keys::Home, SCI_ASHIFT, Message::VCHomeRectExtend}, |
121 | {Keys::End, SCI_NORM, Message::LineEnd}, |
122 | {Keys::End, SCI_SHIFT, Message::LineEndExtend}, |
123 | {Keys::End, SCI_CTRL, Message::DocumentEnd}, |
124 | {Keys::End, SCI_CSHIFT, Message::DocumentEndExtend}, |
125 | {Keys::End, SCI_ALT, Message::LineEndDisplay}, |
126 | {Keys::End, SCI_ASHIFT, Message::LineEndRectExtend}, |
127 | {Keys::Prior, SCI_NORM, Message::PageUp}, |
128 | {Keys::Prior, SCI_SHIFT, Message::PageUpExtend}, |
129 | {Keys::Prior, SCI_ASHIFT, Message::PageUpRectExtend}, |
130 | {Keys::Next, SCI_NORM, Message::PageDown}, |
131 | {Keys::Next, SCI_SHIFT, Message::PageDownExtend}, |
132 | {Keys::Next, SCI_ASHIFT, Message::PageDownRectExtend}, |
133 | {Keys::Delete, SCI_NORM, Message::Clear}, |
134 | {Keys::Delete, SCI_SHIFT, Message::Cut}, |
135 | {Keys::Delete, SCI_CTRL, Message::DelWordRight}, |
136 | {Keys::Delete, SCI_CSHIFT, Message::DelLineRight}, |
137 | {Keys::Insert, SCI_NORM, Message::EditToggleOvertype}, |
138 | {Keys::Insert, SCI_SHIFT, Message::Paste}, |
139 | {Keys::Insert, SCI_CTRL, Message::Copy}, |
140 | {Keys::Escape, SCI_NORM, Message::Cancel}, |
141 | {Keys::Back, SCI_NORM, Message::DeleteBack}, |
142 | {Keys::Back, SCI_SHIFT, Message::DeleteBack}, |
143 | {Keys::Back, SCI_CTRL, Message::DelWordLeft}, |
144 | {Keys::Back, SCI_ALT, Message::Undo}, |
145 | {Keys::Back, SCI_CSHIFT, Message::DelLineLeft}, |
146 | {Key('Z'), SCI_CTRL, Message::Undo}, |
147 | #if OS_X_KEYS |
148 | {Key('Z'), SCI_CSHIFT, Message::Redo}, |
149 | #else |
150 | {Key('Y'), SCI_CTRL, Message::Redo}, |
151 | #endif |
152 | {Key('X'), SCI_CTRL, Message::Cut}, |
153 | {Key('C'), SCI_CTRL, Message::Copy}, |
154 | {Key('V'), SCI_CTRL, Message::Paste}, |
155 | {Key('A'), SCI_CTRL, Message::SelectAll}, |
156 | {Keys::Tab, SCI_NORM, Message::Tab}, |
157 | {Keys::Tab, SCI_SHIFT, Message::BackTab}, |
158 | {Keys::Return, SCI_NORM, Message::NewLine}, |
159 | {Keys::Return, SCI_SHIFT, Message::NewLine}, |
160 | {Keys::Add, SCI_CTRL, Message::ZoomIn}, |
161 | {Keys::Subtract, SCI_CTRL, Message::ZoomOut}, |
162 | {Keys::Divide, SCI_CTRL, Message::SetZoom}, |
163 | {Key('L'), SCI_CTRL, Message::LineCut}, |
164 | {Key('L'), SCI_CSHIFT, Message::LineDelete}, |
165 | {Key('T'), SCI_CSHIFT, Message::LineCopy}, |
166 | {Key('T'), SCI_CTRL, Message::LineTranspose}, |
167 | {Key('D'), SCI_CTRL, Message::SelectionDuplicate}, |
168 | {Key('U'), SCI_CTRL, Message::LowerCase}, |
169 | {Key('U'), SCI_CSHIFT, Message::UpperCase}, |
170 | {Key(0),SCI_NORM,static_cast<Message>(0)}, |
171 | }; |
172 | |
173 | |