some playing with bbs - new fm
[mirrors/Programs.git] / bash / bbs / utils / fm / fm / cmd.c
1 /* Copyright (C) 2008 Ricardo Catalinas Jiménez <jimenezrick@gmail.com>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "fm.h"
18
19 void get_key(void)
20 {
21 static int command_repetitions = -1;
22 static chtype previous_key = 0;
23 char *info;
24 chtype key;
25
26 #ifdef INOTIFY
27 while ((key = getch()) == ERR)
28 watch_events();
29 #else
30 key = getch();
31 #endif
32 if (key != KEY_RESIZE)
33 clear_info();
34
35 if (isdigit(key)) {
36 if (command_repetitions == -1)
37 command_repetitions = key - '0';
38 else {
39 command_repetitions *= 10;
40 command_repetitions += key - '0';
41 }
42 previous_key = key;
43
44 return;
45 }
46
47 if (previous_key == 'f') {
48 select_next_line_by_first_letter((char) key);
49 command_repetitions = -1;
50 previous_key = 0;
51
52 return;
53 } else if (previous_key == 'F') {
54 select_previous_line_by_first_letter((char) key);
55 command_repetitions = -1;
56 previous_key = 0;
57
58 return;
59 }
60
61 if (command_repetitions == -1)
62 command_repetitions = 1;
63
64 switch (key) {
65 case KEY_RESIZE:
66 endwin();
67 init_curses();
68 update_last_line();
69 print_lines(first_line, last_line, TRUE);
70 select_line_inside_window();
71 PRINT_LAST_INFO();
72 break;
73 case 0x0c: /* Ctrl + l */
74 clearok(curscr, TRUE);
75 if (!G_NODE_IS_ROOT(NODE(selected_line)))
76 select_file(NODE(selected_line)->parent);
77 update_directory(NODE(selected_line));
78 break;
79 case 0x1b: /* Escape */
80 command_repetitions = -1;
81 previous_key = 0;
82
83 return;
84 case KEY_NPAGE:
85 case 0x06: /* Ctrl + f */
86 select_line(last_line);
87 scroll_tree(command_repetitions * (getmaxy(tree_window) - 1));
88 break;
89 case KEY_PPAGE:
90 case 0x02: /* Ctrl + b */
91 select_line(first_line);
92 scroll_tree(command_repetitions * (-(getmaxy(tree_window) - 1)));
93 break;
94 case 0x04: /* Ctrl + d */
95 scroll_tree(command_repetitions * getmaxy(tree_window) / 2);
96 select_nth_line(command_repetitions * getmaxy(tree_window) / 2);
97 break;
98 case 0x15: /* Ctrl + u */
99 scroll_tree(command_repetitions * -getmaxy(tree_window) / 2);
100 select_nth_line(command_repetitions * -getmaxy(tree_window) / 2);
101 break;
102 case 'g':
103 if (previous_key == 'g')
104 select_line(lines);
105 break;
106 case 'G':
107 select_line(g_list_last(lines));
108 break;
109 case 0x07: /* Ctrl + g */
110 if ((info = get_file_info(NODE(selected_line))) != NULL) {
111 print_info(info, FALSE);
112 free(info);
113 }
114 break;
115 case 'z':
116 if (previous_key == 'z')
117 scroll_tree(g_list_position(first_line, selected_line) -
118 getmaxy(tree_window) / 2);
119 break;
120 case 'H':
121 select_line(first_line);
122 break;
123 case 'L':
124 select_line(last_line);
125 break;
126 case KEY_DOWN:
127 case 'j':
128 select_nth_line(command_repetitions);
129 break;
130 case KEY_UP:
131 case 'k':
132 select_nth_line(-command_repetitions);
133 break;
134 case KEY_RIGHT:
135 case 'l':
136 if (FILE(NODE(selected_line))->type == directory_type &&
137 FILE(NODE(selected_line))->open == FALSE)
138 open_directory(NODE(selected_line));
139 else if (FILE(NODE(selected_line))->type == directory_type &&
140 FILE(NODE(selected_line))->open == TRUE &&
141 FILE(NODE(selected_line))->show_dotfiles == FALSE)
142 show_dotfiles(NODE(selected_line));
143 else if (FILE(NODE(selected_line))->type == file_type)
144 read_file(NODE(selected_line));
145 break;
146 case KEY_LEFT:
147 case 'h':
148 close_parent: if (FILE(NODE(selected_line))->type == directory_type &&
149 FILE(NODE(selected_line))->open == TRUE &&
150 FILE(NODE(selected_line))->show_dotfiles == TRUE &&
151 !G_NODE_IS_LEAF(NODE(selected_line)) &&
152 FILE(g_node_first_child(NODE(selected_line)))->name[0] == '.')
153 hide_dotfiles(NODE(selected_line));
154 else if (FILE(NODE(selected_line))->type == directory_type &&
155 FILE(NODE(selected_line))->open == TRUE &&
156 !G_NODE_IS_LEAF(NODE(selected_line)))
157 close_directory(NODE(selected_line));
158 else if (!G_NODE_IS_ROOT(NODE(selected_line))) {
159 select_file(NODE(selected_line)->parent);
160 goto close_parent;
161 }
162 break;
163 case 'q':
164 endwin();
165 clean_up();
166 exit(EXIT_SUCCESS);
167 break;
168 case '{':
169 if (g_node_prev_sibling(NODE(selected_line)) != NULL)
170 select_file(g_node_prev_sibling(NODE(selected_line)));
171 else
172 select_nth_line(-1);
173 break;
174 case '}':
175 if (g_node_next_sibling(NODE(selected_line)) != NULL)
176 select_file(g_node_next_sibling(NODE(selected_line)));
177 else
178 select_nth_line(1);
179 break;
180 case '[':
181 if (previous_key == '[' && !G_NODE_IS_ROOT(NODE(selected_line)))
182 select_file(NODE(selected_line)->parent);
183 break;
184 case 's':
185 if (!G_NODE_IS_ROOT(NODE(selected_line)))
186 run_shell(NODE(selected_line)->parent);
187 else
188 run_shell(NODE(selected_line));
189 break;
190 case KEY_ENTER:
191 case 0x0d: /* Enter */
192 if (FILE(NODE(selected_line))->type == file_type)
193 edit_file(NODE(selected_line));
194 break;
195 }
196 if (key != KEY_RESIZE) {
197 command_repetitions = -1;
198 previous_key = key;
199 }
200 }
201
202 void run_program(GNode *current_directory, char *program_name_variable,
203 char *default_program_name, char *arg, gboolean wait_proccess)
204 {
205 char *path, *pwd, *program_name;
206 pid_t child;
207 int status;
208
209 endwin();
210 if ((child = fork()) != 0 && wait_proccess) {
211 unset_sighandlers();
212 waitpid(child, &status, 0);
213 set_sighandlers();
214 } else if (child == 0) {
215 path = get_path(current_directory);
216 if (chdir(path) == -1)
217 exit(EXIT_FAILURE);
218 pwd = g_strconcat("PWD=", path, NULL);
219 putenv(pwd);
220 free(path);
221
222 if (!wait_proccess) {
223 close(0);
224 close(1);
225 close(2);
226 }
227
228 if (program_name_variable != NULL &&
229 (program_name = getenv(program_name_variable)) != NULL) {
230 if (execlp(program_name, program_name, arg, NULL) == -1)
231 exit(EXIT_FAILURE);
232 } else {
233 if (execlp(default_program_name, default_program_name, arg, NULL) == -1)
234 exit(EXIT_FAILURE);
235 }
236 }
237 init_curses();
238 update_last_line();
239 print_lines(first_line, last_line, TRUE);
240 select_line_inside_window();
241
242 if (wait_proccess && WIFEXITED(status) && WEXITSTATUS(status) != EXIT_SUCCESS)
243 PRINT_ERROR_INFO("Something failed when running the external program");
244 }
245
246 void run_shell(GNode *directory)
247 {
248 run_program(directory, "SHELL", DEFAULT_SHELL, NULL, TRUE);
249 }
250
251 void read_file(GNode *file)
252 {
253 if (g_str_has_suffix(FILE(file)->name, ".pdf") ||
254 g_str_has_suffix(FILE(file)->name, ".pdf.gz") ||
255 g_str_has_suffix(FILE(file)->name, ".pdf.Z"))
256 run_program(file->parent, NULL, DEFAULT_PDF_VIEWER, FILE(file)->name, FALSE);
257 else if (g_str_has_suffix(FILE(file)->name, ".ps") ||
258 g_str_has_suffix(FILE(file)->name, ".ps.gz") ||
259 g_str_has_suffix(FILE(file)->name, ".ps.Z"))
260 run_program(file->parent, NULL, DEFAULT_PS_VIEWER, FILE(file)->name, FALSE);
261 else if (g_str_has_suffix(FILE(file)->name, ".jpg") ||
262 g_str_has_suffix(FILE(file)->name, ".jpeg") ||
263 g_str_has_suffix(FILE(file)->name, ".png") ||
264 g_str_has_suffix(FILE(file)->name, ".gif"))
265 run_program(file->parent, NULL, DEFAULT_IMAGE_VIEWER, FILE(file)->name, FALSE);
266 else
267 run_program(file->parent, "PAGER", DEFAULT_PAGER, FILE(file)->name, TRUE);
268 }
269
270 void edit_file(GNode *file)
271 {
272 run_program(file->parent, "EDITOR", DEFAULT_EDITOR, FILE(file)->name, TRUE);
273 }
This page took 0.350135 seconds and 4 git commands to generate.