1 /*
2  * BSD 2-Clause License
3  *
4  * Copyright (C) 2014-2016, Lazaros Koromilas <lostd@2f30.org>
5  * Copyright (C) 2014-2016, Dimitris Papastamos <sin@2f30.org>
6  * Copyright (C) 2016-2021, Arun Prakash Jana <engineerarun@gmail.com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice, this
13  *   list of conditions and the following disclaimer.
14  *
15  * * Redistributions in binary form must reproduce the above copyright notice,
16  *   this list of conditions and the following disclaimer in the documentation
17  *   and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #pragma once
32 
33 #include <curses.h>
34 
35 #define CONTROL(c) ((c) & 0x1f)
36 
37 #ifndef ESC
38 #define ESC (27)
39 #endif
40 
41 #ifndef DEL
42 #define DEL (127)
43 #endif
44 
45 /* Supported actions */
46 enum action {
47 	SEL_BACK = 1,
48 	SEL_OPEN,
49 	SEL_NAV_IN,
50 	SEL_NEXT,
51 	SEL_PREV,
52 	SEL_PGDN,
53 	SEL_PGUP,
54 	SEL_CTRL_D,
55 	SEL_CTRL_U,
56 	SEL_HOME,
57 	SEL_END,
58 	SEL_FIRST,
59 	SEL_CDHOME,
60 	SEL_CDBEGIN,
61 	SEL_CDLAST,
62 	SEL_CDROOT,
63 	SEL_BMOPEN,
64 	SEL_REMOTE,
65 	SEL_CYCLE,
66 	SEL_CYCLER,
67 	SEL_CTX1,
68 	SEL_CTX2,
69 	SEL_CTX3,
70 	SEL_CTX4,
71 #ifdef CTX8
72 	SEL_CTX5,
73 	SEL_CTX6,
74 	SEL_CTX7,
75 	SEL_CTX8,
76 #endif
77 	SEL_MARK,
78 	SEL_BMARK,
79 	SEL_FLTR,
80 	SEL_MFLTR,
81 	SEL_HIDDEN,
82 	SEL_DETAIL,
83 	SEL_STATS,
84 	SEL_CHMODX,
85 	SEL_ARCHIVE,
86 	SEL_SORT,
87 	SEL_REDRAW,
88 	SEL_SEL,
89 	SEL_SELMUL,
90 	SEL_SELALL,
91 	SEL_SELINV,
92 	SEL_SELEDIT,
93 	SEL_CP,
94 	SEL_MV,
95 	SEL_CPMVAS,
96 	SEL_RM,
97 	SEL_OPENWITH,
98 	SEL_NEW,
99 	SEL_RENAME,
100 	SEL_RENAMEMUL,
101 	SEL_UMOUNT,
102 	SEL_HELP,
103 	SEL_AUTONEXT,
104 	SEL_EDIT,
105 	SEL_PLUGIN,
106 	SEL_SHELL,
107 	SEL_LAUNCH,
108 	SEL_PROMPT,
109 	SEL_LOCK,
110 	SEL_SESSIONS,
111 	SEL_EXPORT,
112 	SEL_TIMETYPE,
113 	SEL_QUITCTX,
114 	SEL_QUITCD,
115 	SEL_QUIT,
116 	SEL_QUITERR,
117 #ifndef NOMOUSE
118 	SEL_CLICK,
119 #endif
120 };
121 
122 /* Associate a pressed key to an action */
123 struct key {
124 	int sym;         /* Key pressed */
125 	enum action act; /* Action */
126 };
127 
128 static struct key bindings[] = {
129 	/* Back */
130 	{ KEY_LEFT,       SEL_BACK },
131 	{ 'h',            SEL_BACK },
132 	/* Inside or select */
133 	{ KEY_ENTER,      SEL_OPEN },
134 	{ '\r',           SEL_OPEN },
135 	/* Pure navigate inside */
136 	{ KEY_RIGHT,      SEL_NAV_IN },
137 	{ 'l',            SEL_NAV_IN },
138 	/* Next */
139 	{ 'j',            SEL_NEXT },
140 	{ KEY_DOWN,       SEL_NEXT },
141 	/* Previous */
142 	{ 'k',            SEL_PREV },
143 	{ KEY_UP,         SEL_PREV },
144 	/* Page down */
145 	{ KEY_NPAGE,      SEL_PGDN },
146 	/* Page up */
147 	{ KEY_PPAGE,      SEL_PGUP },
148 	/* Ctrl+D */
149 	{ CONTROL('D'),   SEL_CTRL_D },
150 	/* Ctrl+U */
151 	{ CONTROL('U'),   SEL_CTRL_U },
152 	/* First entry */
153 	{ KEY_HOME,       SEL_HOME },
154 	{ 'g',            SEL_HOME },
155 	{ CONTROL('A'),   SEL_HOME },
156 	/* Last entry */
157 	{ KEY_END,        SEL_END },
158 	{ 'G',            SEL_END },
159 	{ CONTROL('E'),   SEL_END },
160 	/* Go to first file */
161 	{ '\'',           SEL_FIRST },
162 	/* HOME */
163 	{ '~',            SEL_CDHOME },
164 	/* Initial directory */
165 	{ '@',            SEL_CDBEGIN },
166 	/* Last visited dir */
167 	{ '-',            SEL_CDLAST },
168 	/* Go to / */
169 	{ '`',            SEL_CDROOT },
170 	/* Leader key */
171 	{ 'b',            SEL_BMOPEN },
172 	{ CONTROL('_'),   SEL_BMOPEN },
173 	/* Connect to server over SSHFS */
174 	{ 'c',            SEL_REMOTE },
175 	/* Cycle contexts in forward direction */
176 	{ '\t',           SEL_CYCLE },
177 	/* Cycle contexts in reverse direction */
178 	{ KEY_BTAB,       SEL_CYCLER },
179 	/* Go to/create context N */
180 	{ '1',            SEL_CTX1 },
181 	{ '2',            SEL_CTX2 },
182 	{ '3',            SEL_CTX3 },
183 	{ '4',            SEL_CTX4 },
184 #ifdef CTX8
185 	{ '5',            SEL_CTX5 },
186 	{ '6',            SEL_CTX6 },
187 	{ '7',            SEL_CTX7 },
188 	{ '8',            SEL_CTX8 },
189 #endif
190 	/* Mark a path to visit later */
191 	{ ',',            SEL_MARK },
192 	/* Create a bookmark */
193 	{ 'B',            SEL_BMARK },
194 	/* Filter */
195 	{ '/',            SEL_FLTR },
196 	/* Toggle filter mode */
197 	{ CONTROL('N'),   SEL_MFLTR },
198 	/* Toggle hide .dot files */
199 	{ '.',            SEL_HIDDEN },
200 	/* Detailed listing */
201 	{ 'd',            SEL_DETAIL },
202 	/* File details */
203 	{ 'f',            SEL_STATS },
204 	{ CONTROL('F'),   SEL_STATS },
205 	/* Toggle executable status */
206 	{ '*',            SEL_CHMODX },
207 	/* Create archive */
208 	{ 'z',            SEL_ARCHIVE },
209 	/* Sort toggles */
210 	{ 't',            SEL_SORT },
211 	{ CONTROL('T'),   SEL_SORT },
212 	/* Redraw window */
213 	{ CONTROL('L'),   SEL_REDRAW },
214 	/* Select current file path */
215 	{ CONTROL('J'),   SEL_SEL },
216 	{ ' ',            SEL_SEL },
217 	/* Toggle select multiple files */
218 	{ 'm',            SEL_SELMUL },
219 	/* Select all files in current dir */
220 	{ 'a',            SEL_SELALL },
221 	/* Invert selection in current dir */
222 	{ 'A',            SEL_SELINV },
223 	/* List, edit selection */
224 	{ 'E',            SEL_SELEDIT },
225 	/* Copy from selection buffer */
226 	{ 'p',            SEL_CP },
227 	{ CONTROL('P'),   SEL_CP },
228 	/* Move from selection buffer */
229 	{ 'v',            SEL_MV },
230 	{ CONTROL('V'),   SEL_MV },
231 	/* Copy/move from selection buffer and rename */
232 	{ 'w',            SEL_CPMVAS },
233 	{ CONTROL('W'),   SEL_CPMVAS },
234 	/* Delete from selection buffer */
235 	{ 'x',            SEL_RM },
236 	{ CONTROL('X'),   SEL_RM },
237 	/* Open in a custom application */
238 	{ 'o',            SEL_OPENWITH },
239 	{ CONTROL('O'),   SEL_OPENWITH },
240 	/* Create a new file */
241 	{ 'n',            SEL_NEW },
242 	/* Show rename prompt */
243 	{ CONTROL('R'),   SEL_RENAME },
244 	/* Rename contents of current dir */
245 	{ 'r',            SEL_RENAMEMUL },
246 	/* Disconnect a SSHFS mount point */
247 	{ 'u',            SEL_UMOUNT },
248 	/* Show help */
249 	{ '?',            SEL_HELP },
250 	/* Quit a context */
251 	{ '+',            SEL_AUTONEXT },
252 	/* Edit in EDITOR */
253 	{ 'e',            SEL_EDIT },
254 	/* Run a plugin */
255 	{ ';',            SEL_PLUGIN },
256 	/* Run command */
257 	{ '!',            SEL_SHELL },
258 	{ CONTROL(']'),   SEL_SHELL },
259 	/* Launcher */
260 	{ '=',            SEL_LAUNCH },
261 	/* Show command prompt */
262 	{ ']',            SEL_PROMPT },
263 	/* Lock screen */
264 	{ '0',            SEL_LOCK },
265 	/* Manage sessions */
266 	{ 's',            SEL_SESSIONS },
267 	/* Export list */
268 	{ '>',            SEL_EXPORT },
269 	/* Set time type */
270 	{ 'T',            SEL_TIMETYPE },
271 	/* Quit a context */
272 	{ 'q',            SEL_QUITCTX },
273 	/* Change dir on quit */
274 	{ CONTROL('G'),   SEL_QUITCD },
275 	/* Quit */
276 	{ CONTROL('Q'),   SEL_QUIT },
277 	/* Quit with an error code */
278 	{ 'Q',            SEL_QUITERR },
279 #ifndef NOMOUSE
280 	{ KEY_MOUSE,      SEL_CLICK },
281 #endif
282 };
283