1
2 /*
3 emx (small EMacs clone for X)
4 (C) 2002, Jean-Pierre Demailly
5 released in the public domain
6
7 derived from edx ver. 0.56, (C) 2002, Terry Loveall
8 Based upon the original work ee.c of Yijun Ding, (C) 1991 which is
9 in the public domain.
10
11 This program comes with no warranties. Use at your own risk.
12 */
13
14 #define EDIT "emx"
15
16 #ifndef MINIMAL
17 #define DEFAULT_RC "emxrc"
18 #endif
19
20 /* Help screen -- rewrite to suit your own tastes */
21
22 /* include the editor engine */
23 #include "edit.c"
24
25 /* All this stuff consists of the emacs-like bindings */
26
27 #ifdef GREEK
ctrlc_key(int key)28 void ctrlc_key(int key)
29 {
30 key_greek(key);
31 doCtrlC = var_greek;
32 }
33 #endif
34
35 #ifdef MINIMAL
key_binding(int key)36 void key_binding(int key)
37 {
38 switch(key) {
39 case 'c': SYSTEM("xcalc"); break; /* Alt-C xcalc*/
40 case 'd': new_edit("/c/text/phone.dir"); break; /* Alt-D phone Dir */
41 case 'l': SYSTEM("xcalendar"); break; /* Alt-L xcalendar */
42 case 'u': redo(); break; /* Alt-U redo */
43 }
44 }
45 #endif
46
47 /* ctrl X keys */
ctrlx_key(int key)48 void ctrlx_key(int key)
49 {
50 switch(key | 0x60) {
51 case 'c': sys_exit(0); break; /* ^XC exit only if file saved */
52 case 'd': key_delword(0); break; /* ^XD delete word */
53 case 'f': file_save(0,1); break; /* ^XF open new file */
54 case 'h': show_help(0); break; /* ^XH show help menu */
55 case 'i': block_read(); break; /* ^XI read file into cursor pos */
56 case 'k': block_line(); break; /* ^XK delete line */
57 case 'm': key_macros(1); break; /* ^XM record macro */
58 case 'p': key_macros(0); break; /* ^XP play macro */
59 case 'q': sys_exit(2); break; /* ^XQ exit even if file unsaved */
60 case 's': do_save(); break; /* ^XS write block to disk */
61 case 't': tab_size(); break; /* ^XT get tab size */
62 case 'v': block_write(); break; /* ^XV write block to disk */
63 case 'w': file_save(0,-1); break; /* ^XW save file as */
64 case 'x': goto_last(); break; /* ^XX goto last pos */
65 }
66 doCtrlX = 0;
67 show_top();
68 }
69
70 /* Shift, control and bare Function keys */
key_func(int key)71 void key_func(int key)
72 {
73 if(keve->state & ShiftMask)
74 switch(key) {
75 case XK_Insert : do_paste(); return; /* Shift Ins paste */
76 case XK_Delete : do_select(1); return; /* Shift Del cut */
77 }
78 if((keve->state & ShiftMask) && !flag[BLK] &&
79 key >= XK_Home && key <= XK_End) block_mark(); /* enable marked block with Shift */
80 if(keve->state & ControlMask) {
81 switch(key) {
82 case XK_Tab : word_mark(); break; /* ^Tab mark cursor word */
83 #ifndef MINIMAL
84 case XK_F1 : new_edit(DOCDIR"/MANUAL.emx"); break; /* ^F1 open emx Manual */
85 #endif
86 case XK_F9 : new_edit(""); break; /* ^F3 open new emx */
87 case XK_Home : top(); break; /* ^Home bof */
88 case XK_End : goto_y(ytot); break; /* ^End eof */
89 case XK_Left : word_left(); break; /* ^Left word left */
90 case XK_Right : word_right(); break; /* ^Right word right */
91 case XK_Insert : do_select(0); break; /* ^Ins copy */
92 }
93 } else
94 switch(key) {
95 case XK_F1 : show_help(0); break; /* F1 show help */
96 case XK_F2 : do_save(); break; /* F2 save file and resume */
97 case XK_F3 : file_save(0,1); break; /* F3 open new file */
98 case XK_F4 : find_match(); break; /* F4 find {} () [] match */
99 case XK_F5 : run(); break; /* F5 get and run cmd */
100 case XK_F6 : chgdir(); break; /* F6 get & change to dir */
101 case XK_F7 : block_mark(); break; /* F7 set mark block on */
102 case XK_F8 : block_mark(); break; /* F8 set mark block on */
103 #ifndef MINIMAL
104 case XK_F9 : req_edit(); break; /* F9 open new file in new window */
105 #endif
106 case XK_F10 : key_binding('z'); break; /* F10 open rxvt in cur.dir */
107 case XK_F12 : show_flag(OVR, !flag[OVR]); break;/* Ins toggle insert mode */
108 case XK_Return : key_return(); break; /* Enter newline at cursor */
109 case XK_Tab : key_tab(0); break; /* Tab insert tab char at cursor */
110 case XK_BackSpace: key_backspace(); break; /* BS delete prev char */
111 case XK_Insert : show_flag(OVR, !flag[OVR]); break;/* Ins toggle insert mode */
112 case XK_Delete : key_delete(); break; /* Del delete cursor char */
113 case XK_Page_Up : cursor_pageup(); break; /* PgUp */
114 case XK_Page_Down: cursor_pagedown(); break; /* PgDn */
115 case XK_End : goto_x(strlen(line_start+1)+1); break;/* End eol */
116 case XK_Home : goto_x(1); break; /* Home bol */
117 case XK_Up : cursor_up(); break; /* up */
118 case XK_Down : cursor_down(); break; /* down */
119 case XK_Right : cursor_right(); break; /* right */
120 case XK_Left : cursor_left(); break; /* left */
121 }
122 if(!(keve->state & ShiftMask) && flag[BLK]) mark_off(); // turn off marked block
123 }
124
125 /* Control keys */
key_control(int key)126 void key_control(int key)
127 {
128 if(!(keve->state & ShiftMask) && flag[BLK]) mark_off();
129 switch(key|0x60) {
130 case 'a': goto_x(1); break; /* bol */
131 case 'b': cursor_left(); break; /* left */
132 #ifdef GREEK
133 case 'c': doCtrlC = 1; break; /* ^C switch */
134 #endif
135 case 'd': key_delete(); break; /* delete cursor char */
136 case 'e': goto_x(strlen(line_start+1)+1); break; /* goto eol */
137 case 'f': cursor_right(); break; /* right */
138 case 'h': key_backspace(); break; /* destructive backspace */
139 case 'j': key_return(); break; /* newline at cursor */
140 case 'k': key_delword(1); break; /* delete to eol */
141 case 'l': expose=1; scr_update(); expose=0; break; /* refresh screen */
142 case 'n': cursor_down(); break; /* down */
143 case 'o': show_mode(); break; /* change modes */
144 case 'p': cursor_up(); break; /* up */
145 case 'q': literal = 1; break; /* literal */
146 case 'r': goto_search(1); break; /* ^R find backward */
147 case 's': goto_search(0); break; /* ^S find foreword */
148 case 't': transpose(); break; /* ^T transpose */
149 case 'u': if (search_mode<=1) /* repeat search */
150 goto_find(cur_pos, search_mode);
151 else /* repeat replace */
152 ask_replace();
153 break; /* search or replace again */
154 case 'v': cursor_pagedown(); break; /* ^V pgdn */
155 case 'w': reset_mark();
156 block_copy(1); break; /* ^W cut block at buffer */
157 case 'x': doCtrlX = 1; break; /* ^X switch */
158 case 'y': block_paste(); break; /* ^Y copy buffer at cursor */
159 case 'z': iconify(); break; /* ^Z iconify window */
160 case 0x7f: undo(0); break; /* ^_ undo */
161 /* user typed Ctrl-_ */
162 }
163 show_top();
164 }
165
166 /* Escape keys */
key_escape(int key)167 void key_escape(int key)
168 {
169 switch(tolower(key)) {
170 case ' ':
171 case '.': block_mark(); break; /* Esc-BLANK set mark block on */
172 #ifndef MINIMAL
173 case '!': doEscap = 2; show_note(ALT_KEY_BINDINGS); return; /* Esc-! = Alt-key bindings */
174 #endif
175 case '_': redo(); break; /* Esc-_ redo */
176 case '%': goto_replace(); break; /* Esc-% replace */
177
178 case '<': top(); break; /* Esc-< bof */
179 case '>': y = screen_height-1; goto_ptr(file_end); break; /* Esc-> eof */
180 case 'b': word_left(); break; /* Esc-B word left */
181 case 'f': word_right(); break; /* Esc-F word right */
182 case 'g': keve->state & ControlMask ?
183 goto_line() : /* goto line# */
184 key_return(); break; /* newline */
185 #ifdef JUSTIFY
186 case 'j': block_format(1); break; /* Esc-J reformat & fill block */
187 #endif
188 case 'l': chg_case(0); break; /* Esc-L lower case block */
189 case 'm': window_size(); break; /* Esc-M get right margin */
190 case 'n': scroll_up(); break; /* Esc-N scroll down (!) */
191 case 'p': scroll_down(); break; /* Esc-P scroll up (!) */
192 case 'q': block_format(0); break; /* Esc-Q reformat block */
193 case 'u': chg_case(1); break; /* Esc-U upper case block */
194 case 'v': cursor_pageup(); break; /* Esc-V pgup */
195
196 case 'w': reset_mark(); block_copy(0);
197 reset_mark(); break; /* Esc-W copy block to buffer */
198 case 'x': switch_marks(); break; /* Esc-X switch between block marks */
199 }
200 doEscap = 0;
201 show_top();
202 }
203
204 /* single char interpreter */
main_exec(int key)205 void main_exec(int key)
206 {
207 cur_pos = get_cur();
208 if (update_scr) {
209 undraw_cursor();
210 if(flag[REC]) rec_macro(key);
211 }
212 if (help_done){
213 help_done = 0;
214 flag[SHW] = 1;
215 } else if (literal) {
216 key_normal(keve->state & ControlMask ? key & 0x1f : key);
217 literal = 0;
218 } else {
219 if (key==XK_Escape) doEscap = 1; else
220 if (key & 0xFF00) key_func(key); else
221 if (doEscap==2 || (keve->state & Mod1Mask)) key_binding(key);
222 else {
223 if (doEscap==1) key_escape(key); else
224 #ifdef GREEK
225 if (doCtrlC) ctrlc_key(key); else
226 #endif
227 if (doCtrlX) ctrlx_key(key); else
228 {
229 if (keve->state & ControlMask) key &= 0x1f;
230 if (key >= BLNK) {
231 flag[BLK] = 0;
232 key_normal(key);
233 }
234 else key_control(key);
235 }
236 }
237 }
238 if(!doCtrlX && old_pos != line_start) {
239 last_pos = old_pos;
240 old_pos = line_start;
241 }
242 cur_pos = get_cur();
243
244 if(update_scr) scr_update();
245 }
246
247