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 "Platform.h"
9 
10 #include "Scintilla.h"
11 
12 #include "KeyMap.h"
13 
14 #ifdef SCI_NAMESPACE
15 using namespace Scintilla;
16 #endif
17 
KeyMap()18 KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
19 	for (int i = 0; MapDefault[i].key; i++) {
20 		AssignCmdKey(MapDefault[i].key,
21 			MapDefault[i].modifiers,
22 			MapDefault[i].msg);
23 	}
24 }
25 
~KeyMap()26 KeyMap::~KeyMap() {
27 	Clear();
28 }
29 
Clear()30 void KeyMap::Clear() {
31 	delete []kmap;
32 	kmap = 0;
33 	len = 0;
34 	alloc = 0;
35 }
36 
AssignCmdKey(int key,int modifiers,unsigned int msg)37 void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) {
38 	if ((len+1) >= alloc) {
39 		KeyToCommand *ktcNew = new KeyToCommand[alloc + 5];
40 		if (!ktcNew)
41 			return;
42 		for (int k = 0; k < len; k++)
43 			ktcNew[k] = kmap[k];
44 		alloc += 5;
45 		delete []kmap;
46 		kmap = ktcNew;
47 	}
48 	for (int keyIndex = 0; keyIndex < len; keyIndex++) {
49 		if ((key == kmap[keyIndex].key) && (modifiers == kmap[keyIndex].modifiers)) {
50 			kmap[keyIndex].msg = msg;
51 			return;
52 		}
53 	}
54 	kmap[len].key = key;
55 	kmap[len].modifiers = modifiers;
56 	kmap[len].msg = msg;
57 	len++;
58 }
59 
Find(int key,int modifiers)60 unsigned int KeyMap::Find(int key, int modifiers) {
61 	for (int i = 0; i < len; i++) {
62 		if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) {
63 			return kmap[i].msg;
64 		}
65 	}
66 	return 0;
67 }
68 
69 #if PLAT_GTK_MACOSX
70 #define OS_X_KEYS 1
71 #else
72 #define OS_X_KEYS 0
73 #endif
74 
75 // Define a modifier that is exactly Ctrl key on all platforms
76 // Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META
77 #if OS_X_KEYS
78 #define SCI_CTRL_META SCI_META
79 #define SCI_SCTRL_META (SCI_META | SCI_SHIFT)
80 #else
81 #define SCI_CTRL_META SCI_CTRL
82 #define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT)
83 #endif
84 
85 const KeyToCommand KeyMap::MapDefault[] = {
86 
87 #if OS_X_KEYS
88     {SCK_DOWN,		SCI_CTRL,	SCI_DOCUMENTEND},
89     {SCK_DOWN,		SCI_CSHIFT,	SCI_DOCUMENTENDEXTEND},
90     {SCK_UP,		SCI_CTRL,	SCI_DOCUMENTSTART},
91     {SCK_UP,		SCI_CSHIFT,	SCI_DOCUMENTSTARTEXTEND},
92     {SCK_LEFT,		SCI_CTRL,	SCI_VCHOME},
93     {SCK_LEFT,		SCI_CSHIFT,	SCI_VCHOMEEXTEND},
94     {SCK_RIGHT,		SCI_CTRL,	SCI_LINEEND},
95     {SCK_RIGHT,		SCI_CSHIFT,	SCI_LINEENDEXTEND},
96 #endif
97 
98     {SCK_DOWN,		SCI_NORM,	SCI_LINEDOWN},
99     {SCK_DOWN,		SCI_SHIFT,	SCI_LINEDOWNEXTEND},
100     {SCK_DOWN,		SCI_CTRL_META,	SCI_LINESCROLLDOWN},
101     {SCK_DOWN,		SCI_ASHIFT,	SCI_LINEDOWNRECTEXTEND},
102     {SCK_UP,		SCI_NORM,	SCI_LINEUP},
103     {SCK_UP,			SCI_SHIFT,	SCI_LINEUPEXTEND},
104     {SCK_UP,			SCI_CTRL_META,	SCI_LINESCROLLUP},
105     {SCK_UP,		SCI_ASHIFT,	SCI_LINEUPRECTEXTEND},
106     {'[',			SCI_CTRL,		SCI_PARAUP},
107     {'[',			SCI_CSHIFT,	SCI_PARAUPEXTEND},
108     {']',			SCI_CTRL,		SCI_PARADOWN},
109     {']',			SCI_CSHIFT,	SCI_PARADOWNEXTEND},
110     {SCK_LEFT,		SCI_NORM,	SCI_CHARLEFT},
111     {SCK_LEFT,		SCI_SHIFT,	SCI_CHARLEFTEXTEND},
112     {SCK_LEFT,		SCI_CTRL_META,	SCI_WORDLEFT},
113     {SCK_LEFT,		SCI_SCTRL_META,	SCI_WORDLEFTEXTEND},
114     {SCK_LEFT,		SCI_ASHIFT,	SCI_CHARLEFTRECTEXTEND},
115     {SCK_RIGHT,		SCI_NORM,	SCI_CHARRIGHT},
116     {SCK_RIGHT,		SCI_SHIFT,	SCI_CHARRIGHTEXTEND},
117     {SCK_RIGHT,		SCI_CTRL_META,	SCI_WORDRIGHT},
118     {SCK_RIGHT,		SCI_SCTRL_META,	SCI_WORDRIGHTEXTEND},
119     {SCK_RIGHT,		SCI_ASHIFT,	SCI_CHARRIGHTRECTEXTEND},
120     {'/',		SCI_CTRL,		SCI_WORDPARTLEFT},
121     {'/',		SCI_CSHIFT,	SCI_WORDPARTLEFTEXTEND},
122     {'\\',		SCI_CTRL,		SCI_WORDPARTRIGHT},
123     {'\\',		SCI_CSHIFT,	SCI_WORDPARTRIGHTEXTEND},
124     {SCK_HOME,		SCI_NORM,	SCI_VCHOME},
125     {SCK_HOME, 		SCI_SHIFT, 	SCI_VCHOMEEXTEND},
126     {SCK_HOME, 		SCI_CTRL, 	SCI_DOCUMENTSTART},
127     {SCK_HOME, 		SCI_CSHIFT, 	SCI_DOCUMENTSTARTEXTEND},
128     {SCK_HOME, 		SCI_ALT, 	SCI_HOMEDISPLAY},
129     {SCK_HOME,		SCI_ASHIFT,	SCI_VCHOMERECTEXTEND},
130     {SCK_END,	 	SCI_NORM,	SCI_LINEEND},
131     {SCK_END,	 	SCI_SHIFT, 	SCI_LINEENDEXTEND},
132     {SCK_END, 		SCI_CTRL, 	SCI_DOCUMENTEND},
133     {SCK_END, 		SCI_CSHIFT, 	SCI_DOCUMENTENDEXTEND},
134     {SCK_END, 		SCI_ALT, 	SCI_LINEENDDISPLAY},
135     {SCK_END,		SCI_ASHIFT,	SCI_LINEENDRECTEXTEND},
136     {SCK_PRIOR,		SCI_NORM,	SCI_PAGEUP},
137     {SCK_PRIOR,		SCI_SHIFT, 	SCI_PAGEUPEXTEND},
138     {SCK_PRIOR,		SCI_ASHIFT,	SCI_PAGEUPRECTEXTEND},
139     {SCK_NEXT, 		SCI_NORM, 	SCI_PAGEDOWN},
140     {SCK_NEXT, 		SCI_SHIFT, 	SCI_PAGEDOWNEXTEND},
141     {SCK_NEXT,		SCI_ASHIFT,	SCI_PAGEDOWNRECTEXTEND},
142     {SCK_DELETE, 	SCI_NORM,	SCI_CLEAR},
143     {SCK_DELETE, 	SCI_SHIFT,	SCI_CUT},
144     {SCK_DELETE, 	SCI_CTRL,	SCI_DELWORDRIGHT},
145     {SCK_DELETE,	SCI_CSHIFT,	SCI_DELLINERIGHT},
146     {SCK_INSERT, 		SCI_NORM,	SCI_EDITTOGGLEOVERTYPE},
147     {SCK_INSERT, 		SCI_SHIFT,	SCI_PASTE},
148     {SCK_INSERT, 		SCI_CTRL,	SCI_COPY},
149     {SCK_ESCAPE,  	SCI_NORM,	SCI_CANCEL},
150     {SCK_BACK,		SCI_NORM, 	SCI_DELETEBACK},
151     {SCK_BACK,		SCI_SHIFT, 	SCI_DELETEBACK},
152     {SCK_BACK,		SCI_CTRL, 	SCI_DELWORDLEFT},
153     {SCK_BACK, 		SCI_ALT,	SCI_UNDO},
154     {SCK_BACK,		SCI_CSHIFT,	SCI_DELLINELEFT},
155     {'Z', 			SCI_CTRL,	SCI_UNDO},
156 #if OS_X_KEYS
157     {'Z', 			SCI_CSHIFT,	SCI_REDO},
158 #else
159     {'Y', 			SCI_CTRL,	SCI_REDO},
160 #endif
161     {'X', 			SCI_CTRL,	SCI_CUT},
162     {'C', 			SCI_CTRL,	SCI_COPY},
163     {'V', 			SCI_CTRL,	SCI_PASTE},
164     {'A', 			SCI_CTRL,	SCI_SELECTALL},
165     {SCK_TAB,		SCI_NORM,	SCI_TAB},
166     {SCK_TAB,		SCI_SHIFT,	SCI_BACKTAB},
167     {SCK_RETURN, 	SCI_NORM,	SCI_NEWLINE},
168     {SCK_RETURN, 	SCI_SHIFT,	SCI_NEWLINE},
169     {SCK_ADD, 		SCI_CTRL,	SCI_ZOOMIN},
170     {SCK_SUBTRACT,	SCI_CTRL,	SCI_ZOOMOUT},
171     {SCK_DIVIDE,	SCI_CTRL,	SCI_SETZOOM},
172     {'L', 			SCI_CTRL,	SCI_LINECUT},
173     {'L', 			SCI_CSHIFT,	SCI_LINEDELETE},
174     {'T', 			SCI_CSHIFT,	SCI_LINECOPY},
175     {'T', 			SCI_CTRL,	SCI_LINETRANSPOSE},
176     {'D', 			SCI_CTRL,	SCI_SELECTIONDUPLICATE},
177     {'U', 			SCI_CTRL,	SCI_LOWERCASE},
178     {'U', 			SCI_CSHIFT,	SCI_UPPERCASE},
179     {0,0,0},
180 };
181 
182