File COPYING added (mode: 100644) (index 0000000..a43ea21) |
|
1 |
|
GNU GENERAL PUBLIC LICENSE |
|
2 |
|
Version 2, June 1991 |
|
3 |
|
|
|
4 |
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
|
5 |
|
675 Mass Ave, Cambridge, MA 02139, USA |
|
6 |
|
Everyone is permitted to copy and distribute verbatim copies |
|
7 |
|
of this license document, but changing it is not allowed. |
|
8 |
|
|
|
9 |
|
Preamble |
|
10 |
|
|
|
11 |
|
The licenses for most software are designed to take away your |
|
12 |
|
freedom to share and change it. By contrast, the GNU General Public |
|
13 |
|
License is intended to guarantee your freedom to share and change free |
|
14 |
|
software--to make sure the software is free for all its users. This |
|
15 |
|
General Public License applies to most of the Free Software |
|
16 |
|
Foundation's software and to any other program whose authors commit to |
|
17 |
|
using it. (Some other Free Software Foundation software is covered by |
|
18 |
|
the GNU Library General Public License instead.) You can apply it to |
|
19 |
|
your programs, too. |
|
20 |
|
|
|
21 |
|
When we speak of free software, we are referring to freedom, not |
|
22 |
|
price. Our General Public Licenses are designed to make sure that you |
|
23 |
|
have the freedom to distribute copies of free software (and charge for |
|
24 |
|
this service if you wish), that you receive source code or can get it |
|
25 |
|
if you want it, that you can change the software or use pieces of it |
|
26 |
|
in new free programs; and that you know you can do these things. |
|
27 |
|
|
|
28 |
|
To protect your rights, we need to make restrictions that forbid |
|
29 |
|
anyone to deny you these rights or to ask you to surrender the rights. |
|
30 |
|
These restrictions translate to certain responsibilities for you if you |
|
31 |
|
distribute copies of the software, or if you modify it. |
|
32 |
|
|
|
33 |
|
For example, if you distribute copies of such a program, whether |
|
34 |
|
gratis or for a fee, you must give the recipients all the rights that |
|
35 |
|
you have. You must make sure that they, too, receive or can get the |
|
36 |
|
source code. And you must show them these terms so they know their |
|
37 |
|
rights. |
|
38 |
|
|
|
39 |
|
We protect your rights with two steps: (1) copyright the software, and |
|
40 |
|
(2) offer you this license which gives you legal permission to copy, |
|
41 |
|
distribute and/or modify the software. |
|
42 |
|
|
|
43 |
|
Also, for each author's protection and ours, we want to make certain |
|
44 |
|
that everyone understands that there is no warranty for this free |
|
45 |
|
software. If the software is modified by someone else and passed on, we |
|
46 |
|
want its recipients to know that what they have is not the original, so |
|
47 |
|
that any problems introduced by others will not reflect on the original |
|
48 |
|
authors' reputations. |
|
49 |
|
|
|
50 |
|
Finally, any free program is threatened constantly by software |
|
51 |
|
patents. We wish to avoid the danger that redistributors of a free |
|
52 |
|
program will individually obtain patent licenses, in effect making the |
|
53 |
|
program proprietary. To prevent this, we have made it clear that any |
|
54 |
|
patent must be licensed for everyone's free use or not licensed at all. |
|
55 |
|
|
|
56 |
|
The precise terms and conditions for copying, distribution and |
|
57 |
|
modification follow. |
|
58 |
|
|
|
59 |
|
GNU GENERAL PUBLIC LICENSE |
|
60 |
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
61 |
|
|
|
62 |
|
0. This License applies to any program or other work which contains |
|
63 |
|
a notice placed by the copyright holder saying it may be distributed |
|
64 |
|
under the terms of this General Public License. The "Program", below, |
|
65 |
|
refers to any such program or work, and a "work based on the Program" |
|
66 |
|
means either the Program or any derivative work under copyright law: |
|
67 |
|
that is to say, a work containing the Program or a portion of it, |
|
68 |
|
either verbatim or with modifications and/or translated into another |
|
69 |
|
language. (Hereinafter, translation is included without limitation in |
|
70 |
|
the term "modification".) Each licensee is addressed as "you". |
|
71 |
|
|
|
72 |
|
Activities other than copying, distribution and modification are not |
|
73 |
|
covered by this License; they are outside its scope. The act of |
|
74 |
|
running the Program is not restricted, and the output from the Program |
|
75 |
|
is covered only if its contents constitute a work based on the |
|
76 |
|
Program (independent of having been made by running the Program). |
|
77 |
|
Whether that is true depends on what the Program does. |
|
78 |
|
|
|
79 |
|
1. You may copy and distribute verbatim copies of the Program's |
|
80 |
|
source code as you receive it, in any medium, provided that you |
|
81 |
|
conspicuously and appropriately publish on each copy an appropriate |
|
82 |
|
copyright notice and disclaimer of warranty; keep intact all the |
|
83 |
|
notices that refer to this License and to the absence of any warranty; |
|
84 |
|
and give any other recipients of the Program a copy of this License |
|
85 |
|
along with the Program. |
|
86 |
|
|
|
87 |
|
You may charge a fee for the physical act of transferring a copy, and |
|
88 |
|
you may at your option offer warranty protection in exchange for a fee. |
|
89 |
|
|
|
90 |
|
2. You may modify your copy or copies of the Program or any portion |
|
91 |
|
of it, thus forming a work based on the Program, and copy and |
|
92 |
|
distribute such modifications or work under the terms of Section 1 |
|
93 |
|
above, provided that you also meet all of these conditions: |
|
94 |
|
|
|
95 |
|
a) You must cause the modified files to carry prominent notices |
|
96 |
|
stating that you changed the files and the date of any change. |
|
97 |
|
|
|
98 |
|
b) You must cause any work that you distribute or publish, that in |
|
99 |
|
whole or in part contains or is derived from the Program or any |
|
100 |
|
part thereof, to be licensed as a whole at no charge to all third |
|
101 |
|
parties under the terms of this License. |
|
102 |
|
|
|
103 |
|
c) If the modified program normally reads commands interactively |
|
104 |
|
when run, you must cause it, when started running for such |
|
105 |
|
interactive use in the most ordinary way, to print or display an |
|
106 |
|
announcement including an appropriate copyright notice and a |
|
107 |
|
notice that there is no warranty (or else, saying that you provide |
|
108 |
|
a warranty) and that users may redistribute the program under |
|
109 |
|
these conditions, and telling the user how to view a copy of this |
|
110 |
|
License. (Exception: if the Program itself is interactive but |
|
111 |
|
does not normally print such an announcement, your work based on |
|
112 |
|
the Program is not required to print an announcement.) |
|
113 |
|
|
|
114 |
|
These requirements apply to the modified work as a whole. If |
|
115 |
|
identifiable sections of that work are not derived from the Program, |
|
116 |
|
and can be reasonably considered independent and separate works in |
|
117 |
|
themselves, then this License, and its terms, do not apply to those |
|
118 |
|
sections when you distribute them as separate works. But when you |
|
119 |
|
distribute the same sections as part of a whole which is a work based |
|
120 |
|
on the Program, the distribution of the whole must be on the terms of |
|
121 |
|
this License, whose permissions for other licensees extend to the |
|
122 |
|
entire whole, and thus to each and every part regardless of who wrote it. |
|
123 |
|
|
|
124 |
|
Thus, it is not the intent of this section to claim rights or contest |
|
125 |
|
your rights to work written entirely by you; rather, the intent is to |
|
126 |
|
exercise the right to control the distribution of derivative or |
|
127 |
|
collective works based on the Program. |
|
128 |
|
|
|
129 |
|
In addition, mere aggregation of another work not based on the Program |
|
130 |
|
with the Program (or with a work based on the Program) on a volume of |
|
131 |
|
a storage or distribution medium does not bring the other work under |
|
132 |
|
the scope of this License. |
|
133 |
|
|
|
134 |
|
3. You may copy and distribute the Program (or a work based on it, |
|
135 |
|
under Section 2) in object code or executable form under the terms of |
|
136 |
|
Sections 1 and 2 above provided that you also do one of the following: |
|
137 |
|
|
|
138 |
|
a) Accompany it with the complete corresponding machine-readable |
|
139 |
|
source code, which must be distributed under the terms of Sections |
|
140 |
|
1 and 2 above on a medium customarily used for software interchange; or, |
|
141 |
|
|
|
142 |
|
b) Accompany it with a written offer, valid for at least three |
|
143 |
|
years, to give any third party, for a charge no more than your |
|
144 |
|
cost of physically performing source distribution, a complete |
|
145 |
|
machine-readable copy of the corresponding source code, to be |
|
146 |
|
distributed under the terms of Sections 1 and 2 above on a medium |
|
147 |
|
customarily used for software interchange; or, |
|
148 |
|
|
|
149 |
|
c) Accompany it with the information you received as to the offer |
|
150 |
|
to distribute corresponding source code. (This alternative is |
|
151 |
|
allowed only for noncommercial distribution and only if you |
|
152 |
|
received the program in object code or executable form with such |
|
153 |
|
an offer, in accord with Subsection b above.) |
|
154 |
|
|
|
155 |
|
The source code for a work means the preferred form of the work for |
|
156 |
|
making modifications to it. For an executable work, complete source |
|
157 |
|
code means all the source code for all modules it contains, plus any |
|
158 |
|
associated interface definition files, plus the scripts used to |
|
159 |
|
control compilation and installation of the executable. However, as a |
|
160 |
|
special exception, the source code distributed need not include |
|
161 |
|
anything that is normally distributed (in either source or binary |
|
162 |
|
form) with the major components (compiler, kernel, and so on) of the |
|
163 |
|
operating system on which the executable runs, unless that component |
|
164 |
|
itself accompanies the executable. |
|
165 |
|
|
|
166 |
|
If distribution of executable or object code is made by offering |
|
167 |
|
access to copy from a designated place, then offering equivalent |
|
168 |
|
access to copy the source code from the same place counts as |
|
169 |
|
distribution of the source code, even though third parties are not |
|
170 |
|
compelled to copy the source along with the object code. |
|
171 |
|
|
|
172 |
|
4. You may not copy, modify, sublicense, or distribute the Program |
|
173 |
|
except as expressly provided under this License. Any attempt |
|
174 |
|
otherwise to copy, modify, sublicense or distribute the Program is |
|
175 |
|
void, and will automatically terminate your rights under this License. |
|
176 |
|
However, parties who have received copies, or rights, from you under |
|
177 |
|
this License will not have their licenses terminated so long as such |
|
178 |
|
parties remain in full compliance. |
|
179 |
|
|
|
180 |
|
5. You are not required to accept this License, since you have not |
|
181 |
|
signed it. However, nothing else grants you permission to modify or |
|
182 |
|
distribute the Program or its derivative works. These actions are |
|
183 |
|
prohibited by law if you do not accept this License. Therefore, by |
|
184 |
|
modifying or distributing the Program (or any work based on the |
|
185 |
|
Program), you indicate your acceptance of this License to do so, and |
|
186 |
|
all its terms and conditions for copying, distributing or modifying |
|
187 |
|
the Program or works based on it. |
|
188 |
|
|
|
189 |
|
6. Each time you redistribute the Program (or any work based on the |
|
190 |
|
Program), the recipient automatically receives a license from the |
|
191 |
|
original licensor to copy, distribute or modify the Program subject to |
|
192 |
|
these terms and conditions. You may not impose any further |
|
193 |
|
restrictions on the recipients' exercise of the rights granted herein. |
|
194 |
|
You are not responsible for enforcing compliance by third parties to |
|
195 |
|
this License. |
|
196 |
|
|
|
197 |
|
7. If, as a consequence of a court judgment or allegation of patent |
|
198 |
|
infringement or for any other reason (not limited to patent issues), |
|
199 |
|
conditions are imposed on you (whether by court order, agreement or |
|
200 |
|
otherwise) that contradict the conditions of this License, they do not |
|
201 |
|
excuse you from the conditions of this License. If you cannot |
|
202 |
|
distribute so as to satisfy simultaneously your obligations under this |
|
203 |
|
License and any other pertinent obligations, then as a consequence you |
|
204 |
|
may not distribute the Program at all. For example, if a patent |
|
205 |
|
license would not permit royalty-free redistribution of the Program by |
|
206 |
|
all those who receive copies directly or indirectly through you, then |
|
207 |
|
the only way you could satisfy both it and this License would be to |
|
208 |
|
refrain entirely from distribution of the Program. |
|
209 |
|
|
|
210 |
|
If any portion of this section is held invalid or unenforceable under |
|
211 |
|
any particular circumstance, the balance of the section is intended to |
|
212 |
|
apply and the section as a whole is intended to apply in other |
|
213 |
|
circumstances. |
|
214 |
|
|
|
215 |
|
It is not the purpose of this section to induce you to infringe any |
|
216 |
|
patents or other property right claims or to contest validity of any |
|
217 |
|
such claims; this section has the sole purpose of protecting the |
|
218 |
|
integrity of the free software distribution system, which is |
|
219 |
|
implemented by public license practices. Many people have made |
|
220 |
|
generous contributions to the wide range of software distributed |
|
221 |
|
through that system in reliance on consistent application of that |
|
222 |
|
system; it is up to the author/donor to decide if he or she is willing |
|
223 |
|
to distribute software through any other system and a licensee cannot |
|
224 |
|
impose that choice. |
|
225 |
|
|
|
226 |
|
This section is intended to make thoroughly clear what is believed to |
|
227 |
|
be a consequence of the rest of this License. |
|
228 |
|
|
|
229 |
|
8. If the distribution and/or use of the Program is restricted in |
|
230 |
|
certain countries either by patents or by copyrighted interfaces, the |
|
231 |
|
original copyright holder who places the Program under this License |
|
232 |
|
may add an explicit geographical distribution limitation excluding |
|
233 |
|
those countries, so that distribution is permitted only in or among |
|
234 |
|
countries not thus excluded. In such case, this License incorporates |
|
235 |
|
the limitation as if written in the body of this License. |
|
236 |
|
|
|
237 |
|
9. The Free Software Foundation may publish revised and/or new versions |
|
238 |
|
of the General Public License from time to time. Such new versions will |
|
239 |
|
be similar in spirit to the present version, but may differ in detail to |
|
240 |
|
address new problems or concerns. |
|
241 |
|
|
|
242 |
|
Each version is given a distinguishing version number. If the Program |
|
243 |
|
specifies a version number of this License which applies to it and "any |
|
244 |
|
later version", you have the option of following the terms and conditions |
|
245 |
|
either of that version or of any later version published by the Free |
|
246 |
|
Software Foundation. If the Program does not specify a version number of |
|
247 |
|
this License, you may choose any version ever published by the Free Software |
|
248 |
|
Foundation. |
|
249 |
|
|
|
250 |
|
10. If you wish to incorporate parts of the Program into other free |
|
251 |
|
programs whose distribution conditions are different, write to the author |
|
252 |
|
to ask for permission. For software which is copyrighted by the Free |
|
253 |
|
Software Foundation, write to the Free Software Foundation; we sometimes |
|
254 |
|
make exceptions for this. Our decision will be guided by the two goals |
|
255 |
|
of preserving the free status of all derivatives of our free software and |
|
256 |
|
of promoting the sharing and reuse of software generally. |
|
257 |
|
|
|
258 |
|
NO WARRANTY |
|
259 |
|
|
|
260 |
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
|
261 |
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
|
262 |
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
|
263 |
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
|
264 |
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
|
265 |
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
|
266 |
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
|
267 |
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
|
268 |
|
REPAIR OR CORRECTION. |
|
269 |
|
|
|
270 |
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
|
271 |
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
|
272 |
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
|
273 |
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
|
274 |
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
|
275 |
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
|
276 |
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
|
277 |
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
|
278 |
|
POSSIBILITY OF SUCH DAMAGES. |
|
279 |
|
|
|
280 |
|
END OF TERMS AND CONDITIONS |
|
281 |
|
|
|
282 |
|
Appendix: How to Apply These Terms to Your New Programs |
|
283 |
|
|
|
284 |
|
If you develop a new program, and you want it to be of the greatest |
|
285 |
|
possible use to the public, the best way to achieve this is to make it |
|
286 |
|
free software which everyone can redistribute and change under these terms. |
|
287 |
|
|
|
288 |
|
To do so, attach the following notices to the program. It is safest |
|
289 |
|
to attach them to the start of each source file to most effectively |
|
290 |
|
convey the exclusion of warranty; and each file should have at least |
|
291 |
|
the "copyright" line and a pointer to where the full notice is found. |
|
292 |
|
|
|
293 |
|
<one line to give the program's name and a brief idea of what it does.> |
|
294 |
|
Copyright (C) 19yy <name of author> |
|
295 |
|
|
|
296 |
|
This program is free software; you can redistribute it and/or modify |
|
297 |
|
it under the terms of the GNU General Public License as published by |
|
298 |
|
the Free Software Foundation; either version 2 of the License, or |
|
299 |
|
(at your option) any later version. |
|
300 |
|
|
|
301 |
|
This program is distributed in the hope that it will be useful, |
|
302 |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
303 |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
304 |
|
GNU General Public License for more details. |
|
305 |
|
|
|
306 |
|
You should have received a copy of the GNU General Public License |
|
307 |
|
along with this program; if not, write to the Free Software |
|
308 |
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
309 |
|
|
|
310 |
|
Also add information on how to contact you by electronic and paper mail. |
|
311 |
|
|
|
312 |
|
If the program is interactive, make it output a short notice like this |
|
313 |
|
when it starts in an interactive mode: |
|
314 |
|
|
|
315 |
|
Gnomovision version 69, Copyright (C) 19yy name of author |
|
316 |
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
|
317 |
|
This is free software, and you are welcome to redistribute it |
|
318 |
|
under certain conditions; type `show c' for details. |
|
319 |
|
|
|
320 |
|
The hypothetical commands `show w' and `show c' should show the appropriate |
|
321 |
|
parts of the General Public License. Of course, the commands you use may |
|
322 |
|
be called something other than `show w' and `show c'; they could even be |
|
323 |
|
mouse-clicks or menu items--whatever suits your program. |
|
324 |
|
|
|
325 |
|
You should also get your employer (if you work as a programmer) or your |
|
326 |
|
school, if any, to sign a "copyright disclaimer" for the program, if |
|
327 |
|
necessary. Here is a sample; alter the names: |
|
328 |
|
|
|
329 |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
|
330 |
|
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
331 |
|
|
|
332 |
|
<signature of Ty Coon>, 1 April 1989 |
|
333 |
|
Ty Coon, President of Vice |
|
334 |
|
|
|
335 |
|
This General Public License does not permit incorporating your program into |
|
336 |
|
proprietary programs. If your program is a subroutine library, you may |
|
337 |
|
consider it more useful to permit linking proprietary applications with the |
|
338 |
|
library. If this is what you want to do, use the GNU Library General |
|
339 |
|
Public License instead of this License. |
File src/color_scheme.c added (mode: 100644) (index 0000000..1e4e914) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#include<stdio.h> |
|
20 |
|
#include<string.h> |
|
21 |
|
#include<limits.h> |
|
22 |
|
#include<ctype.h> |
|
23 |
|
#include<curses.h> |
|
24 |
|
|
|
25 |
|
#include "color_scheme.h" |
|
26 |
|
#include "config.h" |
|
27 |
|
#include "utils.h" |
|
28 |
|
|
|
29 |
|
#define MAX_LEN 1024 |
|
30 |
|
|
|
31 |
|
void |
|
32 |
|
verify_color_schemes() |
|
33 |
|
{ |
|
34 |
|
|
|
35 |
|
} |
|
36 |
|
|
|
37 |
|
void |
|
38 |
|
load_color_scheme(char *name, char *dir) |
|
39 |
|
{ |
|
40 |
|
|
|
41 |
|
|
|
42 |
|
} |
|
43 |
|
|
|
44 |
|
static void |
|
45 |
|
load_default_colors() |
|
46 |
|
{ |
|
47 |
|
|
|
48 |
|
snprintf(col_schemes[0].name, PATH_MAX, "Default"); |
|
49 |
|
snprintf(col_schemes[0].dir, PATH_MAX, "/"); |
|
50 |
|
|
|
51 |
|
col_schemes[0].color[0].name = MENU_COLOR; |
|
52 |
|
col_schemes[0].color[0].fg = COLOR_WHITE; |
|
53 |
|
col_schemes[0].color[0].bg = COLOR_BLACK; |
|
54 |
|
|
|
55 |
|
col_schemes[0].color[1].name = BORDER_COLOR; |
|
56 |
|
col_schemes[0].color[1].fg = COLOR_BLACK; |
|
57 |
|
col_schemes[0].color[1].bg = COLOR_WHITE; |
|
58 |
|
|
|
59 |
|
col_schemes[0].color[2].name = WIN_COLOR; |
|
60 |
|
col_schemes[0].color[2].fg = COLOR_WHITE; |
|
61 |
|
col_schemes[0].color[2].bg = COLOR_BLACK; |
|
62 |
|
|
|
63 |
|
col_schemes[0].color[3].name = STATUS_BAR_COLOR; |
|
64 |
|
col_schemes[0].color[3].fg = COLOR_WHITE; |
|
65 |
|
col_schemes[0].color[3].bg = COLOR_BLACK; |
|
66 |
|
|
|
67 |
|
col_schemes[0].color[4].name = CURR_LINE_COLOR; |
|
68 |
|
col_schemes[0].color[4].fg = COLOR_WHITE; |
|
69 |
|
col_schemes[0].color[4].bg = COLOR_BLUE; |
|
70 |
|
|
|
71 |
|
col_schemes[0].color[5].name = DIRECTORY_COLOR; |
|
72 |
|
col_schemes[0].color[5].fg = COLOR_CYAN; |
|
73 |
|
col_schemes[0].color[5].bg = COLOR_BLACK; |
|
74 |
|
|
|
75 |
|
col_schemes[0].color[6].name = FIFO_COLOR; |
|
76 |
|
col_schemes[0].color[6].fg = COLOR_YELLOW; |
|
77 |
|
col_schemes[0].color[6].bg = COLOR_BLACK; |
|
78 |
|
|
|
79 |
|
col_schemes[0].color[7].name = DEVICE_COLOR; |
|
80 |
|
col_schemes[0].color[7].fg = COLOR_RED; |
|
81 |
|
col_schemes[0].color[7].bg = COLOR_BLACK; |
|
82 |
|
|
|
83 |
|
col_schemes[0].color[8].name = EXECUTABLE_COLOR; |
|
84 |
|
col_schemes[0].color[8].fg = COLOR_GREEN; |
|
85 |
|
col_schemes[0].color[8].bg = COLOR_BLACK; |
|
86 |
|
|
|
87 |
|
col_schemes[0].color[9].name = SELECTED_COLOR; |
|
88 |
|
col_schemes[0].color[9].fg = COLOR_MAGENTA; |
|
89 |
|
col_schemes[0].color[9].bg = COLOR_BLACK; |
|
90 |
|
|
|
91 |
|
col_schemes[0].color[10].name = CURRENT_COLOR; |
|
92 |
|
col_schemes[0].color[10].fg = COLOR_MAGENTA; |
|
93 |
|
col_schemes[0].color[10].bg = COLOR_BLACK; |
|
94 |
|
|
|
95 |
|
|
|
96 |
|
} |
|
97 |
|
|
|
98 |
|
|
|
99 |
|
/* |
|
100 |
|
* convert possible <color_name> to <int> |
|
101 |
|
*/ |
|
102 |
|
static int |
|
103 |
|
colname2int(char col[]) |
|
104 |
|
{ |
|
105 |
|
/* test if col[] is a number... */ |
|
106 |
|
if (isdigit(col[0])) |
|
107 |
|
return atoi(col); |
|
108 |
|
|
|
109 |
|
/* otherwise convert */ |
|
110 |
|
if(!strcmp(col, "black")) |
|
111 |
|
return COLOR_BLACK; |
|
112 |
|
if(!strcmp(col, "blue")) |
|
113 |
|
return COLOR_BLUE; |
|
114 |
|
if(!strcmp(col, "green")) |
|
115 |
|
return COLOR_GREEN; |
|
116 |
|
if(!strcmp(col, "cyan")) |
|
117 |
|
return COLOR_CYAN; |
|
118 |
|
if(!strcmp(col, "red")) |
|
119 |
|
return COLOR_RED; |
|
120 |
|
if(!strcmp(col, "magenta")) |
|
121 |
|
return COLOR_MAGENTA; |
|
122 |
|
if(!strcmp(col, "yellow")) |
|
123 |
|
return COLOR_YELLOW; |
|
124 |
|
if(!strcmp(col, "white")) |
|
125 |
|
return COLOR_WHITE; |
|
126 |
|
/* return default color */ |
|
127 |
|
return -1; |
|
128 |
|
} |
|
129 |
|
|
|
130 |
|
/* |
|
131 |
|
* add color |
|
132 |
|
*/ |
|
133 |
|
void |
|
134 |
|
add_color(char s1[], char s2[], char s3[]) |
|
135 |
|
{ |
|
136 |
|
int fg, bg; |
|
137 |
|
int scheme = 0; |
|
138 |
|
int x = cfg.color_scheme_num -1; |
|
139 |
|
int y = cfg.color_pairs_num; |
|
140 |
|
|
|
141 |
|
fg = colname2int(s2); |
|
142 |
|
bg = colname2int(s3); |
|
143 |
|
|
|
144 |
|
if(y > 10) |
|
145 |
|
y = (y % 11); |
|
146 |
|
|
|
147 |
|
scheme = ((cfg.color_scheme_num - 1) * 11); |
|
148 |
|
|
|
149 |
|
|
|
150 |
|
if(!strcmp(s1, "MENU")) |
|
151 |
|
col_schemes[x].color[y].name = 0 + scheme; |
|
152 |
|
|
|
153 |
|
if(!strcmp(s1, "BORDER")) |
|
154 |
|
col_schemes[x].color[y].name = 1 + scheme; |
|
155 |
|
|
|
156 |
|
if(!strcmp(s1, "WIN")) |
|
157 |
|
col_schemes[x].color[y].name = 2 + scheme; |
|
158 |
|
|
|
159 |
|
if(!strcmp(s1, "STATUS_BAR")) |
|
160 |
|
col_schemes[x].color[y].name = 3 + scheme; |
|
161 |
|
|
|
162 |
|
if(!strcmp(s1, "CURR_LINE")) |
|
163 |
|
col_schemes[x].color[y].name = 4 + scheme; |
|
164 |
|
|
|
165 |
|
if(!strcmp(s1, "DIRECTORY")) |
|
166 |
|
col_schemes[x].color[y].name = 5 + scheme; |
|
167 |
|
|
|
168 |
|
if(!strcmp(s1, "FIFO")) |
|
169 |
|
col_schemes[x].color[y].name = 6 + scheme; |
|
170 |
|
|
|
171 |
|
if(!strcmp(s1, "DEVICE")) |
|
172 |
|
col_schemes[x].color[y].name = 7 + scheme; |
|
173 |
|
|
|
174 |
|
if(!strcmp(s1, "EXECUTABLE")) |
|
175 |
|
col_schemes[x].color[y].name = 8 + scheme; |
|
176 |
|
|
|
177 |
|
if(!strcmp(s1, "SELECTED")) |
|
178 |
|
col_schemes[x].color[y].name = 9 + scheme; |
|
179 |
|
|
|
180 |
|
if(!strcmp(s1, "CURRENT")) |
|
181 |
|
col_schemes[x].color[y].name = 10 + scheme; |
|
182 |
|
|
|
183 |
|
col_schemes[x].color[y].fg = fg; |
|
184 |
|
col_schemes[x].color[y].bg = bg; |
|
185 |
|
|
|
186 |
|
cfg.color_pairs_num++; |
|
187 |
|
} |
|
188 |
|
|
|
189 |
|
|
|
190 |
|
void |
|
191 |
|
read_color_scheme_file() |
|
192 |
|
{ |
|
193 |
|
|
|
194 |
|
FILE *fp; |
|
195 |
|
char config_file[PATH_MAX]; |
|
196 |
|
char line[MAX_LEN]; |
|
197 |
|
char *s1 = NULL; |
|
198 |
|
char *s2 = NULL; |
|
199 |
|
char *s3 = NULL; |
|
200 |
|
char *sx = NULL; |
|
201 |
|
int args; |
|
202 |
|
|
|
203 |
|
snprintf(config_file, sizeof(config_file), "%s/colorschemes", |
|
204 |
|
cfg.config_dir); |
|
205 |
|
|
|
206 |
|
if((fp = fopen(config_file, "r")) == NULL) |
|
207 |
|
{ |
|
208 |
|
load_default_colors(); |
|
209 |
|
|
|
210 |
|
cfg.color_scheme_num++; |
|
211 |
|
cfg.color_pairs_num = 11; |
|
212 |
|
return; |
|
213 |
|
} |
|
214 |
|
|
|
215 |
|
while(fgets(line, MAX_LEN, fp)) |
|
216 |
|
{ |
|
217 |
|
args = 0; |
|
218 |
|
|
|
219 |
|
if(line[0] == '#') |
|
220 |
|
continue; |
|
221 |
|
|
|
222 |
|
if((sx = s1 = strchr(line, '=')) != NULL) |
|
223 |
|
{ |
|
224 |
|
s1++; |
|
225 |
|
chomp(s1); |
|
226 |
|
*sx = '\0'; |
|
227 |
|
args = 1; |
|
228 |
|
} |
|
229 |
|
else |
|
230 |
|
continue; |
|
231 |
|
if((sx = s2 = strchr(s1, '=')) != NULL) |
|
232 |
|
{ |
|
233 |
|
s2++; |
|
234 |
|
chomp(s2); |
|
235 |
|
*sx = '\0'; |
|
236 |
|
args = 2; |
|
237 |
|
} |
|
238 |
|
if((args == 2) && ((sx = s3 = strchr(s2, '=')) != NULL)) |
|
239 |
|
{ |
|
240 |
|
s3++; |
|
241 |
|
chomp(s3); |
|
242 |
|
*sx = '\0'; |
|
243 |
|
args = 3; |
|
244 |
|
} |
|
245 |
|
|
|
246 |
|
if(args == 1) |
|
247 |
|
{ |
|
248 |
|
if(!strcmp(line, "COLORSCHEME")) |
|
249 |
|
{ |
|
250 |
|
|
|
251 |
|
//check if last colorscheme is complete and pad it before starting |
|
252 |
|
// a new scheme |
|
253 |
|
// verify_scheme(); |
|
254 |
|
|
|
255 |
|
//col_schemes = (Col_scheme *)realloc(col_schemes, |
|
256 |
|
// sizeof(Col_scheme *) +1); |
|
257 |
|
|
|
258 |
|
snprintf(col_schemes[cfg.color_scheme_num].name, |
|
259 |
|
PATH_MAX, "%s", s1); |
|
260 |
|
|
|
261 |
|
cfg.color_scheme_num++; |
|
262 |
|
|
|
263 |
|
if (cfg.color_scheme_num > 8) |
|
264 |
|
break; |
|
265 |
|
|
|
266 |
|
continue; |
|
267 |
|
|
|
268 |
|
} |
|
269 |
|
if(!strcmp(line, "DIRECTORY")) |
|
270 |
|
{ |
|
271 |
|
snprintf(col_schemes[cfg.color_scheme_num - 1].dir, |
|
272 |
|
PATH_MAX, "%s", s1); |
|
273 |
|
|
|
274 |
|
continue; |
|
275 |
|
} |
|
276 |
|
} |
|
277 |
|
if(!strcmp(line, "COLOR") && args == 3) |
|
278 |
|
{ |
|
279 |
|
add_color(s1, s2, s3); |
|
280 |
|
} |
|
281 |
|
|
|
282 |
|
} |
|
283 |
|
|
|
284 |
|
fclose(fp); |
|
285 |
|
|
|
286 |
|
//verify_color_schemes(); |
|
287 |
|
return; |
|
288 |
|
} |
|
289 |
|
|
|
290 |
|
void |
|
291 |
|
write_color_scheme_file() |
|
292 |
|
{ |
|
293 |
|
FILE *fp; |
|
294 |
|
char config_file[PATH_MAX]; |
|
295 |
|
int x, y; |
|
296 |
|
char buf[128]; |
|
297 |
|
char fg_buf[64]; |
|
298 |
|
char bg_buf[64]; |
|
299 |
|
|
|
300 |
|
snprintf(config_file, sizeof(config_file), "%s/colorschemes", |
|
301 |
|
cfg.config_dir); |
|
302 |
|
|
|
303 |
|
if((fp = fopen(config_file, "w")) == NULL) |
|
304 |
|
return; |
|
305 |
|
|
|
306 |
|
fprintf(fp, "# You can edit this file by hand.\n"); |
|
307 |
|
fprintf(fp, "# The # character at the beginning of a line comments out the line.\n"); |
|
308 |
|
fprintf(fp, "# Blank lines are ignored.\n\n"); |
|
309 |
|
|
|
310 |
|
fprintf(fp, "# The Default color scheme is used for any directory that does not have\n"); |
|
311 |
|
fprintf(fp, "# a specified scheme. A color scheme set for a base directory will also\n"); |
|
312 |
|
fprintf(fp, "# be used for the sub directories.\n\n"); |
|
313 |
|
|
|
314 |
|
fprintf(fp, "# The standard pdcurses colors are: \n"); |
|
315 |
|
fprintf(fp, "# Black = 0\n"); |
|
316 |
|
fprintf(fp, "# Blue = 1\n"); |
|
317 |
|
fprintf(fp, "# Green = 2\n"); |
|
318 |
|
fprintf(fp, "# Cyan = 3\n"); |
|
319 |
|
fprintf(fp, "# Red = 4\n"); |
|
320 |
|
fprintf(fp, "# Magenta = 5\n"); |
|
321 |
|
fprintf(fp, "# Yellow = 6\n"); |
|
322 |
|
fprintf(fp, "# White = 7\n\n"); |
|
323 |
|
|
|
324 |
|
fprintf(fp, "# COLORSCHEME=OneWordDescription\n"); |
|
325 |
|
fprintf(fp, "# DIRECTORY=/Full/Path/To/Base/Directory\n"); |
|
326 |
|
fprintf(fp, "# COLOR=Window_name=foreground_color_number=background_color_number\n\n"); |
|
327 |
|
|
|
328 |
|
|
|
329 |
|
for(x = 0; x < cfg.color_scheme_num; x++) |
|
330 |
|
{ |
|
331 |
|
fprintf(fp, "\nCOLORSCHEME=%s\n", col_schemes[x].name); |
|
332 |
|
fprintf(fp, "DIRECTORY=%s\n", col_schemes[x].dir); |
|
333 |
|
|
|
334 |
|
for(y = 0; y < 11; y++) |
|
335 |
|
{ |
|
336 |
|
|
|
337 |
|
while(col_schemes[x].color[y].name > 10) |
|
338 |
|
{ |
|
339 |
|
col_schemes[x].color[y].name = |
|
340 |
|
col_schemes[x].color[y].name - 11; |
|
341 |
|
} |
|
342 |
|
|
|
343 |
|
switch(col_schemes[x].color[y].name) |
|
344 |
|
{ |
|
345 |
|
case 0: |
|
346 |
|
snprintf(buf, sizeof(buf), "MENU"); |
|
347 |
|
break; |
|
348 |
|
case 1: |
|
349 |
|
snprintf(buf, sizeof(buf), "BORDER"); |
|
350 |
|
break; |
|
351 |
|
case 2: |
|
352 |
|
snprintf(buf, sizeof(buf), "WIN"); |
|
353 |
|
break; |
|
354 |
|
case 3: |
|
355 |
|
snprintf(buf, sizeof(buf), "STATUS_BAR"); |
|
356 |
|
break; |
|
357 |
|
case 4: |
|
358 |
|
snprintf(buf, sizeof(buf), "CURR_LINE"); |
|
359 |
|
break; |
|
360 |
|
case 5: |
|
361 |
|
snprintf(buf, sizeof(buf), "DIRECTORY"); |
|
362 |
|
break; |
|
363 |
|
case 6: |
|
364 |
|
snprintf(buf, sizeof(buf), "FIFO"); |
|
365 |
|
break; |
|
366 |
|
case 7: |
|
367 |
|
snprintf(buf, sizeof(buf), "DEVICE"); |
|
368 |
|
break; |
|
369 |
|
case 8: |
|
370 |
|
snprintf(buf, sizeof(buf), "EXECUTABLE"); |
|
371 |
|
break; |
|
372 |
|
case 9: |
|
373 |
|
snprintf(buf, sizeof(buf), "SELECTED"); |
|
374 |
|
break; |
|
375 |
|
case 10: |
|
376 |
|
snprintf(buf, sizeof(buf), "CURRENT"); |
|
377 |
|
break; |
|
378 |
|
default: |
|
379 |
|
snprintf(buf, sizeof(buf), "# Unknown"); |
|
380 |
|
break; |
|
381 |
|
}; |
|
382 |
|
|
|
383 |
|
switch (col_schemes[x].color[y].fg) |
|
384 |
|
{ |
|
385 |
|
case 0: |
|
386 |
|
snprintf(fg_buf, sizeof(fg_buf), "black"); |
|
387 |
|
break; |
|
388 |
|
case 1: |
|
389 |
|
snprintf(fg_buf, sizeof(fg_buf), "blue"); |
|
390 |
|
break; |
|
391 |
|
case 2: |
|
392 |
|
snprintf(fg_buf, sizeof(fg_buf), "green"); |
|
393 |
|
break; |
|
394 |
|
case 3: |
|
395 |
|
snprintf(fg_buf, sizeof(fg_buf), "cyan"); |
|
396 |
|
break; |
|
397 |
|
case 4: |
|
398 |
|
snprintf(fg_buf, sizeof(fg_buf), "red"); |
|
399 |
|
break; |
|
400 |
|
case 5: |
|
401 |
|
snprintf(fg_buf, sizeof(fg_buf), "magenta"); |
|
402 |
|
break; |
|
403 |
|
case 6: |
|
404 |
|
snprintf(fg_buf, sizeof(fg_buf), "yellow"); |
|
405 |
|
break; |
|
406 |
|
case 7: |
|
407 |
|
snprintf(fg_buf, sizeof(fg_buf), "white"); |
|
408 |
|
break; |
|
409 |
|
default: |
|
410 |
|
snprintf(fg_buf, sizeof(fg_buf), "-1"); |
|
411 |
|
break; |
|
412 |
|
} |
|
413 |
|
|
|
414 |
|
switch (col_schemes[x].color[y].bg) |
|
415 |
|
{ |
|
416 |
|
case 0: |
|
417 |
|
snprintf(bg_buf, sizeof(bg_buf), "black"); |
|
418 |
|
break; |
|
419 |
|
case 1: |
|
420 |
|
snprintf(bg_buf, sizeof(bg_buf), "blue"); |
|
421 |
|
break; |
|
422 |
|
case 2: |
|
423 |
|
snprintf(bg_buf, sizeof(bg_buf), "green"); |
|
424 |
|
break; |
|
425 |
|
case 3: |
|
426 |
|
snprintf(bg_buf, sizeof(bg_buf), "cyan"); |
|
427 |
|
break; |
|
428 |
|
case 4: |
|
429 |
|
snprintf(bg_buf, sizeof(bg_buf), "red"); |
|
430 |
|
break; |
|
431 |
|
case 5: |
|
432 |
|
snprintf(bg_buf, sizeof(bg_buf), "magenta"); |
|
433 |
|
break; |
|
434 |
|
case 6: |
|
435 |
|
snprintf(bg_buf, sizeof(bg_buf), "yellow"); |
|
436 |
|
break; |
|
437 |
|
case 7: |
|
438 |
|
snprintf(bg_buf, sizeof(bg_buf), "white"); |
|
439 |
|
break; |
|
440 |
|
default: |
|
441 |
|
snprintf(bg_buf, sizeof(bg_buf), "-1"); |
|
442 |
|
break; |
|
443 |
|
} |
|
444 |
|
|
|
445 |
|
fprintf(fp, "COLOR=%s=%s=%s\n", buf, fg_buf, bg_buf); |
|
446 |
|
|
|
447 |
|
} |
|
448 |
|
} |
|
449 |
|
|
|
450 |
|
fclose(fp); |
|
451 |
|
return; |
|
452 |
|
} |
|
453 |
|
|
|
454 |
|
/* The return value is the color scheme base number for the colorpairs. |
|
455 |
|
* There are 11 color pairs for each color scheme. |
|
456 |
|
* |
|
457 |
|
* Default returns 0; |
|
458 |
|
* Second color scheme returns 11 |
|
459 |
|
* Third color scheme returns 22 |
|
460 |
|
* |
|
461 |
|
* The color scheme with the longest matching directory path is the one that |
|
462 |
|
* should be returned. |
|
463 |
|
*/ |
|
464 |
|
int |
|
465 |
|
check_directory_for_color_scheme(const char *dir) |
|
466 |
|
{ |
|
467 |
|
int x,y; |
|
468 |
|
int z = 0; |
|
469 |
|
int v = 0; |
|
470 |
|
|
|
471 |
|
for(x = 0; x < cfg.color_scheme_num; x++) |
|
472 |
|
{ |
|
473 |
|
y = strlen(col_schemes[x].dir); |
|
474 |
|
|
|
475 |
|
if(!strncmp(col_schemes[x].dir, dir, y)) |
|
476 |
|
{ |
|
477 |
|
if (y > z) |
|
478 |
|
{ |
|
479 |
|
z = y; |
|
480 |
|
v = x; |
|
481 |
|
} |
|
482 |
|
} |
|
483 |
|
|
|
484 |
|
} |
|
485 |
|
|
|
486 |
|
return (v * 11); |
|
487 |
|
} |
|
488 |
|
|
File src/commands.c added (mode: 100644) (index 0000000..0eb6c5e) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
|
|
20 |
|
#include<ctype.h> /* isspace() */ |
|
21 |
|
#include<curses.h> |
|
22 |
|
#include<signal.h> |
|
23 |
|
#include<stdio.h> |
|
24 |
|
#include<stdlib.h> /* system() */ |
|
25 |
|
#include<string.h> /* strncmp() */ |
|
26 |
|
#include<time.h> |
|
27 |
|
#include<unistd.h> /* chdir() */ |
|
28 |
|
#include<windows.h> |
|
29 |
|
#include<process.h>//_execv |
|
30 |
|
|
|
31 |
|
#include"bookmarks.h" |
|
32 |
|
#include"background.h" |
|
33 |
|
#include"color_scheme.h" |
|
34 |
|
#include"commands.h" |
|
35 |
|
#include"config.h" |
|
36 |
|
#include"filelist.h" |
|
37 |
|
#include"fileops.h" |
|
38 |
|
#include"keys.h" |
|
39 |
|
#include"menus.h" |
|
40 |
|
#include"search.h" |
|
41 |
|
#include"sort.h" |
|
42 |
|
#include"status.h" |
|
43 |
|
#include"ui.h" |
|
44 |
|
#include"utils.h" |
|
45 |
|
#include "rline.h" |
|
46 |
|
|
|
47 |
|
enum |
|
48 |
|
{ |
|
49 |
|
COM_EXECUTE, |
|
50 |
|
COM_APROPOS, |
|
51 |
|
COM_CHANGE, |
|
52 |
|
COM_CD, |
|
53 |
|
COM_CMAP, |
|
54 |
|
COM_COLORSCHEME, |
|
55 |
|
COM_COMMAND, |
|
56 |
|
COM_COPY, |
|
57 |
|
COM_DELETE, |
|
58 |
|
COM_DELCOMMAND, |
|
59 |
|
COM_DISPLAY, |
|
60 |
|
COM_EDIT, |
|
61 |
|
COM_EMPTY, |
|
62 |
|
COM_FILTER, |
|
63 |
|
COM_FILE, |
|
64 |
|
COM_HELP, |
|
65 |
|
COM_HISTORY, |
|
66 |
|
COM_INVERT, |
|
67 |
|
COM_JOBS, |
|
68 |
|
COM_LOCATE, |
|
69 |
|
COM_LS, |
|
70 |
|
COM_MAP, |
|
71 |
|
COM_MARKS, |
|
72 |
|
COM_MOVE, |
|
73 |
|
COM_NMAP, |
|
74 |
|
COM_NOH, |
|
75 |
|
COM_ONLY, |
|
76 |
|
COM_PWD, |
|
77 |
|
COM_QUIT, |
|
78 |
|
COM_REGISTER, |
|
79 |
|
COM_SORT, |
|
80 |
|
COM_SHELL, |
|
81 |
|
COM_SYNC, |
|
82 |
|
COM_UNMAP, |
|
83 |
|
COM_VIEW, |
|
84 |
|
COM_VIFM, |
|
85 |
|
COM_VMAP, |
|
86 |
|
COM_VOLUME, |
|
87 |
|
COM_YANK, |
|
88 |
|
COM_X |
|
89 |
|
}; |
|
90 |
|
|
|
91 |
|
/* The order of the commands is important as :e will match the first |
|
92 |
|
* command starting with e. |
|
93 |
|
*/ |
|
94 |
|
char *reserved_commands[] = { |
|
95 |
|
"!", |
|
96 |
|
"apropos", |
|
97 |
|
"change", |
|
98 |
|
"cd", |
|
99 |
|
"cmap", |
|
100 |
|
"colorscheme", |
|
101 |
|
"command", |
|
102 |
|
"copy", |
|
103 |
|
"delete", |
|
104 |
|
"delcommand", |
|
105 |
|
"display", |
|
106 |
|
"edit", |
|
107 |
|
"empty", |
|
108 |
|
"filter", |
|
109 |
|
"file", |
|
110 |
|
"help", |
|
111 |
|
"history", |
|
112 |
|
"invert", |
|
113 |
|
"jobs", |
|
114 |
|
"locate", |
|
115 |
|
"ls", |
|
116 |
|
"map", |
|
117 |
|
"marks", |
|
118 |
|
"move", |
|
119 |
|
"nmap", |
|
120 |
|
"nohlsearch", |
|
121 |
|
"only", |
|
122 |
|
"pwd", |
|
123 |
|
"quit", |
|
124 |
|
"register", |
|
125 |
|
"sort", |
|
126 |
|
"shell", |
|
127 |
|
"sync", |
|
128 |
|
"unmap", |
|
129 |
|
"view", |
|
130 |
|
"vifm", |
|
131 |
|
"vmap", |
|
132 |
|
"volume", |
|
133 |
|
"yank", |
|
134 |
|
"x" |
|
135 |
|
}; |
|
136 |
|
|
|
137 |
|
#define RESERVED 40 |
|
138 |
|
|
|
139 |
|
typedef struct current_command |
|
140 |
|
{ |
|
141 |
|
int start_range; |
|
142 |
|
int end_range; |
|
143 |
|
int count; |
|
144 |
|
char *cmd_name; |
|
145 |
|
char *args; |
|
146 |
|
char *curr_files; /* holds %f macro files */ |
|
147 |
|
char *other_files; /* holds %F macro files */ |
|
148 |
|
char *user_args; /* holds %a macro string */ |
|
149 |
|
char *order; /* holds the order of macros command %a %f or command %f %a */ |
|
150 |
|
int background; |
|
151 |
|
int builtin; |
|
152 |
|
int is_user; |
|
153 |
|
int pos; |
|
154 |
|
int pause; |
|
155 |
|
}cmd_t; |
|
156 |
|
|
|
157 |
|
int |
|
158 |
|
sort_this(const void *one, const void *two) |
|
159 |
|
{ |
|
160 |
|
const command_t *first = (const command_t *)one; |
|
161 |
|
const command_t *second = (const command_t *)two; |
|
162 |
|
|
|
163 |
|
return strcmp(first->name, second->name); |
|
164 |
|
} |
|
165 |
|
|
|
166 |
|
int |
|
167 |
|
command_is_reserved(char *name) |
|
168 |
|
{ |
|
169 |
|
int x; |
|
170 |
|
|
|
171 |
|
for(x = 0; x < RESERVED; x++) |
|
172 |
|
{ |
|
173 |
|
if(!strncmp(reserved_commands[x], name, strlen(name))) |
|
174 |
|
return x; |
|
175 |
|
} |
|
176 |
|
return -1; |
|
177 |
|
} |
|
178 |
|
|
|
179 |
|
int |
|
180 |
|
command_is_being_used(char *command) |
|
181 |
|
{ |
|
182 |
|
int x; |
|
183 |
|
for(x = 0; x < cfg.command_num; x++) |
|
184 |
|
{ |
|
185 |
|
if(!strcmp(command_list[x].name, command)) |
|
186 |
|
return 1; |
|
187 |
|
} |
|
188 |
|
return 0; |
|
189 |
|
|
|
190 |
|
} |
|
191 |
|
|
|
192 |
|
void |
|
193 |
|
save_search_history(char *pattern) |
|
194 |
|
{ |
|
195 |
|
int x = 0; |
|
196 |
|
|
|
197 |
|
if ((cfg.search_history_num + 1) >= cfg.search_history_len) |
|
198 |
|
cfg.search_history_num = x = cfg.search_history_len - 1; |
|
199 |
|
else |
|
200 |
|
x = cfg.search_history_num + 1; |
|
201 |
|
|
|
202 |
|
for (; x > 0; x--) |
|
203 |
|
{ |
|
204 |
|
cfg.search_history[x] = (char *)realloc(cfg.search_history[x], |
|
205 |
|
strlen(cfg.search_history[x - 1]) + 1); |
|
206 |
|
strcpy(cfg.search_history[x], cfg.search_history[x - 1]); |
|
207 |
|
} |
|
208 |
|
|
|
209 |
|
cfg.search_history[0] = (char *)realloc(cfg.search_history[0], |
|
210 |
|
strlen(pattern) + 1); |
|
211 |
|
strcpy(cfg.search_history[0], pattern); |
|
212 |
|
cfg.search_history_num++; |
|
213 |
|
if (cfg.search_history_num >= cfg.search_history_len) |
|
214 |
|
cfg.search_history_num = cfg.search_history_len - 1; |
|
215 |
|
} |
|
216 |
|
|
|
217 |
|
void |
|
218 |
|
save_command_history(char *command) |
|
219 |
|
{ |
|
220 |
|
int x = 0; |
|
221 |
|
|
|
222 |
|
/* Don't add :!! or :! to history list */ |
|
223 |
|
if (!strcmp(command, "!!") || !strcmp(command, "!")) |
|
224 |
|
return; |
|
225 |
|
|
|
226 |
|
if ((cfg.cmd_history_num + 1) >= cfg.cmd_history_len) |
|
227 |
|
cfg.cmd_history_num = x = cfg.cmd_history_len - 1; |
|
228 |
|
else |
|
229 |
|
x = cfg.cmd_history_num + 1; |
|
230 |
|
|
|
231 |
|
for (; x > 0; x--) |
|
232 |
|
{ |
|
233 |
|
cfg.cmd_history[x] = (char *)realloc(cfg.cmd_history[x], |
|
234 |
|
strlen(cfg.cmd_history[x - 1]) + 1); |
|
235 |
|
strcpy(cfg.cmd_history[x], cfg.cmd_history[x - 1]); |
|
236 |
|
} |
|
237 |
|
|
|
238 |
|
cfg.cmd_history[0] = (char *)realloc(cfg.cmd_history[0], |
|
239 |
|
strlen(command) + 1); |
|
240 |
|
strcpy(cfg.cmd_history[0], command); |
|
241 |
|
cfg.cmd_history_num++; |
|
242 |
|
if (cfg.cmd_history_num >= cfg.cmd_history_len) |
|
243 |
|
cfg.cmd_history_num = cfg.cmd_history_len -1; |
|
244 |
|
|
|
245 |
|
} |
|
246 |
|
|
|
247 |
|
/* The string returned needs to be freed in the calling function */ |
|
248 |
|
char * |
|
249 |
|
expand_macros(FileView *view, char *command, char *args, |
|
250 |
|
int *use_menu) |
|
251 |
|
{ |
|
252 |
|
char * expanded = NULL; |
|
253 |
|
int x; |
|
254 |
|
int y = 0; |
|
255 |
|
int len = 0; |
|
256 |
|
|
|
257 |
|
curr_stats.getting_input = 1; |
|
258 |
|
|
|
259 |
|
expanded = (char *)calloc(strlen(command) +1, sizeof(char *)); |
|
260 |
|
|
|
261 |
|
for(x = 0; x < strlen(command); x++) |
|
262 |
|
if(command[x] == '%') |
|
263 |
|
break; |
|
264 |
|
|
|
265 |
|
strncat(expanded, command, x); |
|
266 |
|
x++; |
|
267 |
|
len = strlen(expanded); |
|
268 |
|
|
|
269 |
|
do |
|
270 |
|
{ |
|
271 |
|
switch(command[x]) |
|
272 |
|
{ |
|
273 |
|
case 'a': /* user arguments */ |
|
274 |
|
{ |
|
275 |
|
if(!args) |
|
276 |
|
break; |
|
277 |
|
else |
|
278 |
|
{ |
|
279 |
|
char arg_buf[strlen(args) +2]; |
|
280 |
|
|
|
281 |
|
expanded = (char *)realloc(expanded, |
|
282 |
|
strlen(expanded) + strlen(args) +3); |
|
283 |
|
snprintf(arg_buf, sizeof(arg_buf), "%s ", args); |
|
284 |
|
strcat(expanded, arg_buf); |
|
285 |
|
len = strlen(expanded); |
|
286 |
|
} |
|
287 |
|
} |
|
288 |
|
break; |
|
289 |
|
case 'f': /* current dir selected files */ |
|
290 |
|
{ |
|
291 |
|
if(view->selected_files) |
|
292 |
|
{ |
|
293 |
|
int y = 0; |
|
294 |
|
for(y = 0; y < view->list_rows; y++) |
|
295 |
|
{ |
|
296 |
|
if(view->dir_entry[y].selected) |
|
297 |
|
{ |
|
298 |
|
expanded = (char *)realloc(expanded, |
|
299 |
|
len + strlen(view->dir_entry[y].name) +5); |
|
300 |
|
|
|
301 |
|
/* Directory has / appended to the name this removes it. */ |
|
302 |
|
if(view->dir_entry[y].type == FILE_ATTRIBUTE_DIRECTORY) |
|
303 |
|
{ |
|
304 |
|
strncat(expanded, view->dir_entry[y].name, |
|
305 |
|
strlen(view->dir_entry[y].name) -1); |
|
306 |
|
} |
|
307 |
|
else |
|
308 |
|
{ |
|
309 |
|
char *temp = NULL; |
|
310 |
|
temp = escape_filename(view->dir_entry[y].name, 1); |
|
311 |
|
expanded = (char *)realloc(expanded, strlen(expanded) + |
|
312 |
|
strlen(temp) +3); |
|
313 |
|
strcat(expanded, temp); |
|
314 |
|
|
|
315 |
|
my_free(temp); |
|
316 |
|
} |
|
317 |
|
strcat(expanded, " "); |
|
318 |
|
len = strlen(expanded); |
|
319 |
|
} |
|
320 |
|
} |
|
321 |
|
} |
|
322 |
|
else |
|
323 |
|
{ |
|
324 |
|
expanded = (char *)realloc(expanded, strlen(expanded) + |
|
325 |
|
strlen(view->dir_entry[view->list_pos].name) +3); |
|
326 |
|
|
|
327 |
|
if(view->dir_entry[view->list_pos].type == FILE_ATTRIBUTE_DIRECTORY) |
|
328 |
|
{ |
|
329 |
|
strncat(expanded, view->dir_entry[view->list_pos].name, |
|
330 |
|
strlen(view->dir_entry[view->list_pos].name) -1); |
|
331 |
|
} |
|
332 |
|
else |
|
333 |
|
{ |
|
334 |
|
char *temp = |
|
335 |
|
escape_filename(view->dir_entry[view->list_pos].name, 1); |
|
336 |
|
|
|
337 |
|
expanded = (char *)realloc(expanded, strlen(expanded) + |
|
338 |
|
strlen(temp) +3); |
|
339 |
|
strcat(expanded, temp); |
|
340 |
|
my_free(temp); |
|
341 |
|
} |
|
342 |
|
len = strlen(expanded); |
|
343 |
|
} |
|
344 |
|
} |
|
345 |
|
break; |
|
346 |
|
case 'F': /* other dir selected files */ |
|
347 |
|
{ |
|
348 |
|
if(other_view->selected_files) |
|
349 |
|
{ |
|
350 |
|
int y = 0; |
|
351 |
|
|
|
352 |
|
for(y = 0; y < other_view->list_rows; y++) |
|
353 |
|
{ |
|
354 |
|
if(other_view->dir_entry[y].selected) |
|
355 |
|
{ |
|
356 |
|
expanded = (char *)realloc(expanded, len + |
|
357 |
|
strlen(other_view->dir_entry[y].name) + |
|
358 |
|
strlen(other_view->curr_dir) + 3); |
|
359 |
|
|
|
360 |
|
if(expanded == NULL) |
|
361 |
|
{ |
|
362 |
|
show_error_msg("Memory Error", "Unable to allocate memory"); |
|
363 |
|
return NULL; |
|
364 |
|
} |
|
365 |
|
|
|
366 |
|
strcat(expanded, other_view->curr_dir); |
|
367 |
|
strcat(expanded, "/"); |
|
368 |
|
|
|
369 |
|
if(other_view->dir_entry[y].type == FILE_ATTRIBUTE_DIRECTORY) |
|
370 |
|
strncat(expanded, other_view->dir_entry[y].name, |
|
371 |
|
strlen(other_view->dir_entry[y].name) -1); |
|
372 |
|
else |
|
373 |
|
{ |
|
374 |
|
char *temp = NULL; |
|
375 |
|
temp = escape_filename(other_view->dir_entry[y].name, 1); |
|
376 |
|
|
|
377 |
|
expanded = (char *)realloc(expanded, strlen(expanded) + |
|
378 |
|
strlen(temp +3)); |
|
379 |
|
strcat(expanded, temp); |
|
380 |
|
|
|
381 |
|
my_free(temp); |
|
382 |
|
} |
|
383 |
|
|
|
384 |
|
strcat(expanded, " "); |
|
385 |
|
len = strlen(expanded); |
|
386 |
|
} |
|
387 |
|
} |
|
388 |
|
} |
|
389 |
|
else |
|
390 |
|
{ |
|
391 |
|
expanded = (char *)realloc(expanded, len + |
|
392 |
|
strlen(other_view->dir_entry[other_view->list_pos].name) + |
|
393 |
|
strlen(other_view->curr_dir) +4); |
|
394 |
|
if(expanded == NULL) |
|
395 |
|
{ |
|
396 |
|
show_error_msg("Memory Error", "Unable to allocate memory"); |
|
397 |
|
return NULL; |
|
398 |
|
} |
|
399 |
|
|
|
400 |
|
strcat(expanded, other_view->curr_dir); |
|
401 |
|
strcat(expanded, "/"); |
|
402 |
|
|
|
403 |
|
if(other_view->dir_entry[other_view->list_pos].type == FILE_ATTRIBUTE_DIRECTORY) |
|
404 |
|
strncat(expanded, |
|
405 |
|
other_view->dir_entry[other_view->list_pos].name, |
|
406 |
|
strlen(other_view->dir_entry[other_view->list_pos].name) -1); |
|
407 |
|
else |
|
408 |
|
{ |
|
409 |
|
char *temp = |
|
410 |
|
escape_filename(other_view->dir_entry[other_view->list_pos].name, 1); |
|
411 |
|
expanded = (char *)realloc(expanded, strlen(expanded) + |
|
412 |
|
strlen(temp) + 3); |
|
413 |
|
strcat(expanded, temp); |
|
414 |
|
my_free(temp); |
|
415 |
|
} |
|
416 |
|
|
|
417 |
|
len = strlen(expanded); |
|
418 |
|
} |
|
419 |
|
} |
|
420 |
|
break; |
|
421 |
|
case 'd': /* current directory */ |
|
422 |
|
{ |
|
423 |
|
expanded = (char *)realloc(expanded, |
|
424 |
|
len + strlen(view->curr_dir) +3); |
|
425 |
|
strcat(expanded, "\""); |
|
426 |
|
strcat(expanded, view->curr_dir); |
|
427 |
|
strcat(expanded, "\""); |
|
428 |
|
len = strlen(expanded); |
|
429 |
|
} |
|
430 |
|
break; |
|
431 |
|
case 'D': /* other directory */ |
|
432 |
|
{ |
|
433 |
|
expanded = (char *)realloc(expanded, |
|
434 |
|
len + strlen(other_view->curr_dir) +3); |
|
435 |
|
if(!expanded) |
|
436 |
|
{ |
|
437 |
|
show_error_msg("Memory Error", "Unable to allocate memory"); |
|
438 |
|
return NULL; |
|
439 |
|
} |
|
440 |
|
strcat(expanded, "\""); |
|
441 |
|
strcat(expanded, other_view->curr_dir); |
|
442 |
|
strcat(expanded, "\""); |
|
443 |
|
len = strlen(expanded); |
|
444 |
|
} |
|
445 |
|
break; |
|
446 |
|
case 'm': /* use menu */ |
|
447 |
|
*use_menu = 1; |
|
448 |
|
break; |
|
449 |
|
default: |
|
450 |
|
break; |
|
451 |
|
} |
|
452 |
|
x++; |
|
453 |
|
y = x; |
|
454 |
|
|
|
455 |
|
for(; x < strlen(command); x++) |
|
456 |
|
{ |
|
457 |
|
if(command[x] == '%') |
|
458 |
|
break; |
|
459 |
|
} |
|
460 |
|
expanded = (char *)realloc(expanded, len + strlen(command) +1); |
|
461 |
|
strncat(expanded, command + y, x - y); |
|
462 |
|
len = strlen(expanded); |
|
463 |
|
x++; |
|
464 |
|
}while(x < strlen(command)); |
|
465 |
|
|
|
466 |
|
len++; |
|
467 |
|
expanded[len] = '\0'; |
|
468 |
|
if (len > cfg.max_args/2) |
|
469 |
|
show_error_msg("Argument is too long", " FIXME "); |
|
470 |
|
|
|
471 |
|
curr_stats.getting_input = 0; |
|
472 |
|
|
|
473 |
|
return expanded; |
|
474 |
|
} |
|
475 |
|
|
|
476 |
|
int |
|
477 |
|
is_user_command(char *command) |
|
478 |
|
{ |
|
479 |
|
char buf[strlen(command) +1]; |
|
480 |
|
char *com; |
|
481 |
|
char *ptr; |
|
482 |
|
int x; |
|
483 |
|
|
|
484 |
|
com = strcpy(buf, command); |
|
485 |
|
|
|
486 |
|
if((ptr = strchr(com, ' ')) != NULL) |
|
487 |
|
*ptr = '\0'; |
|
488 |
|
|
|
489 |
|
for(x = 0; x < cfg.command_num; x++) |
|
490 |
|
{ |
|
491 |
|
if(!strncmp(com, command_list[x].name, strlen(com))) |
|
492 |
|
{ |
|
493 |
|
return x; |
|
494 |
|
} |
|
495 |
|
} |
|
496 |
|
|
|
497 |
|
return -1; |
|
498 |
|
} |
|
499 |
|
|
|
500 |
|
void |
|
501 |
|
remove_command(char *name) |
|
502 |
|
{ |
|
503 |
|
char *ptr = NULL; |
|
504 |
|
char *s = name; |
|
505 |
|
int x; |
|
506 |
|
int found = 0; |
|
507 |
|
|
|
508 |
|
if((ptr = strchr(s, ' ')) != NULL) |
|
509 |
|
*ptr = '\0'; |
|
510 |
|
|
|
511 |
|
if(command_is_reserved(s) > -1) |
|
512 |
|
{ |
|
513 |
|
show_error_msg(" Trying to delete a reserved Command ", s); |
|
514 |
|
return; |
|
515 |
|
} |
|
516 |
|
|
|
517 |
|
for(x = 0; x < cfg.command_num; x++) |
|
518 |
|
{ |
|
519 |
|
if(!strcmp(s, command_list[x].name)) |
|
520 |
|
{ |
|
521 |
|
found = 1; |
|
522 |
|
break; |
|
523 |
|
} |
|
524 |
|
} |
|
525 |
|
if(found) |
|
526 |
|
{ |
|
527 |
|
cfg.command_num--; |
|
528 |
|
while(x < cfg.command_num) |
|
529 |
|
{ |
|
530 |
|
command_list[x].name = (char *)realloc(command_list[x].name, |
|
531 |
|
strlen(command_list[x +1].name +1)); |
|
532 |
|
strcpy(command_list[x].name, command_list[x +1].name); |
|
533 |
|
command_list[x].action = (char *)realloc(command_list[x].action, |
|
534 |
|
strlen(command_list[x +1].action +1)); |
|
535 |
|
strcpy(command_list[x].action, command_list[x +1].action); |
|
536 |
|
x++; |
|
537 |
|
} |
|
538 |
|
|
|
539 |
|
if(strlen(command_list[x].name)) |
|
540 |
|
my_free(command_list[x].name); |
|
541 |
|
|
|
542 |
|
if(strlen(command_list[x].action)) |
|
543 |
|
my_free(command_list[x].action); |
|
544 |
|
|
|
545 |
|
} |
|
546 |
|
else |
|
547 |
|
show_error_msg(" Command Not Found ", s); |
|
548 |
|
} |
|
549 |
|
|
|
550 |
|
void |
|
551 |
|
add_command(char *name, char *action) |
|
552 |
|
{ |
|
553 |
|
if(command_is_reserved(name) > -1) |
|
554 |
|
return; |
|
555 |
|
if(isdigit(*name)) |
|
556 |
|
{ |
|
557 |
|
show_error_msg(" Invalid Command Name ", |
|
558 |
|
"Commands cannot start with a number."); |
|
559 |
|
return; |
|
560 |
|
} |
|
561 |
|
|
|
562 |
|
if(command_is_being_used(name)) |
|
563 |
|
{ |
|
564 |
|
return; |
|
565 |
|
} |
|
566 |
|
|
|
567 |
|
command_list = (command_t *)realloc(command_list, |
|
568 |
|
(cfg.command_num +1) * sizeof(command_t)); |
|
569 |
|
|
|
570 |
|
command_list[cfg.command_num].name = (char *)malloc(strlen(name) +1); |
|
571 |
|
strcpy(command_list[cfg.command_num].name, name); |
|
572 |
|
command_list[cfg.command_num].action = (char *)malloc(strlen(action) +1); |
|
573 |
|
strcpy(command_list[cfg.command_num].action, action); |
|
574 |
|
cfg.command_num++; |
|
575 |
|
|
|
576 |
|
qsort(command_list, cfg.command_num, sizeof(command_t), sort_this); |
|
577 |
|
} |
|
578 |
|
|
|
579 |
|
static void |
|
580 |
|
set_user_command(char * command, int overwrite, int background) |
|
581 |
|
{ |
|
582 |
|
char buf[80]; |
|
583 |
|
char *ptr = NULL; |
|
584 |
|
char *com_name = NULL; |
|
585 |
|
char *com_action = NULL; |
|
586 |
|
|
|
587 |
|
while(isspace(*command)) |
|
588 |
|
command++; |
|
589 |
|
|
|
590 |
|
com_name = command; |
|
591 |
|
|
|
592 |
|
if((ptr = strchr(command, ' ')) == NULL) |
|
593 |
|
return; |
|
594 |
|
|
|
595 |
|
*ptr = '\0'; |
|
596 |
|
ptr++; |
|
597 |
|
|
|
598 |
|
while(isspace(*ptr) && *ptr != '\0') |
|
599 |
|
ptr++; |
|
600 |
|
|
|
601 |
|
if((strlen(ptr) < 1)) |
|
602 |
|
{ |
|
603 |
|
show_error_msg(" To set a Command Use: ", |
|
604 |
|
":com command_name command_action"); |
|
605 |
|
return; |
|
606 |
|
} |
|
607 |
|
|
|
608 |
|
com_action = strdup(ptr); |
|
609 |
|
|
|
610 |
|
if(background) |
|
611 |
|
{ |
|
612 |
|
com_action = (char *)realloc(com_action, |
|
613 |
|
(strlen(com_action) + 4) * sizeof(char)); |
|
614 |
|
snprintf(com_action, (strlen(com_action) + 3) * sizeof(char), "%s &", ptr); |
|
615 |
|
} |
|
616 |
|
|
|
617 |
|
if(command_is_reserved(com_name) > -1) |
|
618 |
|
{ |
|
619 |
|
snprintf(buf, sizeof(buf), "%s is a reserved command name", com_name); |
|
620 |
|
show_error_msg("", buf); |
|
621 |
|
my_free(com_action); |
|
622 |
|
return; |
|
623 |
|
} |
|
624 |
|
if(command_is_being_used(com_name)) |
|
625 |
|
{ |
|
626 |
|
if(overwrite) |
|
627 |
|
{ |
|
628 |
|
remove_command(com_name); |
|
629 |
|
add_command(com_name, com_action); |
|
630 |
|
} |
|
631 |
|
else |
|
632 |
|
{ |
|
633 |
|
snprintf(buf, sizeof(buf), "%s is already set. Use :com! to overwrite.", |
|
634 |
|
com_name); |
|
635 |
|
show_error_msg("", buf); |
|
636 |
|
} |
|
637 |
|
} |
|
638 |
|
else |
|
639 |
|
{ |
|
640 |
|
add_command(com_name, com_action); |
|
641 |
|
} |
|
642 |
|
} |
|
643 |
|
|
|
644 |
|
//shellout(char *command, int pause, int background) |
|
645 |
|
void |
|
646 |
|
shellout(char *command, int pause) |
|
647 |
|
{ |
|
648 |
|
char buf[1024]; |
|
649 |
|
|
|
650 |
|
if(!strcmp(cfg.shell_cmd, "sh")) |
|
651 |
|
{ |
|
652 |
|
if(command != NULL) |
|
653 |
|
{ |
|
654 |
|
if(pause) |
|
655 |
|
snprintf(buf, sizeof(buf), "sh %s", command); |
|
656 |
|
else |
|
657 |
|
snprintf(buf, sizeof(buf), "sh %s", command); |
|
658 |
|
} |
|
659 |
|
else |
|
660 |
|
{ |
|
661 |
|
snprintf(buf, sizeof(buf), "sh"); |
|
662 |
|
} |
|
663 |
|
} |
|
664 |
|
else if(!strcmp(cfg.shell_cmd, "powershell")) |
|
665 |
|
{ |
|
666 |
|
if(command != NULL) |
|
667 |
|
{ |
|
668 |
|
if(pause) |
|
669 |
|
snprintf(buf, sizeof(buf), "powershell -NoExit -NoLogo -Command %s", command); |
|
670 |
|
else |
|
671 |
|
snprintf(buf, sizeof(buf), "powershell -NoLogo -Command %s", command); |
|
672 |
|
} |
|
673 |
|
else |
|
674 |
|
{ |
|
675 |
|
snprintf(buf, sizeof(buf), "powershell -nologo -noexit"); |
|
676 |
|
} |
|
677 |
|
|
|
678 |
|
} |
|
679 |
|
else |
|
680 |
|
{ |
|
681 |
|
if(command != NULL) |
|
682 |
|
{ |
|
683 |
|
if(pause) |
|
684 |
|
snprintf(buf, sizeof(buf), "cmd chdir %s & %s", |
|
685 |
|
curr_view->curr_dir, command); |
|
686 |
|
else |
|
687 |
|
snprintf(buf, sizeof(buf), "cmd /C chdir %s & %s", |
|
688 |
|
curr_view->curr_dir, command); |
|
689 |
|
} |
|
690 |
|
else |
|
691 |
|
{ |
|
692 |
|
snprintf(buf, sizeof(buf), "cmd /K chdir %s ", |
|
693 |
|
curr_view->curr_dir); |
|
694 |
|
} |
|
695 |
|
} |
|
696 |
|
|
|
697 |
|
|
|
698 |
|
def_prog_mode(); |
|
699 |
|
endwin(); |
|
700 |
|
|
|
701 |
|
system("cls"); |
|
702 |
|
system(buf); |
|
703 |
|
|
|
704 |
|
// my_system("cls"); |
|
705 |
|
// my_system(buf); |
|
706 |
|
|
|
707 |
|
|
|
708 |
|
/* There is a problem with using the screen program and |
|
709 |
|
* catching all the SIGWICH signals. So just redraw the window. |
|
710 |
|
*/ |
|
711 |
|
if (!isendwin()) |
|
712 |
|
redraw_window(); |
|
713 |
|
|
|
714 |
|
curs_set(0); |
|
715 |
|
} |
|
716 |
|
|
|
717 |
|
static void |
|
718 |
|
initialize_command_struct(cmd_t *cmd) |
|
719 |
|
{ |
|
720 |
|
cmd->start_range = 0; |
|
721 |
|
cmd->end_range = 0; |
|
722 |
|
cmd->count = 0; |
|
723 |
|
cmd->cmd_name = NULL; |
|
724 |
|
cmd->args = NULL; |
|
725 |
|
cmd->background = 0; |
|
726 |
|
cmd->builtin = -1; |
|
727 |
|
cmd->is_user = -1; |
|
728 |
|
cmd->pos = 0; |
|
729 |
|
cmd->pause = 0; |
|
730 |
|
} |
|
731 |
|
|
|
732 |
|
static int |
|
733 |
|
select_files_in_range(FileView *view, cmd_t * cmd) |
|
734 |
|
{ |
|
735 |
|
|
|
736 |
|
int x; |
|
737 |
|
int y = 0; |
|
738 |
|
|
|
739 |
|
/* Both a starting range and an ending range are given. */ |
|
740 |
|
if(cmd->start_range > -1) |
|
741 |
|
{ |
|
742 |
|
if(cmd->end_range < cmd->start_range) |
|
743 |
|
{ |
|
744 |
|
show_error_msg(" Command Error ", "Backward range given."); |
|
745 |
|
//save_msg = 1; |
|
746 |
|
//break; |
|
747 |
|
} |
|
748 |
|
|
|
749 |
|
for(x = 0; x < view->list_rows; x++) |
|
750 |
|
view->dir_entry[x].selected = 0; |
|
751 |
|
|
|
752 |
|
for(x = cmd->start_range; x <= cmd->end_range; x++) |
|
753 |
|
{ |
|
754 |
|
view->dir_entry[x].selected = 1; |
|
755 |
|
y++; |
|
756 |
|
} |
|
757 |
|
view->selected_files = y; |
|
758 |
|
} |
|
759 |
|
/* A count is given */ |
|
760 |
|
else if(cmd->count) |
|
761 |
|
{ |
|
762 |
|
if(!cmd->count) |
|
763 |
|
cmd->count = 1; |
|
764 |
|
|
|
765 |
|
/* A one digit range with a count. :4y5 */ |
|
766 |
|
if(cmd->end_range) |
|
767 |
|
{ |
|
768 |
|
y = 0; |
|
769 |
|
for(x = 0; x < view->list_rows; x++) |
|
770 |
|
view->dir_entry[x].selected = 0; |
|
771 |
|
|
|
772 |
|
for(x = cmd->end_range; x < view->list_rows; x++) |
|
773 |
|
{ |
|
774 |
|
if(cmd->count == y) |
|
775 |
|
break; |
|
776 |
|
view->dir_entry[x].selected = 1; |
|
777 |
|
y++; |
|
778 |
|
|
|
779 |
|
} |
|
780 |
|
view->selected_files = y; |
|
781 |
|
} |
|
782 |
|
/* Just a count is given. */ |
|
783 |
|
else |
|
784 |
|
{ |
|
785 |
|
y = 0; |
|
786 |
|
|
|
787 |
|
for(x = 0; x < view->list_rows; x++) |
|
788 |
|
view->dir_entry[x].selected = 0; |
|
789 |
|
|
|
790 |
|
for(x = view->list_pos; x < view->list_rows; x++) |
|
791 |
|
{ |
|
792 |
|
if(cmd->count == y ) |
|
793 |
|
break; |
|
794 |
|
|
|
795 |
|
view->dir_entry[x].selected = 1; |
|
796 |
|
y++; |
|
797 |
|
} |
|
798 |
|
view->selected_files = y; |
|
799 |
|
|
|
800 |
|
} |
|
801 |
|
} |
|
802 |
|
|
|
803 |
|
return 0; |
|
804 |
|
} |
|
805 |
|
|
|
806 |
|
static int |
|
807 |
|
check_for_range(FileView *view, char *command, cmd_t *cmd) |
|
808 |
|
{ |
|
809 |
|
|
|
810 |
|
while(isspace(command[cmd->pos]) && cmd->pos < strlen(command)) |
|
811 |
|
cmd->pos++; |
|
812 |
|
|
|
813 |
|
/* |
|
814 |
|
* First check for a count or a range |
|
815 |
|
* This should be changed to include the rest of the range |
|
816 |
|
* characters [/?\/\?\&] |
|
817 |
|
*/ |
|
818 |
|
if(command[cmd->pos] == '\'') |
|
819 |
|
{ |
|
820 |
|
char mark; |
|
821 |
|
cmd->pos++; |
|
822 |
|
mark = command[cmd->pos]; |
|
823 |
|
cmd->start_range = check_mark_directory(view, mark); |
|
824 |
|
if(cmd->start_range < 0) |
|
825 |
|
{ |
|
826 |
|
show_error_msg("Invalid mark in range", "Trying to use an invalid mark."); |
|
827 |
|
return -1; |
|
828 |
|
} |
|
829 |
|
cmd->pos++; |
|
830 |
|
} |
|
831 |
|
else if(command[cmd->pos] == '$') |
|
832 |
|
{ |
|
833 |
|
cmd->count = view->list_rows; |
|
834 |
|
if(strlen(command) == strlen("$")) |
|
835 |
|
{ |
|
836 |
|
moveto_list_pos(view, cmd->count -1); |
|
837 |
|
return -10; |
|
838 |
|
} |
|
839 |
|
cmd->pos++; |
|
840 |
|
} |
|
841 |
|
else if(command[cmd->pos] == '.') |
|
842 |
|
{ |
|
843 |
|
cmd->start_range = view->list_pos; |
|
844 |
|
cmd->pos++; |
|
845 |
|
} |
|
846 |
|
else if(command[cmd->pos] == '%') |
|
847 |
|
{ |
|
848 |
|
cmd->start_range = 1; |
|
849 |
|
cmd->end_range = view->list_rows; |
|
850 |
|
cmd->pos++; |
|
851 |
|
} |
|
852 |
|
else if(isdigit(command[cmd->pos])) |
|
853 |
|
{ |
|
854 |
|
char num_buf[strlen(command)]; |
|
855 |
|
int z = 0; |
|
856 |
|
while(isdigit(command[cmd->pos])) |
|
857 |
|
{ |
|
858 |
|
num_buf[z] = command[cmd->pos]; |
|
859 |
|
cmd->pos++; |
|
860 |
|
z++; |
|
861 |
|
} |
|
862 |
|
num_buf[z] = '\0'; |
|
863 |
|
cmd->start_range = atoi(num_buf); |
|
864 |
|
|
|
865 |
|
/* The command is just a number */ |
|
866 |
|
if(strlen(num_buf) == strlen(command)) |
|
867 |
|
{ |
|
868 |
|
moveto_list_pos(view, cmd->start_range - 1); |
|
869 |
|
return -10; |
|
870 |
|
} |
|
871 |
|
} |
|
872 |
|
while(isspace(command[cmd->pos]) && cmd->pos < strlen(command)) |
|
873 |
|
cmd->pos++; |
|
874 |
|
|
|
875 |
|
/* Check for second number of range. */ |
|
876 |
|
if(command[cmd->pos] == ',') |
|
877 |
|
{ |
|
878 |
|
cmd->pos++; |
|
879 |
|
|
|
880 |
|
if(command[cmd->pos] == '\'') |
|
881 |
|
{ |
|
882 |
|
char mark; |
|
883 |
|
cmd->pos++; |
|
884 |
|
mark = command[cmd->pos]; |
|
885 |
|
cmd->end_range = check_mark_directory(view, mark); |
|
886 |
|
if(cmd->end_range < 0) |
|
887 |
|
{ |
|
888 |
|
show_error_msg("Invalid mark in range", |
|
889 |
|
"Trying to use an invalid mark."); |
|
890 |
|
return -1; |
|
891 |
|
} |
|
892 |
|
cmd->pos++; |
|
893 |
|
} |
|
894 |
|
else if(command[cmd->pos] == '$') |
|
895 |
|
{ |
|
896 |
|
cmd->end_range = view->list_rows - 1; |
|
897 |
|
cmd->pos++; |
|
898 |
|
} |
|
899 |
|
else if(command[cmd->pos] == '.') |
|
900 |
|
{ |
|
901 |
|
cmd->end_range = view->list_pos; |
|
902 |
|
cmd->pos++; |
|
903 |
|
} |
|
904 |
|
else if(isdigit(command[cmd->pos])) |
|
905 |
|
{ |
|
906 |
|
char num_buf[strlen(command)]; |
|
907 |
|
int z = 0; |
|
908 |
|
while(isdigit(command[cmd->pos])) |
|
909 |
|
{ |
|
910 |
|
num_buf[z] = command[cmd->pos]; |
|
911 |
|
cmd->pos++; |
|
912 |
|
z++; |
|
913 |
|
} |
|
914 |
|
num_buf[z] = '\0'; |
|
915 |
|
cmd->end_range = atoi(num_buf); |
|
916 |
|
} |
|
917 |
|
else |
|
918 |
|
cmd->pos--; |
|
919 |
|
} |
|
920 |
|
else if(!cmd->end_range)/* Only one number is given for the range */ |
|
921 |
|
{ |
|
922 |
|
cmd->end_range = cmd->start_range; |
|
923 |
|
cmd->start_range = -1; |
|
924 |
|
} |
|
925 |
|
return 1; |
|
926 |
|
} |
|
927 |
|
|
|
928 |
|
|
|
929 |
|
static int |
|
930 |
|
parse_command(FileView *view, char *command, cmd_t *cmd) |
|
931 |
|
{ |
|
932 |
|
int result; |
|
933 |
|
|
|
934 |
|
initialize_command_struct(cmd); |
|
935 |
|
|
|
936 |
|
while(strlen(command) > 0 && isspace(command[strlen(command) -1])) |
|
937 |
|
command[strlen(command) -1] = '\0'; |
|
938 |
|
|
|
939 |
|
result = check_for_range(view, command, cmd); |
|
940 |
|
|
|
941 |
|
|
|
942 |
|
/* Just a :number - :12 - or :$ handled in check_for_range() */ |
|
943 |
|
if(result == -10) |
|
944 |
|
return 0; |
|
945 |
|
|
|
946 |
|
/* If the range is invalid give up. */ |
|
947 |
|
if(result < 0) |
|
948 |
|
return -1; |
|
949 |
|
|
|
950 |
|
/* If it is :!! handle and skip everything else. */ |
|
951 |
|
if(!strcmp(command + cmd->pos, "!!")) |
|
952 |
|
{ |
|
953 |
|
if(cfg.cmd_history[0] != NULL) |
|
954 |
|
{ |
|
955 |
|
/* Just a safety check this should never happen. */ |
|
956 |
|
if (!strcmp(cfg.cmd_history[0], "!!")) |
|
957 |
|
show_error_msg("Command Error", "Error in parsing command."); |
|
958 |
|
else |
|
959 |
|
execute_command(view, cfg.cmd_history[0]); |
|
960 |
|
} |
|
961 |
|
else |
|
962 |
|
show_error_msg(" Command Error", "No Previous Commands in History List"); |
|
963 |
|
|
|
964 |
|
return 0; |
|
965 |
|
} |
|
966 |
|
|
|
967 |
|
cmd->cmd_name = strdup(command + cmd->pos); |
|
968 |
|
|
|
969 |
|
/* The builtin commands do not contain numbers and ! is only used at the |
|
970 |
|
* end of the command name. |
|
971 |
|
*/ |
|
972 |
|
while(cmd->cmd_name[cmd->pos] != ' ' && cmd->pos < strlen(cmd->cmd_name) |
|
973 |
|
&& cmd->cmd_name[cmd->pos] != '!') |
|
974 |
|
cmd->pos++; |
|
975 |
|
|
|
976 |
|
if (cmd->cmd_name[cmd->pos] != '!' || cmd->pos == 0) |
|
977 |
|
{ |
|
978 |
|
cmd->cmd_name[cmd->pos] = '\0'; |
|
979 |
|
cmd->pos++; |
|
980 |
|
} |
|
981 |
|
else /* Prevent eating '!' after command name. by not doing cmd->pos++ */ |
|
982 |
|
cmd->cmd_name[cmd->pos] = '\0'; |
|
983 |
|
|
|
984 |
|
|
|
985 |
|
|
|
986 |
|
if(strlen(command) > cmd->pos) |
|
987 |
|
{ |
|
988 |
|
|
|
989 |
|
/* Check whether to run command in background */ |
|
990 |
|
if(command[strlen(command) -1] == '&' && command[strlen(command) -2] == ' ') |
|
991 |
|
{ |
|
992 |
|
int x = 2; |
|
993 |
|
|
|
994 |
|
command[strlen(command) - 1] = '\0'; |
|
995 |
|
|
|
996 |
|
while(isspace(command[strlen(command) - x])) |
|
997 |
|
{ |
|
998 |
|
command[strlen(command) - x] = '\0'; |
|
999 |
|
x++; |
|
1000 |
|
} |
|
1001 |
|
cmd->background = 1; |
|
1002 |
|
|
|
1003 |
|
} |
|
1004 |
|
cmd->args = strdup(command + cmd->pos); |
|
1005 |
|
} |
|
1006 |
|
|
|
1007 |
|
/* Get the actual command name. */ |
|
1008 |
|
if((cmd->builtin = command_is_reserved(cmd->cmd_name)) > -1) |
|
1009 |
|
{ |
|
1010 |
|
cmd->cmd_name = (char *)realloc(cmd->cmd_name, |
|
1011 |
|
strlen(reserved_commands[cmd->builtin]) +1); |
|
1012 |
|
snprintf(cmd->cmd_name, sizeof(reserved_commands[cmd->builtin]), |
|
1013 |
|
"%s", reserved_commands[cmd->builtin]); |
|
1014 |
|
} |
|
1015 |
|
else if((cmd->is_user = is_user_command(cmd->cmd_name)) > -1) |
|
1016 |
|
{ |
|
1017 |
|
cmd->cmd_name =(char *)realloc(cmd->cmd_name, |
|
1018 |
|
strlen(command_list[cmd->is_user].name) + 1); |
|
1019 |
|
snprintf(cmd->cmd_name, sizeof(command_list[cmd->is_user].name), |
|
1020 |
|
"%s", command_list[cmd->is_user].name); |
|
1021 |
|
} |
|
1022 |
|
else |
|
1023 |
|
{ |
|
1024 |
|
my_free(cmd->cmd_name); |
|
1025 |
|
my_free(cmd->args); |
|
1026 |
|
status_bar_message("Unknown Command"); |
|
1027 |
|
return -1; |
|
1028 |
|
} |
|
1029 |
|
|
|
1030 |
|
return 1; |
|
1031 |
|
} |
|
1032 |
|
|
|
1033 |
|
int |
|
1034 |
|
execute_builtin_command(FileView *view, cmd_t *cmd) |
|
1035 |
|
{ |
|
1036 |
|
int save_msg = 0; |
|
1037 |
|
|
|
1038 |
|
switch(cmd->builtin) |
|
1039 |
|
{ |
|
1040 |
|
case COM_EXECUTE: |
|
1041 |
|
{ |
|
1042 |
|
int i = 0; |
|
1043 |
|
int pause = 0; |
|
1044 |
|
char *com = NULL; |
|
1045 |
|
|
|
1046 |
|
if (cmd->args) |
|
1047 |
|
{ |
|
1048 |
|
int m = 0; |
|
1049 |
|
if(strchr(cmd->args, '%') != NULL) |
|
1050 |
|
com = expand_macros(view, cmd->args, NULL, &m); |
|
1051 |
|
else |
|
1052 |
|
com = strdup(cmd->args); |
|
1053 |
|
|
|
1054 |
|
if(com[i] == '!') |
|
1055 |
|
{ |
|
1056 |
|
pause = 1; |
|
1057 |
|
i++; |
|
1058 |
|
} |
|
1059 |
|
while(isspace(com[i]) && i < strlen(com)) |
|
1060 |
|
i++; |
|
1061 |
|
if((strlen(com + i) > 0) && cmd->background) |
|
1062 |
|
start_background_job(com + i); |
|
1063 |
|
else if(strlen(com + i) > 0) |
|
1064 |
|
{ |
|
1065 |
|
shellout(com +i, pause); |
|
1066 |
|
} |
|
1067 |
|
if(!cmd->background) |
|
1068 |
|
my_free(com); |
|
1069 |
|
|
|
1070 |
|
} |
|
1071 |
|
else |
|
1072 |
|
{ |
|
1073 |
|
show_error_msg(" Command Error ", |
|
1074 |
|
"The :! command requires an argument - :!command"); |
|
1075 |
|
save_msg = 1; |
|
1076 |
|
} |
|
1077 |
|
} |
|
1078 |
|
break; |
|
1079 |
|
case COM_APROPOS: |
|
1080 |
|
{ |
|
1081 |
|
if(cmd->args) |
|
1082 |
|
{ |
|
1083 |
|
show_apropos_menu(view, cmd->args); |
|
1084 |
|
} |
|
1085 |
|
} |
|
1086 |
|
break; |
|
1087 |
|
case COM_CHANGE: |
|
1088 |
|
show_change_window(view, FILE_CHANGE); |
|
1089 |
|
break; |
|
1090 |
|
case COM_CD: |
|
1091 |
|
{ |
|
1092 |
|
char dir[PATH_MAX]; |
|
1093 |
|
|
|
1094 |
|
if(cmd->args) |
|
1095 |
|
{ |
|
1096 |
|
if(cmd->args[0] == '/') |
|
1097 |
|
{ |
|
1098 |
|
change_directory(view, cmd->args); |
|
1099 |
|
load_dir_list(view, 0); |
|
1100 |
|
moveto_list_pos(view, view->list_pos); |
|
1101 |
|
} |
|
1102 |
|
else if(cmd->args[0] == '~') |
|
1103 |
|
{ |
|
1104 |
|
snprintf(dir, sizeof(dir), "%s%s", getenv("HOME"), cmd->args +1); |
|
1105 |
|
change_directory(view, dir); |
|
1106 |
|
load_dir_list(view, 0); |
|
1107 |
|
moveto_list_pos(view, view->list_pos); |
|
1108 |
|
} |
|
1109 |
|
else |
|
1110 |
|
{ |
|
1111 |
|
snprintf(dir, sizeof(dir), "%s/%s", view->curr_dir, cmd->args); |
|
1112 |
|
change_directory(view, dir); |
|
1113 |
|
load_dir_list(view, 0); |
|
1114 |
|
moveto_list_pos(view, view->list_pos); |
|
1115 |
|
} |
|
1116 |
|
} |
|
1117 |
|
else |
|
1118 |
|
{ |
|
1119 |
|
change_directory(view, getenv("HOME")); |
|
1120 |
|
load_dir_list(view, 0); |
|
1121 |
|
moveto_list_pos(view, view->list_pos); |
|
1122 |
|
} |
|
1123 |
|
} |
|
1124 |
|
break; |
|
1125 |
|
case COM_CMAP: |
|
1126 |
|
break; |
|
1127 |
|
case COM_COLORSCHEME: |
|
1128 |
|
{ |
|
1129 |
|
if(cmd->args) |
|
1130 |
|
{ |
|
1131 |
|
//snprintf(buf, sizeof(buf), "args are %s", cmd->args); |
|
1132 |
|
show_error_msg("Color Scheme", |
|
1133 |
|
"The :colorscheme command is reserved "); |
|
1134 |
|
|
|
1135 |
|
} |
|
1136 |
|
else /* Should show error message with colorschemes listed */ |
|
1137 |
|
{ |
|
1138 |
|
show_error_msg("Color Scheme", |
|
1139 |
|
"The :colorscheme command is reserved "); |
|
1140 |
|
} |
|
1141 |
|
|
|
1142 |
|
break; |
|
1143 |
|
} |
|
1144 |
|
case COM_COMMAND: |
|
1145 |
|
{ |
|
1146 |
|
if(cmd->args) |
|
1147 |
|
{ |
|
1148 |
|
if(cmd->args[0] == '!') |
|
1149 |
|
{ |
|
1150 |
|
int x = 1; |
|
1151 |
|
while(isspace(cmd->args[x]) && x < strlen(cmd->args)) |
|
1152 |
|
x++; |
|
1153 |
|
set_user_command(cmd->args + x, 1, cmd->background); |
|
1154 |
|
} |
|
1155 |
|
else |
|
1156 |
|
set_user_command(cmd->args, 0, cmd->background); |
|
1157 |
|
} |
|
1158 |
|
else |
|
1159 |
|
show_commands_menu(view); |
|
1160 |
|
} |
|
1161 |
|
break; |
|
1162 |
|
case COM_COPY: |
|
1163 |
|
{ |
|
1164 |
|
copy_files(view); |
|
1165 |
|
load_dir_list(other_view, 1); |
|
1166 |
|
load_dir_list(curr_view, 1); |
|
1167 |
|
moveto_list_pos(view, view->list_pos); |
|
1168 |
|
} |
|
1169 |
|
break; |
|
1170 |
|
case COM_DELETE: |
|
1171 |
|
{ |
|
1172 |
|
/* |
|
1173 |
|
int selection_worked; |
|
1174 |
|
|
|
1175 |
|
selection_worked = select_files_in_range(view, cmd); |
|
1176 |
|
|
|
1177 |
|
if (selection_worked) |
|
1178 |
|
*/ |
|
1179 |
|
select_files_in_range(view, cmd); |
|
1180 |
|
delete_file(view); |
|
1181 |
|
} |
|
1182 |
|
break; |
|
1183 |
|
case COM_DELCOMMAND: |
|
1184 |
|
{ |
|
1185 |
|
if(cmd->args) |
|
1186 |
|
{ |
|
1187 |
|
remove_command(cmd->args); |
|
1188 |
|
//write_config_file(); |
|
1189 |
|
} |
|
1190 |
|
} |
|
1191 |
|
break; |
|
1192 |
|
case COM_DISPLAY: |
|
1193 |
|
case COM_REGISTER: |
|
1194 |
|
show_register_menu(view); |
|
1195 |
|
break; |
|
1196 |
|
case COM_EDIT: |
|
1197 |
|
{ |
|
1198 |
|
if((!view->selected_files) || |
|
1199 |
|
(!view->dir_entry[view->list_pos].selected)) |
|
1200 |
|
{ |
|
1201 |
|
char buf[PATH_MAX]; |
|
1202 |
|
if(view->dir_entry[view->list_pos].name != NULL) |
|
1203 |
|
{ |
|
1204 |
|
char *temp = |
|
1205 |
|
escape_filename(view->dir_entry[view->list_pos].name, 0); |
|
1206 |
|
snprintf(buf, sizeof(buf), "%s %s/%s", cfg.vi_command, |
|
1207 |
|
view->curr_dir, temp); |
|
1208 |
|
shellout(buf, 0); |
|
1209 |
|
my_free(temp); |
|
1210 |
|
} |
|
1211 |
|
} |
|
1212 |
|
else |
|
1213 |
|
{ |
|
1214 |
|
int m = 0; |
|
1215 |
|
char *buf = NULL; |
|
1216 |
|
char *files = expand_macros(view, "%f", NULL, &m); |
|
1217 |
|
|
|
1218 |
|
if((buf = (char *)malloc(strlen(cfg.vi_command) + strlen(files) + 2)) |
|
1219 |
|
== NULL) |
|
1220 |
|
{ |
|
1221 |
|
show_error_msg("Unable to allocate enough memory", |
|
1222 |
|
"Cannot load file"); |
|
1223 |
|
break; |
|
1224 |
|
} |
|
1225 |
|
snprintf(buf, strlen(cfg.vi_command) + strlen(files) +1, |
|
1226 |
|
"%s %s", cfg.vi_command, files); |
|
1227 |
|
|
|
1228 |
|
shellout(buf, 0); |
|
1229 |
|
my_free(files); |
|
1230 |
|
my_free(buf); |
|
1231 |
|
} |
|
1232 |
|
} |
|
1233 |
|
break; |
|
1234 |
|
case COM_EMPTY: |
|
1235 |
|
{ |
|
1236 |
|
char buf[256]; |
|
1237 |
|
snprintf(buf, sizeof(buf), "%s/Trash", cfg.config_dir); |
|
1238 |
|
if(chdir(buf)) |
|
1239 |
|
break; |
|
1240 |
|
|
|
1241 |
|
start_background_job("rm -fr * .[!.]*"); |
|
1242 |
|
chdir(view->curr_dir); |
|
1243 |
|
} |
|
1244 |
|
break; |
|
1245 |
|
case COM_FILTER: |
|
1246 |
|
{ |
|
1247 |
|
if(cmd->args) |
|
1248 |
|
{ |
|
1249 |
|
view->invert = 1; |
|
1250 |
|
view->filename_filter = (char *)realloc(view->filename_filter, |
|
1251 |
|
strlen(cmd->args) +2); |
|
1252 |
|
snprintf(view->filename_filter, strlen(cmd->args) +1, |
|
1253 |
|
"%s", cmd->args); |
|
1254 |
|
load_dir_list(view, 1); |
|
1255 |
|
moveto_list_pos(view, 0); |
|
1256 |
|
} |
|
1257 |
|
else |
|
1258 |
|
{ |
|
1259 |
|
show_error_msg(" Command Error ", |
|
1260 |
|
"The :filter command requires an argument - :filter pattern"); |
|
1261 |
|
save_msg = 1; |
|
1262 |
|
} |
|
1263 |
|
} |
|
1264 |
|
break; |
|
1265 |
|
case COM_FILE: |
|
1266 |
|
show_filetypes_menu(view); |
|
1267 |
|
break; |
|
1268 |
|
case COM_HELP: |
|
1269 |
|
{ |
|
1270 |
|
char help_file[PATH_MAX]; |
|
1271 |
|
|
|
1272 |
|
if(cfg.use_vim_help) |
|
1273 |
|
{ |
|
1274 |
|
if(cmd->args) |
|
1275 |
|
{ |
|
1276 |
|
snprintf(help_file, sizeof(help_file), |
|
1277 |
|
"%s \"-c help %s\" \"-c only\"", cfg.vi_command, cmd->args); |
|
1278 |
|
shellout(help_file, 0); |
|
1279 |
|
} |
|
1280 |
|
else |
|
1281 |
|
{ |
|
1282 |
|
snprintf(help_file, sizeof(help_file), |
|
1283 |
|
"%s \"-c help vifm\" \"-c only\"", cfg.vi_command); |
|
1284 |
|
shellout(help_file, 0); |
|
1285 |
|
} |
|
1286 |
|
} |
|
1287 |
|
else |
|
1288 |
|
{ |
|
1289 |
|
snprintf(help_file, sizeof(help_file), |
|
1290 |
|
"%s \"%s\\vifm-help.txt\"", |
|
1291 |
|
cfg.vi_command, cfg.config_dir); |
|
1292 |
|
|
|
1293 |
|
shellout(help_file, 0); |
|
1294 |
|
} |
|
1295 |
|
} |
|
1296 |
|
break; |
|
1297 |
|
case COM_HISTORY: |
|
1298 |
|
show_history_menu(view); |
|
1299 |
|
break; |
|
1300 |
|
case COM_INVERT: |
|
1301 |
|
{ |
|
1302 |
|
if(view->invert) |
|
1303 |
|
view->invert = 0; |
|
1304 |
|
else |
|
1305 |
|
view->invert = 1; |
|
1306 |
|
load_dir_list(view, 1); |
|
1307 |
|
moveto_list_pos(view, 0); |
|
1308 |
|
} |
|
1309 |
|
break; |
|
1310 |
|
case COM_JOBS: |
|
1311 |
|
//show_jobs_menu(view); |
|
1312 |
|
break; |
|
1313 |
|
case COM_LOCATE: |
|
1314 |
|
{ |
|
1315 |
|
if(cmd->args) |
|
1316 |
|
{ |
|
1317 |
|
show_locate_menu(view, cmd->args); |
|
1318 |
|
} |
|
1319 |
|
} |
|
1320 |
|
break; |
|
1321 |
|
case COM_MAP: |
|
1322 |
|
break; |
|
1323 |
|
case COM_MARKS: |
|
1324 |
|
show_bookmarks_menu(view); |
|
1325 |
|
break; |
|
1326 |
|
case COM_MOVE: |
|
1327 |
|
{ |
|
1328 |
|
move_files(view); |
|
1329 |
|
load_dir_list(other_view, 1); |
|
1330 |
|
load_dir_list(curr_view, 1); |
|
1331 |
|
moveto_list_pos(view, view->list_pos); |
|
1332 |
|
} |
|
1333 |
|
break; |
|
1334 |
|
case COM_NMAP: |
|
1335 |
|
break; |
|
1336 |
|
case COM_NOH: |
|
1337 |
|
{ |
|
1338 |
|
if(view->selected_files) |
|
1339 |
|
{ |
|
1340 |
|
int y = 0; |
|
1341 |
|
for(y = 0; y < view->list_rows; y++) |
|
1342 |
|
{ |
|
1343 |
|
if(view->dir_entry[y].selected) |
|
1344 |
|
view->dir_entry[y].selected = 0; |
|
1345 |
|
} |
|
1346 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
1347 |
|
moveto_list_pos(view, view->list_pos); |
|
1348 |
|
} |
|
1349 |
|
} |
|
1350 |
|
break; |
|
1351 |
|
case COM_ONLY: |
|
1352 |
|
{ |
|
1353 |
|
if (curr_stats.number_of_windows) |
|
1354 |
|
curr_stats.number_of_windows = 2; |
|
1355 |
|
else |
|
1356 |
|
curr_stats.number_of_windows = 1; |
|
1357 |
|
|
|
1358 |
|
redraw_window(); |
|
1359 |
|
//my_system("screen -X eval \"only\""); |
|
1360 |
|
} |
|
1361 |
|
break; |
|
1362 |
|
case COM_PWD: |
|
1363 |
|
status_bar_message(view->curr_dir); |
|
1364 |
|
save_msg = 1; |
|
1365 |
|
break; |
|
1366 |
|
case COM_X: |
|
1367 |
|
case COM_QUIT: |
|
1368 |
|
{ |
|
1369 |
|
if(cfg.vim_filter) |
|
1370 |
|
{ |
|
1371 |
|
char buf[256]; |
|
1372 |
|
FILE *fp; |
|
1373 |
|
|
|
1374 |
|
|
|
1375 |
|
snprintf(buf, sizeof(buf), "%s\\vimfiles", cfg.config_dir); |
|
1376 |
|
fp = fopen(buf, "w"); |
|
1377 |
|
endwin(); |
|
1378 |
|
fprintf(fp, "NULL"); |
|
1379 |
|
fclose(fp); |
|
1380 |
|
exit(0); |
|
1381 |
|
} |
|
1382 |
|
|
|
1383 |
|
write_config_file(); |
|
1384 |
|
|
|
1385 |
|
endwin(); |
|
1386 |
|
system("cls"); |
|
1387 |
|
exit(0); |
|
1388 |
|
} |
|
1389 |
|
break; |
|
1390 |
|
case COM_SORT: |
|
1391 |
|
show_sort_menu(view); |
|
1392 |
|
break; |
|
1393 |
|
case COM_SHELL: |
|
1394 |
|
shellout(NULL, 0); |
|
1395 |
|
break; |
|
1396 |
|
case COM_SYNC: |
|
1397 |
|
change_directory(other_view, view->curr_dir); |
|
1398 |
|
load_dir_list(other_view, 0); |
|
1399 |
|
break; |
|
1400 |
|
case COM_UNMAP: |
|
1401 |
|
break; |
|
1402 |
|
case COM_VIEW: |
|
1403 |
|
{ |
|
1404 |
|
if(curr_stats.number_of_windows == 1) |
|
1405 |
|
{ |
|
1406 |
|
show_error_msg("Cannot view files", |
|
1407 |
|
"Cannot view files in one window mode "); |
|
1408 |
|
break; |
|
1409 |
|
} |
|
1410 |
|
if(curr_stats.view) |
|
1411 |
|
{ |
|
1412 |
|
curr_stats.view = 0; |
|
1413 |
|
|
|
1414 |
|
wbkgdset(other_view->title, |
|
1415 |
|
COLOR_PAIR(BORDER_COLOR + other_view->color_scheme)); |
|
1416 |
|
wbkgdset(other_view->win, |
|
1417 |
|
COLOR_PAIR(WIN_COLOR + other_view->color_scheme)); |
|
1418 |
|
change_directory(other_view, other_view->curr_dir); |
|
1419 |
|
load_dir_list(other_view, 0); |
|
1420 |
|
change_directory(curr_view, curr_view->curr_dir); |
|
1421 |
|
load_dir_list(curr_view, 0); |
|
1422 |
|
moveto_list_pos(curr_view, curr_view->list_pos); |
|
1423 |
|
} |
|
1424 |
|
else |
|
1425 |
|
{ |
|
1426 |
|
curr_stats.view = 1; |
|
1427 |
|
quick_view_file(view); |
|
1428 |
|
} |
|
1429 |
|
} |
|
1430 |
|
break; |
|
1431 |
|
case COM_VIFM: |
|
1432 |
|
show_error_msg(" I haven't gotten here yet ", |
|
1433 |
|
"Sorry this is not implemented "); |
|
1434 |
|
break; |
|
1435 |
|
case COM_YANK: |
|
1436 |
|
{ |
|
1437 |
|
/* |
|
1438 |
|
int selection_worked = 0; |
|
1439 |
|
|
|
1440 |
|
selection_worked = select_files_in_range(view); |
|
1441 |
|
|
|
1442 |
|
if (selection_worked) |
|
1443 |
|
yank_selected_files(view); |
|
1444 |
|
*/ |
|
1445 |
|
show_error_msg(":yank is not implemented yet", |
|
1446 |
|
":yank is not implemented yet "); |
|
1447 |
|
} |
|
1448 |
|
break; |
|
1449 |
|
case COM_VMAP: |
|
1450 |
|
break; |
|
1451 |
|
case COM_VOLUME: |
|
1452 |
|
show_volume_menu(view); |
|
1453 |
|
break; |
|
1454 |
|
default: |
|
1455 |
|
{ |
|
1456 |
|
char buf[48]; |
|
1457 |
|
snprintf(buf, sizeof(buf), "Builtin is %d", cmd->builtin); |
|
1458 |
|
show_error_msg("Internal Error in Command.c", buf); |
|
1459 |
|
} |
|
1460 |
|
break; |
|
1461 |
|
} |
|
1462 |
|
|
|
1463 |
|
if (view->selected_files) |
|
1464 |
|
{ |
|
1465 |
|
int x; |
|
1466 |
|
for (x = 0; x < view->list_rows; x++) |
|
1467 |
|
view->dir_entry[x].selected = 0; |
|
1468 |
|
|
|
1469 |
|
} |
|
1470 |
|
|
|
1471 |
|
return save_msg; |
|
1472 |
|
} |
|
1473 |
|
|
|
1474 |
|
int |
|
1475 |
|
execute_user_command(FileView *view, cmd_t *cmd) |
|
1476 |
|
{ |
|
1477 |
|
char *expanded_com = NULL; |
|
1478 |
|
int use_menu = 0; |
|
1479 |
|
|
|
1480 |
|
if(strchr(command_list[cmd->is_user].action, '%') != NULL) |
|
1481 |
|
expanded_com = expand_macros(view, command_list[cmd->is_user].action, |
|
1482 |
|
cmd->args, &use_menu); |
|
1483 |
|
else |
|
1484 |
|
expanded_com = strdup(command_list[cmd->is_user].action); |
|
1485 |
|
|
|
1486 |
|
while(isspace(expanded_com[strlen(expanded_com) -1])) |
|
1487 |
|
expanded_com[strlen(expanded_com) -1] = '\0'; |
|
1488 |
|
|
|
1489 |
|
if(expanded_com[strlen(expanded_com)-1] == '&' |
|
1490 |
|
&& expanded_com[strlen(expanded_com) -2] == ' ') |
|
1491 |
|
{ |
|
1492 |
|
expanded_com[strlen(expanded_com)-1] = '\0'; |
|
1493 |
|
cmd->background = 1; |
|
1494 |
|
} |
|
1495 |
|
|
|
1496 |
|
if (use_menu) |
|
1497 |
|
{ |
|
1498 |
|
|
|
1499 |
|
show_user_menu(view, expanded_com); |
|
1500 |
|
|
|
1501 |
|
if(!cmd->background) |
|
1502 |
|
my_free(expanded_com); |
|
1503 |
|
|
|
1504 |
|
return 0; |
|
1505 |
|
} |
|
1506 |
|
|
|
1507 |
|
|
|
1508 |
|
if(!strncmp(expanded_com, "filter ", 7)) |
|
1509 |
|
{ |
|
1510 |
|
view->invert = 1; |
|
1511 |
|
view->filename_filter = (char *)realloc(view->filename_filter, |
|
1512 |
|
strlen(strchr(expanded_com, ' ')) +1); |
|
1513 |
|
snprintf(view->filename_filter, |
|
1514 |
|
strlen(strchr(expanded_com, ' ')) +1, "%s", |
|
1515 |
|
strchr(expanded_com, ' ') +1); |
|
1516 |
|
|
|
1517 |
|
load_dir_list(view, 1); |
|
1518 |
|
moveto_list_pos(view, 0); |
|
1519 |
|
} |
|
1520 |
|
else if(!strncmp(expanded_com, "!", 1)) |
|
1521 |
|
{ |
|
1522 |
|
char buf[strlen(expanded_com) + 1]; |
|
1523 |
|
char *tmp = strcpy(buf, expanded_com); |
|
1524 |
|
int pause = 0; |
|
1525 |
|
tmp++; |
|
1526 |
|
if(*tmp == '!') |
|
1527 |
|
{ |
|
1528 |
|
pause = 1; |
|
1529 |
|
tmp++; |
|
1530 |
|
} |
|
1531 |
|
while(isspace(*tmp)) |
|
1532 |
|
tmp++; |
|
1533 |
|
|
|
1534 |
|
if((strlen(tmp) > 0) && cmd->background) |
|
1535 |
|
start_background_job(tmp); |
|
1536 |
|
else if(strlen(tmp) > 0) |
|
1537 |
|
shellout(tmp, pause); |
|
1538 |
|
} |
|
1539 |
|
else if(!strncmp(expanded_com, "/", 1)) |
|
1540 |
|
{ |
|
1541 |
|
strncpy(view->regexp, expanded_com +1, sizeof(view->regexp)); |
|
1542 |
|
return find_pattern(view, view->regexp); |
|
1543 |
|
} |
|
1544 |
|
else if(cmd->background) |
|
1545 |
|
{ |
|
1546 |
|
char buf[strlen(expanded_com) + 1]; |
|
1547 |
|
char *tmp = strcpy(buf, expanded_com); |
|
1548 |
|
start_background_job(tmp); |
|
1549 |
|
} |
|
1550 |
|
else |
|
1551 |
|
shellout(expanded_com, 0); |
|
1552 |
|
|
|
1553 |
|
if(!cmd->background) |
|
1554 |
|
my_free(expanded_com); |
|
1555 |
|
|
|
1556 |
|
|
|
1557 |
|
if(view->selected_files) |
|
1558 |
|
{ |
|
1559 |
|
free_selected_file_array(view); |
|
1560 |
|
view->selected_files = 0; |
|
1561 |
|
load_dir_list(view, 1); |
|
1562 |
|
} |
|
1563 |
|
return 0; |
|
1564 |
|
} |
|
1565 |
|
|
|
1566 |
|
int |
|
1567 |
|
execute_command(FileView *view, char *command) |
|
1568 |
|
{ |
|
1569 |
|
cmd_t cmd; |
|
1570 |
|
int result; |
|
1571 |
|
|
|
1572 |
|
cmd.cmd_name = NULL; |
|
1573 |
|
cmd.args = NULL; |
|
1574 |
|
|
|
1575 |
|
result = parse_command(view, command, &cmd); |
|
1576 |
|
|
|
1577 |
|
/* !! command is already handled in parse_command() */ |
|
1578 |
|
if(result == 0) |
|
1579 |
|
return 0; |
|
1580 |
|
|
|
1581 |
|
/* Invalid command or range. */ |
|
1582 |
|
if(result < 0) |
|
1583 |
|
return 1; |
|
1584 |
|
|
|
1585 |
|
if(cmd.builtin > -1) |
|
1586 |
|
execute_builtin_command(view, &cmd); |
|
1587 |
|
else |
|
1588 |
|
execute_user_command(view, &cmd); |
|
1589 |
|
|
|
1590 |
|
my_free(cmd.cmd_name); |
|
1591 |
|
my_free(cmd.args); |
|
1592 |
|
|
|
1593 |
|
return 0; |
|
1594 |
|
} |
|
1595 |
|
|
|
1596 |
|
int |
|
1597 |
|
get_command(FileView *view, int type, void * ptr) |
|
1598 |
|
{ |
|
1599 |
|
char * command = my_rl_gets(type); |
|
1600 |
|
|
|
1601 |
|
if(command == NULL) |
|
1602 |
|
{ |
|
1603 |
|
if (type == GET_SEARCH_PATTERN || type == MAPPED_SEARCH) |
|
1604 |
|
return find_pattern(view, view->regexp); |
|
1605 |
|
else |
|
1606 |
|
return 1; |
|
1607 |
|
} |
|
1608 |
|
|
|
1609 |
|
if(type == GET_COMMAND || type == MAPPED_COMMAND |
|
1610 |
|
|| type == GET_VISUAL_COMMAND) |
|
1611 |
|
{ |
|
1612 |
|
save_command_history(command); |
|
1613 |
|
return execute_command(view, command); |
|
1614 |
|
} |
|
1615 |
|
else if(type == GET_SEARCH_PATTERN || type == MAPPED_SEARCH) |
|
1616 |
|
{ |
|
1617 |
|
strncpy(view->regexp, command, sizeof(view->regexp)); |
|
1618 |
|
save_search_history(command); |
|
1619 |
|
return find_pattern(view, command); |
|
1620 |
|
} |
|
1621 |
|
else if (type == MENU_SEARCH) |
|
1622 |
|
return search_menu_list(view, command, ptr); |
|
1623 |
|
/* |
|
1624 |
|
else if (type == MENU_COMMAND) |
|
1625 |
|
return execute_menu_command(view, command, ptr); |
|
1626 |
|
*/ |
|
1627 |
|
|
|
1628 |
|
return 0; |
|
1629 |
|
} |
|
1630 |
|
|
File src/config.c added (mode: 100644) (index 0000000..71e0aab) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#define CP_HELP "cp /usr/local/share/vifm/vifm-help.txt ~/.vifm" |
|
20 |
|
#define CP_RC "cp /usr/local/share/vifm/vifmrc ~/.vifm" |
|
21 |
|
|
|
22 |
|
#include<stdio.h> /* FILE */ |
|
23 |
|
#include<stdlib.h> /* getenv */ |
|
24 |
|
#include<unistd.h> /* chdir */ |
|
25 |
|
#include<sys/stat.h> /* mkdir */ |
|
26 |
|
#include<string.h> |
|
27 |
|
#include<ctype.h> /* isalnum */ |
|
28 |
|
|
|
29 |
|
#include"bookmarks.h" |
|
30 |
|
#include"color_scheme.h" |
|
31 |
|
#include"fileops.h" |
|
32 |
|
#include"filetype.h" |
|
33 |
|
#include"registers.h" |
|
34 |
|
#include"status.h" |
|
35 |
|
#include"commands.h" |
|
36 |
|
#include"config.h" |
|
37 |
|
#include"utils.h" |
|
38 |
|
|
|
39 |
|
#define MAX_LEN 1024 |
|
40 |
|
#define DEFAULT_FILENAME_FILTER "\\.o$" |
|
41 |
|
|
|
42 |
|
void |
|
43 |
|
init_config(void) |
|
44 |
|
{ |
|
45 |
|
int i; |
|
46 |
|
|
|
47 |
|
/* init bookmarks */ |
|
48 |
|
for (i = 0; i < NUM_BOOKMARKS; ++i) |
|
49 |
|
{ |
|
50 |
|
bookmarks[i].directory = NULL; |
|
51 |
|
bookmarks[i].file = NULL; |
|
52 |
|
} |
|
53 |
|
cfg.num_bookmarks = 0; |
|
54 |
|
for ( i = 0; i < NUM_REGISTERS; ++i) |
|
55 |
|
{ |
|
56 |
|
reg[i].name = valid_registers[i]; |
|
57 |
|
reg[i].num_files = 0; |
|
58 |
|
reg[i].files = NULL; |
|
59 |
|
reg[i].deleted = 0; |
|
60 |
|
} |
|
61 |
|
} |
|
62 |
|
|
|
63 |
|
|
|
64 |
|
/* |
|
65 |
|
static void |
|
66 |
|
create_help_file(void) |
|
67 |
|
{ |
|
68 |
|
char command[PATH_MAX]; |
|
69 |
|
|
|
70 |
|
snprintf(command, sizeof(command), CP_HELP); |
|
71 |
|
file_exec(command); |
|
72 |
|
} |
|
73 |
|
|
|
74 |
|
static void |
|
75 |
|
create_rc_file(void) |
|
76 |
|
{ |
|
77 |
|
char command[PATH_MAX]; |
|
78 |
|
|
|
79 |
|
snprintf(command, sizeof(command), CP_RC); |
|
80 |
|
file_exec(command); |
|
81 |
|
add_bookmark('H', getenv("HOME"), "../"); |
|
82 |
|
add_bookmark('z', cfg.config_dir, "../"); |
|
83 |
|
} |
|
84 |
|
*/ |
|
85 |
|
|
|
86 |
|
/* This is just a safety check so that vifm will still load and run if |
|
87 |
|
* the configuration file is not present. |
|
88 |
|
*/ |
|
89 |
|
static void |
|
90 |
|
load_default_configuration(void) |
|
91 |
|
{ |
|
92 |
|
cfg.use_trash = 1; |
|
93 |
|
cfg.vi_command = strdup("vim"); |
|
94 |
|
cfg.shell_cmd = strdup("cmd"); |
|
95 |
|
cfg.history_len = 15; |
|
96 |
|
cfg.use_vim_help = 0; |
|
97 |
|
strncpy(lwin.regexp, "\\..~$", sizeof(lwin.regexp) -1); |
|
98 |
|
|
|
99 |
|
lwin.filename_filter = (char *)realloc(lwin.filename_filter, |
|
100 |
|
strlen(DEFAULT_FILENAME_FILTER) +1); |
|
101 |
|
strcpy(lwin.filename_filter, DEFAULT_FILENAME_FILTER); |
|
102 |
|
lwin.prev_filter = (char *)realloc(lwin.prev_filter, |
|
103 |
|
strlen(DEFAULT_FILENAME_FILTER) +1); |
|
104 |
|
strcpy(lwin.prev_filter, DEFAULT_FILENAME_FILTER); |
|
105 |
|
|
|
106 |
|
lwin.invert = TRUE; |
|
107 |
|
strncpy(rwin.regexp, "\\..~$", sizeof(rwin.regexp) -1); |
|
108 |
|
|
|
109 |
|
rwin.filename_filter = (char *)realloc(rwin.filename_filter, |
|
110 |
|
strlen(DEFAULT_FILENAME_FILTER) +1); |
|
111 |
|
strcpy(rwin.filename_filter, DEFAULT_FILENAME_FILTER); |
|
112 |
|
rwin.prev_filter = (char *)realloc(rwin.prev_filter, |
|
113 |
|
strlen(DEFAULT_FILENAME_FILTER) +1); |
|
114 |
|
strcpy(rwin.prev_filter, DEFAULT_FILENAME_FILTER); |
|
115 |
|
|
|
116 |
|
rwin.invert = TRUE; |
|
117 |
|
lwin.sort_type = SORT_BY_NAME; |
|
118 |
|
rwin.sort_type = SORT_BY_NAME; |
|
119 |
|
|
|
120 |
|
read_color_scheme_file(); |
|
121 |
|
} |
|
122 |
|
|
|
123 |
|
void |
|
124 |
|
set_config_dir(void) |
|
125 |
|
{ |
|
126 |
|
// char *programfiles = getenv("ProgramFiles"); |
|
127 |
|
char *appfiles = getenv("APPDATA"); |
|
128 |
|
|
|
129 |
|
if(appfiles) |
|
130 |
|
{ |
|
131 |
|
char rc_file[PATH_MAX]; |
|
132 |
|
|
|
133 |
|
snprintf(rc_file, sizeof(rc_file), "%s\\Vifm\\vifmrc", |
|
134 |
|
appfiles); |
|
135 |
|
/* |
|
136 |
|
snprintf(help_file, sizeof(help_file), "%s/.vifm/vifm-help_txt", |
|
137 |
|
home_dir); |
|
138 |
|
*/ |
|
139 |
|
snprintf(cfg.config_dir, sizeof(cfg.config_dir), |
|
140 |
|
"%s\\Vifm", |
|
141 |
|
appfiles); |
|
142 |
|
snprintf(cfg.trash_dir, sizeof(cfg.trash_dir), "%s\\Vifm\\Trash", |
|
143 |
|
appfiles); |
|
144 |
|
|
|
145 |
|
if(chdir(cfg.config_dir)) |
|
146 |
|
{ |
|
147 |
|
if(mkdir(cfg.config_dir)) |
|
148 |
|
return; |
|
149 |
|
if(mkdir(cfg.trash_dir)) |
|
150 |
|
return; |
|
151 |
|
} |
|
152 |
|
} |
|
153 |
|
|
|
154 |
|
|
|
155 |
|
/* |
|
156 |
|
if(programfiles) |
|
157 |
|
{ |
|
158 |
|
//char help_file[PATH_MAX]; |
|
159 |
|
char rc_file[PATH_MAX]; |
|
160 |
|
|
|
161 |
|
snprintf(rc_file, sizeof(rc_file), "%s\\Vifm\\vifmrc", |
|
162 |
|
programfiles); |
|
163 |
|
snprintf(help_file, sizeof(help_file), "%s/.vifm/vifm-help_txt", |
|
164 |
|
home_dir); |
|
165 |
|
snprintf(cfg.config_dir, sizeof(cfg.config_dir), |
|
166 |
|
"%s\\Vifm", |
|
167 |
|
programfiles); |
|
168 |
|
snprintf(cfg.trash_dir, sizeof(cfg.trash_dir), "%s\\Vifm\\Trash", |
|
169 |
|
programfiles); |
|
170 |
|
|
|
171 |
|
if(chdir(cfg.config_dir)) |
|
172 |
|
{ |
|
173 |
|
if(mkdir(cfg.config_dir)) |
|
174 |
|
return; |
|
175 |
|
if(mkdir(cfg.trash_dir)) |
|
176 |
|
return; |
|
177 |
|
//if((f = fopen(helpfile, "r")) == NULL) |
|
178 |
|
// create_help_file(); |
|
179 |
|
//if((f = fopen(rc_file, "r")) == NULL) |
|
180 |
|
// create_rc_file(); |
|
181 |
|
} |
|
182 |
|
|
|
183 |
|
} |
|
184 |
|
*/ |
|
185 |
|
} |
|
186 |
|
|
|
187 |
|
|
|
188 |
|
int |
|
189 |
|
read_config_file(void) |
|
190 |
|
{ |
|
191 |
|
FILE *fp; |
|
192 |
|
char config_file[PATH_MAX]; |
|
193 |
|
char line[MAX_LEN]; |
|
194 |
|
char *s1 = NULL; |
|
195 |
|
char *s2 = NULL; |
|
196 |
|
char *s3 = NULL; |
|
197 |
|
char *sx = NULL; |
|
198 |
|
int args; |
|
199 |
|
|
|
200 |
|
|
|
201 |
|
snprintf(config_file, sizeof(config_file), "%s\\vifmrc", cfg.config_dir); |
|
202 |
|
|
|
203 |
|
if((fp = fopen(config_file, "r")) == NULL) |
|
204 |
|
{ |
|
205 |
|
fprintf(stdout, "Unable to find configuration file.\n Using defaults."); |
|
206 |
|
load_default_configuration(); |
|
207 |
|
return 0; |
|
208 |
|
} |
|
209 |
|
|
|
210 |
|
while(fgets(line, MAX_LEN, fp)) |
|
211 |
|
{ |
|
212 |
|
args = 0; |
|
213 |
|
if(line[0] == '#') |
|
214 |
|
continue; |
|
215 |
|
|
|
216 |
|
if((sx = s1 = strchr(line, '=')) != NULL) |
|
217 |
|
{ |
|
218 |
|
s1++; |
|
219 |
|
chomp(s1); |
|
220 |
|
*sx = '\0'; |
|
221 |
|
args = 1; |
|
222 |
|
} |
|
223 |
|
else |
|
224 |
|
continue; |
|
225 |
|
if((sx = s2 = strchr(s1, '=')) != NULL) |
|
226 |
|
{ |
|
227 |
|
s2++; |
|
228 |
|
chomp(s2); |
|
229 |
|
*sx = '\0'; |
|
230 |
|
args = 2; |
|
231 |
|
} |
|
232 |
|
/* COMMAND is handled here so that the command can have an '=' */ |
|
233 |
|
if(!strcmp(line, "COMMAND")) |
|
234 |
|
add_command(s1, s2); |
|
235 |
|
else if((args == 2) && ((sx = s3 = strchr(s2, '=')) != NULL)) |
|
236 |
|
{ |
|
237 |
|
s3++; |
|
238 |
|
chomp(s3); |
|
239 |
|
*sx = '\0'; |
|
240 |
|
args = 3; |
|
241 |
|
} |
|
242 |
|
if(args == 1) |
|
243 |
|
{ |
|
244 |
|
if(!strcmp(line, "VI_COMMAND")) |
|
245 |
|
{ |
|
246 |
|
if(cfg.vi_command != NULL) |
|
247 |
|
free(cfg.vi_command); |
|
248 |
|
|
|
249 |
|
cfg.vi_command = strdup(s1); |
|
250 |
|
continue; |
|
251 |
|
} |
|
252 |
|
if(!strcmp(line, "SHELL_COMMAND")) |
|
253 |
|
{ |
|
254 |
|
if(cfg.shell_cmd != NULL) |
|
255 |
|
free(cfg.shell_cmd); |
|
256 |
|
|
|
257 |
|
cfg.shell_cmd = strdup(s1); |
|
258 |
|
continue; |
|
259 |
|
} |
|
260 |
|
if(!strcmp(line, "USE_TRASH")) |
|
261 |
|
{ |
|
262 |
|
cfg.use_trash = atoi(s1); |
|
263 |
|
continue; |
|
264 |
|
} |
|
265 |
|
if(!strcmp(line, "USE_ONE_WINDOW")) |
|
266 |
|
{ |
|
267 |
|
cfg.show_one_window = atoi(s1); |
|
268 |
|
continue; |
|
269 |
|
} |
|
270 |
|
if(!strcmp(line, "HISTORY_LENGTH")) |
|
271 |
|
{ |
|
272 |
|
cfg.history_len = atoi(s1); |
|
273 |
|
continue; |
|
274 |
|
} |
|
275 |
|
if(!strcmp(line, "LEFT_WINDOW_SORT_TYPE")) |
|
276 |
|
{ |
|
277 |
|
lwin.sort_type = atoi(s1); |
|
278 |
|
continue; |
|
279 |
|
} |
|
280 |
|
if(!strcmp(line, "RIGHT_WINDOW_SORT_TYPE")) |
|
281 |
|
{ |
|
282 |
|
rwin.sort_type = atoi(s1); |
|
283 |
|
continue; |
|
284 |
|
} |
|
285 |
|
if(!strcmp(line, "LWIN_FILTER")) |
|
286 |
|
{ |
|
287 |
|
lwin.filename_filter = strdup(s1); |
|
288 |
|
lwin.prev_filter = strdup(s1); |
|
289 |
|
/* |
|
290 |
|
lwin.filename_filter = (char *)realloc(lwin.filename_filter, |
|
291 |
|
strlen(s1) +1); |
|
292 |
|
strncpy(lwin.filename_filter, s1, strlen(s1)); |
|
293 |
|
lwin.prev_filter = (char *)realloc(lwin.prev_filter, |
|
294 |
|
strlen(s1) +1); |
|
295 |
|
strncpy(lwin.prev_filter, s1, strlen(s1)); |
|
296 |
|
*/ |
|
297 |
|
continue; |
|
298 |
|
} |
|
299 |
|
if(!strcmp(line, "LWIN_INVERT")) |
|
300 |
|
{ |
|
301 |
|
lwin.invert = atoi(s1); |
|
302 |
|
continue; |
|
303 |
|
} |
|
304 |
|
if(!strcmp(line, "RWIN_FILTER")) |
|
305 |
|
{ |
|
306 |
|
rwin.filename_filter = strdup(s1); |
|
307 |
|
rwin.prev_filter = strdup(s1); |
|
308 |
|
/* |
|
309 |
|
rwin.filename_filter = (char *)realloc(rwin.filename_filter, |
|
310 |
|
strlen(s1) +1); |
|
311 |
|
strncpy(rwin.filename_filter, s1, strlen(s1)); |
|
312 |
|
rwin.prev_filter = (char *)realloc(rwin.prev_filter, |
|
313 |
|
strlen(s1) +1); |
|
314 |
|
strncpy(rwin.prev_filter, s1, strlen(s1)); |
|
315 |
|
*/ |
|
316 |
|
continue; |
|
317 |
|
} |
|
318 |
|
if(!strcmp(line, "RWIN_INVERT")) |
|
319 |
|
{ |
|
320 |
|
rwin.invert = atoi(s1); |
|
321 |
|
continue; |
|
322 |
|
} |
|
323 |
|
if(!strcmp(line, "USE_VIM_HELP")) |
|
324 |
|
{ |
|
325 |
|
cfg.use_vim_help = atoi(s1); |
|
326 |
|
continue; |
|
327 |
|
} |
|
328 |
|
if(!strcmp(line, "RUN_EXECUTABLE")) |
|
329 |
|
{ |
|
330 |
|
cfg.auto_execute = atoi(s1); |
|
331 |
|
continue; |
|
332 |
|
} |
|
333 |
|
} |
|
334 |
|
if(args == 3) |
|
335 |
|
{ |
|
336 |
|
if(!strcmp(line, "FILETYPE")) |
|
337 |
|
{ |
|
338 |
|
add_filetype(s1, s2, s3); |
|
339 |
|
continue; |
|
340 |
|
} |
|
341 |
|
if(!strcmp(line, "BOOKMARKS")) |
|
342 |
|
{ |
|
343 |
|
if(isalnum(*s1)) |
|
344 |
|
add_bookmark(*s1, s2, s3); |
|
345 |
|
continue; |
|
346 |
|
} |
|
347 |
|
} |
|
348 |
|
} |
|
349 |
|
|
|
350 |
|
fclose(fp); |
|
351 |
|
|
|
352 |
|
read_color_scheme_file(); |
|
353 |
|
|
|
354 |
|
return 1; |
|
355 |
|
} |
|
356 |
|
|
|
357 |
|
void |
|
358 |
|
write_config_file(void) |
|
359 |
|
{ |
|
360 |
|
FILE *fp; |
|
361 |
|
int x; |
|
362 |
|
char config_file[PATH_MAX]; |
|
363 |
|
curr_stats.getting_input = 1; |
|
364 |
|
|
|
365 |
|
snprintf(config_file, sizeof(config_file), "%s\\vifmrc", cfg.config_dir); |
|
366 |
|
|
|
367 |
|
if((fp = fopen(config_file, "w")) == NULL) |
|
368 |
|
return; |
|
369 |
|
|
|
370 |
|
fprintf(fp, "# You can edit this file by hand.\n"); |
|
371 |
|
fprintf(fp, "# The # character at the beginning of a line comments out the line.\n"); |
|
372 |
|
fprintf(fp, "# Blank lines are ignored.\n"); |
|
373 |
|
fprintf(fp, "# The basic format for each item is shown with an example.\n"); |
|
374 |
|
fprintf(fp, |
|
375 |
|
"# The '=' character is used to separate fields within a single line.\n"); |
|
376 |
|
fprintf(fp, "# Most settings are true = 1 or false = 0.\n"); |
|
377 |
|
|
|
378 |
|
fprintf(fp, "\n# This is the actual command used to start vi. The default is vi.\n"); |
|
379 |
|
fprintf(fp, |
|
380 |
|
"# If you would like to use another vi clone such as Vim, Elvis, or Vile\n"); |
|
381 |
|
fprintf(fp, "# you will need to change this setting.\n"); |
|
382 |
|
fprintf(fp, "\nVI_COMMAND=%s", cfg.vi_command); |
|
383 |
|
fprintf(fp, "\n# VI_COMMAND=vim"); |
|
384 |
|
fprintf(fp, "\n# VI_COMMAND=elvis -G termcap"); |
|
385 |
|
fprintf(fp, "\n# VI_COMMAND=vile"); |
|
386 |
|
fprintf(fp, "\n"); |
|
387 |
|
fprintf(fp, "\n#If you would like to use PowerShell instead of cmd.exe,"); |
|
388 |
|
fprintf(fp, "\n#change SHELL_COMMAND=cmd to SHELL_COMMAND=powershell\n"); |
|
389 |
|
fprintf(fp, "\nSHELL_COMMAND=%s", cfg.shell_cmd); |
|
390 |
|
|
|
391 |
|
fprintf(fp, "\n"); |
|
392 |
|
|
|
393 |
|
fprintf(fp, "\n# Trash Directory\n"); |
|
394 |
|
fprintf(fp, "# The default is to move files that are deleted with dd or :d to\n"); |
|
395 |
|
fprintf(fp, "# the trash directory. 1 means use the trash directory 0 means\n"); |
|
396 |
|
fprintf(fp, "# just use rm. If you change this you will not be able to move\n"); |
|
397 |
|
fprintf(fp, "# files by deleting them and then using p to put the file in the new location.\n"); |
|
398 |
|
fprintf(fp, "# I recommend not changing this until you are familiar with vifm.\n"); |
|
399 |
|
fprintf(fp, "# This probably shouldn't be an option.\n"); |
|
400 |
|
fprintf(fp, "\nUSE_TRASH=%d\n", cfg.use_trash); |
|
401 |
|
|
|
402 |
|
fprintf(fp, "\n# Show only one Window\n"); |
|
403 |
|
fprintf(fp, "# If you would like to start vifm with only one window set this to 1\n"); |
|
404 |
|
fprintf(fp, "\nUSE_ONE_WINDOW=%d\n", curr_stats.number_of_windows == 1 ? 1 : 0); |
|
405 |
|
|
|
406 |
|
fprintf(fp, "\n# 1 means use color if the terminal supports it.\n"); |
|
407 |
|
fprintf(fp, "# 0 means don't use color even if supported.\n"); |
|
408 |
|
|
|
409 |
|
fprintf(fp, "\n# This is how many files to show in the directory history menu.\n"); |
|
410 |
|
fprintf(fp, "\nHISTORY_LENGTH=%d\n", cfg.history_len); |
|
411 |
|
|
|
412 |
|
fprintf(fp, "\n# The sort type is how the files will be sorted in the file listing.\n"); |
|
413 |
|
fprintf(fp, "# Sort by File Extension = 0\n"); |
|
414 |
|
fprintf(fp, "# Sort by File Name = 1\n"); |
|
415 |
|
fprintf(fp, "# Sort by Group ID = 2\n"); |
|
416 |
|
fprintf(fp, "# Sort by Group Name = 3\n"); |
|
417 |
|
fprintf(fp, "# Sort by Mode = 4\n"); |
|
418 |
|
fprintf(fp, "# Sort by Owner ID = 5\n"); |
|
419 |
|
fprintf(fp, "# Sort by Owner Name = 6\n"); |
|
420 |
|
fprintf(fp, "# Sort by Size = 7\n"); |
|
421 |
|
fprintf(fp, "# Sort by Time Accessed =8\n"); |
|
422 |
|
fprintf(fp, "# Sort by Time Changed =9\n"); |
|
423 |
|
fprintf(fp, "# Sort by Time Modified =10\n"); |
|
424 |
|
fprintf(fp, "# This can be set with the :sort command in vifm.\n"); |
|
425 |
|
fprintf(fp, "\nLEFT_WINDOW_SORT_TYPE=%d\n", lwin.sort_type); |
|
426 |
|
fprintf(fp, "\nRIGHT_WINDOW_SORT_TYPE=%d\n", rwin.sort_type); |
|
427 |
|
|
|
428 |
|
fprintf(fp, "\n# The regular expression used to filter files out of\n"); |
|
429 |
|
fprintf(fp, "# the directory listings.\n"); |
|
430 |
|
fprintf(fp, "# LWIN_FILTER=\\.o$ and LWIN_INVERT=1 would filter out all\n"); |
|
431 |
|
fprintf(fp, "# of the .o files from the directory listing. LWIN_INVERT=0\n"); |
|
432 |
|
fprintf(fp, "# would show only the .o files\n"); |
|
433 |
|
fprintf(fp, "\nLWIN_FILTER=%s\n", lwin.filename_filter); |
|
434 |
|
fprintf(fp, "LWIN_INVERT=%d\n", lwin.invert); |
|
435 |
|
fprintf(fp, "RWIN_FILTER=%s\n", rwin.filename_filter); |
|
436 |
|
fprintf(fp, "RWIN_INVERT=%d\n", rwin.invert); |
|
437 |
|
|
|
438 |
|
fprintf(fp, "\n# If you installed the vim.txt help file change this to 1.\n"); |
|
439 |
|
fprintf(fp, "# If would rather use a plain text help file set this to 0.\n"); |
|
440 |
|
fprintf(fp, "\nUSE_VIM_HELP=%d\n", cfg.use_vim_help); |
|
441 |
|
|
|
442 |
|
fprintf(fp, "\n# If you would like to run an executable file when you \n"); |
|
443 |
|
fprintf(fp, "# press return on the file name set this to 1.\n"); |
|
444 |
|
fprintf(fp, "\nRUN_EXECUTABLE=%d\n", cfg.auto_execute); |
|
445 |
|
|
|
446 |
|
fprintf(fp, "\n# BOOKMARKS=mark=/full/directory/path=filename\n\n"); |
|
447 |
|
for(x = 0; x < NUM_BOOKMARKS; x++) |
|
448 |
|
{ |
|
449 |
|
if (is_bookmark(x)) |
|
450 |
|
{ |
|
451 |
|
fprintf(fp, "BOOKMARKS=%c=%s=%s\n", |
|
452 |
|
index2mark(x), |
|
453 |
|
bookmarks[x].directory, bookmarks[x].file); |
|
454 |
|
} |
|
455 |
|
} |
|
456 |
|
|
|
457 |
|
fprintf(fp, "\n# COMMAND=command_name=action\n"); |
|
458 |
|
fprintf(fp, "# The following macros can be used in a command\n"); |
|
459 |
|
fprintf(fp, "# %%a is replaced with the user arguments.\n"); |
|
460 |
|
fprintf(fp, "# %%f the current selected file, or files.\n"); |
|
461 |
|
fprintf(fp, "# %%F the current selected file, or files in the other directoy.\n"); |
|
462 |
|
fprintf(fp, "# %%d the current directory name.\n"); |
|
463 |
|
fprintf(fp, "# %%D the other window directory name.\n"); |
|
464 |
|
fprintf(fp, "# %%m run the command in a menu window\n\n"); |
|
465 |
|
for(x = 0; x < cfg.command_num; x++) |
|
466 |
|
{ |
|
467 |
|
fprintf(fp, "COMMAND=%s=%s\n", command_list[x].name, |
|
468 |
|
command_list[x].action); |
|
469 |
|
} |
|
470 |
|
|
|
471 |
|
fprintf(fp, "\n# The file type is for the default programs to be used with\n"); |
|
472 |
|
fprintf(fp, "# a file extension. \n"); |
|
473 |
|
fprintf(fp, "# FILETYPE=description=extension1,extension2=defaultprogram, program2\n"); |
|
474 |
|
fprintf(fp, "# FILETYPE=Web=html,htm,shtml=links,mozilla,elvis\n"); |
|
475 |
|
fprintf(fp, "# would set links as the default program for .html .htm .shtml files\n"); |
|
476 |
|
fprintf(fp, "# The other programs for the file type can be accessed with the :file command\n"); |
|
477 |
|
fprintf(fp, "# The command macros %%f, %%F, %%d, %%F may be used in the commands.\n"); |
|
478 |
|
fprintf(fp, "# The %%a macro is ignored. To use a %% you must put %%%%.\n\n"); |
|
479 |
|
for(x = 0; x < cfg.filetypes_num; x++) |
|
480 |
|
{ |
|
481 |
|
fprintf(fp, "FILETYPE=%s=%s=%s\n", filetypes[x].type, filetypes[x].ext, filetypes[x].programs); |
|
482 |
|
} |
|
483 |
|
|
|
484 |
|
fclose(fp); |
|
485 |
|
|
|
486 |
|
write_color_scheme_file(); |
|
487 |
|
|
|
488 |
|
curr_stats.getting_input = 0; |
|
489 |
|
} |
File src/file_info.c added (mode: 100644) (index 0000000..b7f7f7e) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#include<stdio.h> |
|
20 |
|
//#include<sys/time.h> |
|
21 |
|
#include<time.h> |
|
22 |
|
#include <unistd.h> |
|
23 |
|
#include<stdlib.h> |
|
24 |
|
#include<signal.h> |
|
25 |
|
#include<string.h> |
|
26 |
|
#include<sys/stat.h> |
|
27 |
|
|
|
28 |
|
#include "config.h" |
|
29 |
|
#include "filelist.h" |
|
30 |
|
#include "ui.h" |
|
31 |
|
#include "utils.h" |
|
32 |
|
#include "menus.h" |
|
33 |
|
#include "status.h" |
|
34 |
|
|
|
35 |
|
|
|
36 |
|
void |
|
37 |
|
describe_file_size (char* buf, int buf_size, FileView *view) |
|
38 |
|
{ |
|
39 |
|
if (view->dir_entry[view->list_pos].size < 10240) /* less than 10K */ |
|
40 |
|
{ |
|
41 |
|
snprintf (buf, buf_size, "%5d bytes", |
|
42 |
|
(int) view->dir_entry[view->list_pos].size); |
|
43 |
|
} |
|
44 |
|
else if (view->dir_entry[view->list_pos].size < 1048576)/*less than a meg */ |
|
45 |
|
{ |
|
46 |
|
snprintf (buf, buf_size, "%5.2f Kbytes", |
|
47 |
|
((float) view->dir_entry[view->list_pos].size / 1024.0)); |
|
48 |
|
} |
|
49 |
|
else /* more than a meg */ |
|
50 |
|
{ |
|
51 |
|
snprintf (buf, buf_size, "%5.2f Mbytes", |
|
52 |
|
((float) view->dir_entry[view->list_pos].size / 1048576.0)); |
|
53 |
|
} |
|
54 |
|
} |
|
55 |
|
|
|
56 |
|
void |
|
57 |
|
get_perm_string (char * buf, int len, mode_t mode) |
|
58 |
|
{ |
|
59 |
|
/* |
|
60 |
|
char *perm_sets[] = |
|
61 |
|
{ "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" }; |
|
62 |
|
int u, g, o; |
|
63 |
|
|
|
64 |
|
u = (mode & S_IRWXU) >> 6; |
|
65 |
|
g = (mode & S_IRWXG) >> 3; |
|
66 |
|
o = (mode & S_IRWXO); |
|
67 |
|
|
|
68 |
|
snprintf (buf, len, "-%s%s%s", perm_sets[u], perm_sets[g], perm_sets[o]); |
|
69 |
|
|
|
70 |
|
if (S_ISLNK (mode)) |
|
71 |
|
buf[0] = 'l'; |
|
72 |
|
else if (S_ISDIR (mode)) |
|
73 |
|
buf[0] = 'd'; |
|
74 |
|
else if (S_ISBLK (mode)) |
|
75 |
|
buf[0] = 'b'; |
|
76 |
|
else if (S_ISCHR (mode)) |
|
77 |
|
buf[0] = 'c'; |
|
78 |
|
else if (S_ISFIFO (mode)) |
|
79 |
|
buf[0] = 'f'; |
|
80 |
|
else if (S_ISSOCK (mode)) |
|
81 |
|
buf[0] = 's'; |
|
82 |
|
|
|
83 |
|
if (mode & S_ISVTX) |
|
84 |
|
buf[9] = (buf[9] == '-') ? 'T' : 't'; |
|
85 |
|
if (mode & S_ISGID) |
|
86 |
|
buf[6] = (buf[6] == '-') ? 'S' : 's'; |
|
87 |
|
if (mode & S_ISUID) |
|
88 |
|
buf[3] = (buf[3] == '-') ? 'S' : 's'; |
|
89 |
|
*/ |
|
90 |
|
} |
|
91 |
|
|
|
92 |
|
void |
|
93 |
|
show_full_file_properties(FileView *view) |
|
94 |
|
{ |
|
95 |
|
char name_buf[PATH_MAX]; |
|
96 |
|
// char perm_buf[26]; |
|
97 |
|
char size_buf[56]; |
|
98 |
|
// char uid_buf[26]; |
|
99 |
|
char buf[256]; |
|
100 |
|
//struct passwd *pwd_buf; |
|
101 |
|
//struct group *grp_buf; |
|
102 |
|
struct tm *tm_ptr; |
|
103 |
|
int x, y; |
|
104 |
|
int key = 0; |
|
105 |
|
int done = 0; |
|
106 |
|
|
|
107 |
|
|
|
108 |
|
curr_stats.show_full = 0; |
|
109 |
|
|
|
110 |
|
setup_menu(view); |
|
111 |
|
|
|
112 |
|
getmaxyx(menu_win, y, x); |
|
113 |
|
werase(menu_win); |
|
114 |
|
|
|
115 |
|
snprintf(name_buf, sizeof(name_buf), "%s", |
|
116 |
|
view->dir_entry[view->list_pos].name); |
|
117 |
|
|
|
118 |
|
describe_file_size(size_buf, sizeof(size_buf), view); |
|
119 |
|
|
|
120 |
|
|
|
121 |
|
mvwaddstr(menu_win, 2, 2, "File: "); |
|
122 |
|
mvwaddnstr(menu_win, 2, 8, name_buf, x - 8); |
|
123 |
|
mvwaddstr(menu_win, 4, 2, "Size: "); |
|
124 |
|
mvwaddstr(menu_win, 4, 8, size_buf); |
|
125 |
|
|
|
126 |
|
/* |
|
127 |
|
mvwaddstr(menu_win, 6, 2, "Type: "); |
|
128 |
|
if(S_ISLNK(view->dir_entry[view->list_pos].mode)) |
|
129 |
|
{ |
|
130 |
|
char linkto[PATH_MAX +NAME_MAX]; |
|
131 |
|
int len; |
|
132 |
|
char *filename = strdup(view->dir_entry[view->list_pos].name); |
|
133 |
|
len = strlen(filename); |
|
134 |
|
if (filename[len - 1] == '/') |
|
135 |
|
filename[len - 1] = '\0'; |
|
136 |
|
|
|
137 |
|
mvwaddstr(menu_win, 6, 8, "Link"); |
|
138 |
|
len = readlink (filename, linkto, sizeof (linkto)); |
|
139 |
|
|
|
140 |
|
mvwaddstr(menu_win, 7, 2, "Link To: "); |
|
141 |
|
if (len > 0) |
|
142 |
|
{ |
|
143 |
|
linkto[len] = '\0'; |
|
144 |
|
mvwaddnstr(menu_win, 7, 11, linkto, x - 11); |
|
145 |
|
} |
|
146 |
|
else |
|
147 |
|
mvwaddstr(menu_win, 7, 11, "Couldn't Resolve Link"); |
|
148 |
|
} |
|
149 |
|
else if (S_ISREG (view->dir_entry[view->list_pos].mode)) |
|
150 |
|
{ |
|
151 |
|
FILE *pipe; |
|
152 |
|
char command[1024]; |
|
153 |
|
char buf[NAME_MAX]; |
|
154 |
|
*/ |
|
155 |
|
|
|
156 |
|
/* Use the file command to get file information */ |
|
157 |
|
/* |
|
158 |
|
snprintf(command, sizeof(command), "file \"%s\" -b", |
|
159 |
|
view->dir_entry[view->list_pos].name); |
|
160 |
|
|
|
161 |
|
if ((pipe = popen(command, "r")) == NULL) |
|
162 |
|
{ |
|
163 |
|
mvwaddstr(menu_win, 6, 8, "Unable to open pipe to read file"); |
|
164 |
|
return; |
|
165 |
|
} |
|
166 |
|
|
|
167 |
|
fgets(buf, sizeof(buf), pipe); |
|
168 |
|
|
|
169 |
|
pclose(pipe); |
|
170 |
|
|
|
171 |
|
mvwaddnstr(menu_win, 6, 8, buf, x - 9); |
|
172 |
|
*/ |
|
173 |
|
/* |
|
174 |
|
if((S_IXUSR &view->dir_entry[view->list_pos].mode) |
|
175 |
|
|| (S_IXGRP &view->dir_entry[view->list_pos].mode) |
|
176 |
|
|| (S_IXOTH &view->dir_entry[view->list_pos].mode)) |
|
177 |
|
|
|
178 |
|
mvwaddstr(other_view->win, 6, 8, "Executable"); |
|
179 |
|
else |
|
180 |
|
mvwaddstr(other_view->win, 6, 8, "Regular File"); |
|
181 |
|
} |
|
182 |
|
if (S_ISDIR (view->dir_entry[view->list_pos].mode)) |
|
183 |
|
{ |
|
184 |
|
mvwaddstr(menu_win, 6, 8, "Directory"); |
|
185 |
|
} |
|
186 |
|
else if (S_ISCHR (view->dir_entry[view->list_pos].mode)) |
|
187 |
|
{ |
|
188 |
|
mvwaddstr(menu_win, 6, 8, "Character Device"); |
|
189 |
|
} |
|
190 |
|
else if (S_ISBLK (view->dir_entry[view->list_pos].mode)) |
|
191 |
|
{ |
|
192 |
|
mvwaddstr(menu_win, 6, 8, "Block Device"); |
|
193 |
|
} |
|
194 |
|
else if (S_ISFIFO (view->dir_entry[view->list_pos].mode)) |
|
195 |
|
{ |
|
196 |
|
mvwaddstr(menu_win, 6, 8, "Fifo Pipe"); |
|
197 |
|
} |
|
198 |
|
else if (S_ISSOCK (view->dir_entry[view->list_pos].mode)) |
|
199 |
|
{ |
|
200 |
|
mvwaddstr(menu_win, 6, 8, "Socket"); |
|
201 |
|
} |
|
202 |
|
else |
|
203 |
|
{ |
|
204 |
|
mvwaddstr(menu_win, 6, 8, "Unknown"); |
|
205 |
|
} |
|
206 |
|
*/ |
|
207 |
|
|
|
208 |
|
// mvwaddstr(menu_win, 8, 2, "Permissions: "); |
|
209 |
|
// mvwaddstr(menu_win, 8, 15, perm_buf); |
|
210 |
|
mvwaddstr(menu_win, 10, 2, "Modified: "); |
|
211 |
|
tm_ptr = localtime(&view->dir_entry[view->list_pos].mtime); |
|
212 |
|
strftime (buf, sizeof (buf), "%a %b %d %I:%M %p", tm_ptr); |
|
213 |
|
mvwaddstr(menu_win, 10, 13, buf); |
|
214 |
|
mvwaddstr(menu_win, 12, 2, "Accessed: "); |
|
215 |
|
tm_ptr = localtime(&view->dir_entry[view->list_pos].atime); |
|
216 |
|
strftime (buf, sizeof (buf), "%a %b %d %I:%M %p", tm_ptr); |
|
217 |
|
mvwaddstr(menu_win, 12, 13, buf); |
|
218 |
|
mvwaddstr(menu_win, 14, 2, "Changed: "); |
|
219 |
|
tm_ptr = localtime(&view->dir_entry[view->list_pos].ctime); |
|
220 |
|
strftime (buf, sizeof (buf), "%a %b %d %I:%M %p", tm_ptr); |
|
221 |
|
mvwaddstr(menu_win, 14, 13, buf); |
|
222 |
|
//mvwaddstr(menu_win, 16, 2, "Owner: "); |
|
223 |
|
//mvwaddstr(menu_win, 16, 10, uid_buf); |
|
224 |
|
//mvwaddstr(menu_win, 18, 2, "Group: "); |
|
225 |
|
/* |
|
226 |
|
if((grp_buf = getgrgid(view->dir_entry[view->list_pos].gid)) != NULL) |
|
227 |
|
{ |
|
228 |
|
mvwaddstr(menu_win, 18, 10, grp_buf->gr_name); |
|
229 |
|
} |
|
230 |
|
*/ |
|
231 |
|
wnoutrefresh(menu_win); |
|
232 |
|
|
|
233 |
|
box(menu_win, 0, 0); |
|
234 |
|
wrefresh(menu_win); |
|
235 |
|
while(!done) |
|
236 |
|
{ |
|
237 |
|
key = wgetch(menu_win); |
|
238 |
|
|
|
239 |
|
/* ascii Return - Ctrl-c - Escape */ |
|
240 |
|
if(key == 13 || key == 3 || key == 27) |
|
241 |
|
done = 1; |
|
242 |
|
} |
|
243 |
|
werase(menu_win); |
|
244 |
|
curr_stats.menu = 0; |
|
245 |
|
redraw_window(); |
|
246 |
|
} |
|
247 |
|
|
|
248 |
|
|
File src/filelist.c added (mode: 100644) (index 0000000..df9b0d0) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#if(defined(BSD) && (BSD>=199103)) |
|
20 |
|
#include<sys/types.h> /* required for regex.h on FreeBSD 4.2 */ |
|
21 |
|
#endif |
|
22 |
|
|
|
23 |
|
#include<curses.h> |
|
24 |
|
#include<unistd.h> /* chdir() */ |
|
25 |
|
#include<stdlib.h> /* malloc qsort */ |
|
26 |
|
#include<sys/stat.h> /* stat */ |
|
27 |
|
#include<sys/time.h> /* localtime */ |
|
28 |
|
#include<time.h> |
|
29 |
|
#include<regex.h> |
|
30 |
|
#include<dirent.h> /* DIR */ |
|
31 |
|
#include<string.h> /* strcat() */ |
|
32 |
|
#include<windows.h> |
|
33 |
|
//#include<pwd.h> |
|
34 |
|
//#include<grp.h> |
|
35 |
|
|
|
36 |
|
#include "color_scheme.h" |
|
37 |
|
#include "config.h" /* menu colors */ |
|
38 |
|
#include "filelist.h" |
|
39 |
|
#include "keys.h" |
|
40 |
|
#include "menus.h" |
|
41 |
|
#include "sort.h" |
|
42 |
|
#include "status.h" |
|
43 |
|
#include "ui.h" |
|
44 |
|
#include "utils.h" /* update_term_title() */ |
|
45 |
|
|
|
46 |
|
|
|
47 |
|
static void |
|
48 |
|
add_sort_type_info(FileView *view, int y, int x, int current_line) |
|
49 |
|
{ |
|
50 |
|
char buf[24]; |
|
51 |
|
|
|
52 |
|
switch(view->sort_type) |
|
53 |
|
{ |
|
54 |
|
/* |
|
55 |
|
case SORT_BY_OWNER_NAME: |
|
56 |
|
if((pwd_buf = getpwuid(view->dir_entry[x].uid)) != NULL) |
|
57 |
|
{ |
|
58 |
|
snprintf(buf, sizeof(buf), " %s", pwd_buf->pw_name); |
|
59 |
|
break; |
|
60 |
|
} |
|
61 |
|
case SORT_BY_OWNER_ID: |
|
62 |
|
snprintf(buf, sizeof(buf), " %d", (int) view->dir_entry[x].uid); |
|
63 |
|
break; |
|
64 |
|
case SORT_BY_GROUP_NAME: |
|
65 |
|
if((grp_buf = getgrgid(view->dir_entry[x].gid)) != NULL) |
|
66 |
|
{ |
|
67 |
|
snprintf(buf, sizeof(buf), " %s", grp_buf->gr_name); |
|
68 |
|
break; |
|
69 |
|
} |
|
70 |
|
case SORT_BY_GROUP_ID: |
|
71 |
|
snprintf(buf, sizeof(buf), " %d", (int) view->dir_entry[x].gid); |
|
72 |
|
break; |
|
73 |
|
case SORT_BY_MODE: |
|
74 |
|
{ |
|
75 |
|
if (S_ISREG (view->dir_entry[x].mode)) |
|
76 |
|
{ |
|
77 |
|
if((S_IXUSR &view->dir_entry[x].mode) |
|
78 |
|
|| (S_IXGRP &view->dir_entry[x].mode) |
|
79 |
|
|| (S_IXOTH &view->dir_entry[x].mode)) |
|
80 |
|
|
|
81 |
|
snprintf(buf, sizeof(buf), " exe"); |
|
82 |
|
else |
|
83 |
|
snprintf(buf, sizeof(buf), " reg"); |
|
84 |
|
} |
|
85 |
|
else if(S_ISLNK(view->dir_entry[x].mode)) |
|
86 |
|
snprintf(buf, sizeof(buf), " link"); |
|
87 |
|
else if (S_ISDIR (view->dir_entry[x].mode)) |
|
88 |
|
snprintf(buf, sizeof(buf), " dir"); |
|
89 |
|
else if (S_ISCHR (view->dir_entry[x].mode)) |
|
90 |
|
snprintf(buf, sizeof(buf), " char"); |
|
91 |
|
else if (S_ISBLK (view->dir_entry[x].mode)) |
|
92 |
|
snprintf(buf, sizeof(buf), " block"); |
|
93 |
|
else if (S_ISFIFO (view->dir_entry[x].mode)) |
|
94 |
|
snprintf(buf, sizeof(buf), " fifo"); |
|
95 |
|
else if (S_ISSOCK (view->dir_entry[x].mode)) |
|
96 |
|
snprintf(buf, sizeof(buf), " sock"); |
|
97 |
|
else |
|
98 |
|
snprintf(buf, sizeof(buf), " ? "); |
|
99 |
|
break; |
|
100 |
|
} |
|
101 |
|
case SORT_BY_TIME_MODIFIED: |
|
102 |
|
tm_ptr = localtime(&view->dir_entry[x].mtime); |
|
103 |
|
strftime(buf, sizeof(buf), " %m/%d-%H:%M", tm_ptr); |
|
104 |
|
break; |
|
105 |
|
case SORT_BY_TIME_ACCESSED: |
|
106 |
|
tm_ptr = localtime(&view->dir_entry[x].atime); |
|
107 |
|
strftime(buf, sizeof(buf), " %m/%d-%H:%M", tm_ptr); |
|
108 |
|
break; |
|
109 |
|
case SORT_BY_TIME_CHANGED: |
|
110 |
|
tm_ptr = localtime(&view->dir_entry[x].ctime); |
|
111 |
|
strftime(buf, sizeof(buf), " %m/%d-%H:%M", tm_ptr); |
|
112 |
|
break; |
|
113 |
|
*/ |
|
114 |
|
case SORT_BY_NAME: |
|
115 |
|
case SORT_BY_EXTENSION: |
|
116 |
|
case SORT_BY_SIZE: |
|
117 |
|
snprintf(buf, sizeof(buf), " %d", view->dir_entry[x].size); |
|
118 |
|
break; |
|
119 |
|
default: |
|
120 |
|
snprintf(buf, sizeof(buf), " %d", view->dir_entry[x].size); |
|
121 |
|
break; |
|
122 |
|
} |
|
123 |
|
|
|
124 |
|
if (current_line) |
|
125 |
|
wattron(view->win, COLOR_PAIR(CURR_LINE_COLOR + view->color_scheme) |
|
126 |
|
| A_BOLD); |
|
127 |
|
|
|
128 |
|
mvwaddstr(view->win, y, |
|
129 |
|
view->window_width - strlen(buf), buf); |
|
130 |
|
|
|
131 |
|
if (current_line) |
|
132 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR + view->color_scheme) |
|
133 |
|
| A_BOLD); |
|
134 |
|
} |
|
135 |
|
|
|
136 |
|
void |
|
137 |
|
quick_view_file(FileView *view) |
|
138 |
|
{ |
|
139 |
|
FILE *fp; |
|
140 |
|
char line[1024]; |
|
141 |
|
char buf[PATH_MAX]; |
|
142 |
|
int x = 1; |
|
143 |
|
int y = 1; |
|
144 |
|
|
|
145 |
|
snprintf(buf, view->window_width, "File: %s", |
|
146 |
|
view->dir_entry[view->list_pos].name); |
|
147 |
|
|
|
148 |
|
wbkgdset(other_view->title, COLOR_PAIR(BORDER_COLOR + view->color_scheme)); |
|
149 |
|
wbkgdset(other_view->win, COLOR_PAIR(WIN_COLOR + view->color_scheme)); |
|
150 |
|
wclear(other_view->win); |
|
151 |
|
wclear(other_view->title); |
|
152 |
|
wattron(other_view->win, A_BOLD); |
|
153 |
|
mvwaddstr(other_view->win, x, y, buf); |
|
154 |
|
wattroff(other_view->win, A_BOLD); |
|
155 |
|
x++; |
|
156 |
|
|
|
157 |
|
switch (view->dir_entry[view->list_pos].type) |
|
158 |
|
{ |
|
159 |
|
case DIRECTORY: |
|
160 |
|
mvwaddstr(other_view->win, ++x, y, "File is a Directory"); |
|
161 |
|
break; |
|
162 |
|
case DEVICE: |
|
163 |
|
mvwaddstr(other_view->win, ++x, y, "File is a Device"); |
|
164 |
|
break; |
|
165 |
|
/* |
|
166 |
|
case SOCKET: |
|
167 |
|
mvwaddstr(other_view->win, ++x, y, "File is a Socket"); |
|
168 |
|
break; |
|
169 |
|
*/ |
|
170 |
|
default: |
|
171 |
|
{ |
|
172 |
|
if((fp = fopen(view->dir_entry[view->list_pos].name, "r")) |
|
173 |
|
== NULL) |
|
174 |
|
{ |
|
175 |
|
mvwaddstr(other_view->win, ++x, y, "Cannot open file"); |
|
176 |
|
return; |
|
177 |
|
} |
|
178 |
|
|
|
179 |
|
while(fgets(line, other_view->window_width, fp) |
|
180 |
|
&& (x < other_view->window_rows - 2)) |
|
181 |
|
{ |
|
182 |
|
mvwaddstr(other_view->win, ++x, y, line); |
|
183 |
|
} |
|
184 |
|
|
|
185 |
|
|
|
186 |
|
fclose(fp); |
|
187 |
|
} |
|
188 |
|
break; |
|
189 |
|
} |
|
190 |
|
} |
|
191 |
|
|
|
192 |
|
char * |
|
193 |
|
get_current_file_name(FileView *view) |
|
194 |
|
{ |
|
195 |
|
return view->dir_entry[view->list_pos].name; |
|
196 |
|
} |
|
197 |
|
|
|
198 |
|
void |
|
199 |
|
free_selected_file_array(FileView *view) |
|
200 |
|
{ |
|
201 |
|
int x; |
|
202 |
|
if(view->selected_filelist) |
|
203 |
|
{ |
|
204 |
|
for(x = 0; x < view->selected_files; x++) |
|
205 |
|
{ |
|
206 |
|
if(view->selected_filelist[x]) |
|
207 |
|
{ |
|
208 |
|
my_free(view->selected_filelist[x]); |
|
209 |
|
} |
|
210 |
|
|
|
211 |
|
} |
|
212 |
|
if(view->selected_filelist) |
|
213 |
|
my_free(view->selected_filelist); |
|
214 |
|
view->selected_filelist = NULL; |
|
215 |
|
} |
|
216 |
|
} |
|
217 |
|
|
|
218 |
|
/* If you use this function using the free_selected_file_array() |
|
219 |
|
* will clean up the allocated memory |
|
220 |
|
*/ |
|
221 |
|
void |
|
222 |
|
get_all_selected_files(FileView *view) |
|
223 |
|
{ |
|
224 |
|
size_t namelen; |
|
225 |
|
int x; |
|
226 |
|
int y = 0; |
|
227 |
|
|
|
228 |
|
/* No selected files so just use the current file */ |
|
229 |
|
if(!view->selected_files) |
|
230 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
231 |
|
|
|
232 |
|
view->selected_filelist = |
|
233 |
|
(char **)calloc(view->selected_files, sizeof(char *)); |
|
234 |
|
if(view->selected_filelist == NULL) |
|
235 |
|
{ |
|
236 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory"); |
|
237 |
|
return; |
|
238 |
|
} |
|
239 |
|
|
|
240 |
|
for(x = 0; x < view->list_rows; x++) |
|
241 |
|
{ |
|
242 |
|
if(view->dir_entry[x].selected) |
|
243 |
|
{ |
|
244 |
|
namelen = strlen(view->dir_entry[x].name); |
|
245 |
|
view->selected_filelist[y] = malloc(namelen +1); |
|
246 |
|
if(view->selected_filelist[y] == NULL) |
|
247 |
|
{ |
|
248 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory"); |
|
249 |
|
return; |
|
250 |
|
} |
|
251 |
|
strcpy(view->selected_filelist[y], |
|
252 |
|
view->dir_entry[x].name); |
|
253 |
|
y++; |
|
254 |
|
} |
|
255 |
|
} |
|
256 |
|
view->selected_files = y; |
|
257 |
|
} |
|
258 |
|
|
|
259 |
|
|
|
260 |
|
int |
|
261 |
|
find_file_pos_in_list(FileView *view, char *file) |
|
262 |
|
{ |
|
263 |
|
int x; |
|
264 |
|
int found = 0; |
|
265 |
|
|
|
266 |
|
for(x = 0; x < view->list_rows; x++) |
|
267 |
|
{ |
|
268 |
|
if(!strcmp(view->dir_entry[x].name, file)) |
|
269 |
|
{ |
|
270 |
|
found = 1; |
|
271 |
|
break; |
|
272 |
|
} |
|
273 |
|
} |
|
274 |
|
if(found) |
|
275 |
|
return x; |
|
276 |
|
else |
|
277 |
|
return -1; |
|
278 |
|
} |
|
279 |
|
|
|
280 |
|
void |
|
281 |
|
draw_dir_list(FileView *view, int top, int pos) |
|
282 |
|
{ |
|
283 |
|
int x; |
|
284 |
|
int y = 0; |
|
285 |
|
char file_name[view->window_width -2]; |
|
286 |
|
int LINE_COLOR; |
|
287 |
|
int bold = 1; |
|
288 |
|
int color_scheme = 0; |
|
289 |
|
|
|
290 |
|
color_scheme = check_directory_for_color_scheme(view->curr_dir); |
|
291 |
|
|
|
292 |
|
/* |
|
293 |
|
wattrset(view->title, COLOR_PAIR(BORDER_COLOR + color_scheme)); |
|
294 |
|
wattron(view->title, COLOR_PAIR(BORDER_COLOR + color_scheme)); |
|
295 |
|
*/ |
|
296 |
|
if(view->color_scheme != color_scheme) |
|
297 |
|
{ |
|
298 |
|
view->color_scheme = color_scheme; |
|
299 |
|
wbkgdset(view->title, COLOR_PAIR(BORDER_COLOR + color_scheme)); |
|
300 |
|
wbkgdset(view->win, COLOR_PAIR(WIN_COLOR + color_scheme)); |
|
301 |
|
} |
|
302 |
|
|
|
303 |
|
werase(view->win); |
|
304 |
|
werase(view->title); |
|
305 |
|
|
|
306 |
|
|
|
307 |
|
/* FIXME change to truncate directory names */ |
|
308 |
|
|
|
309 |
|
//wattron(view->title, A_BOLD); |
|
310 |
|
wprintw(view->title, "%s", view->curr_dir); |
|
311 |
|
wnoutrefresh(view->title); |
|
312 |
|
|
|
313 |
|
/* This is needed for reloading a list that has had files deleted */ |
|
314 |
|
while((view->list_rows - view->list_pos) <= 0) |
|
315 |
|
{ |
|
316 |
|
view->list_pos--; |
|
317 |
|
view->curr_line--; |
|
318 |
|
} |
|
319 |
|
|
|
320 |
|
/* Show as much of the directory as possible. */ |
|
321 |
|
if(view->window_rows >= view->list_rows) |
|
322 |
|
top = 0; |
|
323 |
|
else if((view->list_rows - top) <= view->window_rows) |
|
324 |
|
{ |
|
325 |
|
top = view->list_rows - view->window_rows -1; |
|
326 |
|
view->curr_line++; |
|
327 |
|
} |
|
328 |
|
|
|
329 |
|
/* Colorize the files */ |
|
330 |
|
|
|
331 |
|
|
|
332 |
|
for(x = top; x < view->list_rows; x++) |
|
333 |
|
{ |
|
334 |
|
/* Extra long file names are truncated to fit */ |
|
335 |
|
|
|
336 |
|
snprintf(file_name, view->window_width - 2, "%s", |
|
337 |
|
view->dir_entry[x].name); |
|
338 |
|
|
|
339 |
|
wmove(view->win, y, 1); |
|
340 |
|
if(view->dir_entry[x].selected) |
|
341 |
|
{ |
|
342 |
|
LINE_COLOR = SELECTED_COLOR + color_scheme; |
|
343 |
|
} |
|
344 |
|
else |
|
345 |
|
{ |
|
346 |
|
switch(view->dir_entry[x].type) |
|
347 |
|
{ |
|
348 |
|
case DIRECTORY: |
|
349 |
|
LINE_COLOR = DIRECTORY_COLOR + color_scheme; |
|
350 |
|
break; |
|
351 |
|
case FIFO: |
|
352 |
|
LINE_COLOR = FIFO_COLOR + color_scheme; |
|
353 |
|
break; |
|
354 |
|
case DEVICE: |
|
355 |
|
LINE_COLOR = DEVICE_COLOR + color_scheme; |
|
356 |
|
break; |
|
357 |
|
case EXECUTABLE: |
|
358 |
|
LINE_COLOR = EXECUTABLE_COLOR + color_scheme; |
|
359 |
|
break; |
|
360 |
|
default: |
|
361 |
|
LINE_COLOR = WIN_COLOR + color_scheme; |
|
362 |
|
bold = 0; |
|
363 |
|
break; |
|
364 |
|
} |
|
365 |
|
} |
|
366 |
|
if(bold) |
|
367 |
|
{ |
|
368 |
|
wattrset(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
369 |
|
wattron(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
370 |
|
wprintw(view->win, "%s", file_name); |
|
371 |
|
wattroff(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
372 |
|
|
|
373 |
|
add_sort_type_info(view, y, x, 0); |
|
374 |
|
} |
|
375 |
|
else |
|
376 |
|
{ |
|
377 |
|
wattrset(view->win, COLOR_PAIR(LINE_COLOR)); |
|
378 |
|
wattron(view->win, COLOR_PAIR(LINE_COLOR)); |
|
379 |
|
wprintw(view->win, "%s", file_name); |
|
380 |
|
wattroff(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
381 |
|
|
|
382 |
|
add_sort_type_info(view, y, x, 0); |
|
383 |
|
bold = 1; |
|
384 |
|
} |
|
385 |
|
y++; |
|
386 |
|
if(y > view->window_rows) |
|
387 |
|
break; |
|
388 |
|
} |
|
389 |
|
|
|
390 |
|
if(view != curr_view) |
|
391 |
|
mvwaddstr(view->win, view->curr_line, 0, "*"); |
|
392 |
|
|
|
393 |
|
view->top_line = top; |
|
394 |
|
} |
|
395 |
|
|
|
396 |
|
int |
|
397 |
|
S_ISEXE(mode_t mode) |
|
398 |
|
{ |
|
399 |
|
/* |
|
400 |
|
if((S_IXUSR & mode) || (S_IXGRP & mode) || (S_IXOTH & mode)) |
|
401 |
|
return 1; |
|
402 |
|
*/ |
|
403 |
|
|
|
404 |
|
return 0; |
|
405 |
|
} |
|
406 |
|
|
|
407 |
|
void |
|
408 |
|
erase_current_line_bar(FileView *view) |
|
409 |
|
{ |
|
410 |
|
int old_cursor = view->curr_line; |
|
411 |
|
int old_pos = view->top_line + old_cursor; |
|
412 |
|
char file_name[view->window_width -2]; |
|
413 |
|
int bold = 1; |
|
414 |
|
int LINE_COLOR; |
|
415 |
|
|
|
416 |
|
/* Extra long file names are truncated to fit */ |
|
417 |
|
|
|
418 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR + view->color_scheme) | A_BOLD); |
|
419 |
|
if((old_pos > -1) && (old_pos < view->list_rows)) |
|
420 |
|
{ |
|
421 |
|
snprintf(file_name, view->window_width - 2, "%s", |
|
422 |
|
view->dir_entry[old_pos].name); |
|
423 |
|
} |
|
424 |
|
else /* The entire list is going to be redrawn so just return. */ |
|
425 |
|
return; |
|
426 |
|
|
|
427 |
|
|
|
428 |
|
wmove(view->win, old_cursor, 1); |
|
429 |
|
|
|
430 |
|
wclrtoeol(view->win); |
|
431 |
|
|
|
432 |
|
if(view->dir_entry[old_pos].selected) |
|
433 |
|
{ |
|
434 |
|
LINE_COLOR = SELECTED_COLOR + view->color_scheme; |
|
435 |
|
} |
|
436 |
|
else |
|
437 |
|
{ |
|
438 |
|
switch(view->dir_entry[old_pos].type) |
|
439 |
|
{ |
|
440 |
|
case DIRECTORY: |
|
441 |
|
LINE_COLOR = DIRECTORY_COLOR + view->color_scheme; |
|
442 |
|
break; |
|
443 |
|
case FIFO: |
|
444 |
|
LINE_COLOR = FIFO + view->color_scheme; |
|
445 |
|
break; |
|
446 |
|
case DEVICE: |
|
447 |
|
LINE_COLOR = DEVICE_COLOR + view->color_scheme; |
|
448 |
|
break; |
|
449 |
|
case EXECUTABLE: |
|
450 |
|
LINE_COLOR = EXECUTABLE_COLOR + view->color_scheme; |
|
451 |
|
break; |
|
452 |
|
default: |
|
453 |
|
LINE_COLOR = WIN_COLOR + view->color_scheme; |
|
454 |
|
bold = 0; |
|
455 |
|
break; |
|
456 |
|
} |
|
457 |
|
} |
|
458 |
|
if(bold) |
|
459 |
|
{ |
|
460 |
|
wattrset(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
461 |
|
wattron(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
462 |
|
mvwaddnstr(view->win, old_cursor, 1, file_name, view->window_width -2); |
|
463 |
|
wattroff(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
464 |
|
|
|
465 |
|
add_sort_type_info(view, old_cursor, old_pos, 0); |
|
466 |
|
} |
|
467 |
|
else |
|
468 |
|
{ |
|
469 |
|
wattrset(view->win, COLOR_PAIR(LINE_COLOR)); |
|
470 |
|
wattron(view->win, COLOR_PAIR(LINE_COLOR)); |
|
471 |
|
mvwaddnstr(view->win, old_cursor, 1, file_name, view->window_width -2); |
|
472 |
|
wattroff(view->win, COLOR_PAIR(LINE_COLOR) | A_BOLD); |
|
473 |
|
bold = 1; |
|
474 |
|
add_sort_type_info(view, old_cursor, old_pos, 0); |
|
475 |
|
} |
|
476 |
|
} |
|
477 |
|
|
|
478 |
|
void |
|
479 |
|
moveto_list_pos(FileView *view, int pos) |
|
480 |
|
{ |
|
481 |
|
int redraw = 0; |
|
482 |
|
int old_cursor = view->curr_line; |
|
483 |
|
char file_name[view->window_width -2]; |
|
484 |
|
int x; |
|
485 |
|
|
|
486 |
|
if(pos < 1) |
|
487 |
|
pos = 0; |
|
488 |
|
|
|
489 |
|
if(pos > view->list_rows -1) |
|
490 |
|
pos = (view->list_rows -1); |
|
491 |
|
|
|
492 |
|
|
|
493 |
|
if(view->curr_line > view->list_rows -1) |
|
494 |
|
view->curr_line = view->list_rows -1; |
|
495 |
|
|
|
496 |
|
erase_current_line_bar(view); |
|
497 |
|
|
|
498 |
|
if((view->top_line <= pos) && (pos <= (view->top_line + view->window_rows))) |
|
499 |
|
{ |
|
500 |
|
view->curr_line = pos - view->top_line; |
|
501 |
|
} |
|
502 |
|
else if((pos > (view->top_line + view->window_rows))) |
|
503 |
|
{ |
|
504 |
|
while(pos > (view->top_line + view->window_rows)) |
|
505 |
|
view->top_line++; |
|
506 |
|
|
|
507 |
|
view->curr_line = view->window_rows; |
|
508 |
|
redraw = 1; |
|
509 |
|
} |
|
510 |
|
else if(pos < view->top_line) |
|
511 |
|
{ |
|
512 |
|
while(pos < view->top_line) |
|
513 |
|
view->top_line--; |
|
514 |
|
|
|
515 |
|
view->curr_line = 0; |
|
516 |
|
redraw = 1; |
|
517 |
|
} |
|
518 |
|
|
|
519 |
|
view->list_pos = pos; |
|
520 |
|
|
|
521 |
|
|
|
522 |
|
|
|
523 |
|
if(redraw) |
|
524 |
|
draw_dir_list(view, view->top_line, view->curr_line); |
|
525 |
|
|
|
526 |
|
|
|
527 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR + view->color_scheme)); |
|
528 |
|
mvwaddstr(view->win, old_cursor, 0, " "); |
|
529 |
|
|
|
530 |
|
wattron(view->win, COLOR_PAIR(CURR_LINE_COLOR + view->color_scheme) | A_BOLD); |
|
531 |
|
|
|
532 |
|
/* Blank the current line and |
|
533 |
|
* print out the current line bar |
|
534 |
|
*/ |
|
535 |
|
|
|
536 |
|
for (x = 0; x < view->window_width ; x++) |
|
537 |
|
file_name[x] = ' '; |
|
538 |
|
|
|
539 |
|
file_name[view->window_width] = ' '; |
|
540 |
|
file_name[view->window_width +1 ] = '\0'; |
|
541 |
|
|
|
542 |
|
|
|
543 |
|
mvwaddstr(view->win, view->curr_line, 0, file_name); |
|
544 |
|
|
|
545 |
|
snprintf(file_name, view->window_width - 2, "%s", |
|
546 |
|
view->dir_entry[pos].name); |
|
547 |
|
|
|
548 |
|
mvwaddstr(view->win, view->curr_line, 1, file_name); |
|
549 |
|
add_sort_type_info(view, view->curr_line, pos, 1); |
|
550 |
|
|
|
551 |
|
if(curr_stats.view) |
|
552 |
|
quick_view_file(view); |
|
553 |
|
|
|
554 |
|
} |
|
555 |
|
|
|
556 |
|
|
|
557 |
|
static int |
|
558 |
|
regexp_filter_match(FileView *view, char *filename) |
|
559 |
|
{ |
|
560 |
|
regex_t re; |
|
561 |
|
|
|
562 |
|
if(regcomp(&re, view->filename_filter, REG_EXTENDED) == 0) |
|
563 |
|
{ |
|
564 |
|
if(regexec(&re, filename, 0, NULL, 0) == 0) |
|
565 |
|
{ |
|
566 |
|
regfree(&re); |
|
567 |
|
return !view->invert; |
|
568 |
|
} |
|
569 |
|
regfree(&re); |
|
570 |
|
return view->invert; |
|
571 |
|
} |
|
572 |
|
regfree(&re); |
|
573 |
|
return 1; |
|
574 |
|
} |
|
575 |
|
|
|
576 |
|
void |
|
577 |
|
save_view_history(FileView *view) |
|
578 |
|
{ |
|
579 |
|
int x = 0; |
|
580 |
|
int found = 0; |
|
581 |
|
|
|
582 |
|
for(x = 0; x < view->history_num; x++) |
|
583 |
|
{ |
|
584 |
|
if(strlen(view->history[x].dir) < 1) |
|
585 |
|
break; |
|
586 |
|
if(!strcmp(view->history[x].dir, view->curr_dir)) |
|
587 |
|
{ |
|
588 |
|
found = 1; |
|
589 |
|
break; |
|
590 |
|
} |
|
591 |
|
} |
|
592 |
|
if(found) |
|
593 |
|
{ |
|
594 |
|
snprintf(view->history[x].file, sizeof(view->history[x].file), |
|
595 |
|
"%s", view->dir_entry[view->list_pos].name); |
|
596 |
|
return; |
|
597 |
|
} |
|
598 |
|
|
|
599 |
|
if(x == cfg.history_len) |
|
600 |
|
{ |
|
601 |
|
int y; |
|
602 |
|
for(y = 0; y < cfg.history_len -1; y++) |
|
603 |
|
{ |
|
604 |
|
snprintf(view->history[y].file, sizeof(view->history[y].file), |
|
605 |
|
"%s", view->history[y +1].file); |
|
606 |
|
snprintf(view->history[y].dir, sizeof(view->history[y].dir), |
|
607 |
|
"%s", view->history[y +1].dir); |
|
608 |
|
} |
|
609 |
|
snprintf(view->history[cfg.history_len -1].file, |
|
610 |
|
sizeof(view->history[cfg.history_len -1].file), |
|
611 |
|
"%s", view->dir_entry[view->list_pos].name); |
|
612 |
|
snprintf(view->history[cfg.history_len -1].dir, |
|
613 |
|
sizeof(view->history[cfg.history_len -1].dir), |
|
614 |
|
"%s", view->curr_dir); |
|
615 |
|
} |
|
616 |
|
else |
|
617 |
|
{ |
|
618 |
|
snprintf(view->history[x].dir, sizeof(view->history[x].dir), |
|
619 |
|
"%s", view->curr_dir); |
|
620 |
|
snprintf(view->history[x].file, sizeof(view->history[x].file), |
|
621 |
|
"%s", view->dir_entry[view->list_pos].name); |
|
622 |
|
view->history_num++; |
|
623 |
|
} |
|
624 |
|
return; |
|
625 |
|
|
|
626 |
|
} |
|
627 |
|
|
|
628 |
|
static void |
|
629 |
|
check_view_dir_history(FileView *view) |
|
630 |
|
{ |
|
631 |
|
int x = 0; |
|
632 |
|
int found = 0; |
|
633 |
|
int pos = 0; |
|
634 |
|
|
|
635 |
|
if(curr_stats.is_updir) |
|
636 |
|
{ |
|
637 |
|
pos = find_file_pos_in_list(view, curr_stats.updir_file); |
|
638 |
|
} |
|
639 |
|
else |
|
640 |
|
{ |
|
641 |
|
for(x = 0; x < view->history_num ; x++) |
|
642 |
|
{ |
|
643 |
|
if(strlen(view->history[x].dir) < 1) |
|
644 |
|
break; |
|
645 |
|
if(!strcmp(view->history[x].dir, view->curr_dir)) |
|
646 |
|
{ |
|
647 |
|
found = 1; |
|
648 |
|
break; |
|
649 |
|
} |
|
650 |
|
} |
|
651 |
|
if(found) |
|
652 |
|
{ |
|
653 |
|
pos = find_file_pos_in_list(view, view->history[x].file); |
|
654 |
|
} |
|
655 |
|
else |
|
656 |
|
{ |
|
657 |
|
view->list_pos = 0; |
|
658 |
|
view->curr_line = 0; |
|
659 |
|
view->top_line = 0; |
|
660 |
|
return; |
|
661 |
|
} |
|
662 |
|
} |
|
663 |
|
|
|
664 |
|
if(pos < 0) |
|
665 |
|
pos = 0; |
|
666 |
|
|
|
667 |
|
view->list_pos = pos; |
|
668 |
|
|
|
669 |
|
if(view->list_pos <= view->window_rows) |
|
670 |
|
{ |
|
671 |
|
view->top_line = 0; |
|
672 |
|
view->curr_line = view->list_pos; |
|
673 |
|
} |
|
674 |
|
else if(view->list_pos > (view->top_line + view->window_rows)) |
|
675 |
|
{ |
|
676 |
|
while(view->list_pos > (view->top_line + view->window_rows)) |
|
677 |
|
view->top_line++; |
|
678 |
|
|
|
679 |
|
view->curr_line = view->window_rows; |
|
680 |
|
} |
|
681 |
|
return; |
|
682 |
|
} |
|
683 |
|
|
|
684 |
|
void |
|
685 |
|
clean_selected_files(FileView *view) |
|
686 |
|
{ |
|
687 |
|
int x; |
|
688 |
|
|
|
689 |
|
if(view->selected_files) |
|
690 |
|
{ |
|
691 |
|
for(x = 0; x < view->list_rows; x++) |
|
692 |
|
view->dir_entry[x].selected = 0; |
|
693 |
|
|
|
694 |
|
view->selected_files = 0; |
|
695 |
|
} |
|
696 |
|
|
|
697 |
|
} |
|
698 |
|
|
|
699 |
|
void |
|
700 |
|
change_directory(FileView *view, char *directory) |
|
701 |
|
{ |
|
702 |
|
DIR *dir; |
|
703 |
|
struct stat s; |
|
704 |
|
|
|
705 |
|
if(!strcmp(directory, "../")) |
|
706 |
|
{ |
|
707 |
|
char *str1, *str2; |
|
708 |
|
curr_stats.is_updir = 1; |
|
709 |
|
str2 = str1 = view->curr_dir; |
|
710 |
|
while((str1 = strstr(str1, "\\")) != NULL) |
|
711 |
|
{ |
|
712 |
|
str1++; |
|
713 |
|
str2 = str1; |
|
714 |
|
} |
|
715 |
|
snprintf(curr_stats.updir_file, sizeof(curr_stats.updir_file), |
|
716 |
|
"%s/", str2); |
|
717 |
|
} |
|
718 |
|
else |
|
719 |
|
curr_stats.is_updir = 0; |
|
720 |
|
|
|
721 |
|
|
|
722 |
|
|
|
723 |
|
if(access(directory, F_OK) != 0) |
|
724 |
|
{ |
|
725 |
|
show_error_msg(" Directory Access Error ", "That directory does not exist."); |
|
726 |
|
change_directory(view, view->last_dir); |
|
727 |
|
clean_selected_files(view); |
|
728 |
|
return; |
|
729 |
|
} |
|
730 |
|
if(access(directory, R_OK) != 0) |
|
731 |
|
{ |
|
732 |
|
show_error_msg(" Directory Access Error ", "You do not have read access on that directory"); |
|
733 |
|
|
|
734 |
|
clean_selected_files(view); |
|
735 |
|
return; |
|
736 |
|
} |
|
737 |
|
|
|
738 |
|
dir = opendir(directory); |
|
739 |
|
|
|
740 |
|
if(dir == NULL) |
|
741 |
|
{ |
|
742 |
|
clean_selected_files(view); |
|
743 |
|
return; |
|
744 |
|
} |
|
745 |
|
|
|
746 |
|
|
|
747 |
|
if(chdir(directory) == -1) |
|
748 |
|
{ |
|
749 |
|
closedir(dir); |
|
750 |
|
status_bar_message("Couldn't open directory"); |
|
751 |
|
return; |
|
752 |
|
} |
|
753 |
|
|
|
754 |
|
snprintf(view->last_dir, sizeof(view->last_dir), "%s", view->curr_dir); |
|
755 |
|
|
|
756 |
|
clean_selected_files(view); |
|
757 |
|
|
|
758 |
|
save_view_history(view); |
|
759 |
|
getcwd(view->curr_dir, sizeof(view->curr_dir)); |
|
760 |
|
|
|
761 |
|
/* Save the directory modified time to check for file changes */ |
|
762 |
|
stat(view->curr_dir, &s); |
|
763 |
|
view->dir_mtime = s.st_mtime; |
|
764 |
|
closedir(dir); |
|
765 |
|
SetConsoleTitle(view->curr_dir); |
|
766 |
|
} |
|
767 |
|
|
|
768 |
|
static void |
|
769 |
|
reset_selected_files(FileView *view) |
|
770 |
|
{ |
|
771 |
|
int x; |
|
772 |
|
for(x = 0; x < view->selected_files; x++) |
|
773 |
|
{ |
|
774 |
|
if(view->selected_filelist[x]) |
|
775 |
|
{ |
|
776 |
|
int pos = find_file_pos_in_list(view, view->selected_filelist[x]); |
|
777 |
|
if(pos >= 0 && pos < view->list_rows) |
|
778 |
|
view->dir_entry[pos].selected = 1; |
|
779 |
|
} |
|
780 |
|
} |
|
781 |
|
free_selected_file_array(view); |
|
782 |
|
} |
|
783 |
|
|
|
784 |
|
|
|
785 |
|
void |
|
786 |
|
load_dir_list(FileView *view, int reload) |
|
787 |
|
{ |
|
788 |
|
DIR *dir; |
|
789 |
|
struct dirent *d; |
|
790 |
|
struct stat s; |
|
791 |
|
int x; |
|
792 |
|
int namelen = 0; |
|
793 |
|
int old_list = view->list_rows; |
|
794 |
|
|
|
795 |
|
dir = opendir(view->curr_dir); |
|
796 |
|
|
|
797 |
|
if(dir == NULL) |
|
798 |
|
return; |
|
799 |
|
|
|
800 |
|
|
|
801 |
|
view->filtered = 0; |
|
802 |
|
|
|
803 |
|
//lstat(view->curr_dir, &s); |
|
804 |
|
view->dir_mtime = s.st_mtime; |
|
805 |
|
|
|
806 |
|
if(!reload && s.st_size > 2048) |
|
807 |
|
{ |
|
808 |
|
status_bar_message("Reading Directory..."); |
|
809 |
|
} |
|
810 |
|
|
|
811 |
|
update_all_windows(); |
|
812 |
|
|
|
813 |
|
if(reload && view->selected_files) |
|
814 |
|
get_all_selected_files(view); |
|
815 |
|
|
|
816 |
|
|
|
817 |
|
if(view->dir_entry) |
|
818 |
|
{ |
|
819 |
|
for(x = 0; x < old_list; x++) |
|
820 |
|
{ |
|
821 |
|
if(view->dir_entry[x].name) |
|
822 |
|
{ |
|
823 |
|
my_free(view->dir_entry[x].name); |
|
824 |
|
view->dir_entry[x].name = NULL; |
|
825 |
|
} |
|
826 |
|
} |
|
827 |
|
|
|
828 |
|
my_free(view->dir_entry); |
|
829 |
|
view->dir_entry = NULL; |
|
830 |
|
} |
|
831 |
|
view->dir_entry = (dir_entry_t *)malloc(sizeof(dir_entry_t)); |
|
832 |
|
if(view->dir_entry == NULL) |
|
833 |
|
{ |
|
834 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory."); |
|
835 |
|
return; |
|
836 |
|
} |
|
837 |
|
|
|
838 |
|
for(view->list_rows = 0; (d = readdir(dir)); view->list_rows++) |
|
839 |
|
{ |
|
840 |
|
/* Ignore the "." directory. */ |
|
841 |
|
if(strcmp(d->d_name, ".") == 0) |
|
842 |
|
{ |
|
843 |
|
view->list_rows--; |
|
844 |
|
continue; |
|
845 |
|
} |
|
846 |
|
/* Always include the ../ directory unless it is the root directory. */ |
|
847 |
|
if(strcmp(d->d_name, "..") == 0) |
|
848 |
|
{ |
|
849 |
|
if(!strcmp("/", view->curr_dir)) |
|
850 |
|
{ |
|
851 |
|
view->list_rows--; |
|
852 |
|
continue; |
|
853 |
|
} |
|
854 |
|
} |
|
855 |
|
if(!regexp_filter_match(view, d->d_name) && strcmp("..", d->d_name)) |
|
856 |
|
{ |
|
857 |
|
view->filtered++; |
|
858 |
|
view->list_rows--; |
|
859 |
|
continue; |
|
860 |
|
} |
|
861 |
|
|
|
862 |
|
|
|
863 |
|
if(d->d_name[0] == '.') |
|
864 |
|
{ |
|
865 |
|
if((strcmp(d->d_name, "..")) && (view->hide_dot)) |
|
866 |
|
{ |
|
867 |
|
view->filtered++; |
|
868 |
|
view->list_rows--; |
|
869 |
|
continue; |
|
870 |
|
} |
|
871 |
|
} |
|
872 |
|
|
|
873 |
|
view->dir_entry = (dir_entry_t *)realloc(view->dir_entry, |
|
874 |
|
(view->list_rows + 1) * sizeof(dir_entry_t)); |
|
875 |
|
if(view->dir_entry == NULL) |
|
876 |
|
{ |
|
877 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory"); |
|
878 |
|
return ; |
|
879 |
|
} |
|
880 |
|
|
|
881 |
|
namelen = strlen(d->d_name); |
|
882 |
|
/* Allocate extra for adding / to directories. */ |
|
883 |
|
view->dir_entry[view->list_rows].name = malloc(namelen + 2); |
|
884 |
|
if(view->dir_entry[view->list_rows].name == NULL) |
|
885 |
|
{ |
|
886 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory"); |
|
887 |
|
return; |
|
888 |
|
} |
|
889 |
|
|
|
890 |
|
strcpy(view->dir_entry[view->list_rows].name, d->d_name); |
|
891 |
|
|
|
892 |
|
/* All files start as unselected */ |
|
893 |
|
view->dir_entry[view->list_rows].selected = 0; |
|
894 |
|
|
|
895 |
|
/* Load the inode info */ |
|
896 |
|
stat(view->dir_entry[view->list_rows].name, &s); |
|
897 |
|
|
|
898 |
|
view->dir_entry[view->list_rows].size = (int)s.st_size; |
|
899 |
|
//view->dir_entry[view->list_rows].mode = s.st_mode; |
|
900 |
|
//view->dir_entry[view->list_rows].uid = s.st_uid; |
|
901 |
|
//view->dir_entry[view->list_rows].gid = s.st_gid; |
|
902 |
|
view->dir_entry[view->list_rows].mtime = s.st_mtime; |
|
903 |
|
view->dir_entry[view->list_rows].atime = s.st_atime; |
|
904 |
|
view->dir_entry[view->list_rows].ctime = s.st_ctime; |
|
905 |
|
|
|
906 |
|
if(1)//s.st_ino is always 0 in windows) |
|
907 |
|
{ |
|
908 |
|
switch(s.st_mode & _S_IFMT) |
|
909 |
|
{ |
|
910 |
|
case S_IFDIR: |
|
911 |
|
namelen = sizeof(view->dir_entry[view->list_rows].name); |
|
912 |
|
strcat(view->dir_entry[view->list_rows].name, "/"); |
|
913 |
|
view->dir_entry[view->list_rows].type = DIRECTORY; |
|
914 |
|
break; |
|
915 |
|
case S_IFCHR: |
|
916 |
|
case S_IFBLK: |
|
917 |
|
view->dir_entry[view->list_rows].type = DEVICE; |
|
918 |
|
break; |
|
919 |
|
case S_IFREG: |
|
920 |
|
if(S_ISEXE(s.st_mode)) |
|
921 |
|
{ |
|
922 |
|
view->dir_entry[view->list_rows].type = EXECUTABLE; |
|
923 |
|
break; |
|
924 |
|
} |
|
925 |
|
view->dir_entry[view->list_rows].type = NORMAL; |
|
926 |
|
break; |
|
927 |
|
// use NORMAL for default hack to allow filetypes to |
|
928 |
|
// work. |
|
929 |
|
default: |
|
930 |
|
view->dir_entry[view->list_rows].type = NORMAL; |
|
931 |
|
break; |
|
932 |
|
} |
|
933 |
|
} |
|
934 |
|
} |
|
935 |
|
|
|
936 |
|
closedir(dir); |
|
937 |
|
|
|
938 |
|
if(!reload && s.st_size > 2048) |
|
939 |
|
{ |
|
940 |
|
status_bar_message("Sorting Directory..."); |
|
941 |
|
} |
|
942 |
|
qsort(view->dir_entry, view->list_rows, sizeof(dir_entry_t), |
|
943 |
|
sort_dir_list); |
|
944 |
|
|
|
945 |
|
for(x = 0; x < view->list_rows; x++) |
|
946 |
|
view->dir_entry[x].list_num = x; |
|
947 |
|
|
|
948 |
|
/* If reloading the same directory don't jump to |
|
949 |
|
* history position. Stay at the current line |
|
950 |
|
*/ |
|
951 |
|
if(!reload) |
|
952 |
|
check_view_dir_history(view); |
|
953 |
|
|
|
954 |
|
|
|
955 |
|
/* |
|
956 |
|
* It is possible to set the file name filter so that no files are showing |
|
957 |
|
* in the / directory. All other directorys will always show at least the |
|
958 |
|
* ../ file. This resets the filter and reloads the directory. |
|
959 |
|
*/ |
|
960 |
|
if(view->list_rows < 1) |
|
961 |
|
{ |
|
962 |
|
char msg[64]; |
|
963 |
|
|
|
964 |
|
/* Empty Directory not even ../ Possible access error such as |
|
965 |
|
* trying to read a secure drive. |
|
966 |
|
*/ |
|
967 |
|
if(view->filtered < 1) |
|
968 |
|
{ |
|
969 |
|
show_error_msg(" Empty Directory Error ", "Empty Directory or Secure Drive - Cannot Load Directory "); |
|
970 |
|
change_directory(view, view->last_dir); |
|
971 |
|
load_dir_list(view, 1); |
|
972 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
973 |
|
return; |
|
974 |
|
} |
|
975 |
|
|
|
976 |
|
snprintf(msg, sizeof(msg), |
|
977 |
|
"The %s pattern %s did not match any files. It was reset.", |
|
978 |
|
view->filename_filter, view->invert==1 ? "inverted" : ""); |
|
979 |
|
status_bar_message(msg); |
|
980 |
|
view->filename_filter = (char *)realloc(view->filename_filter, |
|
981 |
|
strlen("*") +1); |
|
982 |
|
if(view->filename_filter == NULL) |
|
983 |
|
{ |
|
984 |
|
show_error_msg(" Memory Error ", "Unable to allocate enough memory"); |
|
985 |
|
return; |
|
986 |
|
} |
|
987 |
|
snprintf(view->filename_filter, sizeof(view->filename_filter), "*"); |
|
988 |
|
if(view->invert) |
|
989 |
|
view->invert = 0; |
|
990 |
|
|
|
991 |
|
load_dir_list(view, 1); |
|
992 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
993 |
|
return; |
|
994 |
|
} |
|
995 |
|
|
|
996 |
|
if(reload && view->selected_files) |
|
997 |
|
reset_selected_files(view); |
|
998 |
|
|
|
999 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
1000 |
|
|
|
1001 |
|
return; |
|
1002 |
|
} |
|
1003 |
|
|
|
1004 |
|
|
File src/fileops.c added (mode: 100644) (index 0000000..4c81155) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
|
|
20 |
|
#include<curses.h> |
|
21 |
|
//#include<unistd.h> |
|
22 |
|
#include<errno.h> /* errno */ |
|
23 |
|
//#include<sys/wait.h> /* waitpid() */ |
|
24 |
|
#include<sys/types.h> /* waitpid() */ |
|
25 |
|
#include<sys/stat.h> /* stat */ |
|
26 |
|
#include<stdio.h> |
|
27 |
|
#include<string.h> |
|
28 |
|
|
|
29 |
|
#include<windows.h> |
|
30 |
|
#include<process.h> |
|
31 |
|
|
|
32 |
|
#include"background.h" |
|
33 |
|
#include"color_scheme.h" |
|
34 |
|
#include"commands.h" |
|
35 |
|
#include"config.h" |
|
36 |
|
#include"filelist.h" |
|
37 |
|
#include"fileops.h" |
|
38 |
|
#include"filetype.h" |
|
39 |
|
#include"keys.h" |
|
40 |
|
#include"menus.h" |
|
41 |
|
#include"registers.h" |
|
42 |
|
#include"status.h" |
|
43 |
|
#include"ui.h" |
|
44 |
|
#include"utils.h" |
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
|
48 |
|
void |
|
49 |
|
move_files(FileView *view) |
|
50 |
|
{ |
|
51 |
|
char buf[PATH_MAX]; |
|
52 |
|
char newbuf[PATH_MAX]; |
|
53 |
|
int x; |
|
54 |
|
int retval = 1; |
|
55 |
|
int answer = 0; |
|
56 |
|
|
|
57 |
|
if(!view->selected_files) |
|
58 |
|
{ |
|
59 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
60 |
|
view->selected_files = 1; |
|
61 |
|
} |
|
62 |
|
|
|
63 |
|
get_all_selected_files(view); |
|
64 |
|
yank_selected_files(view); |
|
65 |
|
|
|
66 |
|
for(x = 0; x < view->selected_files; x++) |
|
67 |
|
{ |
|
68 |
|
if(!strcmp("../", view->selected_filelist[x])) |
|
69 |
|
{ |
|
70 |
|
show_error_msg(" Background Process Error ", |
|
71 |
|
"You cannot move the ../ directory "); |
|
72 |
|
continue; |
|
73 |
|
} |
|
74 |
|
snprintf(buf, sizeof(buf), "%s\\%s", view->curr_dir, |
|
75 |
|
view->selected_filelist[x]); |
|
76 |
|
if(view == curr_view) |
|
77 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", other_view->curr_dir, |
|
78 |
|
view->selected_filelist[x]); |
|
79 |
|
else |
|
80 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", curr_view->curr_dir, |
|
81 |
|
view->selected_filelist[x]); |
|
82 |
|
|
|
83 |
|
retval = MoveFile(buf, newbuf); |
|
84 |
|
if(!retval) |
|
85 |
|
{ |
|
86 |
|
DWORD dw = GetLastError(); |
|
87 |
|
|
|
88 |
|
if((int)dw == 183) |
|
89 |
|
{ |
|
90 |
|
if (answer != 1) |
|
91 |
|
answer = show_overwrite_file_menu(view->selected_filelist[x]); |
|
92 |
|
if (answer != 2) |
|
93 |
|
retval = MoveFileEx(buf, newbuf, MOVEFILE_REPLACE_EXISTING); |
|
94 |
|
|
|
95 |
|
} |
|
96 |
|
else |
|
97 |
|
show_error_msg(" Error in moving file ", |
|
98 |
|
"Error in moving file. "); |
|
99 |
|
} |
|
100 |
|
|
|
101 |
|
// background_and_wait_for_errors(buf); |
|
102 |
|
} |
|
103 |
|
free_selected_file_array(view); |
|
104 |
|
view->selected_files = 0; |
|
105 |
|
|
|
106 |
|
} |
|
107 |
|
|
|
108 |
|
void |
|
109 |
|
copy_files(FileView *view) |
|
110 |
|
{ |
|
111 |
|
char buf[PATH_MAX]; |
|
112 |
|
char newbuf[PATH_MAX]; |
|
113 |
|
int x; |
|
114 |
|
int retval = 1; |
|
115 |
|
int answer = 0; |
|
116 |
|
|
|
117 |
|
if(!view->selected_files) |
|
118 |
|
{ |
|
119 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
120 |
|
view->selected_files = 1; |
|
121 |
|
} |
|
122 |
|
|
|
123 |
|
get_all_selected_files(view); |
|
124 |
|
yank_selected_files(view); |
|
125 |
|
|
|
126 |
|
for(x = 0; x < view->selected_files; x++) |
|
127 |
|
{ |
|
128 |
|
if(!strcmp("../", view->selected_filelist[x])) |
|
129 |
|
{ |
|
130 |
|
show_error_msg(" Background Process Error ", |
|
131 |
|
"You cannot copy the ../ directory "); |
|
132 |
|
continue; |
|
133 |
|
} |
|
134 |
|
snprintf(buf, sizeof(buf), "%s\\%s", view->curr_dir, |
|
135 |
|
view->selected_filelist[x]); |
|
136 |
|
if(view == curr_view) |
|
137 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", other_view->curr_dir, |
|
138 |
|
view->selected_filelist[x]); |
|
139 |
|
else |
|
140 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", curr_view->curr_dir, |
|
141 |
|
view->selected_filelist[x]); |
|
142 |
|
|
|
143 |
|
retval = CopyFile(buf, newbuf, TRUE); |
|
144 |
|
if(!retval) |
|
145 |
|
{ |
|
146 |
|
DWORD dw = GetLastError(); |
|
147 |
|
|
|
148 |
|
if((int)dw == 80) |
|
149 |
|
{ |
|
150 |
|
if (answer != 1) |
|
151 |
|
answer = show_overwrite_file_menu(view->selected_filelist[x]); |
|
152 |
|
if (answer != 2) |
|
153 |
|
retval = CopyFile(buf, newbuf, FALSE); |
|
154 |
|
|
|
155 |
|
} |
|
156 |
|
else |
|
157 |
|
{ |
|
158 |
|
snprintf(buf, sizeof(buf), "-%d- is error code ", (int)dw); |
|
159 |
|
show_error_msg(" Error in copying file ", buf); |
|
160 |
|
} |
|
161 |
|
} |
|
162 |
|
} |
|
163 |
|
free_selected_file_array(view); |
|
164 |
|
view->selected_files = 0; |
|
165 |
|
|
|
166 |
|
} |
|
167 |
|
|
|
168 |
|
int |
|
169 |
|
my_system(char *command) |
|
170 |
|
{ |
|
171 |
|
|
|
172 |
|
return 0; |
|
173 |
|
} |
|
174 |
|
|
|
175 |
|
static int |
|
176 |
|
execute(char **args) |
|
177 |
|
{ |
|
178 |
|
/* |
|
179 |
|
int pid; |
|
180 |
|
|
|
181 |
|
if((pid = fork()) == 0) |
|
182 |
|
{ |
|
183 |
|
setsid(); |
|
184 |
|
close(0); |
|
185 |
|
execvp(args[0], args); |
|
186 |
|
exit(127); |
|
187 |
|
} |
|
188 |
|
|
|
189 |
|
return pid; |
|
190 |
|
*/ |
|
191 |
|
return 0; |
|
192 |
|
} |
|
193 |
|
|
|
194 |
|
void |
|
195 |
|
yank_selected_files(FileView *view) |
|
196 |
|
{ |
|
197 |
|
int x; |
|
198 |
|
size_t namelen; |
|
199 |
|
int old_list = curr_stats.num_yanked_files; |
|
200 |
|
|
|
201 |
|
|
|
202 |
|
|
|
203 |
|
if(curr_stats.yanked_files) |
|
204 |
|
{ |
|
205 |
|
for(x = 0; x < old_list; x++) |
|
206 |
|
{ |
|
207 |
|
if(curr_stats.yanked_files[x]) |
|
208 |
|
{ |
|
209 |
|
my_free(curr_stats.yanked_files[x]); |
|
210 |
|
curr_stats.yanked_files[x] = NULL; |
|
211 |
|
} |
|
212 |
|
} |
|
213 |
|
my_free(curr_stats.yanked_files); |
|
214 |
|
curr_stats.yanked_files = NULL; |
|
215 |
|
} |
|
216 |
|
|
|
217 |
|
curr_stats.yanked_files = (char **)calloc(view->selected_files, |
|
218 |
|
sizeof(char *)); |
|
219 |
|
|
|
220 |
|
if ((curr_stats.use_register) && (curr_stats.register_saved)) |
|
221 |
|
{ |
|
222 |
|
/* A - Z append to register otherwise replace */ |
|
223 |
|
if ((curr_stats.curr_register < 65) || (curr_stats.curr_register > 90)) |
|
224 |
|
clear_register(curr_stats.curr_register); |
|
225 |
|
else |
|
226 |
|
curr_stats.curr_register = curr_stats.curr_register + 32; |
|
227 |
|
} |
|
228 |
|
|
|
229 |
|
for(x = 0; x < view->selected_files; x++) |
|
230 |
|
{ |
|
231 |
|
if(view->selected_filelist[x]) |
|
232 |
|
{ |
|
233 |
|
char buf[PATH_MAX]; |
|
234 |
|
namelen = strlen(view->selected_filelist[x]); |
|
235 |
|
curr_stats.yanked_files[x] = malloc(namelen +1); |
|
236 |
|
strcpy(curr_stats.yanked_files[x], view->selected_filelist[x]); |
|
237 |
|
snprintf(buf, sizeof(buf), "%s/%s", view->curr_dir, |
|
238 |
|
view->selected_filelist[x]); |
|
239 |
|
append_to_register(curr_stats.curr_register, view->selected_filelist[x]); |
|
240 |
|
} |
|
241 |
|
else |
|
242 |
|
{ |
|
243 |
|
x--; |
|
244 |
|
break; |
|
245 |
|
} |
|
246 |
|
} |
|
247 |
|
curr_stats.num_yanked_files = x; |
|
248 |
|
|
|
249 |
|
strncpy(curr_stats.yanked_files_dir, view->curr_dir, |
|
250 |
|
sizeof(curr_stats.yanked_files_dir) -1); |
|
251 |
|
} |
|
252 |
|
|
|
253 |
|
/* execute command. */ |
|
254 |
|
int |
|
255 |
|
file_exec(char *command) |
|
256 |
|
{ |
|
257 |
|
char *args[4]; |
|
258 |
|
pid_t pid; |
|
259 |
|
|
|
260 |
|
args[0] = "sh"; |
|
261 |
|
args[1] = "-c"; |
|
262 |
|
args[2] = command; |
|
263 |
|
args[3] = NULL; |
|
264 |
|
|
|
265 |
|
pid = execute(args); |
|
266 |
|
return pid; |
|
267 |
|
} |
|
268 |
|
|
|
269 |
|
void |
|
270 |
|
view_file(FileView *view) |
|
271 |
|
{ |
|
272 |
|
char command[PATH_MAX + 5] = ""; |
|
273 |
|
char *filename = escape_filename(get_current_file_name(view), 0); |
|
274 |
|
|
|
275 |
|
snprintf(command, sizeof(command), "%s %s", cfg.vi_command, filename); |
|
276 |
|
|
|
277 |
|
shellout(command, 0); |
|
278 |
|
my_free(filename); |
|
279 |
|
curs_set(0); |
|
280 |
|
} |
|
281 |
|
|
|
282 |
|
void |
|
283 |
|
handle_file(FileView *view) |
|
284 |
|
{ |
|
285 |
|
if(DIRECTORY == view->dir_entry[view->list_pos].type) |
|
286 |
|
{ |
|
287 |
|
char *filename = get_current_file_name(view); |
|
288 |
|
change_directory(view, filename); |
|
289 |
|
load_dir_list(view, 0); |
|
290 |
|
moveto_list_pos(view, view->curr_line); |
|
291 |
|
return; |
|
292 |
|
} |
|
293 |
|
|
|
294 |
|
if(cfg.vim_filter) |
|
295 |
|
{ |
|
296 |
|
FILE *fp; |
|
297 |
|
char filename[PATH_MAX] = ""; |
|
298 |
|
|
|
299 |
|
snprintf(filename, sizeof(filename), "%s\\vimfiles", cfg.config_dir); |
|
300 |
|
fp = fopen(filename, "w"); |
|
301 |
|
snprintf(filename, sizeof(filename), "%s\\%s", |
|
302 |
|
view->curr_dir, |
|
303 |
|
view->dir_entry[view->list_pos].name); |
|
304 |
|
|
|
305 |
|
endwin(); |
|
306 |
|
fprintf(fp, "%s", filename); |
|
307 |
|
fclose(fp); |
|
308 |
|
exit(0); |
|
309 |
|
} |
|
310 |
|
/* |
|
311 |
|
|
|
312 |
|
if(FILE_ATTRIBUTE_EXECUTABLE == view->dir_entry[view->list_pos].type) |
|
313 |
|
{ |
|
314 |
|
if(cfg.auto_execute) |
|
315 |
|
{ |
|
316 |
|
char buf[PATH_MAX]; |
|
317 |
|
snprintf(buf, sizeof(buf), "./%s", get_current_file_name(view)); |
|
318 |
|
shellout(buf, 1); |
|
319 |
|
return; |
|
320 |
|
} |
|
321 |
|
else // Check for a filetype |
|
322 |
|
{ |
|
323 |
|
char *program = NULL; |
|
324 |
|
|
|
325 |
|
if((program = get_default_program_for_file( |
|
326 |
|
view->dir_entry[view->list_pos].name)) != NULL) |
|
327 |
|
{ |
|
328 |
|
if(strchr(program, '%')) |
|
329 |
|
{ |
|
330 |
|
int m = 0; |
|
331 |
|
int s = 0; |
|
332 |
|
char *command = expand_macros(view, program, NULL, &m, &s); |
|
333 |
|
shellout(command, 0); |
|
334 |
|
my_free(command); |
|
335 |
|
return; |
|
336 |
|
} |
|
337 |
|
else |
|
338 |
|
{ |
|
339 |
|
char buf[PATH_MAX *2]; |
|
340 |
|
char *temp = escape_filename(view->dir_entry[view->list_pos].name, 0); |
|
341 |
|
|
|
342 |
|
snprintf(buf, sizeof(buf), "%s %s", program, temp); |
|
343 |
|
shellout(buf, 0); |
|
344 |
|
my_free(program); |
|
345 |
|
my_free(temp); |
|
346 |
|
return; |
|
347 |
|
} |
|
348 |
|
} else // vi is set as the default for any extension without a program |
|
349 |
|
{ |
|
350 |
|
view_file(view); |
|
351 |
|
} |
|
352 |
|
return; |
|
353 |
|
} |
|
354 |
|
} |
|
355 |
|
*/ |
|
356 |
|
if(NORMAL == view->dir_entry[view->list_pos].type) |
|
357 |
|
{ |
|
358 |
|
char *program = NULL; |
|
359 |
|
|
|
360 |
|
if((program = get_default_program_for_file( |
|
361 |
|
view->dir_entry[view->list_pos].name)) != NULL) |
|
362 |
|
{ |
|
363 |
|
if(strchr(program, '%')) |
|
364 |
|
{ |
|
365 |
|
int s = 0; |
|
366 |
|
char *command = expand_macros(view, program, NULL, &s); |
|
367 |
|
shellout(command, 0); |
|
368 |
|
my_free(command); |
|
369 |
|
return; |
|
370 |
|
} |
|
371 |
|
else |
|
372 |
|
{ |
|
373 |
|
char buf[PATH_MAX]; |
|
374 |
|
char *temp = escape_filename(view->dir_entry[view->list_pos].name, 0); |
|
375 |
|
|
|
376 |
|
snprintf(buf, sizeof(buf), "%s %s", program, temp); |
|
377 |
|
shellout(buf, 0); |
|
378 |
|
my_free(program); |
|
379 |
|
my_free(temp); |
|
380 |
|
return; |
|
381 |
|
} |
|
382 |
|
} |
|
383 |
|
// use Windows default program for file extension |
|
384 |
|
|
|
385 |
|
else if (ShellExecute(NULL, "open", view->dir_entry[view->list_pos].name, NULL, NULL, SW_SHOW) > 32) |
|
386 |
|
return; |
|
387 |
|
|
|
388 |
|
else /* vi is set as the default for any extension without a program */ |
|
389 |
|
view_file(view); |
|
390 |
|
|
|
391 |
|
} |
|
392 |
|
/* |
|
393 |
|
if(FILE_ATTRIBUTE_REPARSE_POINT == view->dir_entry[view->list_pos].type) |
|
394 |
|
{ |
|
395 |
|
char linkto[PATH_MAX]; |
|
396 |
|
int len; |
|
397 |
|
char *filename = strdup(view->dir_entry[view->list_pos].name); |
|
398 |
|
len = strlen(filename); |
|
399 |
|
if (filename[len - 1] == '/') |
|
400 |
|
filename[len - 1] = '\0'; |
|
401 |
|
|
|
402 |
|
len = readlink (filename, linkto, sizeof (linkto)); |
|
403 |
|
|
|
404 |
|
if (len > 0) |
|
405 |
|
{ |
|
406 |
|
struct stat s; |
|
407 |
|
int is_dir = 0; |
|
408 |
|
int is_file = 0; |
|
409 |
|
char *dir = NULL; |
|
410 |
|
char *file = NULL; |
|
411 |
|
char *link_dup = strdup(linkto); |
|
412 |
|
linkto[len] = '\0'; |
|
413 |
|
lstat(linkto, &s); |
|
414 |
|
|
|
415 |
|
if((s.st_mode & S_IFMT) == S_IFDIR) |
|
416 |
|
{ |
|
417 |
|
is_dir = 1; |
|
418 |
|
dir = strdup(linkto); |
|
419 |
|
} |
|
420 |
|
else |
|
421 |
|
{ |
|
422 |
|
int x; |
|
423 |
|
for(x = strlen(linkto); x > 0; x--) |
|
424 |
|
{ |
|
425 |
|
if(linkto[x] == '/') |
|
426 |
|
{ |
|
427 |
|
linkto[x] = '\0'; |
|
428 |
|
lstat(linkto, &s); |
|
429 |
|
if((s.st_mode & S_IFMT) == S_IFDIR) |
|
430 |
|
{ |
|
431 |
|
is_dir = 1; |
|
432 |
|
dir = strdup(linkto); |
|
433 |
|
break; |
|
434 |
|
} |
|
435 |
|
} |
|
436 |
|
} |
|
437 |
|
if((file = strrchr(link_dup, '/'))) |
|
438 |
|
{ |
|
439 |
|
file++; |
|
440 |
|
is_file = 1; |
|
441 |
|
} |
|
442 |
|
} |
|
443 |
|
if(is_dir) |
|
444 |
|
{ |
|
445 |
|
change_directory(view, dir); |
|
446 |
|
load_dir_list(view, 0); |
|
447 |
|
|
|
448 |
|
if(is_file) |
|
449 |
|
{ |
|
450 |
|
int pos = find_file_pos_in_list(view, file); |
|
451 |
|
if(pos >= 0) |
|
452 |
|
moveto_list_pos(view, pos); |
|
453 |
|
|
|
454 |
|
} |
|
455 |
|
else |
|
456 |
|
{ |
|
457 |
|
moveto_list_pos(view, 0); |
|
458 |
|
} |
|
459 |
|
} |
|
460 |
|
else |
|
461 |
|
{ |
|
462 |
|
int pos = find_file_pos_in_list(view, link_dup); |
|
463 |
|
if(pos >= 0) |
|
464 |
|
moveto_list_pos(view, pos); |
|
465 |
|
} |
|
466 |
|
my_free(link_dup); |
|
467 |
|
} |
|
468 |
|
else |
|
469 |
|
status_bar_message("Couldn't Resolve Link"); |
|
470 |
|
} |
|
471 |
|
*/ |
|
472 |
|
} |
|
473 |
|
|
|
474 |
|
|
|
475 |
|
int |
|
476 |
|
pipe_and_capture_errors(char *command) |
|
477 |
|
{ |
|
478 |
|
/* |
|
479 |
|
int file_pipes[2]; |
|
480 |
|
int pid; |
|
481 |
|
int nread; |
|
482 |
|
int error = 0; |
|
483 |
|
char *args[4]; |
|
484 |
|
|
|
485 |
|
if (pipe (file_pipes) != 0) |
|
486 |
|
return 1; |
|
487 |
|
|
|
488 |
|
if ((pid = fork ()) == -1) |
|
489 |
|
return 1; |
|
490 |
|
|
|
491 |
|
if (pid == 0) |
|
492 |
|
{ |
|
493 |
|
close(1); |
|
494 |
|
close(2); |
|
495 |
|
dup(file_pipes[1]); |
|
496 |
|
close (file_pipes[0]); |
|
497 |
|
close (file_pipes[1]); |
|
498 |
|
|
|
499 |
|
args[0] = "sh"; |
|
500 |
|
args[1] = "-c"; |
|
501 |
|
args[2] = command; |
|
502 |
|
args[3] = NULL; |
|
503 |
|
execvp (args[0], args); |
|
504 |
|
exit (127); |
|
505 |
|
} |
|
506 |
|
else |
|
507 |
|
{ |
|
508 |
|
char buf[1024]; |
|
509 |
|
close (file_pipes[1]); |
|
510 |
|
while((nread = read(*file_pipes, buf, sizeof(buf) -1)) > 0) |
|
511 |
|
{ |
|
512 |
|
buf[nread] = '\0'; |
|
513 |
|
error = nread; |
|
514 |
|
} |
|
515 |
|
if(error > 1) |
|
516 |
|
{ |
|
517 |
|
char title[strlen(command) +4]; |
|
518 |
|
snprintf(title, sizeof(title), " %s ", command); |
|
519 |
|
show_error_msg(title, buf); |
|
520 |
|
return 1; |
|
521 |
|
} |
|
522 |
|
} |
|
523 |
|
*/ |
|
524 |
|
return 0; |
|
525 |
|
} |
|
526 |
|
|
|
527 |
|
|
|
528 |
|
void |
|
529 |
|
delete_file(FileView *view) |
|
530 |
|
{ |
|
531 |
|
char buf[PATH_MAX]; |
|
532 |
|
char newbuf[PATH_MAX]; |
|
533 |
|
int x; |
|
534 |
|
int retval = 1; |
|
535 |
|
int answer = 0; |
|
536 |
|
|
|
537 |
|
if(!view->selected_files) |
|
538 |
|
{ |
|
539 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
540 |
|
view->selected_files = 1; |
|
541 |
|
} |
|
542 |
|
|
|
543 |
|
get_all_selected_files(view); |
|
544 |
|
yank_selected_files(view); |
|
545 |
|
strncpy(curr_stats.yanked_files_dir, cfg.trash_dir, |
|
546 |
|
sizeof(curr_stats.yanked_files_dir) -1); |
|
547 |
|
|
|
548 |
|
for(x = 0; x < view->selected_files; x++) |
|
549 |
|
{ |
|
550 |
|
if(!strcmp("../", view->selected_filelist[x])) |
|
551 |
|
{ |
|
552 |
|
show_error_msg(" Background Process Error ", |
|
553 |
|
"You cannot delete the ../ directory "); |
|
554 |
|
continue; |
|
555 |
|
} |
|
556 |
|
snprintf(buf, sizeof(buf), "%s\\%s", view->curr_dir, |
|
557 |
|
view->selected_filelist[x]); |
|
558 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", cfg.trash_dir, |
|
559 |
|
view->selected_filelist[x]); |
|
560 |
|
retval = MoveFile(buf, newbuf); |
|
561 |
|
if(!retval) |
|
562 |
|
{ |
|
563 |
|
DWORD dw = GetLastError(); |
|
564 |
|
|
|
565 |
|
if((int)dw == 183) |
|
566 |
|
{ |
|
567 |
|
if (answer != 1) |
|
568 |
|
answer = show_overwrite_file_menu(view->selected_filelist[x]); |
|
569 |
|
if (answer != 2) |
|
570 |
|
retval = MoveFileEx(buf, newbuf, MOVEFILE_REPLACE_EXISTING); |
|
571 |
|
|
|
572 |
|
} |
|
573 |
|
else |
|
574 |
|
show_error_msg("Error in deleting file ", |
|
575 |
|
"Error in deleting file. "); |
|
576 |
|
} |
|
577 |
|
|
|
578 |
|
// background_and_wait_for_errors(buf); |
|
579 |
|
} |
|
580 |
|
free_selected_file_array(view); |
|
581 |
|
view->selected_files = 0; |
|
582 |
|
|
|
583 |
|
load_dir_list(view, 1); |
|
584 |
|
|
|
585 |
|
moveto_list_pos(view, view->list_pos); |
|
586 |
|
} |
|
587 |
|
|
|
588 |
|
void |
|
589 |
|
file_chmod(FileView *view, char *path, char *mode, int recurse_dirs) |
|
590 |
|
{ |
|
591 |
|
char cmd[PATH_MAX + 128] = " "; |
|
592 |
|
|
|
593 |
|
if (recurse_dirs) |
|
594 |
|
snprintf(cmd, sizeof(cmd), "chmod -R %s %s", mode, path); |
|
595 |
|
else |
|
596 |
|
snprintf(cmd, sizeof(cmd), "chmod %s %s", mode, path); |
|
597 |
|
|
|
598 |
|
start_background_job(cmd); |
|
599 |
|
|
|
600 |
|
load_dir_list(view, 1); |
|
601 |
|
moveto_list_pos(view, view->list_pos); |
|
602 |
|
|
|
603 |
|
} |
|
604 |
|
|
|
605 |
|
static void |
|
606 |
|
reset_change_window(void) |
|
607 |
|
{ |
|
608 |
|
curs_set(0); |
|
609 |
|
werase(change_win); |
|
610 |
|
update_all_windows(); |
|
611 |
|
if(curr_stats.need_redraw) |
|
612 |
|
redraw_window(); |
|
613 |
|
} |
|
614 |
|
|
|
615 |
|
void |
|
616 |
|
change_file_owner(char *file) |
|
617 |
|
{ |
|
618 |
|
|
|
619 |
|
} |
|
620 |
|
|
|
621 |
|
void |
|
622 |
|
change_file_group(char *file) |
|
623 |
|
{ |
|
624 |
|
|
|
625 |
|
} |
|
626 |
|
|
|
627 |
|
void |
|
628 |
|
set_perm_string(FileView *view, int *perms, char *file) |
|
629 |
|
{ |
|
630 |
|
int i = 0; |
|
631 |
|
char *add_perm[] = {"u+r", "u+w", "u+x", "u+s", "g+r", "g+w", "g+x", "g+s", |
|
632 |
|
"o+r", "o+w", "o+x", "o+t"}; |
|
633 |
|
char *sub_perm[] = { "u-r", "u-w", "u-x", "u-s", "g-r", "g-w", "g-x", "g-s", |
|
634 |
|
"o-r", "o-w", "o-x", "o-t"}; |
|
635 |
|
char perm_string[64] = " "; |
|
636 |
|
|
|
637 |
|
for (i = 0; i < 12; i++) |
|
638 |
|
{ |
|
639 |
|
if (perms[i]) |
|
640 |
|
strcat(perm_string, add_perm[i]); |
|
641 |
|
else |
|
642 |
|
strcat(perm_string, sub_perm[i]); |
|
643 |
|
|
|
644 |
|
strcat(perm_string, ","); |
|
645 |
|
} |
|
646 |
|
perm_string[strlen(perm_string) - 1] = '\0'; /* Remove last , */ |
|
647 |
|
|
|
648 |
|
file_chmod(view, file, perm_string, perms[12]); |
|
649 |
|
} |
|
650 |
|
|
|
651 |
|
static void |
|
652 |
|
permissions_key_cb(FileView *view, int *perms, int isdir) |
|
653 |
|
{ |
|
654 |
|
int done = 0; |
|
655 |
|
int abort = 0; |
|
656 |
|
int top = 3; |
|
657 |
|
int bottom = 16; |
|
658 |
|
int curr = 3; |
|
659 |
|
int permnum = 0; |
|
660 |
|
int step = 1; |
|
661 |
|
int col = 9; |
|
662 |
|
char filename[PATH_MAX]; |
|
663 |
|
char path[PATH_MAX]; |
|
664 |
|
int changed = 0; |
|
665 |
|
|
|
666 |
|
if (isdir) |
|
667 |
|
bottom = 17; |
|
668 |
|
|
|
669 |
|
snprintf(filename, sizeof(filename), "%s", |
|
670 |
|
view->dir_entry[view->list_pos].name); |
|
671 |
|
snprintf(path, sizeof(path), "%s/%s", view->curr_dir, |
|
672 |
|
view->dir_entry[view->list_pos].name); |
|
673 |
|
|
|
674 |
|
curs_set(1); |
|
675 |
|
wmove(change_win, curr, col); |
|
676 |
|
wrefresh(change_win); |
|
677 |
|
|
|
678 |
|
while(!done) |
|
679 |
|
{ |
|
680 |
|
int key = wgetch(change_win); |
|
681 |
|
|
|
682 |
|
switch(key) |
|
683 |
|
{ |
|
684 |
|
case 'j': |
|
685 |
|
{ |
|
686 |
|
curr+= step; |
|
687 |
|
permnum++; |
|
688 |
|
|
|
689 |
|
if(curr > bottom) |
|
690 |
|
{ |
|
691 |
|
curr-= step; |
|
692 |
|
permnum--; |
|
693 |
|
} |
|
694 |
|
if (curr == 7 || curr == 12) |
|
695 |
|
curr++; |
|
696 |
|
|
|
697 |
|
wmove(change_win, curr, col); |
|
698 |
|
wrefresh(change_win); |
|
699 |
|
} |
|
700 |
|
break; |
|
701 |
|
case 'k': |
|
702 |
|
{ |
|
703 |
|
curr-= step; |
|
704 |
|
permnum--; |
|
705 |
|
if(curr < top) |
|
706 |
|
{ |
|
707 |
|
curr+= step; |
|
708 |
|
permnum++; |
|
709 |
|
} |
|
710 |
|
|
|
711 |
|
if (curr == 7 || curr == 12) |
|
712 |
|
curr--; |
|
713 |
|
|
|
714 |
|
wmove(change_win, curr, col); |
|
715 |
|
wrefresh(change_win); |
|
716 |
|
} |
|
717 |
|
break; |
|
718 |
|
case 't': |
|
719 |
|
case 32: /* ascii Spacebar */ |
|
720 |
|
{ |
|
721 |
|
changed++; |
|
722 |
|
if (perms[permnum]) |
|
723 |
|
{ |
|
724 |
|
perms[permnum] = 0; |
|
725 |
|
mvwaddch(change_win, curr, col, ' '); |
|
726 |
|
} |
|
727 |
|
else |
|
728 |
|
{ |
|
729 |
|
perms[permnum] = 1; |
|
730 |
|
mvwaddch(change_win, curr, col, '*'); |
|
731 |
|
} |
|
732 |
|
|
|
733 |
|
wmove(change_win, curr, col); |
|
734 |
|
wrefresh(change_win); |
|
735 |
|
} |
|
736 |
|
break; |
|
737 |
|
case 3: /* ascii Ctrl C */ |
|
738 |
|
case 27: /* ascii Escape */ |
|
739 |
|
done = 1; |
|
740 |
|
abort = 1; |
|
741 |
|
break; |
|
742 |
|
case 'l': |
|
743 |
|
case 13: /* ascii Return */ |
|
744 |
|
done = 1; |
|
745 |
|
break; |
|
746 |
|
default: |
|
747 |
|
break; |
|
748 |
|
} |
|
749 |
|
} |
|
750 |
|
|
|
751 |
|
reset_change_window(); |
|
752 |
|
|
|
753 |
|
curs_set(0); |
|
754 |
|
|
|
755 |
|
if (abort) |
|
756 |
|
{ |
|
757 |
|
moveto_list_pos(view, find_file_pos_in_list(view, filename)); |
|
758 |
|
return; |
|
759 |
|
} |
|
760 |
|
|
|
761 |
|
if (changed) |
|
762 |
|
{ |
|
763 |
|
set_perm_string(view, perms, path); |
|
764 |
|
load_dir_list(view, 1); |
|
765 |
|
moveto_list_pos(view, view->curr_line); |
|
766 |
|
} |
|
767 |
|
|
|
768 |
|
} |
|
769 |
|
|
|
770 |
|
static void |
|
771 |
|
change_key_cb(FileView *view, int type) |
|
772 |
|
{ |
|
773 |
|
int done = 0; |
|
774 |
|
int abort = 0; |
|
775 |
|
int top = 2; |
|
776 |
|
int bottom = 8; |
|
777 |
|
int curr = 2; |
|
778 |
|
int step = 2; |
|
779 |
|
int col = 6; |
|
780 |
|
char filename[PATH_MAX]; |
|
781 |
|
|
|
782 |
|
snprintf(filename, sizeof(filename), "%s", |
|
783 |
|
view->dir_entry[view->list_pos].name); |
|
784 |
|
|
|
785 |
|
curs_set(0); |
|
786 |
|
wmove(change_win, curr, col); |
|
787 |
|
wrefresh(change_win); |
|
788 |
|
|
|
789 |
|
while(!done) |
|
790 |
|
{ |
|
791 |
|
int key = wgetch(change_win); |
|
792 |
|
|
|
793 |
|
switch(key) |
|
794 |
|
{ |
|
795 |
|
case 'j': |
|
796 |
|
{ |
|
797 |
|
mvwaddch(change_win, curr, col, ' '); |
|
798 |
|
curr+= step; |
|
799 |
|
|
|
800 |
|
if(curr > bottom) |
|
801 |
|
curr-= step; |
|
802 |
|
|
|
803 |
|
mvwaddch(change_win, curr, col, '*'); |
|
804 |
|
wmove(change_win, curr, col); |
|
805 |
|
wrefresh(change_win); |
|
806 |
|
} |
|
807 |
|
break; |
|
808 |
|
case 'k': |
|
809 |
|
{ |
|
810 |
|
|
|
811 |
|
mvwaddch(change_win, curr, col, ' '); |
|
812 |
|
curr-= step; |
|
813 |
|
if(curr < top) |
|
814 |
|
curr+= step; |
|
815 |
|
|
|
816 |
|
mvwaddch(change_win, curr, col, '*'); |
|
817 |
|
wmove(change_win, curr, col); |
|
818 |
|
wrefresh(change_win); |
|
819 |
|
} |
|
820 |
|
break; |
|
821 |
|
case 3: /* ascii Ctrl C */ |
|
822 |
|
case 27: /* ascii Escape */ |
|
823 |
|
done = 1; |
|
824 |
|
abort = 1; |
|
825 |
|
break; |
|
826 |
|
case 'l': |
|
827 |
|
case 13: /* ascii Return */ |
|
828 |
|
done = 1; |
|
829 |
|
break; |
|
830 |
|
default: |
|
831 |
|
break; |
|
832 |
|
} |
|
833 |
|
} |
|
834 |
|
|
|
835 |
|
reset_change_window(); |
|
836 |
|
|
|
837 |
|
if(abort) |
|
838 |
|
{ |
|
839 |
|
moveto_list_pos(view, find_file_pos_in_list(view, filename)); |
|
840 |
|
return; |
|
841 |
|
} |
|
842 |
|
|
|
843 |
|
switch(type) |
|
844 |
|
{ |
|
845 |
|
case FILE_CHANGE: |
|
846 |
|
{ |
|
847 |
|
if (curr == FILE_NAME) |
|
848 |
|
rename_file(view); |
|
849 |
|
else |
|
850 |
|
show_change_window(view, curr); |
|
851 |
|
/* |
|
852 |
|
char * filename = get_current_file_name(view); |
|
853 |
|
switch(curr) |
|
854 |
|
{ |
|
855 |
|
case FILE_NAME: |
|
856 |
|
rename_file(view); |
|
857 |
|
break; |
|
858 |
|
case FILE_OWNER: |
|
859 |
|
change_file_owner(filename); |
|
860 |
|
break; |
|
861 |
|
case FILE_GROUP: |
|
862 |
|
change_file_group(filename); |
|
863 |
|
break; |
|
864 |
|
case FILE_PERMISSIONS: |
|
865 |
|
show_change_window(view, type); |
|
866 |
|
break; |
|
867 |
|
default: |
|
868 |
|
break; |
|
869 |
|
} |
|
870 |
|
*/ |
|
871 |
|
} |
|
872 |
|
break; |
|
873 |
|
case FILE_NAME: |
|
874 |
|
break; |
|
875 |
|
case FILE_OWNER: |
|
876 |
|
break; |
|
877 |
|
case FILE_GROUP: |
|
878 |
|
break; |
|
879 |
|
case FILE_PERMISSIONS: |
|
880 |
|
break; |
|
881 |
|
default: |
|
882 |
|
break; |
|
883 |
|
} |
|
884 |
|
} |
|
885 |
|
|
|
886 |
|
void |
|
887 |
|
show_file_permissions_menu(FileView *view, int x) |
|
888 |
|
{ |
|
889 |
|
//mode_t mode = view->dir_entry[view->list_pos].mode; |
|
890 |
|
char *filename = get_current_file_name(view); |
|
891 |
|
int perms[] = {0,0,0,0,0,0,0,0,0,0,0,0,0}; |
|
892 |
|
int isdir = 0; |
|
893 |
|
|
|
894 |
|
if (strlen(filename) > x - 2) |
|
895 |
|
filename[x - 4] = '\0'; |
|
896 |
|
|
|
897 |
|
mvwaddnstr(change_win, 1, (x - strlen(filename))/2, filename, x - 2); |
|
898 |
|
|
|
899 |
|
mvwaddstr(change_win, 3, 2, "Owner [ ] Read"); |
|
900 |
|
/* |
|
901 |
|
if (mode & S_IRUSR) |
|
902 |
|
{ |
|
903 |
|
perms[0] = 1; |
|
904 |
|
mvwaddch(change_win, 3, 9, '*'); |
|
905 |
|
} |
|
906 |
|
mvwaddstr(change_win, 4, 6, " [ ] Write"); |
|
907 |
|
|
|
908 |
|
if (mode & S_IWUSR) |
|
909 |
|
{ |
|
910 |
|
perms[1] = 1; |
|
911 |
|
mvwaddch(change_win, 4, 9, '*'); |
|
912 |
|
} |
|
913 |
|
mvwaddstr(change_win, 5, 6, " [ ] Execute"); |
|
914 |
|
|
|
915 |
|
if (mode & S_IXUSR) |
|
916 |
|
{ |
|
917 |
|
perms[2] = 1; |
|
918 |
|
mvwaddch(change_win, 5, 9, '*'); |
|
919 |
|
} |
|
920 |
|
|
|
921 |
|
mvwaddstr(change_win, 6, 6, " [ ] SetUID"); |
|
922 |
|
if (mode & S_ISUID) |
|
923 |
|
{ |
|
924 |
|
perms[3] = 1; |
|
925 |
|
mvwaddch(change_win, 6, 9, '*'); |
|
926 |
|
} |
|
927 |
|
|
|
928 |
|
mvwaddstr(change_win, 8, 2, "Group [ ] Read"); |
|
929 |
|
if (mode & S_IRGRP) |
|
930 |
|
{ |
|
931 |
|
perms[4] = 1; |
|
932 |
|
mvwaddch(change_win, 8, 9, '*'); |
|
933 |
|
} |
|
934 |
|
|
|
935 |
|
mvwaddstr(change_win, 9, 6, " [ ] Write"); |
|
936 |
|
if (mode & S_IWGRP) |
|
937 |
|
{ |
|
938 |
|
perms[5] = 1; |
|
939 |
|
mvwaddch(change_win, 9, 9, '*'); |
|
940 |
|
} |
|
941 |
|
|
|
942 |
|
mvwaddstr(change_win, 10, 6, " [ ] Execute"); |
|
943 |
|
if (mode & S_IXGRP) |
|
944 |
|
{ |
|
945 |
|
perms[6] = 1; |
|
946 |
|
mvwaddch(change_win, 10, 9, '*'); |
|
947 |
|
} |
|
948 |
|
|
|
949 |
|
mvwaddstr(change_win, 11, 6, " [ ] SetGID"); |
|
950 |
|
if (mode & S_ISGID) |
|
951 |
|
{ |
|
952 |
|
perms[7] = 1; |
|
953 |
|
mvwaddch(change_win, 11, 9, '*'); |
|
954 |
|
} |
|
955 |
|
|
|
956 |
|
mvwaddstr(change_win, 13, 2, "Other [ ] Read"); |
|
957 |
|
if (mode & S_IROTH) |
|
958 |
|
{ |
|
959 |
|
perms[8] = 1; |
|
960 |
|
mvwaddch(change_win, 13, 9, '*'); |
|
961 |
|
} |
|
962 |
|
|
|
963 |
|
mvwaddstr(change_win, 14, 6, " [ ] Write"); |
|
964 |
|
if (mode & S_IWOTH) |
|
965 |
|
{ |
|
966 |
|
perms[9] = 1; |
|
967 |
|
mvwaddch(change_win, 14, 9, '*'); |
|
968 |
|
} |
|
969 |
|
|
|
970 |
|
mvwaddstr(change_win, 15, 6, " [ ] Execute"); |
|
971 |
|
if (mode & S_IXOTH) |
|
972 |
|
{ |
|
973 |
|
perms[10] = 1; |
|
974 |
|
mvwaddch(change_win, 15, 9, '*'); |
|
975 |
|
} |
|
976 |
|
|
|
977 |
|
mvwaddstr(change_win, 16, 6, " [ ] Sticky"); |
|
978 |
|
if (mode & S_ISVTX) |
|
979 |
|
{ |
|
980 |
|
perms[11] = 1; |
|
981 |
|
mvwaddch(change_win, 16, 9, '*'); |
|
982 |
|
} |
|
983 |
|
|
|
984 |
|
if (is_dir(filename)) |
|
985 |
|
{ |
|
986 |
|
mvwaddstr(change_win, 17, 6, " [ ] Set Recursively"); |
|
987 |
|
isdir = 1; |
|
988 |
|
} |
|
989 |
|
*/ |
|
990 |
|
|
|
991 |
|
permissions_key_cb(view, perms, isdir); |
|
992 |
|
} |
|
993 |
|
|
|
994 |
|
|
|
995 |
|
void |
|
996 |
|
show_change_window(FileView *view, int type) |
|
997 |
|
{ |
|
998 |
|
int x, y; |
|
999 |
|
|
|
1000 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
1001 |
|
curs_set(0); |
|
1002 |
|
doupdate(); |
|
1003 |
|
wclear(change_win); |
|
1004 |
|
|
|
1005 |
|
getmaxyx(stdscr, y, x); |
|
1006 |
|
mvwin(change_win, (y - 20)/2, (x - 30)/2); |
|
1007 |
|
box(change_win, ACS_VLINE, ACS_HLINE); |
|
1008 |
|
|
|
1009 |
|
curs_set(1); |
|
1010 |
|
wrefresh(change_win); |
|
1011 |
|
|
|
1012 |
|
|
|
1013 |
|
switch(type) |
|
1014 |
|
{ |
|
1015 |
|
case FILE_CHANGE: |
|
1016 |
|
{ |
|
1017 |
|
mvwaddstr(change_win, 0, (x - 20)/2, " Change Current File "); |
|
1018 |
|
mvwaddstr(change_win, 2, 4, " [ ] Name"); |
|
1019 |
|
mvwaddstr(change_win, 4, 4, " [ ] Owner"); |
|
1020 |
|
mvwaddstr(change_win, 6, 4, " [ ] Group"); |
|
1021 |
|
mvwaddstr(change_win, 8, 4, " [ ] Permissions"); |
|
1022 |
|
mvwaddch(change_win, 2, 6, '*'); |
|
1023 |
|
change_key_cb(view, type); |
|
1024 |
|
} |
|
1025 |
|
break; |
|
1026 |
|
case FILE_NAME: |
|
1027 |
|
return; |
|
1028 |
|
break; |
|
1029 |
|
case FILE_OWNER: |
|
1030 |
|
return; |
|
1031 |
|
break; |
|
1032 |
|
case FILE_GROUP: |
|
1033 |
|
return; |
|
1034 |
|
break; |
|
1035 |
|
case FILE_PERMISSIONS: |
|
1036 |
|
show_file_permissions_menu(view, x); |
|
1037 |
|
break; |
|
1038 |
|
default: |
|
1039 |
|
break; |
|
1040 |
|
} |
|
1041 |
|
} |
File src/keys.c added (mode: 100644) (index 0000000..bf11746) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
|
|
20 |
|
#include<curses.h> |
|
21 |
|
//#include<unistd.h> /* for chdir */ |
|
22 |
|
#include<string.h> /* strncpy */ |
|
23 |
|
#include<sys/time.h> /* select() */ |
|
24 |
|
#include<sys/types.h> /* select() */ |
|
25 |
|
#include<unistd.h> /* select() */ |
|
26 |
|
#include<windows.h> |
|
27 |
|
|
|
28 |
|
#include "background.h" |
|
29 |
|
#include "bookmarks.h" |
|
30 |
|
#include "color_scheme.h" |
|
31 |
|
#include "commands.h" |
|
32 |
|
#include "config.h" |
|
33 |
|
#include "file_info.h" |
|
34 |
|
#include "filelist.h" |
|
35 |
|
#include "fileops.h" |
|
36 |
|
#include "keys.h" |
|
37 |
|
#include "menus.h" |
|
38 |
|
#include "registers.h" |
|
39 |
|
#include "search.h" |
|
40 |
|
#include "signals.h" |
|
41 |
|
#include "sort.h" |
|
42 |
|
#include "status.h" |
|
43 |
|
#include "ui.h" |
|
44 |
|
#include "utils.h" |
|
45 |
|
#include "visual.h" |
|
46 |
|
|
|
47 |
|
void |
|
48 |
|
switch_views(void) |
|
49 |
|
{ |
|
50 |
|
FileView *tmp = curr_view; |
|
51 |
|
curr_view = other_view; |
|
52 |
|
other_view = tmp; |
|
53 |
|
} |
|
54 |
|
|
|
55 |
|
void |
|
56 |
|
clean_status_bar(FileView *view) |
|
57 |
|
{ |
|
58 |
|
werase(status_bar); |
|
59 |
|
wnoutrefresh(status_bar); |
|
60 |
|
} |
|
61 |
|
|
|
62 |
|
static void |
|
63 |
|
update_num_window(char *text) |
|
64 |
|
{ |
|
65 |
|
werase(num_win); |
|
66 |
|
mvwaddstr(num_win, 0, 0, text); |
|
67 |
|
wrefresh(num_win); |
|
68 |
|
} |
|
69 |
|
|
|
70 |
|
static void |
|
71 |
|
clear_num_window(void) |
|
72 |
|
{ |
|
73 |
|
werase(num_win); |
|
74 |
|
wrefresh(num_win); |
|
75 |
|
} |
|
76 |
|
|
|
77 |
|
static void |
|
78 |
|
reload_window(FileView *view) |
|
79 |
|
{ |
|
80 |
|
struct stat s; |
|
81 |
|
|
|
82 |
|
stat(view->curr_dir, &s); |
|
83 |
|
if(view != curr_view) |
|
84 |
|
change_directory(view, view->curr_dir); |
|
85 |
|
|
|
86 |
|
load_dir_list(view, 1); |
|
87 |
|
view->dir_mtime = s.st_mtime; |
|
88 |
|
|
|
89 |
|
if(view != curr_view) |
|
90 |
|
{ |
|
91 |
|
change_directory(curr_view, curr_view->curr_dir); |
|
92 |
|
mvwaddstr(view->win, view->curr_line, 0, "*"); |
|
93 |
|
wrefresh(view->win); |
|
94 |
|
} |
|
95 |
|
else |
|
96 |
|
moveto_list_pos(view, view->list_pos); |
|
97 |
|
|
|
98 |
|
} |
|
99 |
|
/* |
|
100 |
|
* This checks the modified times of the directories. |
|
101 |
|
*/ |
|
102 |
|
static void |
|
103 |
|
check_if_filelists_have_changed(FileView *view) |
|
104 |
|
{ |
|
105 |
|
struct stat s; |
|
106 |
|
|
|
107 |
|
stat(view->curr_dir, &s); |
|
108 |
|
if(s.st_mtime != view->dir_mtime) |
|
109 |
|
reload_window(view); |
|
110 |
|
|
|
111 |
|
if (curr_stats.number_of_windows != 1 && curr_stats.view != 1) |
|
112 |
|
{ |
|
113 |
|
stat(other_view->curr_dir, &s); |
|
114 |
|
if(s.st_mtime != other_view->dir_mtime) |
|
115 |
|
reload_window(other_view); |
|
116 |
|
} |
|
117 |
|
|
|
118 |
|
} |
|
119 |
|
|
|
120 |
|
static void |
|
121 |
|
repeat_last_command(FileView *view) |
|
122 |
|
{ |
|
123 |
|
if (0 > cfg.cmd_history_num) |
|
124 |
|
show_error_msg(" Command Error ", "Command history list is empty. "); |
|
125 |
|
else |
|
126 |
|
execute_command(view, cfg.cmd_history[0]); |
|
127 |
|
} |
|
128 |
|
|
|
129 |
|
|
|
130 |
|
void |
|
131 |
|
rename_file(FileView *view) |
|
132 |
|
{ |
|
133 |
|
char * filename = get_current_file_name(view); |
|
134 |
|
char command[1024]; |
|
135 |
|
int key; |
|
136 |
|
int pos = strlen(filename) + 1; |
|
137 |
|
int index = pos - 1; |
|
138 |
|
int done = 0; |
|
139 |
|
int abort = 0; |
|
140 |
|
int len = pos; |
|
141 |
|
int found = -1; |
|
142 |
|
char buf[view->window_width -2]; |
|
143 |
|
|
|
144 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR)); |
|
145 |
|
wmove(view->win, view->curr_line, 0); |
|
146 |
|
wclrtoeol(view->win); |
|
147 |
|
wmove(view->win, view->curr_line, 1); |
|
148 |
|
waddstr(view->win, filename); |
|
149 |
|
memset(buf, '\0', view->window_width -2); |
|
150 |
|
strncpy(buf, filename, sizeof(buf)); |
|
151 |
|
len = strlen(filename); |
|
152 |
|
wmove(view->win, view->curr_line, strlen(filename) + 1); |
|
153 |
|
|
|
154 |
|
curs_set(1); |
|
155 |
|
|
|
156 |
|
while(!done) |
|
157 |
|
{ |
|
158 |
|
if(curr_stats.freeze) |
|
159 |
|
continue; |
|
160 |
|
curs_set(1); |
|
161 |
|
flushinp(); |
|
162 |
|
curr_stats.getting_input = 1; |
|
163 |
|
key = wgetch(view->win); |
|
164 |
|
|
|
165 |
|
switch(key) |
|
166 |
|
{ |
|
167 |
|
case 27: /* ascii Escape */ |
|
168 |
|
case 3: /* ascii Ctrl C */ |
|
169 |
|
done = 1; |
|
170 |
|
abort = 1; |
|
171 |
|
break; |
|
172 |
|
case 13: /* ascii Return */ |
|
173 |
|
done = 1; |
|
174 |
|
break; |
|
175 |
|
/* This needs to be changed to a value that is read from |
|
176 |
|
* the termcap file. |
|
177 |
|
*/ |
|
178 |
|
case 0x7f: /* This is the one that works on my machine */ |
|
179 |
|
case 8: /* ascii Backspace ascii Ctrl H */ |
|
180 |
|
case KEY_BACKSPACE: /* ncurses BACKSPACE KEY */ |
|
181 |
|
{ |
|
182 |
|
/* |
|
183 |
|
if(index == len) |
|
184 |
|
{ |
|
185 |
|
*/ |
|
186 |
|
pos--; |
|
187 |
|
index--; |
|
188 |
|
len--; |
|
189 |
|
|
|
190 |
|
if(pos < 1) |
|
191 |
|
pos = 1; |
|
192 |
|
if(index < 0) |
|
193 |
|
index = 0; |
|
194 |
|
|
|
195 |
|
mvwdelch(view->win, view->curr_line, pos); |
|
196 |
|
buf[index] = '\0'; |
|
197 |
|
buf[len] = '\0'; |
|
198 |
|
// } |
|
199 |
|
} |
|
200 |
|
break; |
|
201 |
|
case KEY_LEFT: |
|
202 |
|
{ |
|
203 |
|
index--; |
|
204 |
|
pos--; |
|
205 |
|
|
|
206 |
|
if(index < 0) |
|
207 |
|
index = 0; |
|
208 |
|
|
|
209 |
|
if(pos < 1) |
|
210 |
|
pos = 1; |
|
211 |
|
|
|
212 |
|
wmove(view->win, view->curr_line, pos); |
|
213 |
|
|
|
214 |
|
} |
|
215 |
|
break; |
|
216 |
|
case KEY_RIGHT: |
|
217 |
|
{ |
|
218 |
|
index++; |
|
219 |
|
pos++; |
|
220 |
|
|
|
221 |
|
if(index > len) |
|
222 |
|
index = len; |
|
223 |
|
|
|
224 |
|
if(pos > len + 1) |
|
225 |
|
pos = len + 1; |
|
226 |
|
|
|
227 |
|
wmove(view->win, view->curr_line, pos); |
|
228 |
|
} |
|
229 |
|
break; |
|
230 |
|
default: |
|
231 |
|
if(key > 31 && key < 127) |
|
232 |
|
{ |
|
233 |
|
mvwaddch(view->win, view->curr_line, pos, key); |
|
234 |
|
buf[index] = key; |
|
235 |
|
index++; |
|
236 |
|
buf[index] = '\0'; |
|
237 |
|
if(len < index) |
|
238 |
|
{ |
|
239 |
|
len++; |
|
240 |
|
buf[index] = '\0'; |
|
241 |
|
} |
|
242 |
|
if(index > 62) |
|
243 |
|
{ |
|
244 |
|
abort = 1; |
|
245 |
|
done = 1; |
|
246 |
|
} |
|
247 |
|
|
|
248 |
|
pos++; |
|
249 |
|
len++; |
|
250 |
|
} |
|
251 |
|
break; |
|
252 |
|
} |
|
253 |
|
curr_stats.getting_input = 0; |
|
254 |
|
} |
|
255 |
|
curs_set(0); |
|
256 |
|
|
|
257 |
|
if(abort) |
|
258 |
|
{ |
|
259 |
|
load_dir_list(view, 1); |
|
260 |
|
moveto_list_pos(view, view->list_pos); |
|
261 |
|
return; |
|
262 |
|
} |
|
263 |
|
|
|
264 |
|
if (access(buf, F_OK) == 0 && strncmp(filename, buf, len) != 0) |
|
265 |
|
{ |
|
266 |
|
show_error_msg("File exists", "That file already exists. Will not overwrite."); |
|
267 |
|
|
|
268 |
|
load_dir_list(view, 1); |
|
269 |
|
moveto_list_pos(view, view->list_pos); |
|
270 |
|
return; |
|
271 |
|
} |
|
272 |
|
snprintf(command, sizeof(command), "mv -f \'%s\' \'%s\'", filename, buf); |
|
273 |
|
|
|
274 |
|
my_system(command); |
|
275 |
|
|
|
276 |
|
load_dir_list(view, 0); |
|
277 |
|
found = find_file_pos_in_list(view, buf); |
|
278 |
|
if(found >= 0) |
|
279 |
|
moveto_list_pos(view, found); |
|
280 |
|
else |
|
281 |
|
moveto_list_pos(view, view->list_pos); |
|
282 |
|
} |
|
283 |
|
|
|
284 |
|
void |
|
285 |
|
remove_filename_filter(FileView *view) |
|
286 |
|
{ |
|
287 |
|
int found; |
|
288 |
|
char file[PATH_MAX]; |
|
289 |
|
|
|
290 |
|
snprintf(file, sizeof(file), "%s", |
|
291 |
|
view->dir_entry[view->list_pos].name); |
|
292 |
|
view->prev_filter = (char *)realloc(view->prev_filter, |
|
293 |
|
strlen(view->filename_filter) +1); |
|
294 |
|
snprintf(view->prev_filter, |
|
295 |
|
sizeof(view->prev_filter), view->filename_filter); |
|
296 |
|
view->filename_filter = (char *)realloc(view->filename_filter, |
|
297 |
|
strlen("*") +1); |
|
298 |
|
snprintf(view->filename_filter, |
|
299 |
|
sizeof(view->filename_filter), "*"); |
|
300 |
|
view->prev_invert = view->invert; |
|
301 |
|
view->invert = 0; |
|
302 |
|
load_dir_list(view, 0); |
|
303 |
|
found = find_file_pos_in_list(view, file); |
|
304 |
|
if(found >= 0) |
|
305 |
|
moveto_list_pos(view, found); |
|
306 |
|
else |
|
307 |
|
moveto_list_pos(view, view->list_pos); |
|
308 |
|
} |
|
309 |
|
|
|
310 |
|
static void |
|
311 |
|
restore_filename_filter(FileView *view) |
|
312 |
|
{ |
|
313 |
|
int found; |
|
314 |
|
char file[PATH_MAX]; |
|
315 |
|
|
|
316 |
|
snprintf(file, sizeof(file), "%s", |
|
317 |
|
view->dir_entry[view->list_pos].name); |
|
318 |
|
|
|
319 |
|
view->filename_filter = (char *)realloc(view->filename_filter, |
|
320 |
|
strlen(view->prev_filter) +1); |
|
321 |
|
snprintf(view->filename_filter, sizeof(view->filename_filter), |
|
322 |
|
"%s", view->prev_filter); |
|
323 |
|
view->invert = view->prev_invert; |
|
324 |
|
load_dir_list(view, 0); |
|
325 |
|
found = find_file_pos_in_list(view, file); |
|
326 |
|
|
|
327 |
|
|
|
328 |
|
if(found >= 0) |
|
329 |
|
moveto_list_pos(view, found); |
|
330 |
|
else |
|
331 |
|
moveto_list_pos(view, view->list_pos); |
|
332 |
|
} |
|
333 |
|
|
|
334 |
|
static void |
|
335 |
|
yank_files(FileView *view, int count, char *count_buf) |
|
336 |
|
{ |
|
337 |
|
int x; |
|
338 |
|
char buf[32]; |
|
339 |
|
|
|
340 |
|
if(count) |
|
341 |
|
{ |
|
342 |
|
int y = view->list_pos; |
|
343 |
|
|
|
344 |
|
for(x = 0; x < view->list_rows; x++) |
|
345 |
|
view->dir_entry[x].selected = 0; |
|
346 |
|
|
|
347 |
|
for(x = 0; x < atoi(count_buf); x++) |
|
348 |
|
{ |
|
349 |
|
view->dir_entry[y].selected = 1; |
|
350 |
|
y++; |
|
351 |
|
if (y >= view->list_rows) |
|
352 |
|
break; |
|
353 |
|
} |
|
354 |
|
view->selected_files = y - view->list_pos; |
|
355 |
|
} |
|
356 |
|
else if(!view->selected_files) |
|
357 |
|
{ |
|
358 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
359 |
|
view->selected_files = 1; |
|
360 |
|
} |
|
361 |
|
|
|
362 |
|
get_all_selected_files(view); |
|
363 |
|
yank_selected_files(view); |
|
364 |
|
free_selected_file_array(view); |
|
365 |
|
count = view->selected_files; |
|
366 |
|
|
|
367 |
|
for(x = 0; x < view->list_rows; x++) |
|
368 |
|
view->dir_entry[x].selected = 0; |
|
369 |
|
|
|
370 |
|
view->selected_files = 0; |
|
371 |
|
|
|
372 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
373 |
|
moveto_list_pos(view, view->list_pos); |
|
374 |
|
snprintf(buf, sizeof(buf), " %d %s yanked.", count, |
|
375 |
|
count == 1 ? "file" : "files"); |
|
376 |
|
status_bar_message(buf); |
|
377 |
|
} |
|
378 |
|
|
|
379 |
|
static void |
|
380 |
|
tag_file(FileView *view) |
|
381 |
|
{ |
|
382 |
|
if(view->dir_entry[view->list_pos].selected == 0) |
|
383 |
|
{ |
|
384 |
|
/* The ../ dir cannot be selected */ |
|
385 |
|
if (!strcmp(view->dir_entry[view->list_pos].name, "../")) |
|
386 |
|
return; |
|
387 |
|
|
|
388 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
389 |
|
view->selected_files++; |
|
390 |
|
} |
|
391 |
|
else |
|
392 |
|
{ |
|
393 |
|
view->dir_entry[view->list_pos].selected = 0; |
|
394 |
|
view->selected_files--; |
|
395 |
|
} |
|
396 |
|
|
|
397 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
398 |
|
wattron(view->win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
399 |
|
mvwaddstr(view->win, view->curr_line, 0, " "); |
|
400 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR)); |
|
401 |
|
wmove(view->win, view->curr_line, 0); |
|
402 |
|
} |
|
403 |
|
|
|
404 |
|
int |
|
405 |
|
put_files_from_register(FileView *view) |
|
406 |
|
{ |
|
407 |
|
int x; |
|
408 |
|
int i = -1; |
|
409 |
|
int y = 0; |
|
410 |
|
char buf[PATH_MAX + 4]; |
|
411 |
|
|
|
412 |
|
for (x = 0; x < NUM_REGISTERS; x++) |
|
413 |
|
{ |
|
414 |
|
if (reg[x].name == curr_stats.curr_register) |
|
415 |
|
{ |
|
416 |
|
i = x; |
|
417 |
|
break; |
|
418 |
|
} |
|
419 |
|
} |
|
420 |
|
|
|
421 |
|
if ((i < 0) || (reg[i].num_files < 1)) |
|
422 |
|
{ |
|
423 |
|
status_bar_message("Register is empty"); |
|
424 |
|
wrefresh(status_bar); |
|
425 |
|
return 1; |
|
426 |
|
} |
|
427 |
|
|
|
428 |
|
for (x = 0; x < reg[i].num_files; x++) |
|
429 |
|
{ |
|
430 |
|
snprintf(buf, sizeof(buf), "%s/%s", cfg.trash_dir, reg[i].files[x]); |
|
431 |
|
if (!access(buf, F_OK)) |
|
432 |
|
{ |
|
433 |
|
snprintf(buf, sizeof(buf), "mv \"%s/%s\" %s", |
|
434 |
|
cfg.trash_dir, reg[i].files[x], view->curr_dir); |
|
435 |
|
if ( background_and_wait_for_errors(buf)) |
|
436 |
|
y++; |
|
437 |
|
} |
|
438 |
|
} |
|
439 |
|
|
|
440 |
|
clear_register(curr_stats.curr_register); |
|
441 |
|
curr_stats.use_register = 0; |
|
442 |
|
curr_stats.register_saved = 0; |
|
443 |
|
|
|
444 |
|
if (y) |
|
445 |
|
{ |
|
446 |
|
snprintf(buf, sizeof(buf), " %d %s inserted", y, |
|
447 |
|
y==1 ? "file" : "files"); |
|
448 |
|
|
|
449 |
|
load_dir_list(view, 0); |
|
450 |
|
moveto_list_pos(view, view->curr_line); |
|
451 |
|
|
|
452 |
|
status_bar_message(buf); |
|
453 |
|
return 1; |
|
454 |
|
} |
|
455 |
|
|
|
456 |
|
return 0; |
|
457 |
|
} |
|
458 |
|
|
|
459 |
|
int |
|
460 |
|
put_files(FileView *view) |
|
461 |
|
{ |
|
462 |
|
int x; |
|
463 |
|
char buf[PATH_MAX]; |
|
464 |
|
char newbuf[PATH_MAX]; |
|
465 |
|
int y = 0; |
|
466 |
|
int retval = 1; |
|
467 |
|
int answer = 0; |
|
468 |
|
|
|
469 |
|
if (curr_stats.use_register && curr_stats.register_saved) |
|
470 |
|
return put_files_from_register(view); |
|
471 |
|
|
|
472 |
|
if (!curr_stats.num_yanked_files) |
|
473 |
|
return 0; |
|
474 |
|
|
|
475 |
|
|
|
476 |
|
for(x = 0; x < curr_stats.num_yanked_files; x++) |
|
477 |
|
{ |
|
478 |
|
if(!strcmp("../", curr_stats.yanked_files[x])) |
|
479 |
|
{ |
|
480 |
|
show_error_msg(" Background Process Error ", |
|
481 |
|
"You cannot move the ../ directory "); |
|
482 |
|
continue; |
|
483 |
|
} |
|
484 |
|
|
|
485 |
|
snprintf(buf, sizeof(buf), "%s\\%s", curr_stats.yanked_files_dir, |
|
486 |
|
curr_stats.yanked_files[x]); |
|
487 |
|
snprintf(newbuf, sizeof(newbuf), "%s\\%s", view->curr_dir, |
|
488 |
|
curr_stats.yanked_files[x]); |
|
489 |
|
|
|
490 |
|
retval = CopyFile(buf, newbuf, TRUE); |
|
491 |
|
y++; |
|
492 |
|
|
|
493 |
|
if(!retval) |
|
494 |
|
{ |
|
495 |
|
DWORD dw = GetLastError(); |
|
496 |
|
|
|
497 |
|
if((int)dw == 80) |
|
498 |
|
{ |
|
499 |
|
if (answer != 1) |
|
500 |
|
answer = |
|
501 |
|
show_overwrite_file_menu(curr_stats.yanked_files[x]); |
|
502 |
|
if (answer != 2) |
|
503 |
|
retval = CopyFile(buf, newbuf, FALSE); |
|
504 |
|
|
|
505 |
|
} |
|
506 |
|
else |
|
507 |
|
{ |
|
508 |
|
snprintf(newbuf, sizeof(newbuf), "-%d- is error code ", (int)dw); |
|
509 |
|
show_error_msg(" Error in copyinging file ", newbuf); |
|
510 |
|
show_error_msg(" Old buf is ", buf); |
|
511 |
|
} |
|
512 |
|
} |
|
513 |
|
} |
|
514 |
|
|
|
515 |
|
if (y) |
|
516 |
|
{ |
|
517 |
|
snprintf(buf, sizeof(buf), " %d %s inserted", y, |
|
518 |
|
y==1 ? "file" : "files"); |
|
519 |
|
|
|
520 |
|
load_dir_list(view, 0); |
|
521 |
|
moveto_list_pos(view, view->curr_line); |
|
522 |
|
|
|
523 |
|
status_bar_message(buf); |
|
524 |
|
|
|
525 |
|
return 1; |
|
526 |
|
} |
|
527 |
|
|
|
528 |
|
return 0; |
|
529 |
|
} |
|
530 |
|
|
|
531 |
|
void |
|
532 |
|
show_dot_files(FileView *view) |
|
533 |
|
{ |
|
534 |
|
int found; |
|
535 |
|
char file[256]; |
|
536 |
|
|
|
537 |
|
snprintf(file, sizeof(file), "%s", |
|
538 |
|
view->dir_entry[view->list_pos].name); |
|
539 |
|
view->hide_dot = 0; |
|
540 |
|
load_dir_list(view, 1); |
|
541 |
|
found = find_file_pos_in_list(view, file); |
|
542 |
|
|
|
543 |
|
if(found >= 0) |
|
544 |
|
moveto_list_pos(view, found); |
|
545 |
|
else |
|
546 |
|
moveto_list_pos(view, view->list_pos); |
|
547 |
|
} |
|
548 |
|
|
|
549 |
|
static void |
|
550 |
|
hide_dot_files(FileView *view) |
|
551 |
|
{ |
|
552 |
|
int found; |
|
553 |
|
char file[PATH_MAX]; |
|
554 |
|
|
|
555 |
|
snprintf(file, sizeof(file), "%s", |
|
556 |
|
view->dir_entry[view->list_pos].name); |
|
557 |
|
view->hide_dot = 1; |
|
558 |
|
load_dir_list(view, 1); |
|
559 |
|
found = find_file_pos_in_list(view, file); |
|
560 |
|
|
|
561 |
|
if(found >= 0) |
|
562 |
|
moveto_list_pos(view, found); |
|
563 |
|
else |
|
564 |
|
moveto_list_pos(view, view->list_pos); |
|
565 |
|
} |
|
566 |
|
|
|
567 |
|
static void |
|
568 |
|
toggle_dot_files(FileView *view) |
|
569 |
|
{ |
|
570 |
|
int found; |
|
571 |
|
char file[PATH_MAX]; |
|
572 |
|
|
|
573 |
|
snprintf(file, sizeof(file), "%s", |
|
574 |
|
view->dir_entry[view->list_pos].name); |
|
575 |
|
if(view->hide_dot) |
|
576 |
|
view->hide_dot = 0; |
|
577 |
|
else |
|
578 |
|
view->hide_dot = 1; |
|
579 |
|
load_dir_list(view, 1); |
|
580 |
|
found = find_file_pos_in_list(view, file); |
|
581 |
|
|
|
582 |
|
if(found >= 0) |
|
583 |
|
moveto_list_pos(view, found); |
|
584 |
|
else |
|
585 |
|
moveto_list_pos(view, view->list_pos); |
|
586 |
|
} |
|
587 |
|
|
|
588 |
|
void |
|
589 |
|
change_window(FileView **view) |
|
590 |
|
{ |
|
591 |
|
switch_views(); |
|
592 |
|
*view = curr_view; |
|
593 |
|
|
|
594 |
|
if (curr_stats.number_of_windows != 1) |
|
595 |
|
{ |
|
596 |
|
wattroff(other_view->title, A_BOLD); |
|
597 |
|
wattroff(other_view->win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
598 |
|
mvwaddstr(other_view->win, other_view->curr_line, 0, "*"); |
|
599 |
|
erase_current_line_bar(other_view); |
|
600 |
|
werase(other_view->title); |
|
601 |
|
wprintw(other_view->title, "%s", other_view->curr_dir); |
|
602 |
|
wnoutrefresh(other_view->title); |
|
603 |
|
} |
|
604 |
|
|
|
605 |
|
if (curr_stats.view) |
|
606 |
|
{ |
|
607 |
|
|
|
608 |
|
wbkgdset(curr_view->title, |
|
609 |
|
COLOR_PAIR(BORDER_COLOR + curr_view->color_scheme)); |
|
610 |
|
wbkgdset(curr_view->win, |
|
611 |
|
COLOR_PAIR(WIN_COLOR + curr_view->color_scheme)); |
|
612 |
|
change_directory(other_view, other_view->curr_dir); |
|
613 |
|
load_dir_list(other_view, 0); |
|
614 |
|
change_directory(curr_view, curr_view->curr_dir); |
|
615 |
|
load_dir_list(curr_view, 0); |
|
616 |
|
|
|
617 |
|
} |
|
618 |
|
|
|
619 |
|
change_directory(curr_view, curr_view->curr_dir); |
|
620 |
|
|
|
621 |
|
wattron(curr_view->title, A_BOLD); |
|
622 |
|
werase(curr_view->title); |
|
623 |
|
wprintw(curr_view->title, "%s", curr_view->curr_dir); |
|
624 |
|
wattroff(curr_view->title, A_BOLD); |
|
625 |
|
wnoutrefresh(curr_view->title); |
|
626 |
|
|
|
627 |
|
wnoutrefresh(other_view->win); |
|
628 |
|
wnoutrefresh(curr_view->win); |
|
629 |
|
|
|
630 |
|
|
|
631 |
|
if (curr_stats.number_of_windows == 1) |
|
632 |
|
load_dir_list(curr_view, 1); |
|
633 |
|
|
|
634 |
|
moveto_list_pos(curr_view, curr_view->list_pos); |
|
635 |
|
werase(status_bar); |
|
636 |
|
wnoutrefresh(status_bar); |
|
637 |
|
|
|
638 |
|
if (curr_stats.number_of_windows == 1) |
|
639 |
|
update_all_windows(); |
|
640 |
|
|
|
641 |
|
refresh(); |
|
642 |
|
|
|
643 |
|
|
|
644 |
|
} |
|
645 |
|
|
|
646 |
|
static void |
|
647 |
|
filter_selected_files(FileView *view) |
|
648 |
|
{ |
|
649 |
|
size_t buf_size = 0; |
|
650 |
|
int x; |
|
651 |
|
|
|
652 |
|
if(!view->selected_files) |
|
653 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
654 |
|
|
|
655 |
|
for(x = 0; x < view->list_rows; x++) |
|
656 |
|
{ |
|
657 |
|
if(view->dir_entry[x].selected) |
|
658 |
|
{ |
|
659 |
|
if(view->filtered) |
|
660 |
|
{ |
|
661 |
|
char *buf = NULL; |
|
662 |
|
|
|
663 |
|
buf_size = strlen(view->dir_entry[x].name) +7; |
|
664 |
|
buf = (char *)realloc(buf, strlen(view->dir_entry[x].name) +7); |
|
665 |
|
snprintf(buf, buf_size, |
|
666 |
|
"|\\<%s\\>$", view->dir_entry[x].name); |
|
667 |
|
view->filename_filter = (char *) |
|
668 |
|
realloc(view->filename_filter, strlen(view->filename_filter) + |
|
669 |
|
strlen(buf) +1); |
|
670 |
|
strcat(view->filename_filter, buf); |
|
671 |
|
view->filtered++; |
|
672 |
|
my_free(buf); |
|
673 |
|
} |
|
674 |
|
else |
|
675 |
|
{ |
|
676 |
|
buf_size = strlen(view->dir_entry[x].name) +6; |
|
677 |
|
view->filename_filter = (char *) |
|
678 |
|
realloc(view->filename_filter, strlen(view->dir_entry[x].name) +6); |
|
679 |
|
snprintf(view->filename_filter, buf_size, |
|
680 |
|
"\\<%s\\>$", view->dir_entry[x].name); |
|
681 |
|
view->filtered = 1; |
|
682 |
|
} |
|
683 |
|
} |
|
684 |
|
} |
|
685 |
|
view->invert = 1; |
|
686 |
|
clean_status_bar(view); |
|
687 |
|
load_dir_list(view, 1); |
|
688 |
|
moveto_list_pos(view, 0); |
|
689 |
|
} |
|
690 |
|
|
|
691 |
|
void |
|
692 |
|
update_all_windows(void) |
|
693 |
|
{ |
|
694 |
|
/* In One window view */ |
|
695 |
|
if (curr_stats.number_of_windows == 1) |
|
696 |
|
{ |
|
697 |
|
if (curr_view == &lwin) |
|
698 |
|
{ |
|
699 |
|
touchwin(lwin.title); |
|
700 |
|
touchwin(lwin.win); |
|
701 |
|
touchwin(lborder); |
|
702 |
|
touchwin(stat_win); |
|
703 |
|
touchwin(status_bar); |
|
704 |
|
touchwin(pos_win); |
|
705 |
|
touchwin(num_win); |
|
706 |
|
touchwin(rborder); |
|
707 |
|
|
|
708 |
|
/* |
|
709 |
|
* redrawwin() shouldn't be needed. But without it there is a |
|
710 |
|
* lot of flickering when redrawing the windows? |
|
711 |
|
*/ |
|
712 |
|
|
|
713 |
|
redrawwin(lborder); |
|
714 |
|
redrawwin(stat_win); |
|
715 |
|
redrawwin(status_bar); |
|
716 |
|
redrawwin(pos_win); |
|
717 |
|
redrawwin(lwin.title); |
|
718 |
|
redrawwin(lwin.win); |
|
719 |
|
redrawwin(num_win); |
|
720 |
|
redrawwin(rborder); |
|
721 |
|
|
|
722 |
|
wnoutrefresh(lwin.title); |
|
723 |
|
wnoutrefresh(lwin.win); |
|
724 |
|
} |
|
725 |
|
else |
|
726 |
|
{ |
|
727 |
|
touchwin(rwin.title); |
|
728 |
|
touchwin(rwin.win); |
|
729 |
|
touchwin(lborder); |
|
730 |
|
touchwin(stat_win); |
|
731 |
|
touchwin(status_bar); |
|
732 |
|
touchwin(pos_win); |
|
733 |
|
touchwin(num_win); |
|
734 |
|
touchwin(rborder); |
|
735 |
|
|
|
736 |
|
redrawwin(rwin.title); |
|
737 |
|
redrawwin(rwin.win); |
|
738 |
|
redrawwin(lborder); |
|
739 |
|
redrawwin(stat_win); |
|
740 |
|
redrawwin(status_bar); |
|
741 |
|
redrawwin(pos_win); |
|
742 |
|
redrawwin(num_win); |
|
743 |
|
redrawwin(rborder); |
|
744 |
|
|
|
745 |
|
wnoutrefresh(rwin.title); |
|
746 |
|
wnoutrefresh(rwin.win); |
|
747 |
|
} |
|
748 |
|
} |
|
749 |
|
/* Two Pane View */ |
|
750 |
|
else |
|
751 |
|
{ |
|
752 |
|
touchwin(lwin.title); |
|
753 |
|
touchwin(lwin.win); |
|
754 |
|
touchwin(mborder); |
|
755 |
|
touchwin(rwin.title); |
|
756 |
|
touchwin(rwin.win); |
|
757 |
|
touchwin(lborder); |
|
758 |
|
touchwin(stat_win); |
|
759 |
|
touchwin(status_bar); |
|
760 |
|
touchwin(pos_win); |
|
761 |
|
touchwin(num_win); |
|
762 |
|
touchwin(rborder); |
|
763 |
|
|
|
764 |
|
redrawwin(lwin.title); |
|
765 |
|
redrawwin(lwin.win); |
|
766 |
|
redrawwin(mborder); |
|
767 |
|
redrawwin(rwin.title); |
|
768 |
|
redrawwin(rwin.win); |
|
769 |
|
redrawwin(lborder); |
|
770 |
|
redrawwin(stat_win); |
|
771 |
|
redrawwin(status_bar); |
|
772 |
|
redrawwin(pos_win); |
|
773 |
|
redrawwin(num_win); |
|
774 |
|
redrawwin(rborder); |
|
775 |
|
|
|
776 |
|
wnoutrefresh(lwin.title); |
|
777 |
|
wnoutrefresh(lwin.win); |
|
778 |
|
wnoutrefresh(mborder); |
|
779 |
|
wnoutrefresh(rwin.title); |
|
780 |
|
wnoutrefresh(rwin.win); |
|
781 |
|
} |
|
782 |
|
|
|
783 |
|
wnoutrefresh(lborder); |
|
784 |
|
wnoutrefresh(stat_win); |
|
785 |
|
wnoutrefresh(status_bar); |
|
786 |
|
wnoutrefresh(pos_win); |
|
787 |
|
wnoutrefresh(num_win); |
|
788 |
|
wnoutrefresh(rborder); |
|
789 |
|
|
|
790 |
|
doupdate(); |
|
791 |
|
} |
|
792 |
|
|
|
793 |
|
|
|
794 |
|
|
|
795 |
|
/* |
|
796 |
|
* Main Loop |
|
797 |
|
* Everything is driven from this function with the exception of |
|
798 |
|
* signals which are handled in signals.c |
|
799 |
|
*/ |
|
800 |
|
void |
|
801 |
|
main_key_press_cb(FileView *view) |
|
802 |
|
{ |
|
803 |
|
int done = 0; |
|
804 |
|
int reset_last_char = 0; |
|
805 |
|
int save_count = 0; |
|
806 |
|
int count = 0; |
|
807 |
|
int key = 0; |
|
808 |
|
char count_buf[64] = ""; |
|
809 |
|
char status_buf[64] = ""; |
|
810 |
|
int save_reg = 0; |
|
811 |
|
|
|
812 |
|
curs_set(0); |
|
813 |
|
|
|
814 |
|
wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR)); |
|
815 |
|
|
|
816 |
|
/* Set keypress timeout to 1 second */ |
|
817 |
|
wtimeout(curr_view->win, 1000); |
|
818 |
|
wtimeout(other_view->win, 1000); |
|
819 |
|
|
|
820 |
|
update_stat_window(view); |
|
821 |
|
|
|
822 |
|
if (view->selected_files) |
|
823 |
|
{ |
|
824 |
|
snprintf(status_buf, sizeof(status_buf), "%d %s Selected", |
|
825 |
|
view->selected_files, view->selected_files == 1 ? "File" : |
|
826 |
|
"Files"); |
|
827 |
|
status_bar_message(status_buf); |
|
828 |
|
} |
|
829 |
|
|
|
830 |
|
while (!done) |
|
831 |
|
{ |
|
832 |
|
if (curr_stats.freeze) |
|
833 |
|
continue; |
|
834 |
|
|
|
835 |
|
/* Everything from here to if (key == ERR) gets called once a second */ |
|
836 |
|
|
|
837 |
|
check_if_filelists_have_changed(view); |
|
838 |
|
check_background_jobs(); |
|
839 |
|
check_messages(); |
|
840 |
|
|
|
841 |
|
if (!curr_stats.save_msg) |
|
842 |
|
{ |
|
843 |
|
clean_status_bar(view); |
|
844 |
|
wrefresh(status_bar); |
|
845 |
|
} |
|
846 |
|
|
|
847 |
|
/* This waits for 1 second then skips if no keypress. */ |
|
848 |
|
key = wgetch(view->win); |
|
849 |
|
|
|
850 |
|
|
|
851 |
|
if (key == ERR) |
|
852 |
|
continue; |
|
853 |
|
else /* Puts the cursor at the start of the line for speakup */ |
|
854 |
|
{ |
|
855 |
|
/* |
|
856 |
|
int x, y; |
|
857 |
|
char buf[256]; |
|
858 |
|
|
|
859 |
|
getyx(view->win, y, x); |
|
860 |
|
|
|
861 |
|
snprintf(buf, sizeof(buf), "x is %d y is %d ", x, y); |
|
862 |
|
show_error_msg("cursor curr_win", buf); |
|
863 |
|
|
|
864 |
|
wmove(stdscr, y + 2, 0); |
|
865 |
|
wrefresh(stdscr); |
|
866 |
|
|
|
867 |
|
getyx(stdscr, y, x); |
|
868 |
|
snprintf(buf, sizeof(buf), "x is %d y is %d ", x, y); |
|
869 |
|
show_error_msg("stdscr win", buf); |
|
870 |
|
*/ |
|
871 |
|
} |
|
872 |
|
|
|
873 |
|
/* This point down gets called only when a key is actually pressed */ |
|
874 |
|
|
|
875 |
|
curr_stats.save_msg = 0; |
|
876 |
|
|
|
877 |
|
if (curr_stats.use_register && !curr_stats.register_saved) |
|
878 |
|
{ |
|
879 |
|
if (is_valid_register(key)) |
|
880 |
|
{ |
|
881 |
|
curr_stats.curr_register = key; |
|
882 |
|
curr_stats.register_saved = 1; |
|
883 |
|
save_reg = 1; |
|
884 |
|
continue; |
|
885 |
|
} |
|
886 |
|
else |
|
887 |
|
{ |
|
888 |
|
status_bar_message("Invalid Register Key"); |
|
889 |
|
curr_stats.save_msg = 1; |
|
890 |
|
wrefresh(status_bar); |
|
891 |
|
curr_stats.use_register = 0; |
|
892 |
|
curr_stats.curr_register = -1; |
|
893 |
|
curr_stats.register_saved = 0; |
|
894 |
|
save_reg = 0; |
|
895 |
|
continue; |
|
896 |
|
} |
|
897 |
|
} |
|
898 |
|
else if((key > 47) && (key < 58)) /* ascii 0 - 9 */ |
|
899 |
|
{ |
|
900 |
|
if (count > 62) |
|
901 |
|
{ |
|
902 |
|
show_error_msg(" Number is too large ", |
|
903 |
|
"Vifm cannot handle that large of a number as a count. "); |
|
904 |
|
clear_num_window(); |
|
905 |
|
continue; |
|
906 |
|
} |
|
907 |
|
|
|
908 |
|
count_buf[count] = key; |
|
909 |
|
count++; |
|
910 |
|
count_buf[count] = '\0'; |
|
911 |
|
update_num_window(count_buf); |
|
912 |
|
continue; |
|
913 |
|
} |
|
914 |
|
else |
|
915 |
|
clear_num_window(); |
|
916 |
|
|
|
917 |
|
switch(key) |
|
918 |
|
{ |
|
919 |
|
case '"': /* "register */ |
|
920 |
|
curr_stats.use_register = 1; |
|
921 |
|
break; |
|
922 |
|
case 2: /* ascii Ctrl B */ |
|
923 |
|
case KEY_PPAGE: |
|
924 |
|
view->list_pos = view->list_pos - view->window_rows; |
|
925 |
|
moveto_list_pos(view, view->list_pos); |
|
926 |
|
break; |
|
927 |
|
case 3: /* ascii Ctrl C */ |
|
928 |
|
case 27: /* ascii Escape */ |
|
929 |
|
{ |
|
930 |
|
int x; |
|
931 |
|
|
|
932 |
|
for(x = 0; x < view->list_rows; x++) |
|
933 |
|
view->dir_entry[x].selected = 0; |
|
934 |
|
|
|
935 |
|
view->selected_files = 0; |
|
936 |
|
load_dir_list(curr_view, 1);// redraw_window(); |
|
937 |
|
curs_set(0); |
|
938 |
|
} |
|
939 |
|
break; |
|
940 |
|
case 6: /* ascii Ctrl F */ |
|
941 |
|
case KEY_NPAGE: |
|
942 |
|
view->list_pos = view->list_pos + view->window_rows; |
|
943 |
|
moveto_list_pos(view, view->list_pos); |
|
944 |
|
break; |
|
945 |
|
case 7: /* ascii Ctrl G */ |
|
946 |
|
if(!curr_stats.show_full) |
|
947 |
|
curr_stats.show_full = 1; |
|
948 |
|
break; |
|
949 |
|
case 9: /* ascii Tab */ |
|
950 |
|
case 32: /* ascii Spacebar */ |
|
951 |
|
change_window(&view); |
|
952 |
|
break; |
|
953 |
|
case 12: /* ascii Ctrl L - clear screen and redraw */ |
|
954 |
|
redraw_window(); |
|
955 |
|
curs_set(0); |
|
956 |
|
break; |
|
957 |
|
case 13: /* ascii Return */ |
|
958 |
|
handle_file(view); |
|
959 |
|
break; |
|
960 |
|
case 23: /* ascii Ctrl W - change windows */ |
|
961 |
|
{ |
|
962 |
|
int letter; |
|
963 |
|
curr_stats.getting_input = 1; |
|
964 |
|
letter = wgetch(view->win); |
|
965 |
|
curr_stats.getting_input = 0; |
|
966 |
|
|
|
967 |
|
if((letter == 'h') && (view->win == rwin.win)) |
|
968 |
|
change_window(&view); |
|
969 |
|
else if((letter == 'l') && (view->win == lwin.win)) |
|
970 |
|
change_window(&view); |
|
971 |
|
} |
|
972 |
|
break; |
|
973 |
|
case '.': /* repeat last change */ |
|
974 |
|
repeat_last_command(view); |
|
975 |
|
break; |
|
976 |
|
case ':': /* command */ |
|
977 |
|
curr_stats.save_msg = get_command(view, GET_COMMAND, NULL); |
|
978 |
|
break; |
|
979 |
|
case '/': /* search */ |
|
980 |
|
curr_stats.save_msg = get_command(view, GET_SEARCH_PATTERN, NULL); |
|
981 |
|
break; |
|
982 |
|
case '?': /* search backwards */ |
|
983 |
|
break; |
|
984 |
|
case '\'': /* mark */ |
|
985 |
|
curr_stats.save_msg = get_bookmark(view); |
|
986 |
|
break; |
|
987 |
|
case '%': /* Jump to percent of file. */ |
|
988 |
|
if(count) |
|
989 |
|
{ |
|
990 |
|
int percent = atoi(count_buf); |
|
991 |
|
int line = (percent * (view->list_rows)/100); |
|
992 |
|
moveto_list_pos(view, line -1); |
|
993 |
|
reset_last_char = 1; |
|
994 |
|
} |
|
995 |
|
break; |
|
996 |
|
case 'G': /* Jump to bottom of list. */ |
|
997 |
|
{ |
|
998 |
|
if(count) |
|
999 |
|
moveto_list_pos(view, atoi(count_buf) -1); |
|
1000 |
|
else |
|
1001 |
|
moveto_list_pos(view, view->list_rows - 1); |
|
1002 |
|
reset_last_char = 1; |
|
1003 |
|
} |
|
1004 |
|
break; |
|
1005 |
|
/* tbrown */ |
|
1006 |
|
case 'H': /* go to first file in window */ |
|
1007 |
|
view->list_pos = view->top_line; |
|
1008 |
|
moveto_list_pos(view, view->list_pos); |
|
1009 |
|
reset_last_char =1; |
|
1010 |
|
break; |
|
1011 |
|
/* tbrown */ |
|
1012 |
|
case 'L': /* go to last file in window */ |
|
1013 |
|
view->list_pos = view->top_line + view->window_rows; |
|
1014 |
|
moveto_list_pos(view, view->list_pos); |
|
1015 |
|
reset_last_char =1; |
|
1016 |
|
break; |
|
1017 |
|
case 'M': /* zM Restore filename filter and hide dot files. */ |
|
1018 |
|
if(curr_stats.last_char == 'z') |
|
1019 |
|
{ |
|
1020 |
|
restore_filename_filter(view); |
|
1021 |
|
hide_dot_files(view); |
|
1022 |
|
reset_last_char = 1; |
|
1023 |
|
} |
|
1024 |
|
else |
|
1025 |
|
{ /* tbrown go to middle of window */ |
|
1026 |
|
if (view->list_rows<view->window_rows) |
|
1027 |
|
{ |
|
1028 |
|
view->list_pos = view->list_rows/2; |
|
1029 |
|
} |
|
1030 |
|
else |
|
1031 |
|
{ |
|
1032 |
|
view->list_pos = view->top_line + (view->window_rows/2); |
|
1033 |
|
} |
|
1034 |
|
moveto_list_pos(view, view->list_pos); |
|
1035 |
|
reset_last_char = 1; |
|
1036 |
|
} |
|
1037 |
|
break; |
|
1038 |
|
case 'N': |
|
1039 |
|
find_previous_pattern(view); |
|
1040 |
|
break; |
|
1041 |
|
case 'O': /* zO Remove filename filter. */ |
|
1042 |
|
if(curr_stats.last_char == 'z') |
|
1043 |
|
remove_filename_filter(view); |
|
1044 |
|
reset_last_char = 1; |
|
1045 |
|
break; |
|
1046 |
|
case 'R': /* zR Show all hidden files */ |
|
1047 |
|
{ |
|
1048 |
|
if(curr_stats.last_char == 'z') |
|
1049 |
|
{ |
|
1050 |
|
remove_filename_filter(view); |
|
1051 |
|
show_dot_files(view); |
|
1052 |
|
} |
|
1053 |
|
reset_last_char = 1; |
|
1054 |
|
} |
|
1055 |
|
break; |
|
1056 |
|
case 'a': /* zo Show dot files */ |
|
1057 |
|
if(curr_stats.last_char == 'z') |
|
1058 |
|
toggle_dot_files(view); |
|
1059 |
|
reset_last_char = 1; |
|
1060 |
|
break; |
|
1061 |
|
case 'c': /* cw change word */ |
|
1062 |
|
{ |
|
1063 |
|
save_count = 1; |
|
1064 |
|
update_num_window("c"); |
|
1065 |
|
} |
|
1066 |
|
break; |
|
1067 |
|
case 'd': /* dd delete file */ |
|
1068 |
|
{ |
|
1069 |
|
save_count = 1; |
|
1070 |
|
update_num_window("d"); |
|
1071 |
|
if(curr_stats.last_char == 'd') |
|
1072 |
|
{ |
|
1073 |
|
clear_num_window(); |
|
1074 |
|
if(view->selected_files) |
|
1075 |
|
delete_file(view); |
|
1076 |
|
else if(count) |
|
1077 |
|
{ |
|
1078 |
|
int x; |
|
1079 |
|
int y = view->list_pos; |
|
1080 |
|
for(x = 0; x < atoi(count_buf); x++) |
|
1081 |
|
{ |
|
1082 |
|
view->dir_entry[y].selected = 1; |
|
1083 |
|
y++; |
|
1084 |
|
} |
|
1085 |
|
delete_file(view); |
|
1086 |
|
} |
|
1087 |
|
else |
|
1088 |
|
delete_file(view); |
|
1089 |
|
reset_last_char = 1; |
|
1090 |
|
} |
|
1091 |
|
} |
|
1092 |
|
break; |
|
1093 |
|
case 'f': /* zf filter selected files */ |
|
1094 |
|
if(curr_stats.last_char == 'z') |
|
1095 |
|
filter_selected_files(view); |
|
1096 |
|
break; |
|
1097 |
|
case 'g': /* gg Jump to top of the list. */ |
|
1098 |
|
{ |
|
1099 |
|
save_count = 1; |
|
1100 |
|
if(curr_stats.last_char == 'g') |
|
1101 |
|
{ |
|
1102 |
|
if(count) |
|
1103 |
|
moveto_list_pos(view, atoi(count_buf) -1); |
|
1104 |
|
else |
|
1105 |
|
moveto_list_pos(view, 0); |
|
1106 |
|
|
|
1107 |
|
reset_last_char = 1; |
|
1108 |
|
} |
|
1109 |
|
} |
|
1110 |
|
break; |
|
1111 |
|
case KEY_LEFT: |
|
1112 |
|
case 'h': /* updir */ |
|
1113 |
|
{ |
|
1114 |
|
change_directory(view, "../"); |
|
1115 |
|
load_dir_list(view, 0); |
|
1116 |
|
moveto_list_pos(view, view->list_pos); |
|
1117 |
|
} |
|
1118 |
|
break; |
|
1119 |
|
case KEY_DOWN: |
|
1120 |
|
case 'j': /* Move down one line */ |
|
1121 |
|
{ |
|
1122 |
|
if(count) |
|
1123 |
|
view->list_pos += atoi(count_buf); |
|
1124 |
|
else |
|
1125 |
|
view->list_pos++; |
|
1126 |
|
|
|
1127 |
|
moveto_list_pos(view, view->list_pos); |
|
1128 |
|
reset_last_char =1; |
|
1129 |
|
} |
|
1130 |
|
break; |
|
1131 |
|
case KEY_UP: |
|
1132 |
|
case 'k': /* Move up one line */ |
|
1133 |
|
{ |
|
1134 |
|
if(count) |
|
1135 |
|
view->list_pos -= atoi(count_buf); |
|
1136 |
|
else |
|
1137 |
|
view->list_pos--; |
|
1138 |
|
|
|
1139 |
|
moveto_list_pos(view, view->list_pos); |
|
1140 |
|
reset_last_char = 1; |
|
1141 |
|
} |
|
1142 |
|
break; |
|
1143 |
|
case KEY_RIGHT: |
|
1144 |
|
case 'l': |
|
1145 |
|
handle_file(view); |
|
1146 |
|
break; |
|
1147 |
|
case 'm': /* 'm' set mark and 'zm' hide dot files */ |
|
1148 |
|
{ |
|
1149 |
|
if(curr_stats.last_char == 'z') |
|
1150 |
|
{ |
|
1151 |
|
hide_dot_files(view); |
|
1152 |
|
reset_last_char = 1; |
|
1153 |
|
} |
|
1154 |
|
else |
|
1155 |
|
{ |
|
1156 |
|
int mark; |
|
1157 |
|
curr_stats.getting_input = 1; |
|
1158 |
|
|
|
1159 |
|
wtimeout(curr_view->win, -1); |
|
1160 |
|
mark = wgetch(view->win); |
|
1161 |
|
wtimeout(curr_view->win, 1000); |
|
1162 |
|
curr_stats.getting_input = 0; |
|
1163 |
|
if(key == ERR) |
|
1164 |
|
continue; |
|
1165 |
|
add_bookmark(mark, view->curr_dir, |
|
1166 |
|
get_current_file_name(view)); |
|
1167 |
|
} |
|
1168 |
|
} |
|
1169 |
|
break; |
|
1170 |
|
case 'n': |
|
1171 |
|
find_next_pattern(view); |
|
1172 |
|
break; |
|
1173 |
|
case 'o': /* zo Show dot files */ |
|
1174 |
|
if(curr_stats.last_char == 'z') |
|
1175 |
|
show_dot_files(view); |
|
1176 |
|
reset_last_char = 1; |
|
1177 |
|
break; |
|
1178 |
|
case 'p': /* put files */ |
|
1179 |
|
curr_stats.save_msg = put_files(view); |
|
1180 |
|
break; |
|
1181 |
|
case 's': /* tmp shellout **** This should be done with key mapping */ |
|
1182 |
|
shellout(NULL, 0); |
|
1183 |
|
break; |
|
1184 |
|
case 't': /* Tag file. */ |
|
1185 |
|
tag_file(view); |
|
1186 |
|
break; |
|
1187 |
|
/* tbrown */ |
|
1188 |
|
case 'V': |
|
1189 |
|
case 'v': /* Visual selection of files. */ |
|
1190 |
|
curr_stats.save_msg = start_visual_mode(view); |
|
1191 |
|
break; |
|
1192 |
|
case 'w': /* cw change word */ |
|
1193 |
|
{ |
|
1194 |
|
if (curr_stats.last_char == 'c') |
|
1195 |
|
rename_file(view); |
|
1196 |
|
} |
|
1197 |
|
break; |
|
1198 |
|
/* tbrown */ |
|
1199 |
|
case 'Y': /* Y yank file */ |
|
1200 |
|
yank_files(view, count, count_buf); |
|
1201 |
|
reset_last_char++; |
|
1202 |
|
curr_stats.save_msg = 1; |
|
1203 |
|
break; |
|
1204 |
|
|
|
1205 |
|
case 'y': /* yy yank file */ |
|
1206 |
|
{ |
|
1207 |
|
if(curr_stats.last_char == 'y') |
|
1208 |
|
{ |
|
1209 |
|
yank_files(view, count, count_buf); |
|
1210 |
|
reset_last_char++; |
|
1211 |
|
curr_stats.save_msg = 1; |
|
1212 |
|
save_reg = 0; |
|
1213 |
|
} |
|
1214 |
|
else |
|
1215 |
|
{ |
|
1216 |
|
update_num_window("y"); |
|
1217 |
|
save_reg = 1; |
|
1218 |
|
} |
|
1219 |
|
save_count = 1; |
|
1220 |
|
} |
|
1221 |
|
break; |
|
1222 |
|
case 'z': /* zz redraw with file in center of list */ |
|
1223 |
|
if(curr_stats.last_char == 'z') |
|
1224 |
|
{ |
|
1225 |
|
|
|
1226 |
|
} |
|
1227 |
|
break; |
|
1228 |
|
default: |
|
1229 |
|
break; |
|
1230 |
|
} /* end of switch(key) */ |
|
1231 |
|
|
|
1232 |
|
curr_stats.last_char = key; |
|
1233 |
|
|
|
1234 |
|
if(!save_count) |
|
1235 |
|
count = 0; |
|
1236 |
|
|
|
1237 |
|
if(reset_last_char) |
|
1238 |
|
{ |
|
1239 |
|
curr_stats.last_char = 0; |
|
1240 |
|
reset_last_char = 0; |
|
1241 |
|
count = 0; |
|
1242 |
|
} |
|
1243 |
|
|
|
1244 |
|
if(curr_stats.show_full) |
|
1245 |
|
show_full_file_properties(view); |
|
1246 |
|
else |
|
1247 |
|
update_stat_window(view); |
|
1248 |
|
|
|
1249 |
|
if(view->selected_files) |
|
1250 |
|
{ |
|
1251 |
|
static int number = 0; |
|
1252 |
|
if(number != view->selected_files) |
|
1253 |
|
{ |
|
1254 |
|
snprintf(status_buf, sizeof(status_buf), "%d %s Selected", |
|
1255 |
|
view->selected_files, view->selected_files == 1 ? "File" : |
|
1256 |
|
"Files"); |
|
1257 |
|
status_bar_message(status_buf); |
|
1258 |
|
curr_stats.save_msg = 1; |
|
1259 |
|
} |
|
1260 |
|
} |
|
1261 |
|
|
|
1262 |
|
else if(!curr_stats.save_msg) |
|
1263 |
|
clean_status_bar(view); |
|
1264 |
|
|
|
1265 |
|
if (curr_stats.use_register && curr_stats.register_saved) |
|
1266 |
|
{ |
|
1267 |
|
if (!save_reg) |
|
1268 |
|
{ |
|
1269 |
|
curr_stats.use_register = 0; |
|
1270 |
|
curr_stats.curr_register = -1; |
|
1271 |
|
curr_stats.register_saved = 0; |
|
1272 |
|
} |
|
1273 |
|
} |
|
1274 |
|
|
|
1275 |
|
if(curr_stats.need_redraw) |
|
1276 |
|
load_dir_list(curr_view, 1);// redraw_window(); |
|
1277 |
|
|
|
1278 |
|
update_all_windows(); |
|
1279 |
|
|
|
1280 |
|
} /* end of while(!done) */ |
|
1281 |
|
} |
File src/menus.c added (mode: 100644) (index 0000000..c7db01a) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
#define _WIN32_WINNT 0x0501 |
|
19 |
|
|
|
20 |
|
#include<sys/types.h> |
|
21 |
|
#include<regex.h> |
|
22 |
|
#include<ctype.h> /* isspace() */ |
|
23 |
|
#include<string.h> /* strchr() */ |
|
24 |
|
#include<unistd.h> /* access() */ |
|
25 |
|
//#include<termios.h> /* struct winsize */ |
|
26 |
|
//#include<sys/ioctl.h> |
|
27 |
|
#include<signal.h> |
|
28 |
|
#include<windows.h> |
|
29 |
|
#include<tchar.h> |
|
30 |
|
|
|
31 |
|
#include "background.h" |
|
32 |
|
#include "bookmarks.h" |
|
33 |
|
#include "color_scheme.h" |
|
34 |
|
#include "commands.h" |
|
35 |
|
#include "config.h" |
|
36 |
|
#include "filelist.h" |
|
37 |
|
#include "fileops.h" |
|
38 |
|
#include "filetype.h" |
|
39 |
|
#include "keys.h" |
|
40 |
|
#include "registers.h" |
|
41 |
|
#include "status.h" |
|
42 |
|
#include "ui.h" |
|
43 |
|
#include "utils.h" |
|
44 |
|
|
|
45 |
|
typedef struct menu_info |
|
46 |
|
{ |
|
47 |
|
int top; |
|
48 |
|
int current; |
|
49 |
|
int len; |
|
50 |
|
int pos; |
|
51 |
|
int win_rows; |
|
52 |
|
int type; |
|
53 |
|
int match_dir; |
|
54 |
|
int matching_entries; |
|
55 |
|
char *regexp; |
|
56 |
|
char *title; |
|
57 |
|
char *args; |
|
58 |
|
char **data; |
|
59 |
|
/* For user menus only */ |
|
60 |
|
char *get_info_script; /* program + args to fill in menu. */ |
|
61 |
|
}menu_info; |
|
62 |
|
|
|
63 |
|
enum { |
|
64 |
|
APROPOS, |
|
65 |
|
BOOKMARK, |
|
66 |
|
COMMAND, |
|
67 |
|
FILETYPE, |
|
68 |
|
HISTORY, |
|
69 |
|
JOBS, |
|
70 |
|
LOCATE, |
|
71 |
|
REGISTER, |
|
72 |
|
USER, |
|
73 |
|
VIFM, |
|
74 |
|
VOLUME |
|
75 |
|
}; |
|
76 |
|
|
|
77 |
|
enum { |
|
78 |
|
NONE, |
|
79 |
|
UP, |
|
80 |
|
DOWN |
|
81 |
|
}; |
|
82 |
|
|
|
83 |
|
static void draw_menu(FileView *view, menu_info *m); |
|
84 |
|
|
|
85 |
|
void |
|
86 |
|
show_progress(void) |
|
87 |
|
{ |
|
88 |
|
static int count = 0; |
|
89 |
|
static int pause = 1; |
|
90 |
|
|
|
91 |
|
pause++; |
|
92 |
|
|
|
93 |
|
if ((pause % 1000) == 0) |
|
94 |
|
{ |
|
95 |
|
pause = 1; |
|
96 |
|
|
|
97 |
|
switch(count) |
|
98 |
|
{ |
|
99 |
|
case 0: |
|
100 |
|
status_bar_message("Loading Menu |"); |
|
101 |
|
break; |
|
102 |
|
case 1: |
|
103 |
|
status_bar_message("Loading Menu /"); |
|
104 |
|
break; |
|
105 |
|
case 2: |
|
106 |
|
status_bar_message("Loading Menu -"); |
|
107 |
|
break; |
|
108 |
|
case 3: |
|
109 |
|
status_bar_message("Loading Menu \\"); |
|
110 |
|
count = -1; |
|
111 |
|
break; |
|
112 |
|
default: |
|
113 |
|
count = -1; |
|
114 |
|
break; |
|
115 |
|
} |
|
116 |
|
} |
|
117 |
|
else |
|
118 |
|
return; |
|
119 |
|
|
|
120 |
|
wrefresh(status_bar); |
|
121 |
|
|
|
122 |
|
count++; |
|
123 |
|
} |
|
124 |
|
|
|
125 |
|
static void |
|
126 |
|
show_position_in_menu(menu_info *m) |
|
127 |
|
{ |
|
128 |
|
char pos_buf[14]; |
|
129 |
|
snprintf(pos_buf, sizeof(pos_buf), " %d-%d ", m->pos + 1, m->len); |
|
130 |
|
werase(pos_win); |
|
131 |
|
mvwaddstr(pos_win, 0, 13 - strlen(pos_buf), pos_buf); |
|
132 |
|
wrefresh(pos_win); |
|
133 |
|
} |
|
134 |
|
|
|
135 |
|
static void |
|
136 |
|
clean_menu_position(menu_info *m) |
|
137 |
|
{ |
|
138 |
|
int x, y, z; |
|
139 |
|
char * buf = (char *)NULL; |
|
140 |
|
|
|
141 |
|
getmaxyx(menu_win, y, x); |
|
142 |
|
|
|
143 |
|
buf = (char *)malloc(x + 2); |
|
144 |
|
|
|
145 |
|
|
|
146 |
|
snprintf(buf, x, " %s", m->data[m->pos]); |
|
147 |
|
|
|
148 |
|
for (z = strlen(buf); z < x; z++) |
|
149 |
|
buf[z] = ' '; |
|
150 |
|
|
|
151 |
|
buf[x] = ' '; |
|
152 |
|
buf[x + 1] = '\0'; |
|
153 |
|
|
|
154 |
|
wattron(menu_win, COLOR_PAIR(WIN_COLOR)); |
|
155 |
|
|
|
156 |
|
mvwaddnstr(menu_win, m->current, 1, buf, x - 2); |
|
157 |
|
|
|
158 |
|
wattroff(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
159 |
|
|
|
160 |
|
my_free(buf); |
|
161 |
|
} |
|
162 |
|
|
|
163 |
|
void |
|
164 |
|
show_error_msg(char *title, char *message) |
|
165 |
|
{ |
|
166 |
|
int x, y; |
|
167 |
|
int key; |
|
168 |
|
int done = 0; |
|
169 |
|
int z = 0; |
|
170 |
|
char *dup = strdup(message); |
|
171 |
|
|
|
172 |
|
curr_stats.freeze = 1; |
|
173 |
|
curs_set(0); |
|
174 |
|
werase(error_win); |
|
175 |
|
|
|
176 |
|
getmaxyx(error_win, y, x); |
|
177 |
|
|
|
178 |
|
if(strlen(dup) > x -2) |
|
179 |
|
dup[x -2] = '\0'; |
|
180 |
|
|
|
181 |
|
while ((z < strlen(dup) -1) && isprint(dup[z])) |
|
182 |
|
z++; |
|
183 |
|
|
|
184 |
|
dup[z] = '\0'; |
|
185 |
|
|
|
186 |
|
mvwaddstr(error_win, 2, (x - strlen(dup))/2, dup); |
|
187 |
|
|
|
188 |
|
box(error_win, 0, 0); |
|
189 |
|
mvwaddstr(error_win, 0, (x - strlen(title))/2, title); |
|
190 |
|
|
|
191 |
|
mvwaddstr(error_win, y -2, (x - 25)/2, "Press Return to continue"); |
|
192 |
|
|
|
193 |
|
while(!done) |
|
194 |
|
{ |
|
195 |
|
key = wgetch(error_win); |
|
196 |
|
if(key == 13 || key == 3) /* ascii Return ascii Ctrl-c */ |
|
197 |
|
done = 1; |
|
198 |
|
} |
|
199 |
|
|
|
200 |
|
my_free(dup); |
|
201 |
|
|
|
202 |
|
curr_stats.freeze = 0; |
|
203 |
|
|
|
204 |
|
werase(error_win); |
|
205 |
|
wrefresh(error_win); |
|
206 |
|
|
|
207 |
|
touchwin(stdscr); |
|
208 |
|
|
|
209 |
|
update_all_windows(); |
|
210 |
|
|
|
211 |
|
if(curr_stats.need_redraw) |
|
212 |
|
redraw_window(); |
|
213 |
|
} |
|
214 |
|
|
|
215 |
|
void |
|
216 |
|
reset_popup_menu(menu_info *m) |
|
217 |
|
{ |
|
218 |
|
int z; |
|
219 |
|
|
|
220 |
|
if (m->args) |
|
221 |
|
my_free(m->args); |
|
222 |
|
|
|
223 |
|
for (z = 0; z < m->len; z++) |
|
224 |
|
{ |
|
225 |
|
if (m->data[z]) |
|
226 |
|
my_free(m->data[z]); |
|
227 |
|
} |
|
228 |
|
if (m->regexp) |
|
229 |
|
my_free(m->regexp); |
|
230 |
|
if (m->data) |
|
231 |
|
my_free(m->data); |
|
232 |
|
if (m->title) |
|
233 |
|
my_free(m->title); |
|
234 |
|
|
|
235 |
|
werase(menu_win); |
|
236 |
|
curr_stats.menu = 0; |
|
237 |
|
redraw_window(); |
|
238 |
|
} |
|
239 |
|
|
|
240 |
|
void |
|
241 |
|
setup_menu(FileView *view) |
|
242 |
|
{ |
|
243 |
|
scrollok(menu_win, FALSE); |
|
244 |
|
curr_stats.menu = 1; |
|
245 |
|
curs_set(0); |
|
246 |
|
werase(menu_win); |
|
247 |
|
werase(status_bar); |
|
248 |
|
werase(pos_win); |
|
249 |
|
wrefresh(status_bar); |
|
250 |
|
wrefresh(pos_win); |
|
251 |
|
} |
|
252 |
|
|
|
253 |
|
void |
|
254 |
|
init_active_bookmarks(void) |
|
255 |
|
{ |
|
256 |
|
int i, x; |
|
257 |
|
|
|
258 |
|
i = 0; |
|
259 |
|
for (x = 0; x < NUM_BOOKMARKS; ++x) |
|
260 |
|
{ |
|
261 |
|
if (is_bookmark(x)) |
|
262 |
|
active_bookmarks[i++] = x; |
|
263 |
|
} |
|
264 |
|
} |
|
265 |
|
|
|
266 |
|
static void |
|
267 |
|
moveto_menu_pos(FileView *view, int pos, menu_info *m) |
|
268 |
|
{ |
|
269 |
|
int redraw = 0; |
|
270 |
|
int x, y, z; |
|
271 |
|
char * buf = (char *)NULL; |
|
272 |
|
|
|
273 |
|
getmaxyx(menu_win, y, x); |
|
274 |
|
|
|
275 |
|
|
|
276 |
|
if(pos < 1) |
|
277 |
|
pos = 0; |
|
278 |
|
|
|
279 |
|
if(pos > m->len -1) |
|
280 |
|
pos = m->len -1; |
|
281 |
|
|
|
282 |
|
if((m->top <= pos) && (pos <= (m->top + m->win_rows +1))) |
|
283 |
|
{ |
|
284 |
|
m->current = pos - m->top +1; |
|
285 |
|
} |
|
286 |
|
if((pos >= (m->top + m->win_rows -2))) |
|
287 |
|
{ |
|
288 |
|
while(pos >= (m->top + m->win_rows -2)) |
|
289 |
|
m->top++; |
|
290 |
|
|
|
291 |
|
m->current = m->win_rows -2; |
|
292 |
|
redraw = 1; |
|
293 |
|
} |
|
294 |
|
else if(pos < m->top) |
|
295 |
|
{ |
|
296 |
|
while(pos < m->top) |
|
297 |
|
m->top--; |
|
298 |
|
m->current = 1; |
|
299 |
|
redraw = 1; |
|
300 |
|
} |
|
301 |
|
if(redraw) |
|
302 |
|
draw_menu(view, m); |
|
303 |
|
|
|
304 |
|
|
|
305 |
|
buf = (char *)malloc((x + 2)); |
|
306 |
|
if (!buf) |
|
307 |
|
return; |
|
308 |
|
snprintf(buf, x, " %s", m->data[pos]); |
|
309 |
|
|
|
310 |
|
for (z = strlen(buf); z < x; z++) |
|
311 |
|
buf[z] = ' '; |
|
312 |
|
|
|
313 |
|
buf[x] = ' '; |
|
314 |
|
buf[x + 1] = '\0'; |
|
315 |
|
|
|
316 |
|
wattron(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
317 |
|
|
|
318 |
|
mvwaddnstr(menu_win, m->current, 1, buf, x - 2); |
|
319 |
|
|
|
320 |
|
wattroff(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD); |
|
321 |
|
|
|
322 |
|
m->pos = pos; |
|
323 |
|
my_free(buf); |
|
324 |
|
show_position_in_menu(m); |
|
325 |
|
} |
|
326 |
|
|
|
327 |
|
static void |
|
328 |
|
redraw_menu(FileView *view, menu_info *m) |
|
329 |
|
{ |
|
330 |
|
/* |
|
331 |
|
int screen_x, screen_y; |
|
332 |
|
//struct winsize ws; |
|
333 |
|
|
|
334 |
|
curr_stats.freeze = 1; |
|
335 |
|
curr_stats.redraw_menu = 0; |
|
336 |
|
|
|
337 |
|
//ioctl(0, TIOCGWINSZ, &ws); |
|
338 |
|
//changed for pdcurses |
|
339 |
|
//resizeterm(ws.ws_row, ws.ws_col); |
|
340 |
|
getmaxyx(stdscr, screen_y, screen_x); |
|
341 |
|
|
|
342 |
|
wclear(stdscr); |
|
343 |
|
wclear(menu_win); |
|
344 |
|
wclear(status_bar); |
|
345 |
|
wclear(pos_win); |
|
346 |
|
|
|
347 |
|
wresize(menu_win, screen_y - 1, screen_x); |
|
348 |
|
wresize(status_bar, 1, screen_x -19); |
|
349 |
|
mvwin(status_bar, screen_y -1, 0); |
|
350 |
|
wresize(pos_win, 1, 13); |
|
351 |
|
mvwin(pos_win, screen_y -1, screen_x -13); |
|
352 |
|
box(menu_win, 0, 0); |
|
353 |
|
wrefresh(status_bar); |
|
354 |
|
wrefresh(pos_win); |
|
355 |
|
wrefresh(menu_win); |
|
356 |
|
curr_stats.freeze = 0; |
|
357 |
|
draw_menu(view, m); |
|
358 |
|
moveto_menu_pos(view, m->pos, m); |
|
359 |
|
*/ |
|
360 |
|
} |
|
361 |
|
|
|
362 |
|
int |
|
363 |
|
search_menu_forwards(FileView *view, menu_info *m, int start_pos) |
|
364 |
|
{ |
|
365 |
|
int match_up = -1; |
|
366 |
|
int match_down = -1; |
|
367 |
|
int x; |
|
368 |
|
regex_t re; |
|
369 |
|
m->matching_entries = 0; |
|
370 |
|
|
|
371 |
|
for(x = 0; x < m->len; x++) |
|
372 |
|
{ |
|
373 |
|
if(regcomp(&re, m->regexp, REG_EXTENDED) == 0) |
|
374 |
|
{ |
|
375 |
|
if(regexec(&re, m->data[x], 0, NULL, 0) == 0) |
|
376 |
|
{ |
|
377 |
|
if(match_up < 0) |
|
378 |
|
{ |
|
379 |
|
if (x < start_pos) |
|
380 |
|
match_up = x; |
|
381 |
|
} |
|
382 |
|
if(match_down < 0) |
|
383 |
|
{ |
|
384 |
|
if (x >= start_pos) |
|
385 |
|
match_down = x; |
|
386 |
|
} |
|
387 |
|
m->matching_entries++; |
|
388 |
|
} |
|
389 |
|
} |
|
390 |
|
regfree(&re); |
|
391 |
|
} |
|
392 |
|
|
|
393 |
|
if((match_up > -1) || (match_down > -1)) |
|
394 |
|
{ |
|
395 |
|
char buf[64]; |
|
396 |
|
int pos; |
|
397 |
|
|
|
398 |
|
if (match_down > -1) |
|
399 |
|
pos = match_down; |
|
400 |
|
else |
|
401 |
|
pos = match_up; |
|
402 |
|
|
|
403 |
|
clean_menu_position(m); |
|
404 |
|
moveto_menu_pos(view, pos, m); |
|
405 |
|
snprintf(buf, sizeof(buf), "%d %s", m->matching_entries, |
|
406 |
|
m->matching_entries == 1 ? "match" : "matches"); |
|
407 |
|
status_bar_message(buf); |
|
408 |
|
wrefresh(status_bar); |
|
409 |
|
} |
|
410 |
|
else |
|
411 |
|
{ |
|
412 |
|
char buf[48]; |
|
413 |
|
snprintf(buf, sizeof(buf), "No matches for %s", m->regexp); |
|
414 |
|
status_bar_message(buf); |
|
415 |
|
wrefresh(status_bar); |
|
416 |
|
return 1; |
|
417 |
|
} |
|
418 |
|
return 0; |
|
419 |
|
|
|
420 |
|
} |
|
421 |
|
|
|
422 |
|
int |
|
423 |
|
search_menu_backwards(FileView *view, menu_info *m, int start_pos) |
|
424 |
|
{ |
|
425 |
|
int match_up = -1; |
|
426 |
|
int match_down = -1; |
|
427 |
|
int x; |
|
428 |
|
regex_t re; |
|
429 |
|
m->matching_entries = 0; |
|
430 |
|
|
|
431 |
|
for(x = m->len - 1; x > -1; x--) |
|
432 |
|
{ |
|
433 |
|
if(regcomp(&re, m->regexp, REG_EXTENDED) == 0) |
|
434 |
|
{ |
|
435 |
|
if(regexec(&re, m->data[x], 0, NULL, 0) == 0) |
|
436 |
|
{ |
|
437 |
|
if(match_up < 0) |
|
438 |
|
{ |
|
439 |
|
if (x <= start_pos) |
|
440 |
|
match_up = x; |
|
441 |
|
} |
|
442 |
|
if(match_down < 0) |
|
443 |
|
{ |
|
444 |
|
if (x > start_pos) |
|
445 |
|
match_down = x; |
|
446 |
|
} |
|
447 |
|
m->matching_entries++; |
|
448 |
|
} |
|
449 |
|
} |
|
450 |
|
regfree(&re); |
|
451 |
|
} |
|
452 |
|
|
|
453 |
|
if ((match_up > -1) || (match_down > -1)) |
|
454 |
|
{ |
|
455 |
|
char buf[64]; |
|
456 |
|
int pos; |
|
457 |
|
|
|
458 |
|
if (match_up > - 1) |
|
459 |
|
pos = match_up; |
|
460 |
|
else |
|
461 |
|
pos = match_down; |
|
462 |
|
|
|
463 |
|
clean_menu_position(m); |
|
464 |
|
moveto_menu_pos(view, pos, m); |
|
465 |
|
snprintf(buf, sizeof(buf), "%d %s", m->matching_entries, |
|
466 |
|
m->matching_entries == 1 ? "match" : "matches"); |
|
467 |
|
status_bar_message(buf); |
|
468 |
|
wrefresh(status_bar); |
|
469 |
|
} |
|
470 |
|
else |
|
471 |
|
{ |
|
472 |
|
char buf[48]; |
|
473 |
|
snprintf(buf, sizeof(buf), "No matches for %s", m->regexp); |
|
474 |
|
status_bar_message(buf); |
|
475 |
|
wrefresh(status_bar); |
|
476 |
|
return 1; |
|
477 |
|
} |
|
478 |
|
return 0; |
|
479 |
|
} |
|
480 |
|
|
|
481 |
|
int |
|
482 |
|
search_menu_list(FileView *view, char * pattern, menu_info *m) |
|
483 |
|
{ |
|
484 |
|
int save = 0; |
|
485 |
|
|
|
486 |
|
if (pattern) |
|
487 |
|
m->regexp = strdup(pattern); |
|
488 |
|
|
|
489 |
|
switch (m->match_dir) |
|
490 |
|
{ |
|
491 |
|
case NONE: |
|
492 |
|
save = search_menu_forwards(view, m, m->pos); |
|
493 |
|
break; |
|
494 |
|
case UP: |
|
495 |
|
save = search_menu_backwards(view, m, m->pos - 1); |
|
496 |
|
break; |
|
497 |
|
case DOWN: |
|
498 |
|
save = search_menu_forwards(view, m, m->pos + 1); |
|
499 |
|
break; |
|
500 |
|
default: |
|
501 |
|
break; |
|
502 |
|
} |
|
503 |
|
return save; |
|
504 |
|
} |
|
505 |
|
|
|
506 |
|
static void |
|
507 |
|
execute_jobs_cb(FileView *view, menu_info *m) |
|
508 |
|
{ |
|
509 |
|
|
|
510 |
|
} |
|
511 |
|
|
|
512 |
|
static void |
|
513 |
|
execute_apropos_cb(FileView *view, menu_info *m) |
|
514 |
|
{ |
|
515 |
|
char *line = NULL; |
|
516 |
|
char *man_page = NULL; |
|
517 |
|
char *free_this = NULL; |
|
518 |
|
char *num_str = NULL; |
|
519 |
|
char command[256]; |
|
520 |
|
int z = 0; |
|
521 |
|
|
|
522 |
|
free_this = man_page = line = strdup(m->data[m->pos]); |
|
523 |
|
|
|
524 |
|
if((num_str = strchr(line, '('))) |
|
525 |
|
{ |
|
526 |
|
num_str++; |
|
527 |
|
while(num_str[z] != ')') |
|
528 |
|
{ |
|
529 |
|
z++; |
|
530 |
|
if(z > 40) |
|
531 |
|
return; |
|
532 |
|
} |
|
533 |
|
|
|
534 |
|
num_str[z] = '\0'; |
|
535 |
|
line = strchr(line, ' '); |
|
536 |
|
line[0] = '\0'; |
|
537 |
|
|
|
538 |
|
snprintf(command, sizeof(command), "man %s %s", num_str, |
|
539 |
|
man_page); |
|
540 |
|
|
|
541 |
|
shellout(command, 0); |
|
542 |
|
my_free(free_this); |
|
543 |
|
} |
|
544 |
|
else |
|
545 |
|
my_free(free_this); |
|
546 |
|
} |
|
547 |
|
|
|
548 |
|
|
|
549 |
|
static void |
|
550 |
|
execute_locate_cb(FileView *view, menu_info *m) |
|
551 |
|
{ |
|
552 |
|
char *dir = NULL; |
|
553 |
|
char *file = NULL; |
|
554 |
|
char *free_this = NULL; |
|
555 |
|
int isdir = 0; |
|
556 |
|
|
|
557 |
|
free_this = file = dir = strdup(m->data[m->pos]); |
|
558 |
|
chomp(file); |
|
559 |
|
|
|
560 |
|
/* :locate -h will show help message */ |
|
561 |
|
if(!access(file, R_OK)) |
|
562 |
|
{ |
|
563 |
|
if(is_dir(file)) |
|
564 |
|
isdir = 1; |
|
565 |
|
|
|
566 |
|
file = strrchr(dir, '/'); |
|
567 |
|
*file = '\0'; |
|
568 |
|
file++; |
|
569 |
|
|
|
570 |
|
change_directory(view, dir); |
|
571 |
|
|
|
572 |
|
status_bar_message("Finding the correct directory."); |
|
573 |
|
|
|
574 |
|
wrefresh(status_bar); |
|
575 |
|
load_dir_list(view, 1); |
|
576 |
|
|
|
577 |
|
|
|
578 |
|
if(find_file_pos_in_list(view, file) < 0) |
|
579 |
|
{ |
|
580 |
|
if(isdir) |
|
581 |
|
{ |
|
582 |
|
strcat(file, "/"); |
|
583 |
|
} |
|
584 |
|
|
|
585 |
|
if(file[0] == '.') |
|
586 |
|
show_dot_files(view); |
|
587 |
|
|
|
588 |
|
if(find_file_pos_in_list(view, file) < 0) |
|
589 |
|
remove_filename_filter(view); |
|
590 |
|
|
|
591 |
|
moveto_list_pos(view, find_file_pos_in_list(view, file)); |
|
592 |
|
} |
|
593 |
|
else |
|
594 |
|
moveto_list_pos(view, find_file_pos_in_list(view, file)); |
|
595 |
|
} |
|
596 |
|
|
|
597 |
|
my_free(free_this); |
|
598 |
|
} |
|
599 |
|
|
|
600 |
|
static void |
|
601 |
|
execute_volume_cb(FileView *view, menu_info *m) |
|
602 |
|
{ |
|
603 |
|
char buf[4]; |
|
604 |
|
snprintf(buf, 4, "%s", m->data[m->pos]); |
|
605 |
|
|
|
606 |
|
change_directory(view, buf); |
|
607 |
|
load_dir_list(view, 0); |
|
608 |
|
moveto_list_pos(view, 0); |
|
609 |
|
|
|
610 |
|
} |
|
611 |
|
|
|
612 |
|
static void |
|
613 |
|
execute_filetype_cb(FileView *view, menu_info *m) |
|
614 |
|
{ |
|
615 |
|
/* |
|
616 |
|
char *filename = get_current_file_name(view); |
|
617 |
|
char *prog_str = get_all_programs_for_file(filename); |
|
618 |
|
char command[PATH_MAX]; |
|
619 |
|
char *ptr = NULL; |
|
620 |
|
|
|
621 |
|
|
|
622 |
|
if((ptr = strchr(prog_str, ',')) == NULL) |
|
623 |
|
{ |
|
624 |
|
if(strchr(prog_str, '%')) |
|
625 |
|
{ |
|
626 |
|
int m = 0; |
|
627 |
|
char *expanded_command = expand_macros(view, prog_str, NULL, &m, 0); |
|
628 |
|
shellout(expanded_command, 0); |
|
629 |
|
my_free(expanded_command); |
|
630 |
|
return; |
|
631 |
|
} |
|
632 |
|
else |
|
633 |
|
{ |
|
634 |
|
snprintf(command, sizeof(command), "%s %s", prog_str, filename); |
|
635 |
|
shellout(command, 0); |
|
636 |
|
return; |
|
637 |
|
} |
|
638 |
|
} |
|
639 |
|
else |
|
640 |
|
{ |
|
641 |
|
char *prog_copy = strdup(prog_str); |
|
642 |
|
char *free_this = prog_copy; |
|
643 |
|
char *ptr1 = NULL; |
|
644 |
|
int x = 1; |
|
645 |
|
|
|
646 |
|
while((ptr = ptr1 = strchr(prog_copy, ',')) != NULL) |
|
647 |
|
{ |
|
648 |
|
*ptr = '\0'; |
|
649 |
|
ptr1++; |
|
650 |
|
|
|
651 |
|
if(x == m->pos +1) |
|
652 |
|
{ |
|
653 |
|
if(strchr(prog_str, '%')) |
|
654 |
|
{ |
|
655 |
|
int m = 0; |
|
656 |
|
char *expanded_command = expand_macros(view, prog_copy, NULL, &m, 0); |
|
657 |
|
shellout(expanded_command, 0); |
|
658 |
|
my_free(expanded_command); |
|
659 |
|
free(free_this); |
|
660 |
|
return; |
|
661 |
|
} |
|
662 |
|
else |
|
663 |
|
{ |
|
664 |
|
snprintf(command, sizeof(command), "%s %s", |
|
665 |
|
prog_copy, filename); |
|
666 |
|
shellout(command, 0); |
|
667 |
|
free(free_this); |
|
668 |
|
return; |
|
669 |
|
} |
|
670 |
|
} |
|
671 |
|
prog_copy = ptr1; |
|
672 |
|
x++; |
|
673 |
|
} |
|
674 |
|
if(strchr(prog_str, '%')) |
|
675 |
|
{ |
|
676 |
|
int m = 0; |
|
677 |
|
char *expanded_command = expand_macros(view, prog_copy, NULL, &m, 0); |
|
678 |
|
shellout(expanded_command, 0); |
|
679 |
|
my_free(expanded_command); |
|
680 |
|
free(free_this); |
|
681 |
|
return; |
|
682 |
|
} |
|
683 |
|
else |
|
684 |
|
{ |
|
685 |
|
snprintf(command, sizeof(command), "%s %s", prog_copy, filename); |
|
686 |
|
shellout(command, 0); |
|
687 |
|
free(free_this); |
|
688 |
|
return; |
|
689 |
|
} |
|
690 |
|
} |
|
691 |
|
*/ |
|
692 |
|
} |
|
693 |
|
|
|
694 |
|
static void |
|
695 |
|
execute_menu_cb(FileView *view, menu_info *m) |
|
696 |
|
{ |
|
697 |
|
switch(m->type) |
|
698 |
|
{ |
|
699 |
|
case APROPOS: |
|
700 |
|
execute_apropos_cb(view, m); |
|
701 |
|
break; |
|
702 |
|
case BOOKMARK: |
|
703 |
|
move_to_bookmark(view, index2mark(active_bookmarks[m->pos])); |
|
704 |
|
break; |
|
705 |
|
case COMMAND: |
|
706 |
|
execute_command(view, command_list[m->pos].name); |
|
707 |
|
break; |
|
708 |
|
case FILETYPE: |
|
709 |
|
execute_filetype_cb(view, m); |
|
710 |
|
break; |
|
711 |
|
case HISTORY: |
|
712 |
|
{ |
|
713 |
|
change_directory(view, view->history[m->pos].dir); |
|
714 |
|
load_dir_list(view, 1); |
|
715 |
|
moveto_list_pos(view, find_file_pos_in_list(view, |
|
716 |
|
view->history[m->pos].file)); |
|
717 |
|
} |
|
718 |
|
break; |
|
719 |
|
case JOBS: |
|
720 |
|
execute_jobs_cb(view, m); |
|
721 |
|
break; |
|
722 |
|
case LOCATE: |
|
723 |
|
execute_locate_cb(view, m); |
|
724 |
|
break; |
|
725 |
|
case VIFM: |
|
726 |
|
break; |
|
727 |
|
case VOLUME: |
|
728 |
|
execute_volume_cb(view, m); |
|
729 |
|
break; |
|
730 |
|
default: |
|
731 |
|
break; |
|
732 |
|
} |
|
733 |
|
} |
|
734 |
|
|
|
735 |
|
static void |
|
736 |
|
reload_bookmarks_menu_list(menu_info *m) |
|
737 |
|
{ |
|
738 |
|
int x, i, z, len, j; |
|
739 |
|
char buf[PATH_MAX]; |
|
740 |
|
|
|
741 |
|
getmaxyx(menu_win, z, len); |
|
742 |
|
|
|
743 |
|
|
|
744 |
|
for (z = 0; z < m->len; z++) |
|
745 |
|
{ |
|
746 |
|
if (m->data[z]) |
|
747 |
|
my_free(m->data[z]); |
|
748 |
|
} |
|
749 |
|
|
|
750 |
|
init_active_bookmarks(); |
|
751 |
|
m->len = cfg.num_bookmarks; |
|
752 |
|
x = 0; |
|
753 |
|
|
|
754 |
|
for(i = 1; x < m->len; i++) |
|
755 |
|
{ |
|
756 |
|
j = active_bookmarks[x]; |
|
757 |
|
if (!strcmp(bookmarks[j].directory, "/")) |
|
758 |
|
snprintf(buf, sizeof(buf), " %c /%s", index2mark(j), bookmarks[j].file); |
|
759 |
|
else if (!strcmp(bookmarks[j].file, "../")) |
|
760 |
|
snprintf(buf, sizeof(buf), " %c %s", index2mark(j), |
|
761 |
|
bookmarks[j].directory); |
|
762 |
|
else |
|
763 |
|
snprintf(buf, sizeof(buf), " %c %s/%s", index2mark(j), |
|
764 |
|
bookmarks[j].directory, bookmarks[j].file); |
|
765 |
|
|
|
766 |
|
m->data = (char **)realloc(m->data, sizeof(char *) * (x + 1)); |
|
767 |
|
m->data[x] = (char *)malloc(sizeof(buf) + 2); |
|
768 |
|
snprintf(m->data[x], sizeof(buf), "%s", buf); |
|
769 |
|
|
|
770 |
|
x++; |
|
771 |
|
} |
|
772 |
|
m->len = x; |
|
773 |
|
} |
|
774 |
|
|
|
775 |
|
static void |
|
776 |
|
reload_command_menu_list(menu_info *m) |
|
777 |
|
{ |
|
778 |
|
|
|
779 |
|
int x, i, z, len; |
|
780 |
|
|
|
781 |
|
getmaxyx(menu_win, z, len); |
|
782 |
|
|
|
783 |
|
for (z = 0; z < m->len; z++) |
|
784 |
|
{ |
|
785 |
|
if (m->data[z]) |
|
786 |
|
my_free(m->data[z]); |
|
787 |
|
} |
|
788 |
|
|
|
789 |
|
m->len = cfg.command_num; |
|
790 |
|
|
|
791 |
|
qsort(command_list, cfg.command_num, sizeof(command_t), |
|
792 |
|
sort_this); |
|
793 |
|
|
|
794 |
|
x = 0; |
|
795 |
|
|
|
796 |
|
for (i = 1; x < m->len; i++) |
|
797 |
|
{ |
|
798 |
|
m->data = (char **)realloc(m->data, sizeof(char *) * (x + 1)); |
|
799 |
|
m->data[x] = (char *)malloc(len + 2); |
|
800 |
|
snprintf(m->data[x], len, " %-*s %s ", 10, command_list[x].name, |
|
801 |
|
command_list[x].action); |
|
802 |
|
|
|
803 |
|
x++; |
|
804 |
|
/* This will show the expanded command instead of the macros |
|
805 |
|
* char *expanded = expand_macros(view, command_list[x].action, NULL); |
|
806 |
|
* my_free(expanded); |
|
807 |
|
*/ |
|
808 |
|
} |
|
809 |
|
} |
|
810 |
|
|
|
811 |
|
static void |
|
812 |
|
menu_key_cb(FileView *view, menu_info *m) |
|
813 |
|
{ |
|
814 |
|
int done = 0; |
|
815 |
|
int abort = 0; |
|
816 |
|
int save_msg = 0; |
|
817 |
|
int y, len; |
|
818 |
|
|
|
819 |
|
getmaxyx(menu_win, y, len); |
|
820 |
|
keypad(menu_win, TRUE); |
|
821 |
|
werase(status_bar); |
|
822 |
|
wtimeout(menu_win, 1000); |
|
823 |
|
|
|
824 |
|
while(!done) |
|
825 |
|
{ |
|
826 |
|
int key = wgetch(menu_win); |
|
827 |
|
|
|
828 |
|
switch(key) |
|
829 |
|
{ |
|
830 |
|
case '/': |
|
831 |
|
{ |
|
832 |
|
m->match_dir = NONE; |
|
833 |
|
if (m->regexp) |
|
834 |
|
my_free(m->regexp); |
|
835 |
|
|
|
836 |
|
get_command(view, MENU_SEARCH, m); |
|
837 |
|
} |
|
838 |
|
break; |
|
839 |
|
case ':': |
|
840 |
|
{ |
|
841 |
|
save_msg = get_command(view, MENU_COMMAND, m); |
|
842 |
|
if (save_msg < 0) |
|
843 |
|
{ |
|
844 |
|
done = 1; |
|
845 |
|
abort = 1; |
|
846 |
|
} |
|
847 |
|
} |
|
848 |
|
break; |
|
849 |
|
case '?': |
|
850 |
|
{ |
|
851 |
|
m->match_dir = UP; |
|
852 |
|
|
|
853 |
|
if (m->regexp) |
|
854 |
|
my_free(m->regexp); |
|
855 |
|
|
|
856 |
|
get_command(view, MENU_SEARCH, m); |
|
857 |
|
} |
|
858 |
|
break; |
|
859 |
|
case 2: /* ascii Ctrl B */ |
|
860 |
|
case KEY_PPAGE: |
|
861 |
|
clean_menu_position(m); |
|
862 |
|
moveto_menu_pos(view, m->top - m->win_rows + 2, m); |
|
863 |
|
break; |
|
864 |
|
case 3: /* ascii Ctrl C */ |
|
865 |
|
case 27: /* ascii Escape */ |
|
866 |
|
done = 1; |
|
867 |
|
abort = 1; |
|
868 |
|
break; |
|
869 |
|
case 6: /* ascii Ctrl F */ |
|
870 |
|
{ |
|
871 |
|
clean_menu_position(m); |
|
872 |
|
m->pos = m->pos + m->win_rows; |
|
873 |
|
moveto_menu_pos(view, m->pos, m); |
|
874 |
|
} |
|
875 |
|
break; |
|
876 |
|
case KEY_NPAGE: |
|
877 |
|
break; |
|
878 |
|
case 'l': |
|
879 |
|
case 13: /* ascii Return */ |
|
880 |
|
done = 1; |
|
881 |
|
break; |
|
882 |
|
case 'G': |
|
883 |
|
clean_menu_position(m); |
|
884 |
|
moveto_menu_pos(view, m->len -1, m); |
|
885 |
|
break; |
|
886 |
|
case 'N': |
|
887 |
|
{ |
|
888 |
|
if (m->regexp != NULL) |
|
889 |
|
{ |
|
890 |
|
m->match_dir = UP; |
|
891 |
|
m->matching_entries = 0; |
|
892 |
|
search_menu_list(view, NULL, m); |
|
893 |
|
} |
|
894 |
|
else |
|
895 |
|
{ |
|
896 |
|
status_bar_message("No search pattern set."); |
|
897 |
|
wrefresh(status_bar); |
|
898 |
|
} |
|
899 |
|
} |
|
900 |
|
break; |
|
901 |
|
case 'g': |
|
902 |
|
{ |
|
903 |
|
key = wgetch(menu_win); |
|
904 |
|
if(key == 'g') |
|
905 |
|
{ |
|
906 |
|
clean_menu_position(m); |
|
907 |
|
moveto_menu_pos(view, 0, m); |
|
908 |
|
} |
|
909 |
|
} |
|
910 |
|
break; |
|
911 |
|
case 'd': |
|
912 |
|
{ |
|
913 |
|
key = wgetch(menu_win); |
|
914 |
|
|
|
915 |
|
if(key != 'd') |
|
916 |
|
break; |
|
917 |
|
|
|
918 |
|
if(m->type == COMMAND) |
|
919 |
|
{ |
|
920 |
|
clean_menu_position(m); |
|
921 |
|
remove_command(command_list[m->pos].name); |
|
922 |
|
|
|
923 |
|
reload_command_menu_list(m); |
|
924 |
|
draw_menu(view, m); |
|
925 |
|
|
|
926 |
|
if(m->pos -1 >= 0) |
|
927 |
|
moveto_menu_pos(view, m->pos -1, m); |
|
928 |
|
else |
|
929 |
|
moveto_menu_pos(view, 0, m); |
|
930 |
|
} |
|
931 |
|
else if(m->type == BOOKMARK) |
|
932 |
|
{ |
|
933 |
|
clean_menu_position(m); |
|
934 |
|
remove_bookmark(active_bookmarks[m->pos]); |
|
935 |
|
|
|
936 |
|
reload_bookmarks_menu_list(m); |
|
937 |
|
draw_menu(view, m); |
|
938 |
|
|
|
939 |
|
if(m->pos -1 >= 0) |
|
940 |
|
moveto_menu_pos(view, m->pos -1, m); |
|
941 |
|
else |
|
942 |
|
moveto_menu_pos(view, 0, m); |
|
943 |
|
} |
|
944 |
|
} |
|
945 |
|
break; |
|
946 |
|
case 'j': |
|
947 |
|
case KEY_DOWN: |
|
948 |
|
{ |
|
949 |
|
clean_menu_position(m); |
|
950 |
|
m->pos++; |
|
951 |
|
moveto_menu_pos(view, m->pos, m); |
|
952 |
|
} |
|
953 |
|
break; |
|
954 |
|
case 'k': |
|
955 |
|
case KEY_UP: |
|
956 |
|
{ |
|
957 |
|
clean_menu_position(m); |
|
958 |
|
m->pos--; |
|
959 |
|
moveto_menu_pos(view, m->pos, m); |
|
960 |
|
wrefresh(menu_win); |
|
961 |
|
} |
|
962 |
|
break; |
|
963 |
|
case 'n': |
|
964 |
|
{ |
|
965 |
|
if (m->regexp != NULL) |
|
966 |
|
{ |
|
967 |
|
m->match_dir = DOWN; |
|
968 |
|
m->matching_entries = 0; |
|
969 |
|
search_menu_list(view, NULL, m); |
|
970 |
|
} |
|
971 |
|
else |
|
972 |
|
{ |
|
973 |
|
status_bar_message("No search pattern set>"); |
|
974 |
|
wrefresh(status_bar); |
|
975 |
|
} |
|
976 |
|
} |
|
977 |
|
break; |
|
978 |
|
default: |
|
979 |
|
break; |
|
980 |
|
} |
|
981 |
|
if (curr_stats.redraw_menu) |
|
982 |
|
redraw_menu(view, m); |
|
983 |
|
|
|
984 |
|
} /* end of while(!done) */ |
|
985 |
|
|
|
986 |
|
if (abort) |
|
987 |
|
return; |
|
988 |
|
|
|
989 |
|
execute_menu_cb(view, m); |
|
990 |
|
} |
|
991 |
|
|
|
992 |
|
static void |
|
993 |
|
draw_menu(FileView *view, menu_info *m) |
|
994 |
|
{ |
|
995 |
|
int i; |
|
996 |
|
int x, y; |
|
997 |
|
int len; |
|
998 |
|
|
|
999 |
|
getmaxyx(menu_win, y, x); |
|
1000 |
|
len = x; |
|
1001 |
|
werase(menu_win); |
|
1002 |
|
|
|
1003 |
|
box(menu_win, 0, 0); |
|
1004 |
|
|
|
1005 |
|
if(m->win_rows - 2 >= m->len) |
|
1006 |
|
{ |
|
1007 |
|
m->top = 0; |
|
1008 |
|
} |
|
1009 |
|
x = m->top; |
|
1010 |
|
|
|
1011 |
|
wattron(menu_win, A_BOLD); |
|
1012 |
|
mvwaddstr(menu_win, 0, 3, m->title); |
|
1013 |
|
wattroff(menu_win, A_BOLD); |
|
1014 |
|
|
|
1015 |
|
for(i = 1; x < m->len; i++) |
|
1016 |
|
{ |
|
1017 |
|
char *ptr = NULL; |
|
1018 |
|
chomp(m->data[x]); |
|
1019 |
|
if ((ptr = strchr(m->data[x], '\n')) || (ptr = strchr(m->data[x], '\r'))) |
|
1020 |
|
*ptr = '\0'; |
|
1021 |
|
mvwaddnstr(menu_win, i, 2, m->data[x], len - 4); |
|
1022 |
|
x++; |
|
1023 |
|
|
|
1024 |
|
if(i +3 > y) |
|
1025 |
|
break; |
|
1026 |
|
} |
|
1027 |
|
} |
|
1028 |
|
|
|
1029 |
|
void |
|
1030 |
|
show_apropos_menu(FileView *view, char *args) |
|
1031 |
|
{ |
|
1032 |
|
int x = 0; |
|
1033 |
|
char buf[256]; |
|
1034 |
|
FILE *file; |
|
1035 |
|
int len = 0; |
|
1036 |
|
|
|
1037 |
|
menu_info m; |
|
1038 |
|
m.top = 0; |
|
1039 |
|
m.current = 1; |
|
1040 |
|
m.len = 0; |
|
1041 |
|
m.pos = 0; |
|
1042 |
|
m.win_rows = 0; |
|
1043 |
|
m.type = APROPOS; |
|
1044 |
|
m.matching_entries = 0; |
|
1045 |
|
m.match_dir = NONE; |
|
1046 |
|
m.regexp = NULL; |
|
1047 |
|
m.title = NULL; |
|
1048 |
|
m.args = strdup(args); |
|
1049 |
|
m.data = NULL; |
|
1050 |
|
|
|
1051 |
|
getmaxyx(menu_win, m.win_rows, len); |
|
1052 |
|
|
|
1053 |
|
m.title = (char *)malloc((strlen(args) + 12) * sizeof(char)); |
|
1054 |
|
snprintf(m.title, strlen(args) + 11, " Apropos %s ", args); |
|
1055 |
|
snprintf(buf, sizeof(buf), "apropos %s", args); |
|
1056 |
|
file = popen(buf, "r"); |
|
1057 |
|
|
|
1058 |
|
if(!file) |
|
1059 |
|
{ |
|
1060 |
|
show_error_msg("Trouble opening a file", "Unable to open file"); |
|
1061 |
|
return ; |
|
1062 |
|
} |
|
1063 |
|
x = 0; |
|
1064 |
|
|
|
1065 |
|
curr_stats.search = 1; |
|
1066 |
|
while(fgets(buf, sizeof(buf), file)) |
|
1067 |
|
{ |
|
1068 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1069 |
|
m.data[x] = (char *)malloc(len); |
|
1070 |
|
|
|
1071 |
|
snprintf(m.data[x], len - 2, "%s", buf); |
|
1072 |
|
|
|
1073 |
|
x++; |
|
1074 |
|
} |
|
1075 |
|
pclose(file); |
|
1076 |
|
m.len = x; |
|
1077 |
|
curr_stats.search = 0; |
|
1078 |
|
|
|
1079 |
|
setup_menu(view); |
|
1080 |
|
draw_menu(view, &m); |
|
1081 |
|
moveto_menu_pos(view, 0, &m); |
|
1082 |
|
menu_key_cb(view, &m); |
|
1083 |
|
reset_popup_menu(&m); |
|
1084 |
|
} |
|
1085 |
|
|
|
1086 |
|
void |
|
1087 |
|
show_bookmarks_menu(FileView *view) |
|
1088 |
|
{ |
|
1089 |
|
int i, j, x; |
|
1090 |
|
char buf[PATH_MAX]; |
|
1091 |
|
|
|
1092 |
|
menu_info m; |
|
1093 |
|
m.top = 0; |
|
1094 |
|
m.current = 1; |
|
1095 |
|
m.len = cfg.num_bookmarks; |
|
1096 |
|
m.pos = 0; |
|
1097 |
|
m.win_rows = 0; |
|
1098 |
|
m.type = BOOKMARK; |
|
1099 |
|
m.matching_entries = 0; |
|
1100 |
|
m.match_dir = NONE; |
|
1101 |
|
m.regexp = NULL; |
|
1102 |
|
m.title = NULL; |
|
1103 |
|
m.args = NULL; |
|
1104 |
|
m.data = NULL; |
|
1105 |
|
|
|
1106 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1107 |
|
|
|
1108 |
|
init_active_bookmarks(); |
|
1109 |
|
|
|
1110 |
|
m.title = (char *)malloc((strlen(" Mark -- File ") + 1) * sizeof(char)); |
|
1111 |
|
snprintf(m.title, strlen(" Mark -- File "), " Mark -- File "); |
|
1112 |
|
|
|
1113 |
|
x = 0; |
|
1114 |
|
|
|
1115 |
|
for(i = 1; x < m.len; i++) |
|
1116 |
|
{ |
|
1117 |
|
j = active_bookmarks[x]; |
|
1118 |
|
if (!strcmp(bookmarks[j].directory, "/")) |
|
1119 |
|
snprintf(buf, sizeof(buf), " %c /%s", index2mark(j), bookmarks[j].file); |
|
1120 |
|
else if (!strcmp(bookmarks[j].file, "../")) |
|
1121 |
|
snprintf(buf, sizeof(buf), " %c %s", index2mark(j), |
|
1122 |
|
bookmarks[j].directory); |
|
1123 |
|
else |
|
1124 |
|
snprintf(buf, sizeof(buf), " %c %s/%s", index2mark(j), |
|
1125 |
|
bookmarks[j].directory, bookmarks[j].file); |
|
1126 |
|
|
|
1127 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1128 |
|
m.data[x] = (char *)malloc(sizeof(buf) + 2); |
|
1129 |
|
snprintf(m.data[x], sizeof(buf), "%s", buf); |
|
1130 |
|
|
|
1131 |
|
x++; |
|
1132 |
|
} |
|
1133 |
|
m.len = x; |
|
1134 |
|
|
|
1135 |
|
setup_menu(view); |
|
1136 |
|
draw_menu(view, &m); |
|
1137 |
|
moveto_menu_pos(view, 0, &m); |
|
1138 |
|
menu_key_cb(view, &m); |
|
1139 |
|
reset_popup_menu(&m); |
|
1140 |
|
} |
|
1141 |
|
|
|
1142 |
|
void |
|
1143 |
|
show_commands_menu(FileView *view) |
|
1144 |
|
{ |
|
1145 |
|
int len, i, x; |
|
1146 |
|
|
|
1147 |
|
menu_info m; |
|
1148 |
|
m.top = 0; |
|
1149 |
|
m.current = 1; |
|
1150 |
|
m.len = cfg.command_num; |
|
1151 |
|
m.pos = 0; |
|
1152 |
|
m.win_rows = 0; |
|
1153 |
|
m.type = COMMAND; |
|
1154 |
|
m.matching_entries = 0; |
|
1155 |
|
m.match_dir = NONE; |
|
1156 |
|
m.regexp = NULL; |
|
1157 |
|
m.title = NULL; |
|
1158 |
|
m.args = NULL; |
|
1159 |
|
m.data = NULL; |
|
1160 |
|
|
|
1161 |
|
if (cfg.command_num < 1) |
|
1162 |
|
{ |
|
1163 |
|
show_error_msg("No commands set", "No commands are set."); |
|
1164 |
|
return; |
|
1165 |
|
} |
|
1166 |
|
|
|
1167 |
|
getmaxyx(menu_win, m.win_rows, len); |
|
1168 |
|
qsort(command_list, cfg.command_num, sizeof(command_t), |
|
1169 |
|
sort_this); |
|
1170 |
|
|
|
1171 |
|
m.title = (char *)malloc((strlen(" Command ------ Action ") + 1) |
|
1172 |
|
* sizeof(char)); |
|
1173 |
|
snprintf(m.title, strlen(" Command ------ Action "), |
|
1174 |
|
" Command ------ Action "); |
|
1175 |
|
|
|
1176 |
|
x = 0; |
|
1177 |
|
|
|
1178 |
|
for (i = 1; x < m.len; i++) |
|
1179 |
|
{ |
|
1180 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1181 |
|
m.data[x] = (char *)malloc(len + 2); |
|
1182 |
|
snprintf(m.data[x], len, " %-*s %s ", 10, command_list[x].name, |
|
1183 |
|
command_list[x].action); |
|
1184 |
|
|
|
1185 |
|
x++; |
|
1186 |
|
/* This will show the expanded command instead of the macros |
|
1187 |
|
* char *expanded = expand_macros(view, command_list[x].action, NULL); |
|
1188 |
|
* my_free(expanded); |
|
1189 |
|
*/ |
|
1190 |
|
} |
|
1191 |
|
|
|
1192 |
|
setup_menu(view); |
|
1193 |
|
draw_menu(view, &m); |
|
1194 |
|
moveto_menu_pos(view, 0, &m); |
|
1195 |
|
menu_key_cb(view, &m); |
|
1196 |
|
reset_popup_menu(&m); |
|
1197 |
|
} |
|
1198 |
|
|
|
1199 |
|
void |
|
1200 |
|
show_filetypes_menu(FileView *view) |
|
1201 |
|
{ |
|
1202 |
|
char *filename = get_current_file_name(view); |
|
1203 |
|
char *prog_str = get_all_programs_for_file(filename); |
|
1204 |
|
if (prog_str == NULL) |
|
1205 |
|
{ |
|
1206 |
|
show_error_msg(" Filetype is not set. ", |
|
1207 |
|
"No programs set for this filetype."); |
|
1208 |
|
return; |
|
1209 |
|
} |
|
1210 |
|
else |
|
1211 |
|
{ |
|
1212 |
|
int x = 0; |
|
1213 |
|
int len = 0; |
|
1214 |
|
char *ptr = NULL; |
|
1215 |
|
|
|
1216 |
|
menu_info m; |
|
1217 |
|
m.top = 0; |
|
1218 |
|
m.current = 1; |
|
1219 |
|
m.len = 0; |
|
1220 |
|
m.pos = 0; |
|
1221 |
|
m.win_rows = 0; |
|
1222 |
|
m.type = FILETYPE; |
|
1223 |
|
m.matching_entries = 0; |
|
1224 |
|
m.match_dir = NONE; |
|
1225 |
|
m.regexp = NULL; |
|
1226 |
|
m.title = NULL; |
|
1227 |
|
m.args = NULL; |
|
1228 |
|
m.data = NULL; |
|
1229 |
|
|
|
1230 |
|
getmaxyx(menu_win, m.win_rows, len); |
|
1231 |
|
|
|
1232 |
|
if ((ptr = strchr(prog_str, ',')) == NULL) |
|
1233 |
|
{ |
|
1234 |
|
m.len = 1; |
|
1235 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (len + 1)); |
|
1236 |
|
m.data[0] = strdup(prog_str); |
|
1237 |
|
} |
|
1238 |
|
else |
|
1239 |
|
{ |
|
1240 |
|
char *prog_copy = strdup(prog_str); |
|
1241 |
|
char *free_this = prog_copy; |
|
1242 |
|
char *ptr1 = NULL; |
|
1243 |
|
|
|
1244 |
|
while ((ptr = ptr1 = strchr(prog_copy, ',')) != NULL) |
|
1245 |
|
{ |
|
1246 |
|
*ptr = '\0'; |
|
1247 |
|
ptr1++; |
|
1248 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1)); |
|
1249 |
|
m.data[x] = strdup(prog_copy); |
|
1250 |
|
prog_copy = ptr1; |
|
1251 |
|
x++; |
|
1252 |
|
m.len = x; |
|
1253 |
|
} |
|
1254 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1)); |
|
1255 |
|
m.data[x] = (char *)malloc((len + 1) * sizeof(char)); |
|
1256 |
|
snprintf(m.data[x], len, "%s", prog_copy); |
|
1257 |
|
m.len++; |
|
1258 |
|
|
|
1259 |
|
free(free_this); |
|
1260 |
|
} |
|
1261 |
|
setup_menu(view); |
|
1262 |
|
draw_menu(view, &m); |
|
1263 |
|
moveto_menu_pos(view, 0, &m); |
|
1264 |
|
menu_key_cb(view, &m); |
|
1265 |
|
reset_popup_menu(&m); |
|
1266 |
|
} |
|
1267 |
|
} |
|
1268 |
|
|
|
1269 |
|
void |
|
1270 |
|
show_history_menu(FileView *view) |
|
1271 |
|
{ |
|
1272 |
|
int x; |
|
1273 |
|
menu_info m; |
|
1274 |
|
|
|
1275 |
|
if (view->history_num < 2) |
|
1276 |
|
return; |
|
1277 |
|
|
|
1278 |
|
m.top = 0; |
|
1279 |
|
m.current = 1; |
|
1280 |
|
m.len = view->history_num + 1; |
|
1281 |
|
m.pos = 0; |
|
1282 |
|
m.win_rows = 0; |
|
1283 |
|
m.type = HISTORY; |
|
1284 |
|
m.matching_entries = 0; |
|
1285 |
|
m.match_dir = NONE; |
|
1286 |
|
m.regexp = NULL; |
|
1287 |
|
m.title = strdup("History"); |
|
1288 |
|
m.args = NULL; |
|
1289 |
|
m.data = NULL; |
|
1290 |
|
|
|
1291 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1292 |
|
|
|
1293 |
|
for(x = 0; x < view->history_num + 1; x++) |
|
1294 |
|
{ |
|
1295 |
|
if(strlen(view->history[x].dir) < 1) |
|
1296 |
|
break; |
|
1297 |
|
|
|
1298 |
|
/* Change the current dir to reflect the current file. */ |
|
1299 |
|
if(!strcmp(view->history[x].dir, view->curr_dir)) |
|
1300 |
|
snprintf(view->history[x].file, sizeof(view->history[x].file), |
|
1301 |
|
"%s", view->dir_entry[view->list_pos].name); |
|
1302 |
|
|
|
1303 |
|
if(!strcmp(view->history[x].dir, "/")) |
|
1304 |
|
{ |
|
1305 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1306 |
|
m.data[x] = (char *)malloc((strlen(view->history[x].file) + 1) |
|
1307 |
|
* sizeof(char)); |
|
1308 |
|
snprintf(m.data[x], strlen(view->history[x].file), |
|
1309 |
|
"%s", view->history[x].file); |
|
1310 |
|
} |
|
1311 |
|
else |
|
1312 |
|
{ |
|
1313 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1314 |
|
m.data[x] = (char *)malloc((strlen(view->history[x].file) + |
|
1315 |
|
strlen(view->history[x].dir) + 2) * sizeof(char)); |
|
1316 |
|
snprintf(m.data[x], strlen(view->history[x].file) + |
|
1317 |
|
strlen(view->history[x].dir) + 1, "%s/%s", |
|
1318 |
|
view->history[x].dir, view->history[x].file); |
|
1319 |
|
} |
|
1320 |
|
m.len = x; |
|
1321 |
|
} |
|
1322 |
|
setup_menu(view); |
|
1323 |
|
draw_menu(view, &m); |
|
1324 |
|
moveto_menu_pos(view, 0, &m); |
|
1325 |
|
menu_key_cb(view, &m); |
|
1326 |
|
reset_popup_menu(&m); |
|
1327 |
|
} |
|
1328 |
|
|
|
1329 |
|
void |
|
1330 |
|
show_locate_menu(FileView *view, char *args) |
|
1331 |
|
{ |
|
1332 |
|
int x = 0; |
|
1333 |
|
char buf[256]; |
|
1334 |
|
FILE *file; |
|
1335 |
|
|
|
1336 |
|
menu_info m; |
|
1337 |
|
m.top = 0; |
|
1338 |
|
m.current = 1; |
|
1339 |
|
m.len = 0; |
|
1340 |
|
m.pos = 0; |
|
1341 |
|
m.win_rows = 0; |
|
1342 |
|
m.type = LOCATE; |
|
1343 |
|
m.matching_entries = 0; |
|
1344 |
|
m.match_dir = NONE; |
|
1345 |
|
m.regexp = NULL; |
|
1346 |
|
m.title = NULL; |
|
1347 |
|
m.args = strdup(args); |
|
1348 |
|
m.data = NULL; |
|
1349 |
|
|
|
1350 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1351 |
|
|
|
1352 |
|
snprintf(buf, sizeof(buf), "locate %s", args); |
|
1353 |
|
m.title = strdup(buf); |
|
1354 |
|
file = popen(buf, "r"); |
|
1355 |
|
|
|
1356 |
|
if(!file) |
|
1357 |
|
{ |
|
1358 |
|
show_error_msg("Trouble opening a file", "Unable to open file"); |
|
1359 |
|
return ; |
|
1360 |
|
} |
|
1361 |
|
x = 0; |
|
1362 |
|
|
|
1363 |
|
curr_stats.search = 1; |
|
1364 |
|
|
|
1365 |
|
while(fgets(buf, sizeof(buf), file)) |
|
1366 |
|
{ |
|
1367 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1368 |
|
m.data[x] = (char *)malloc(sizeof(buf) + 2); |
|
1369 |
|
snprintf(m.data[x], sizeof(buf), "%s", buf); |
|
1370 |
|
|
|
1371 |
|
x++; |
|
1372 |
|
} |
|
1373 |
|
|
|
1374 |
|
pclose(file); |
|
1375 |
|
m.len = x; |
|
1376 |
|
curr_stats.search = 0; |
|
1377 |
|
|
|
1378 |
|
if(m.len < 1) |
|
1379 |
|
{ |
|
1380 |
|
char buf[256]; |
|
1381 |
|
|
|
1382 |
|
reset_popup_menu(&m); |
|
1383 |
|
snprintf(buf, sizeof(buf), "No files found matching \"%s\"", args); |
|
1384 |
|
status_bar_message(buf); |
|
1385 |
|
wrefresh(status_bar); |
|
1386 |
|
return; |
|
1387 |
|
} |
|
1388 |
|
|
|
1389 |
|
setup_menu(view); |
|
1390 |
|
draw_menu(view, &m); |
|
1391 |
|
moveto_menu_pos(view, 0, &m); |
|
1392 |
|
menu_key_cb(view, &m); |
|
1393 |
|
reset_popup_menu(&m); |
|
1394 |
|
} |
|
1395 |
|
|
|
1396 |
|
void |
|
1397 |
|
show_user_menu(FileView *view, char *command) |
|
1398 |
|
{ |
|
1399 |
|
int x; |
|
1400 |
|
char buf[256]; |
|
1401 |
|
FILE *file; |
|
1402 |
|
|
|
1403 |
|
menu_info m; |
|
1404 |
|
m.top = 0; |
|
1405 |
|
m.current = 1; |
|
1406 |
|
m.len = 0; |
|
1407 |
|
m.pos = 0; |
|
1408 |
|
m.win_rows = 0; |
|
1409 |
|
m.type = USER; |
|
1410 |
|
m.matching_entries = 0; |
|
1411 |
|
m.match_dir = NONE; |
|
1412 |
|
m.regexp = NULL; |
|
1413 |
|
m.title = NULL; |
|
1414 |
|
m.args = NULL; |
|
1415 |
|
m.data = NULL; |
|
1416 |
|
m.get_info_script = command; |
|
1417 |
|
|
|
1418 |
|
|
|
1419 |
|
for ( x = 0; x < strlen(command); x++) |
|
1420 |
|
{ |
|
1421 |
|
if (command[x] == ',') |
|
1422 |
|
{ |
|
1423 |
|
command[x] = '\0'; |
|
1424 |
|
break; |
|
1425 |
|
} |
|
1426 |
|
} |
|
1427 |
|
|
|
1428 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1429 |
|
|
|
1430 |
|
snprintf(buf, sizeof(buf), " %s ", m.get_info_script); |
|
1431 |
|
m.title = strdup(buf); |
|
1432 |
|
file = popen(buf, "r"); |
|
1433 |
|
|
|
1434 |
|
if(!file) |
|
1435 |
|
{ |
|
1436 |
|
reset_popup_menu(&m); |
|
1437 |
|
show_error_msg("Trouble opening a file", "Unable to open file"); |
|
1438 |
|
return ; |
|
1439 |
|
} |
|
1440 |
|
x = 0; |
|
1441 |
|
|
|
1442 |
|
curr_stats.search = 1; |
|
1443 |
|
|
|
1444 |
|
while(fgets(buf, sizeof(buf), file)) |
|
1445 |
|
{ |
|
1446 |
|
show_progress(); |
|
1447 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1)); |
|
1448 |
|
m.data[x] = (char *)malloc(sizeof(buf) + 2); |
|
1449 |
|
snprintf(m.data[x], sizeof(buf), "%s", buf); |
|
1450 |
|
|
|
1451 |
|
x++; |
|
1452 |
|
} |
|
1453 |
|
|
|
1454 |
|
pclose(file); |
|
1455 |
|
m.len = x; |
|
1456 |
|
curr_stats.search = 0; |
|
1457 |
|
|
|
1458 |
|
if(m.len < 1) |
|
1459 |
|
{ |
|
1460 |
|
char buf[256]; |
|
1461 |
|
|
|
1462 |
|
reset_popup_menu(&m); |
|
1463 |
|
snprintf(buf, sizeof(buf), "No results found"); |
|
1464 |
|
status_bar_message(buf); |
|
1465 |
|
wrefresh(status_bar); |
|
1466 |
|
return; |
|
1467 |
|
} |
|
1468 |
|
|
|
1469 |
|
setup_menu(view); |
|
1470 |
|
draw_menu(view, &m); |
|
1471 |
|
moveto_menu_pos(view, 0, &m); |
|
1472 |
|
menu_key_cb(view, &m); |
|
1473 |
|
reset_popup_menu(&m); |
|
1474 |
|
} |
|
1475 |
|
|
|
1476 |
|
void |
|
1477 |
|
show_register_menu(FileView *view) |
|
1478 |
|
{ |
|
1479 |
|
int x; |
|
1480 |
|
|
|
1481 |
|
menu_info m; |
|
1482 |
|
m.top = 0; |
|
1483 |
|
m.current = 1; |
|
1484 |
|
m.len = 0; |
|
1485 |
|
m.pos = 0; |
|
1486 |
|
m.win_rows = 0; |
|
1487 |
|
m.type = REGISTER; |
|
1488 |
|
m.matching_entries = 0; |
|
1489 |
|
m.match_dir = NONE; |
|
1490 |
|
m.regexp = NULL; |
|
1491 |
|
m.title = strdup(" Registers "); |
|
1492 |
|
m.args = NULL; |
|
1493 |
|
m.data = NULL; |
|
1494 |
|
|
|
1495 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1496 |
|
|
|
1497 |
|
for (x = 0; x < NUM_REGISTERS; x++) |
|
1498 |
|
{ |
|
1499 |
|
if (reg[x].num_files > 0) |
|
1500 |
|
{ |
|
1501 |
|
char buf[56]; |
|
1502 |
|
int y = reg[x].num_files; |
|
1503 |
|
snprintf(buf, sizeof(buf), "\"%c", reg[x].name); |
|
1504 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1)); |
|
1505 |
|
m.data[m.len] = strdup(buf); |
|
1506 |
|
m.len++; |
|
1507 |
|
|
|
1508 |
|
while (y) |
|
1509 |
|
{ |
|
1510 |
|
|
|
1511 |
|
y--; |
|
1512 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1)); |
|
1513 |
|
m.data[m.len] = strdup(reg[x].files[y]); |
|
1514 |
|
|
|
1515 |
|
m.len++; |
|
1516 |
|
} |
|
1517 |
|
} |
|
1518 |
|
} |
|
1519 |
|
|
|
1520 |
|
if (!m.len) |
|
1521 |
|
{ |
|
1522 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * 1); |
|
1523 |
|
m.data[0] = strdup(" Registers are empty "); |
|
1524 |
|
m.len = 1; |
|
1525 |
|
} |
|
1526 |
|
|
|
1527 |
|
setup_menu(view); |
|
1528 |
|
draw_menu(view, &m); |
|
1529 |
|
moveto_menu_pos(view, 0, &m); |
|
1530 |
|
menu_key_cb(view, &m); |
|
1531 |
|
reset_popup_menu(&m); |
|
1532 |
|
} |
|
1533 |
|
|
|
1534 |
|
void |
|
1535 |
|
show_vifm_menu(FileView *view) |
|
1536 |
|
{ |
|
1537 |
|
int x; |
|
1538 |
|
|
|
1539 |
|
menu_info m; |
|
1540 |
|
m.top = 0; |
|
1541 |
|
m.current = 1; |
|
1542 |
|
m.len = 0; |
|
1543 |
|
m.pos = 0; |
|
1544 |
|
m.win_rows = 0; |
|
1545 |
|
m.type = VIFM; |
|
1546 |
|
m.matching_entries = 0; |
|
1547 |
|
m.match_dir = NONE; |
|
1548 |
|
m.regexp = NULL; |
|
1549 |
|
m.title = NULL; |
|
1550 |
|
m.args = NULL; |
|
1551 |
|
m.data = NULL; |
|
1552 |
|
|
|
1553 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1554 |
|
|
|
1555 |
|
setup_menu(view); |
|
1556 |
|
draw_menu(view, &m); |
|
1557 |
|
moveto_menu_pos(view, 0, &m); |
|
1558 |
|
menu_key_cb(view, &m); |
|
1559 |
|
reset_popup_menu(&m); |
|
1560 |
|
} |
|
1561 |
|
|
|
1562 |
|
void |
|
1563 |
|
show_volume_menu(FileView *view) |
|
1564 |
|
{ |
|
1565 |
|
menu_info m; |
|
1566 |
|
int retVal; |
|
1567 |
|
int x; |
|
1568 |
|
TCHAR Drive[] = TEXT("c:\\"); |
|
1569 |
|
TCHAR I; |
|
1570 |
|
TCHAR volName[MAX_PATH]; |
|
1571 |
|
TCHAR fileBuf[MAX_PATH]; |
|
1572 |
|
|
|
1573 |
|
m.top = 0; |
|
1574 |
|
m.current = 1; |
|
1575 |
|
m.len = 0; |
|
1576 |
|
m.pos = 0; |
|
1577 |
|
m.win_rows = 0; |
|
1578 |
|
m.type = VOLUME; |
|
1579 |
|
m.matching_entries = 0; |
|
1580 |
|
m.match_dir = NONE; |
|
1581 |
|
m.regexp = NULL; |
|
1582 |
|
m.title = strdup(" Mounted Volumes "); |
|
1583 |
|
m.args = NULL; |
|
1584 |
|
m.data = NULL; |
|
1585 |
|
|
|
1586 |
|
getmaxyx(menu_win, m.win_rows, x); |
|
1587 |
|
|
|
1588 |
|
for(I = TEXT('a'); I < TEXT('z'); I++) |
|
1589 |
|
{ |
|
1590 |
|
Drive[0] = I; |
|
1591 |
|
retVal = GetDriveType(Drive); |
|
1592 |
|
|
|
1593 |
|
switch(retVal) |
|
1594 |
|
{ |
|
1595 |
|
case DRIVE_CDROM: |
|
1596 |
|
|
|
1597 |
|
case DRIVE_REMOTE: |
|
1598 |
|
|
|
1599 |
|
case DRIVE_RAMDISK: |
|
1600 |
|
|
|
1601 |
|
case DRIVE_REMOVABLE: |
|
1602 |
|
|
|
1603 |
|
case DRIVE_FIXED: |
|
1604 |
|
break; |
|
1605 |
|
|
|
1606 |
|
case DRIVE_UNKNOWN: |
|
1607 |
|
case DRIVE_NO_ROOT_DIR: |
|
1608 |
|
default: |
|
1609 |
|
retVal = 0; |
|
1610 |
|
break; |
|
1611 |
|
} |
|
1612 |
|
if(retVal) |
|
1613 |
|
{ |
|
1614 |
|
if(GetVolumeInformation(Drive, volName, MAX_PATH, NULL, |
|
1615 |
|
NULL, NULL, fileBuf, MAX_PATH)) |
|
1616 |
|
{ |
|
1617 |
|
m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1)); |
|
1618 |
|
m.data[m.len] = (char *)malloc((MAX_PATH + 5) * sizeof(char)); |
|
1619 |
|
|
|
1620 |
|
snprintf(m.data[m.len], MAX_PATH, "%s %s ", Drive, volName); |
|
1621 |
|
m.len++; |
|
1622 |
|
|
|
1623 |
|
} |
|
1624 |
|
} |
|
1625 |
|
} |
|
1626 |
|
|
|
1627 |
|
setup_menu(view); |
|
1628 |
|
draw_menu(view, &m); |
|
1629 |
|
moveto_menu_pos(view, 0, &m); |
|
1630 |
|
menu_key_cb(view, &m); |
|
1631 |
|
reset_popup_menu(&m); |
|
1632 |
|
moveto_list_pos(view, view->list_pos); |
|
1633 |
|
} |
|
1634 |
|
|
|
1635 |
|
int |
|
1636 |
|
show_overwrite_file_menu(char *file) |
|
1637 |
|
{ |
|
1638 |
|
int x, y; |
|
1639 |
|
int key; |
|
1640 |
|
int done = 0; |
|
1641 |
|
int answer = 0; |
|
1642 |
|
char buf[MAX_PATH]; |
|
1643 |
|
|
|
1644 |
|
curr_stats.freeze = 1; |
|
1645 |
|
curs_set(0); |
|
1646 |
|
werase(error_win); |
|
1647 |
|
|
|
1648 |
|
getmaxyx(error_win, y, x); |
|
1649 |
|
|
|
1650 |
|
snprintf(buf, sizeof(buf), " \'%s\' exists would you like to overwrite it? ", file); |
|
1651 |
|
|
|
1652 |
|
|
|
1653 |
|
mvwaddstr(error_win, 2, (x - strlen(buf))/2, buf); |
|
1654 |
|
|
|
1655 |
|
box(error_win, 0, 0); |
|
1656 |
|
mvwaddstr(error_win, 0, (x - strlen(" File Exists "))/2, " File Exists "); |
|
1657 |
|
mvwaddstr(error_win, 4, (x - strlen(" [Y]es [N]o [A]ll "))/2, " [Y]es [N]o [A]ll "); |
|
1658 |
|
|
|
1659 |
|
while(!done) |
|
1660 |
|
{ |
|
1661 |
|
key = wgetch(error_win); |
|
1662 |
|
|
|
1663 |
|
switch (key) |
|
1664 |
|
{ |
|
1665 |
|
case 'a': |
|
1666 |
|
case 'A': |
|
1667 |
|
answer = 1; |
|
1668 |
|
done = 1; |
|
1669 |
|
break; |
|
1670 |
|
case 'n': |
|
1671 |
|
case 'N': |
|
1672 |
|
answer = 2; |
|
1673 |
|
done = 1; |
|
1674 |
|
break; |
|
1675 |
|
case 'y': |
|
1676 |
|
case 'Y': |
|
1677 |
|
answer = 3; |
|
1678 |
|
done = 1; |
|
1679 |
|
break; |
|
1680 |
|
default: |
|
1681 |
|
break; |
|
1682 |
|
} |
|
1683 |
|
|
|
1684 |
|
} |
|
1685 |
|
|
|
1686 |
|
|
|
1687 |
|
curr_stats.freeze = 0; |
|
1688 |
|
|
|
1689 |
|
werase(error_win); |
|
1690 |
|
wrefresh(error_win); |
|
1691 |
|
|
|
1692 |
|
touchwin(stdscr); |
|
1693 |
|
|
|
1694 |
|
update_all_windows(); |
|
1695 |
|
|
|
1696 |
|
if(curr_stats.need_redraw) |
|
1697 |
|
redraw_window(); |
|
1698 |
|
|
|
1699 |
|
return answer; |
|
1700 |
|
|
|
1701 |
|
} |
|
1702 |
|
|
|
1703 |
|
|
|
1704 |
|
|
|
1705 |
|
|
|
1706 |
|
|
|
1707 |
|
|
File src/rline.c added (mode: 100644) (index 0000000..5c7c3d2) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#include<ctype.h> |
|
20 |
|
#include<sys/types.h> /* Needed for Fink with Mac OS X */ |
|
21 |
|
#include<dirent.h> /* DIR */ |
|
22 |
|
#include<curses.h> |
|
23 |
|
#include<signal.h> |
|
24 |
|
#include<string.h> |
|
25 |
|
|
|
26 |
|
#include"commands.h" |
|
27 |
|
#include"config.h" |
|
28 |
|
#include"keys.h" |
|
29 |
|
#include"menus.h" |
|
30 |
|
#include"status.h" |
|
31 |
|
#include"utils.h" |
|
32 |
|
|
|
33 |
|
static char * |
|
34 |
|
check_for_command(char *string) |
|
35 |
|
{ |
|
36 |
|
int pos = -1; |
|
37 |
|
char *command = (char *)NULL; |
|
38 |
|
|
|
39 |
|
if ((pos = command_is_reserved(string)) > -1) |
|
40 |
|
command = strdup(reserved_commands[pos]); |
|
41 |
|
|
|
42 |
|
else if ((pos = is_user_command(string)) > -1) |
|
43 |
|
command = strdup(command_list[pos].name); |
|
44 |
|
|
|
45 |
|
return command; |
|
46 |
|
} |
|
47 |
|
|
|
48 |
|
static char * |
|
49 |
|
check_for_executable(char *string) |
|
50 |
|
{ |
|
51 |
|
char *temp = (char *)NULL; |
|
52 |
|
|
|
53 |
|
if (!string) |
|
54 |
|
return NULL; |
|
55 |
|
|
|
56 |
|
if (string[0] == '!') |
|
57 |
|
{ |
|
58 |
|
if (strlen(string) > 2) |
|
59 |
|
{ |
|
60 |
|
if (string[1] == '!') |
|
61 |
|
temp = strdup(string + 2); |
|
62 |
|
else |
|
63 |
|
temp = strdup(string + 1); |
|
64 |
|
} |
|
65 |
|
else if (strlen(string) > 1) |
|
66 |
|
temp = strdup(string + 1); |
|
67 |
|
} |
|
68 |
|
return temp; |
|
69 |
|
} |
|
70 |
|
|
|
71 |
|
static char * |
|
72 |
|
get_last_word(char * string) |
|
73 |
|
{ |
|
74 |
|
|
|
75 |
|
char * temp = (char *)NULL; |
|
76 |
|
|
|
77 |
|
if (!string) |
|
78 |
|
return NULL; |
|
79 |
|
|
|
80 |
|
/*:command filename */ |
|
81 |
|
temp = strrchr(string, ' '); |
|
82 |
|
|
|
83 |
|
if(temp) |
|
84 |
|
{ |
|
85 |
|
temp++; |
|
86 |
|
return temp; |
|
87 |
|
} |
|
88 |
|
/* :!filename or :!!filename */ |
|
89 |
|
temp = check_for_executable(string); |
|
90 |
|
if (temp) |
|
91 |
|
return temp; |
|
92 |
|
|
|
93 |
|
return NULL; |
|
94 |
|
} |
|
95 |
|
|
|
96 |
|
/* This is from the taken mainly from the readline program it just |
|
97 |
|
* returns the first file name in the directory that matches |
|
98 |
|
* the string passed to the function. I couldn't get readline to handle |
|
99 |
|
* the Ctrl-c or Esc keys correctly so we are doing this the hard way. |
|
100 |
|
*/ |
|
101 |
|
static char * |
|
102 |
|
filename_completion(char *string) |
|
103 |
|
{ |
|
104 |
|
|
|
105 |
|
DIR *dir; |
|
106 |
|
int x = 0; |
|
107 |
|
struct dirent *d; |
|
108 |
|
char * dirname = (char *)NULL; |
|
109 |
|
char * filename = (char *)NULL; |
|
110 |
|
char * temp = (char *)NULL; |
|
111 |
|
int found = 0; |
|
112 |
|
int filename_len = 0; |
|
113 |
|
|
|
114 |
|
if (!string) |
|
115 |
|
return NULL; |
|
116 |
|
|
|
117 |
|
if (!strncmp(string, "~/", 2)) |
|
118 |
|
{ |
|
119 |
|
char * homedir = getenv("HOME"); |
|
120 |
|
|
|
121 |
|
dirname = (char *)malloc((strlen(homedir) + strlen(string) + 1)); |
|
122 |
|
|
|
123 |
|
if (dirname == NULL) |
|
124 |
|
return NULL; |
|
125 |
|
|
|
126 |
|
snprintf(dirname, strlen(homedir) + strlen(string) + 1, "%s/%s", |
|
127 |
|
homedir, string + 2); |
|
128 |
|
|
|
129 |
|
filename = strdup(dirname); |
|
130 |
|
} |
|
131 |
|
else |
|
132 |
|
{ |
|
133 |
|
dirname = strdup(string); |
|
134 |
|
filename = strdup(string); |
|
135 |
|
} |
|
136 |
|
|
|
137 |
|
temp = strrchr(dirname, '/'); |
|
138 |
|
|
|
139 |
|
if (temp) |
|
140 |
|
{ |
|
141 |
|
strcpy(filename, ++temp); |
|
142 |
|
*temp = '\0'; |
|
143 |
|
} |
|
144 |
|
else |
|
145 |
|
{ |
|
146 |
|
dirname[0] = '.'; |
|
147 |
|
dirname[1] = '\0'; |
|
148 |
|
} |
|
149 |
|
|
|
150 |
|
|
|
151 |
|
dir = opendir(dirname); |
|
152 |
|
filename_len = strlen(filename); |
|
153 |
|
|
|
154 |
|
if(dir == NULL) |
|
155 |
|
{ |
|
156 |
|
my_free(filename); |
|
157 |
|
my_free(dirname); |
|
158 |
|
return NULL; |
|
159 |
|
} |
|
160 |
|
|
|
161 |
|
for (x = 0; (d = readdir(dir)); x++) |
|
162 |
|
{ |
|
163 |
|
if (!strncmp(d->d_name, filename, filename_len)) |
|
164 |
|
{ |
|
165 |
|
found++; |
|
166 |
|
break; |
|
167 |
|
} |
|
168 |
|
} |
|
169 |
|
|
|
170 |
|
closedir(dir); |
|
171 |
|
|
|
172 |
|
|
|
173 |
|
if (found) |
|
174 |
|
{ |
|
175 |
|
int isdir = 0; |
|
176 |
|
if (is_dir(d->d_name)) |
|
177 |
|
{ |
|
178 |
|
isdir = 1; |
|
179 |
|
} |
|
180 |
|
else if (strcmp(dirname, ".")) |
|
181 |
|
{ |
|
182 |
|
char * tempfile = (char *)NULL; |
|
183 |
|
int len = strlen(dirname) + strlen(d->d_name) + 1; |
|
184 |
|
tempfile = (char *)malloc((len) * sizeof(char)); |
|
185 |
|
if (!tempfile) |
|
186 |
|
return NULL; |
|
187 |
|
snprintf(tempfile, len, "%s%s", dirname, d->d_name); |
|
188 |
|
if (is_dir(tempfile)) |
|
189 |
|
isdir = 1; |
|
190 |
|
else |
|
191 |
|
temp = strdup(d->d_name); |
|
192 |
|
|
|
193 |
|
my_free(tempfile); |
|
194 |
|
} |
|
195 |
|
else |
|
196 |
|
temp = strdup(d->d_name); |
|
197 |
|
|
|
198 |
|
if (isdir) |
|
199 |
|
{ |
|
200 |
|
char * tempfile = (char *)NULL; |
|
201 |
|
tempfile = (char *) malloc((strlen(d->d_name) + 2) * sizeof(char)); |
|
202 |
|
if (!tempfile) |
|
203 |
|
return NULL; |
|
204 |
|
snprintf(tempfile, strlen(d->d_name) + 2, "%s/", d->d_name); |
|
205 |
|
temp = strdup(tempfile); |
|
206 |
|
|
|
207 |
|
my_free(tempfile); |
|
208 |
|
} |
|
209 |
|
|
|
210 |
|
my_free(filename); |
|
211 |
|
my_free(dirname); |
|
212 |
|
|
|
213 |
|
return temp; |
|
214 |
|
} |
|
215 |
|
else |
|
216 |
|
{ |
|
217 |
|
my_free(filename); |
|
218 |
|
my_free(dirname); |
|
219 |
|
return NULL; |
|
220 |
|
} |
|
221 |
|
} |
|
222 |
|
|
|
223 |
|
char * |
|
224 |
|
my_rl_gets(int type) |
|
225 |
|
{ |
|
226 |
|
static char *line_read = (char *)NULL; |
|
227 |
|
int key; |
|
228 |
|
int pos; |
|
229 |
|
int index = 0; |
|
230 |
|
int done = 0; |
|
231 |
|
int abort = 0; |
|
232 |
|
int len = 0; |
|
233 |
|
int cmd_pos = -1; |
|
234 |
|
int prompt_len; |
|
235 |
|
char prompt[8]; |
|
236 |
|
|
|
237 |
|
/* If the buffer has already been allocated, free the memory. */ |
|
238 |
|
if (line_read) |
|
239 |
|
{ |
|
240 |
|
my_free(line_read); |
|
241 |
|
line_read = (char *)NULL; |
|
242 |
|
} |
|
243 |
|
|
|
244 |
|
if (type == GET_VISUAL_COMMAND) |
|
245 |
|
prompt_len = pos = 6; |
|
246 |
|
else |
|
247 |
|
prompt_len = pos = 1; |
|
248 |
|
|
|
249 |
|
curs_set(1); |
|
250 |
|
werase(status_bar); |
|
251 |
|
|
|
252 |
|
if (type == GET_COMMAND || type == MENU_COMMAND) |
|
253 |
|
snprintf(prompt, sizeof(prompt), ":"); |
|
254 |
|
else if (type == GET_SEARCH_PATTERN || type == MENU_SEARCH) |
|
255 |
|
snprintf(prompt, sizeof(prompt), "/"); |
|
256 |
|
/* |
|
257 |
|
else if (type == MAPPED_COMMAND || type == MAPPED_SEARCH) |
|
258 |
|
{ |
|
259 |
|
snprintf(buf, sizeof(buf), "%s", string); |
|
260 |
|
mvwaddstr(status_bar, 0, 0, string); |
|
261 |
|
pos = strlen(string); |
|
262 |
|
index = pos -1; |
|
263 |
|
len = index; |
|
264 |
|
} |
|
265 |
|
*/ |
|
266 |
|
else if (type == GET_VISUAL_COMMAND) |
|
267 |
|
snprintf(prompt, sizeof(prompt), ":'<,'>"); |
|
268 |
|
|
|
269 |
|
mvwaddstr(status_bar, 0, 0, prompt); |
|
270 |
|
|
|
271 |
|
while (!done) |
|
272 |
|
{ |
|
273 |
|
if(curr_stats.freeze) |
|
274 |
|
continue; |
|
275 |
|
|
|
276 |
|
curs_set(1); |
|
277 |
|
flushinp(); |
|
278 |
|
curr_stats.getting_input = 1; |
|
279 |
|
key = wgetch(status_bar); |
|
280 |
|
|
|
281 |
|
switch (key) |
|
282 |
|
{ |
|
283 |
|
case 27: /* ascii Escape */ |
|
284 |
|
case 3: /* ascii Ctrl C */ |
|
285 |
|
done = 1; |
|
286 |
|
abort = 1; |
|
287 |
|
break; |
|
288 |
|
case 13: /* ascii Return */ |
|
289 |
|
done = 1; |
|
290 |
|
break; |
|
291 |
|
case 9: /* ascii Tab */ |
|
292 |
|
{ |
|
293 |
|
char *last_word = (char *)NULL; |
|
294 |
|
char *raw_name = (char *)NULL; |
|
295 |
|
char *filename = (char *)NULL; |
|
296 |
|
|
|
297 |
|
if (type == MENU_SEARCH || type == MENU_COMMAND) |
|
298 |
|
break; |
|
299 |
|
|
|
300 |
|
if(! line_read) |
|
301 |
|
break; |
|
302 |
|
|
|
303 |
|
last_word = get_last_word(line_read); |
|
304 |
|
|
|
305 |
|
if (last_word) |
|
306 |
|
{ |
|
307 |
|
raw_name = filename_completion(last_word); |
|
308 |
|
if (raw_name) |
|
309 |
|
filename = escape_filename(raw_name, 1); |
|
310 |
|
} |
|
311 |
|
/* :partial_command */ |
|
312 |
|
else |
|
313 |
|
{ |
|
314 |
|
char *complete_command = check_for_command(line_read); |
|
315 |
|
|
|
316 |
|
if (complete_command) |
|
317 |
|
{ |
|
318 |
|
line_read = strdup(complete_command); |
|
319 |
|
|
|
320 |
|
mvwaddstr(status_bar, 0, prompt_len, line_read); |
|
321 |
|
pos = index = strlen(line_read); |
|
322 |
|
pos++; |
|
323 |
|
|
|
324 |
|
my_free(complete_command); |
|
325 |
|
break; |
|
326 |
|
} |
|
327 |
|
else |
|
328 |
|
break; |
|
329 |
|
} |
|
330 |
|
|
|
331 |
|
if (filename) |
|
332 |
|
{ |
|
333 |
|
char *temp = (char *)NULL; |
|
334 |
|
|
|
335 |
|
/* :command /some/directory/partial_filename */ |
|
336 |
|
if ((temp = strrchr(line_read, '/'))) |
|
337 |
|
{ |
|
338 |
|
temp++; |
|
339 |
|
*temp = '\0'; |
|
340 |
|
|
|
341 |
|
line_read = (char *)realloc(line_read, (strlen(line_read) + |
|
342 |
|
strlen(filename) + 1) * sizeof(char)); |
|
343 |
|
|
|
344 |
|
if (!line_read) |
|
345 |
|
{ |
|
346 |
|
my_free(raw_name); |
|
347 |
|
my_free(filename); |
|
348 |
|
break; |
|
349 |
|
} |
|
350 |
|
|
|
351 |
|
strcat(line_read, filename); |
|
352 |
|
my_free(filename); |
|
353 |
|
my_free(raw_name); |
|
354 |
|
|
|
355 |
|
} |
|
356 |
|
/* :command partial_filename */ |
|
357 |
|
else if ((temp = strrchr(line_read, ' '))) |
|
358 |
|
{ |
|
359 |
|
temp++; |
|
360 |
|
*temp = '\0'; |
|
361 |
|
|
|
362 |
|
line_read = (char *)realloc(line_read, (strlen(line_read) + |
|
363 |
|
strlen(filename) + 1) * sizeof(char)); |
|
364 |
|
if (!line_read) |
|
365 |
|
{ |
|
366 |
|
my_free(filename); |
|
367 |
|
break; |
|
368 |
|
} |
|
369 |
|
|
|
370 |
|
strcat(line_read, filename); |
|
371 |
|
my_free(raw_name); |
|
372 |
|
my_free(filename); |
|
373 |
|
} |
|
374 |
|
/* :!partial_filename or :!!partial_filename */ |
|
375 |
|
else if ((temp = strrchr(line_read, '!'))) |
|
376 |
|
{ |
|
377 |
|
temp++; |
|
378 |
|
*temp = '\0'; |
|
379 |
|
|
|
380 |
|
line_read = (char *)realloc(line_read, (strlen(line_read) + |
|
381 |
|
strlen(filename) + 1) * sizeof(char)); |
|
382 |
|
|
|
383 |
|
if (!line_read) |
|
384 |
|
{ |
|
385 |
|
my_free(raw_name); |
|
386 |
|
my_free(filename); |
|
387 |
|
break; |
|
388 |
|
} |
|
389 |
|
|
|
390 |
|
strcat(line_read, filename); |
|
391 |
|
my_free(raw_name); |
|
392 |
|
my_free(filename); |
|
393 |
|
} |
|
394 |
|
/* error */ |
|
395 |
|
else |
|
396 |
|
{ |
|
397 |
|
show_error_msg(" Debug Error ", |
|
398 |
|
"Harmless error in rline.c line 388"); |
|
399 |
|
my_free(raw_name); |
|
400 |
|
my_free(filename); |
|
401 |
|
break; |
|
402 |
|
} |
|
403 |
|
|
|
404 |
|
mvwaddstr(status_bar, 0, prompt_len, line_read); |
|
405 |
|
pos = index = strlen(line_read); |
|
406 |
|
pos++; |
|
407 |
|
} |
|
408 |
|
else |
|
409 |
|
break; |
|
410 |
|
} |
|
411 |
|
break; |
|
412 |
|
case KEY_UP: |
|
413 |
|
{ |
|
414 |
|
if (type == GET_COMMAND) |
|
415 |
|
{ |
|
416 |
|
if (0 > cfg.cmd_history_num) |
|
417 |
|
break; |
|
418 |
|
|
|
419 |
|
cmd_pos++; |
|
420 |
|
|
|
421 |
|
if(cmd_pos > cfg.cmd_history_num) |
|
422 |
|
cmd_pos = 0; |
|
423 |
|
|
|
424 |
|
werase(status_bar); |
|
425 |
|
mvwaddch(status_bar, 0, 0, ':'); |
|
426 |
|
mvwaddstr(status_bar, 0, 1, cfg.cmd_history[cmd_pos]); |
|
427 |
|
pos = strlen(cfg.cmd_history[cmd_pos]) + 1; |
|
428 |
|
line_read = (char *)realloc(line_read, |
|
429 |
|
strlen(cfg.cmd_history[cmd_pos]) + 1); |
|
430 |
|
strcpy(line_read, cfg.cmd_history[cmd_pos]); |
|
431 |
|
index = strlen(line_read); |
|
432 |
|
|
|
433 |
|
if (cmd_pos >= cfg.cmd_history_len - 1) |
|
434 |
|
cmd_pos = cfg.cmd_history_len - 1; |
|
435 |
|
} |
|
436 |
|
else if (type == GET_SEARCH_PATTERN) |
|
437 |
|
{ |
|
438 |
|
if (0 > cfg.search_history_num) |
|
439 |
|
break; |
|
440 |
|
|
|
441 |
|
cmd_pos++; |
|
442 |
|
|
|
443 |
|
if(cmd_pos > cfg.search_history_num) |
|
444 |
|
cmd_pos = 0; |
|
445 |
|
|
|
446 |
|
werase(status_bar); |
|
447 |
|
mvwaddch(status_bar, 0, 0, '/'); |
|
448 |
|
mvwaddstr(status_bar, 0, 1, cfg.search_history[cmd_pos]); |
|
449 |
|
pos = strlen(cfg.search_history[cmd_pos]) + 1; |
|
450 |
|
line_read = (char *)realloc(line_read, |
|
451 |
|
strlen(cfg.search_history[cmd_pos]) + 1); |
|
452 |
|
strcpy(line_read, cfg.search_history[cmd_pos]); |
|
453 |
|
index = strlen(line_read); |
|
454 |
|
|
|
455 |
|
if (cmd_pos >= cfg.search_history_len - 1) |
|
456 |
|
cmd_pos = cfg.search_history_len - 1; |
|
457 |
|
} |
|
458 |
|
} |
|
459 |
|
break; |
|
460 |
|
case KEY_DOWN: |
|
461 |
|
{ |
|
462 |
|
if(type == GET_COMMAND) |
|
463 |
|
{ |
|
464 |
|
if (0 > cfg.cmd_history_num) |
|
465 |
|
break; |
|
466 |
|
|
|
467 |
|
cmd_pos--; |
|
468 |
|
|
|
469 |
|
if (cmd_pos < 0) |
|
470 |
|
cmd_pos = cfg.cmd_history_num; |
|
471 |
|
|
|
472 |
|
werase(status_bar); |
|
473 |
|
mvwaddch(status_bar, 0, 0, ':'); |
|
474 |
|
mvwaddstr(status_bar, 0, 1, cfg.cmd_history[cmd_pos]); |
|
475 |
|
pos = strlen(cfg.cmd_history[cmd_pos]) + 1; |
|
476 |
|
|
|
477 |
|
line_read = (char *)realloc(line_read, |
|
478 |
|
strlen(cfg.cmd_history[cmd_pos]) + 1); |
|
479 |
|
strcpy(line_read, cfg.cmd_history[cmd_pos]); |
|
480 |
|
index = strlen(line_read); |
|
481 |
|
|
|
482 |
|
} |
|
483 |
|
else if (type == GET_SEARCH_PATTERN) |
|
484 |
|
{ |
|
485 |
|
if (0 > cfg.search_history_num) |
|
486 |
|
break; |
|
487 |
|
|
|
488 |
|
cmd_pos--; |
|
489 |
|
|
|
490 |
|
if (cmd_pos < 0) |
|
491 |
|
cmd_pos = cfg.search_history_num; |
|
492 |
|
|
|
493 |
|
werase(status_bar); |
|
494 |
|
mvwaddch(status_bar, 0, 0, '/'); |
|
495 |
|
mvwaddstr(status_bar, 0, 1, cfg.search_history[cmd_pos]); |
|
496 |
|
pos = strlen(cfg.search_history[cmd_pos]) + 1; |
|
497 |
|
|
|
498 |
|
line_read = (char *)realloc(line_read, |
|
499 |
|
strlen(cfg.search_history[cmd_pos]) + 1); |
|
500 |
|
strcpy(line_read, cfg.search_history[cmd_pos]); |
|
501 |
|
index = strlen(line_read); |
|
502 |
|
|
|
503 |
|
} |
|
504 |
|
} |
|
505 |
|
break; |
|
506 |
|
/* This needs to be changed to a value that is read from |
|
507 |
|
* the termcap file. |
|
508 |
|
*/ |
|
509 |
|
case 127: /* ascii Delete */ |
|
510 |
|
case 8: /* ascii Backspace ascii Ctrl H */ |
|
511 |
|
case KEY_BACKSPACE: /* ncurses BACKSPACE KEY */ |
|
512 |
|
{ |
|
513 |
|
pos--; |
|
514 |
|
index--; |
|
515 |
|
len--; |
|
516 |
|
if (type == GET_VISUAL_COMMAND) |
|
517 |
|
{ |
|
518 |
|
if (pos < 6) |
|
519 |
|
pos = 6; |
|
520 |
|
if (index < 0) |
|
521 |
|
index = 0; |
|
522 |
|
} |
|
523 |
|
else |
|
524 |
|
{ |
|
525 |
|
if (pos < 1) |
|
526 |
|
pos = 1; |
|
527 |
|
if (index < 0) |
|
528 |
|
index = 0; |
|
529 |
|
} |
|
530 |
|
mvwdelch(status_bar, 0, pos); |
|
531 |
|
if (line_read) |
|
532 |
|
line_read[index] = '\0'; |
|
533 |
|
} |
|
534 |
|
break; |
|
535 |
|
default: |
|
536 |
|
if (key > 31 && key < 127) |
|
537 |
|
{ |
|
538 |
|
line_read = (char *)realloc(line_read, (index + 2) * (sizeof(char))); |
|
539 |
|
|
|
540 |
|
if (line_read == NULL) |
|
541 |
|
return NULL; |
|
542 |
|
|
|
543 |
|
mvwaddch(status_bar, 0, pos, key); |
|
544 |
|
line_read[index] = key; |
|
545 |
|
index++; |
|
546 |
|
line_read[index] = '\0'; |
|
547 |
|
if (index > 62) |
|
548 |
|
{ |
|
549 |
|
abort = 1; |
|
550 |
|
done = 1; |
|
551 |
|
} |
|
552 |
|
pos++; |
|
553 |
|
len++; |
|
554 |
|
} |
|
555 |
|
break; |
|
556 |
|
} |
|
557 |
|
curr_stats.getting_input = 0; |
|
558 |
|
} |
|
559 |
|
curs_set(0); |
|
560 |
|
werase(status_bar); |
|
561 |
|
wnoutrefresh(status_bar); |
|
562 |
|
|
|
563 |
|
if (abort) |
|
564 |
|
return NULL; |
|
565 |
|
|
|
566 |
|
/* |
|
567 |
|
if (line_read && * line_read) |
|
568 |
|
add_to_command_history(type, line_read); |
|
569 |
|
*/ |
|
570 |
|
|
|
571 |
|
return line_read; |
|
572 |
|
} |
|
573 |
|
|
File src/ui.c added (mode: 100644) (index 0000000..957e7cc) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#define _WIN32_WINNT 0x0500 |
|
20 |
|
#include<signal.h> /* signal() */ |
|
21 |
|
#include<stdlib.h> /* malloc */ |
|
22 |
|
#include<sys/stat.h> /* stat */ |
|
23 |
|
//#include<dirent.h> /* DIR */ |
|
24 |
|
//#include<pwd.h> /* getpwent() */ |
|
25 |
|
#include<string.h> |
|
26 |
|
#include<time.h> |
|
27 |
|
#include<windows.h> |
|
28 |
|
//#include<termios.h> /* struct winsize */ |
|
29 |
|
//#include<sys/ioctl.h> |
|
30 |
|
|
|
31 |
|
#include "color_scheme.h" |
|
32 |
|
#include "config.h" /* for menu colors */ |
|
33 |
|
#include "file_info.h" |
|
34 |
|
#include "filelist.h" |
|
35 |
|
#include "keys.h" |
|
36 |
|
#include "menus.h" |
|
37 |
|
#include "status.h" |
|
38 |
|
#include "ui.h" |
|
39 |
|
#include "utils.h" |
|
40 |
|
|
|
41 |
|
static void |
|
42 |
|
finish(char *message) |
|
43 |
|
{ |
|
44 |
|
endwin(); |
|
45 |
|
write_config_file(); |
|
46 |
|
system("clear"); |
|
47 |
|
printf("%s", message); |
|
48 |
|
exit(0); |
|
49 |
|
} |
|
50 |
|
|
|
51 |
|
void |
|
52 |
|
update_pos_window(FileView *view) |
|
53 |
|
{ |
|
54 |
|
char buf[13]; |
|
55 |
|
|
|
56 |
|
if(curr_stats.freeze) |
|
57 |
|
return; |
|
58 |
|
werase(pos_win); |
|
59 |
|
snprintf(buf, sizeof(buf), "%d-%d ", view->list_pos +1, view->list_rows); |
|
60 |
|
mvwaddstr(pos_win, 0, 13 - strlen(buf), buf); |
|
61 |
|
wnoutrefresh(pos_win); |
|
62 |
|
} |
|
63 |
|
|
|
64 |
|
void |
|
65 |
|
write_stat_win(char *message) |
|
66 |
|
{ |
|
67 |
|
werase(stat_win); |
|
68 |
|
wprintw(stat_win, "%s", message); |
|
69 |
|
wnoutrefresh(stat_win); |
|
70 |
|
} |
|
71 |
|
|
|
72 |
|
void |
|
73 |
|
update_stat_window(FileView *view) |
|
74 |
|
{ |
|
75 |
|
char name_buf[20]; |
|
76 |
|
// char perm_buf[26]; |
|
77 |
|
char size_buf[56]; |
|
78 |
|
// char uid_buf[26]; |
|
79 |
|
//struct passwd *pwd_buf; |
|
80 |
|
int x, y; |
|
81 |
|
|
|
82 |
|
getmaxyx(stat_win, y, x); |
|
83 |
|
snprintf(name_buf, sizeof(name_buf), "%s", get_current_file_name(view)); |
|
84 |
|
describe_file_size(size_buf, sizeof(size_buf), view); |
|
85 |
|
|
|
86 |
|
/* |
|
87 |
|
if((pwd_buf = getpwuid(view->dir_entry[view->list_pos].uid)) == NULL) |
|
88 |
|
{ |
|
89 |
|
snprintf (uid_buf, sizeof(uid_buf), " %d", |
|
90 |
|
(int) view->dir_entry[view->list_pos].uid); |
|
91 |
|
} |
|
92 |
|
else |
|
93 |
|
{ |
|
94 |
|
snprintf(uid_buf, sizeof(uid_buf), " %s", pwd_buf->pw_name); |
|
95 |
|
} |
|
96 |
|
get_perm_string(perm_buf, sizeof(perm_buf), |
|
97 |
|
view->dir_entry[view->list_pos].mode); |
|
98 |
|
*/ |
|
99 |
|
werase(stat_win); |
|
100 |
|
|
|
101 |
|
mvwaddstr(stat_win, 0, 2, name_buf); |
|
102 |
|
mvwaddstr(stat_win, 0, 20, size_buf); |
|
103 |
|
// mvwaddstr(stat_win, 0, 36, perm_buf); |
|
104 |
|
// mvwaddstr(stat_win, 0, 46, uid_buf); |
|
105 |
|
snprintf(name_buf, sizeof(name_buf), "%d %s filtered", |
|
106 |
|
view->filtered, view->filtered == 1 ? "file" : "files"); |
|
107 |
|
|
|
108 |
|
|
|
109 |
|
if(view->filtered > 0) |
|
110 |
|
mvwaddstr(stat_win, 0, x - (strlen(name_buf) +2) , name_buf); |
|
111 |
|
|
|
112 |
|
wnoutrefresh(stat_win); |
|
113 |
|
update_pos_window(view); |
|
114 |
|
} |
|
115 |
|
|
|
116 |
|
void |
|
117 |
|
status_bar_message(char *message) |
|
118 |
|
{ |
|
119 |
|
werase(status_bar); |
|
120 |
|
wprintw(status_bar, "%s", message); |
|
121 |
|
wnoutrefresh(status_bar); |
|
122 |
|
} |
|
123 |
|
|
|
124 |
|
|
|
125 |
|
int |
|
126 |
|
setup_ncurses_interface() |
|
127 |
|
{ |
|
128 |
|
int screen_x, screen_y; |
|
129 |
|
int i, x, y; |
|
130 |
|
|
|
131 |
|
initscr(); |
|
132 |
|
noecho(); |
|
133 |
|
nonl(); |
|
134 |
|
raw(); |
|
135 |
|
|
|
136 |
|
getmaxyx(stdscr, screen_y, screen_x); |
|
137 |
|
/* screen is too small to be useful*/ |
|
138 |
|
if(screen_y < 10) |
|
139 |
|
finish("Terminal is too small to run vifm\n"); |
|
140 |
|
if(screen_x < 30) |
|
141 |
|
finish("Terminal is too small to run vifm\n"); |
|
142 |
|
|
|
143 |
|
if(! has_colors()) |
|
144 |
|
finish("Vifm requires a console that can support color.\n"); |
|
145 |
|
|
|
146 |
|
start_color(); |
|
147 |
|
|
|
148 |
|
x = 0; |
|
149 |
|
|
|
150 |
|
for (i = 0; i < cfg.color_scheme_num; i++) |
|
151 |
|
{ |
|
152 |
|
for(x = 0; x < 12; x++) |
|
153 |
|
init_pair(col_schemes[i].color[x].name, |
|
154 |
|
col_schemes[i].color[x].fg, col_schemes[i].color[x].bg); |
|
155 |
|
} |
|
156 |
|
|
|
157 |
|
werase(stdscr); |
|
158 |
|
|
|
159 |
|
menu_win = newwin(screen_y - 1, screen_x , 0, 0); |
|
160 |
|
wbkgdset(menu_win, COLOR_PAIR(WIN_COLOR)); |
|
161 |
|
werase(menu_win); |
|
162 |
|
|
|
163 |
|
sort_win = newwin(14, 30, (screen_y -12)/2, (screen_x -30)/2); |
|
164 |
|
wbkgdset(sort_win, COLOR_PAIR(WIN_COLOR)); |
|
165 |
|
werase(sort_win); |
|
166 |
|
|
|
167 |
|
change_win = newwin(20, 30, (screen_y -20)/2, (screen_x -30)/2); |
|
168 |
|
wbkgdset(change_win, COLOR_PAIR(WIN_COLOR)); |
|
169 |
|
werase(change_win); |
|
170 |
|
|
|
171 |
|
error_win = newwin(10, screen_x -2, (screen_y -10)/2, 1); |
|
172 |
|
wbkgdset(error_win, COLOR_PAIR(WIN_COLOR)); |
|
173 |
|
werase(error_win); |
|
174 |
|
|
|
175 |
|
lborder = newwin(screen_y - 2, 1, 0, 0); |
|
176 |
|
|
|
177 |
|
wbkgdset(lborder, COLOR_PAIR(BORDER_COLOR)); |
|
178 |
|
|
|
179 |
|
werase(lborder); |
|
180 |
|
|
|
181 |
|
if (curr_stats.number_of_windows == 1) |
|
182 |
|
lwin.title = newwin(0, screen_x -2, 0, 1); |
|
183 |
|
else |
|
184 |
|
lwin.title = newwin(0, screen_x/2 -1, 0, 1); |
|
185 |
|
|
|
186 |
|
wattrset(lwin.title, A_BOLD); |
|
187 |
|
wbkgdset(lwin.title, COLOR_PAIR(BORDER_COLOR)); |
|
188 |
|
|
|
189 |
|
werase(lwin.title); |
|
190 |
|
|
|
191 |
|
if (curr_stats.number_of_windows == 1) |
|
192 |
|
lwin.win = newwin(screen_y - 3, screen_x -2, 1, 1); |
|
193 |
|
else |
|
194 |
|
lwin.win = newwin(screen_y - 3, screen_x/2 -2, 1, 1); |
|
195 |
|
|
|
196 |
|
keypad(lwin.win, TRUE); |
|
197 |
|
wbkgdset(lwin.win, COLOR_PAIR(WIN_COLOR)); |
|
198 |
|
wattrset(lwin.win, A_BOLD); |
|
199 |
|
wattron(lwin.win, A_BOLD); |
|
200 |
|
werase(lwin.win); |
|
201 |
|
getmaxyx(lwin.win, y, x); |
|
202 |
|
lwin.window_rows = y -1; |
|
203 |
|
lwin.window_width = x -1; |
|
204 |
|
|
|
205 |
|
mborder = newwin(screen_y, 2, 0, screen_x/2 -1); |
|
206 |
|
|
|
207 |
|
wbkgdset(mborder, COLOR_PAIR(BORDER_COLOR)); |
|
208 |
|
|
|
209 |
|
werase(mborder); |
|
210 |
|
|
|
211 |
|
if (curr_stats.number_of_windows == 1) |
|
212 |
|
rwin.title = newwin(0, screen_x -2 , 0, 1); |
|
213 |
|
else |
|
214 |
|
rwin.title = newwin(1, screen_x/2 -1 , 0, screen_x/2 +1); |
|
215 |
|
|
|
216 |
|
wbkgdset(rwin.title, COLOR_PAIR(BORDER_COLOR)); |
|
217 |
|
wattrset(rwin.title, A_BOLD); |
|
218 |
|
wattroff(rwin.title, A_BOLD); |
|
219 |
|
|
|
220 |
|
werase(rwin.title); |
|
221 |
|
|
|
222 |
|
if (curr_stats.number_of_windows == 1) |
|
223 |
|
rwin.win = newwin(screen_y - 3, screen_x -2 , 1, 1); |
|
224 |
|
else |
|
225 |
|
rwin.win = newwin(screen_y - 3, screen_x/2 -2 , 1, screen_x/2 +1); |
|
226 |
|
|
|
227 |
|
keypad(rwin.win, TRUE); |
|
228 |
|
wattrset(rwin.win, A_BOLD); |
|
229 |
|
wattron(rwin.win, A_BOLD); |
|
230 |
|
wbkgdset(rwin.win, COLOR_PAIR(WIN_COLOR)); |
|
231 |
|
werase(rwin.win); |
|
232 |
|
getmaxyx(rwin.win, y, x); |
|
233 |
|
rwin.window_rows = y - 1; |
|
234 |
|
rwin.window_width = x -1; |
|
235 |
|
|
|
236 |
|
rborder = newwin(screen_y - 2, 1, 0, screen_x -1); |
|
237 |
|
|
|
238 |
|
wbkgdset(rborder, COLOR_PAIR(BORDER_COLOR)); |
|
239 |
|
|
|
240 |
|
werase(rborder); |
|
241 |
|
|
|
242 |
|
stat_win = newwin(1, screen_x, screen_y -2, 0); |
|
243 |
|
|
|
244 |
|
wbkgdset(stat_win, COLOR_PAIR(BORDER_COLOR)); |
|
245 |
|
|
|
246 |
|
werase(stat_win); |
|
247 |
|
|
|
248 |
|
status_bar = newwin(1, screen_x - 19, screen_y -1, 0); |
|
249 |
|
keypad(status_bar, TRUE); |
|
250 |
|
wattrset(status_bar, A_BOLD); |
|
251 |
|
wattron(status_bar, A_BOLD); |
|
252 |
|
wbkgdset(status_bar, COLOR_PAIR(STATUS_BAR_COLOR)); |
|
253 |
|
werase(status_bar); |
|
254 |
|
|
|
255 |
|
pos_win = newwin(1, 13, screen_y - 1, screen_x -13); |
|
256 |
|
wattrset(pos_win, A_BOLD); |
|
257 |
|
wattron(pos_win, A_BOLD); |
|
258 |
|
wbkgdset(pos_win, COLOR_PAIR(STATUS_BAR_COLOR)); |
|
259 |
|
werase(pos_win); |
|
260 |
|
|
|
261 |
|
num_win = newwin(1, 6, screen_y - 1, screen_x -19); |
|
262 |
|
wattrset(num_win, A_BOLD); |
|
263 |
|
wattron(num_win, A_BOLD); |
|
264 |
|
wbkgdset(num_win, COLOR_PAIR(STATUS_BAR_COLOR)); |
|
265 |
|
werase(num_win); |
|
266 |
|
|
|
267 |
|
|
|
268 |
|
wnoutrefresh(lwin.title); |
|
269 |
|
wnoutrefresh(lwin.win); |
|
270 |
|
wnoutrefresh(rwin.win); |
|
271 |
|
wnoutrefresh(rwin.title); |
|
272 |
|
wnoutrefresh(stat_win); |
|
273 |
|
wnoutrefresh(status_bar); |
|
274 |
|
wnoutrefresh(pos_win); |
|
275 |
|
wnoutrefresh(num_win); |
|
276 |
|
wnoutrefresh(lborder); |
|
277 |
|
wnoutrefresh(mborder); |
|
278 |
|
wnoutrefresh(rborder); |
|
279 |
|
|
|
280 |
|
return 1; |
|
281 |
|
} |
|
282 |
|
|
|
283 |
|
void |
|
284 |
|
redraw_window(void) |
|
285 |
|
{ |
|
286 |
|
int color_scheme = 0; |
|
287 |
|
|
|
288 |
|
endwin(); |
|
289 |
|
|
|
290 |
|
resize_term(0, 0); |
|
291 |
|
|
|
292 |
|
|
|
293 |
|
//setup_ncurses_interface(); |
|
294 |
|
color_scheme = check_directory_for_color_scheme(lwin.curr_dir); |
|
295 |
|
wbkgdset(lwin.title, COLOR_PAIR(BORDER_COLOR + color_scheme)); |
|
296 |
|
wbkgdset(lwin.win, COLOR_PAIR(WIN_COLOR + color_scheme)); |
|
297 |
|
|
|
298 |
|
color_scheme = check_directory_for_color_scheme(rwin.curr_dir); |
|
299 |
|
wbkgdset(rwin.title, COLOR_PAIR(BORDER_COLOR + color_scheme)); |
|
300 |
|
wbkgdset(rwin.win, COLOR_PAIR(WIN_COLOR + color_scheme)); |
|
301 |
|
|
|
302 |
|
curs_set(0); |
|
303 |
|
|
|
304 |
|
doupdate(); |
|
305 |
|
|
|
306 |
|
load_dir_list(other_view, 0); |
|
307 |
|
load_dir_list(curr_view, 0); |
|
308 |
|
|
|
309 |
|
curr_stats.freeze = 0; |
|
310 |
|
curr_stats.need_redraw = 0; |
|
311 |
|
|
|
312 |
|
} |
|
313 |
|
|
|
314 |
|
|
File src/vifm-help.txt added (mode: 100644) (index 0000000..b889ee9) |
|
1 |
|
The basic vi key bindings are used to move through the files and popup |
|
2 |
|
windows. |
|
3 |
|
|
|
4 |
|
k is up |
|
5 |
|
j is down |
|
6 |
|
|
|
7 |
|
h is updir |
|
8 |
|
l is handle file and is the same as Return. |
|
9 |
|
|
|
10 |
|
Ctrl-c or the Escape key will cancel most operations. |
|
11 |
|
Ctrl-l will clear and redraw the screen. |
|
12 |
|
|
|
13 |
|
gg top of list |
|
14 |
|
G bottom of list |
|
15 |
|
cw change word is used to rename a file. |
|
16 |
|
m [a-z][A-Z][0-9] to set bookmark |
|
17 |
|
' letter to goto bookmark |
|
18 |
|
v start or stop visualy selecting files. This works with the j and k keys |
|
19 |
|
for movement. This is different then in vi in that v in visual mode will |
|
20 |
|
leave the selected files highlighted. If you want to clear the selected |
|
21 |
|
files Ctrl-c or Esc will unselect the files. |
|
22 |
|
dd - the default setting is to move the selected files to the trash |
|
23 |
|
directory. |
|
24 |
|
yy - will yank the selected files. |
|
25 |
|
p - will copy the yanked files to the current directory or move the files |
|
26 |
|
to the current directory if they were deleted with dd or :d or if the |
|
27 |
|
files were yanked 'yy' from the Trash directory. |
|
28 |
|
|
|
29 |
|
Space or Tab to switch lists. |
|
30 |
|
|
|
31 |
|
Most movement commands also accept a count 12j would move down 12 lines. |
|
32 |
|
[count] % percent of file list |
|
33 |
|
[count] j or k |
|
34 |
|
[count] G or gg |
|
35 |
|
[count] dd or yy the count is from the current file downward. |
|
36 |
|
:[count] user command is not yet implemented. |
|
37 |
|
:[count] command |
|
38 |
|
The only builtin :[count] command is :[count]d[elete]. :3d would delete |
|
39 |
|
three files starting at the current file position moving down. |
|
40 |
|
|
|
41 |
|
:number - move to the line number :12 would move to the 12th line. |
|
42 |
|
:0 move to the top of the list. |
|
43 |
|
:$ move to the bottom of the list. |
|
44 |
|
|
|
45 |
|
Return or l - handle file |
|
46 |
|
Default file type program or if on a directory enter the directory |
|
47 |
|
|
|
48 |
|
Ctrl-g toggles full file information window. |
|
49 |
|
Ctrl-b - jump back one page. |
|
50 |
|
Ctrl-f - jump forward one page. |
|
51 |
|
|
|
52 |
|
/regular expression pattern - will highlight all files matching the pattern |
|
53 |
|
in the current file list. /\.c$ would highlight all the .c files. |
|
54 |
|
N find previous match. |
|
55 |
|
n find next match. |
|
56 |
|
|
|
57 |
|
Files can also be tagged or selected with 't'. Pressing 't' on a selected |
|
58 |
|
file will unselect it. This can be used by itself to select files or with a |
|
59 |
|
/search pattern or with visually selected files. |
|
60 |
|
|
|
61 |
|
:commands |
|
62 |
|
:com is a menu of user commands |
|
63 |
|
:com name action - will set a new user command |
|
64 |
|
Unlike vim user commands do not have to start with a capital letter. |
|
65 |
|
User commands are run in a shell by default. To run a command in |
|
66 |
|
the background you must set it as a background command with & at the end |
|
67 |
|
of the commands action. |
|
68 |
|
:com rm rm %f & |
|
69 |
|
|
|
70 |
|
:com! name action - will overwrite a preciously set command. |
|
71 |
|
:delc command_name will remove the command_name user command |
|
72 |
|
:fil regular_expression pattern will filter the files out of the directory |
|
73 |
|
listing that match the regular expression. |
|
74 |
|
:fil \.o$ - would filter all files ending in .o from the filelist. |
|
75 |
|
:empty will permanently remove 'rm -fr' files from the Trash directory. |
|
76 |
|
:sh will start a shell |
|
77 |
|
:q or :x will exit vifm |
|
78 |
|
:! program will execute the program in a shell |
|
79 |
|
:!command & will run the process in the background. |
|
80 |
|
programs that write to stdout like ls will create an error message |
|
81 |
|
showing partial output of the command. |
|
82 |
|
:!! same as :! but will pause the screen before returning to vifm. |
|
83 |
|
:!!ls -l |
|
84 |
|
:e load file into vi |
|
85 |
|
:pwd - show the present working directory |
|
86 |
|
:ch[ange] - create a menu window to alter a files properties. |
|
87 |
|
:cd - change directory |
|
88 |
|
:cd ~/bin |
|
89 |
|
:s[ort] - popup menu of different sorting methods |
|
90 |
|
:sp[lit] - switch to a two window view. |
|
91 |
|
:his[tory] - popup menu of directories visited |
|
92 |
|
:view - toggle on and off the quick file view. |
|
93 |
|
:h[elp] - this crude help file |
|
94 |
|
:marks - popup menu of bookmarks |
|
95 |
|
:screen toggles whether to use the screen program or not. |
|
96 |
|
:sync - change the other panel to the current panel directory. |
|
97 |
|
|
|
98 |
|
:copy - copy selected file or files to other directory - win32 only |
|
99 |
|
:move - move selected file or files to other directory - win32 only |
|
100 |
|
:volume - show mounted volumes - win32 only |
|
101 |
|
|
|
102 |
|
|
|
103 |
|
command macros |
|
104 |
|
%a user arguments |
|
105 |
|
%f all of the selected files |
|
106 |
|
%F all of the selected files in the other directory list. |
|
107 |
|
%d current directory name |
|
108 |
|
%D other file list directory name |
|
109 |
|
:com mv mv %f %D |
|
110 |
|
would set the mv command to mv all of the selected files to the other |
|
111 |
|
directory. |
|
112 |
|
|
|
113 |
|
If you want a command to accept arguments you must use %a. |
|
114 |
|
:com mkdir mkdir %a & |
|
115 |
|
:com mygrep vim "+grep %a" |
|
116 |
|
%a is simply replaced with the user arguments and the arguments are |
|
117 |
|
considered to be optional. |
|
118 |
|
:com lsl ls -l %a | less - would run ls -l | less with or without |
|
119 |
|
an argument being given. |
|
120 |
|
|
|
121 |
|
search patterns can be set with :com name /pattern |
|
122 |
|
:com backup /~$ |
|
123 |
|
|
|
124 |
|
|
|
125 |
|
file filters |
|
126 |
|
The basic vim folding key bindings are used for filtering files. |
|
127 |
|
zO show the filtered files |
|
128 |
|
zM Filter the files matching the filename filter. |
|
129 |
|
zo show all the dot files |
|
130 |
|
zm filter all the .dot files |
|
131 |
|
zf filter all the selected files |
|
132 |
|
This will work with all selecting methods. Visually selecting files, |
|
133 |
|
using a / search pattern or in combination with 't'. |
|
134 |
|
:fil[ter] regular expression |
|
135 |
|
:in[vert] invert the filter |
|
136 |
|
All directorys will show the ../ file no matter what the filter setting is |
|
137 |
|
with the exception of the / directory. |
|
138 |
|
Each file list has its own filter. |
|
139 |
|
filtered files are not checked in / search or :commands |
|
140 |
|
|
|
141 |
|
file name filters can be set with :com name fil pattern |
|
142 |
|
:com ofiles fil \.o$ |
|
143 |
|
|
|
144 |
|
Configuration. |
|
145 |
|
|
|
146 |
|
The default configuration file is %APPDATA\Vifm\vifmrc |
|
147 |
|
If you want to change any settings vifm must not be running when you edit |
|
148 |
|
the file as it will overwrite any changes you make when it exits. |
|
149 |
|
|
|
150 |
|
|
|
151 |
|
Misc. |
|
152 |
|
Ctrl-c or Escape to clear all selected files |
|
153 |
|
|
|
154 |
|
vifm.vim is a vim plugin that allows the use of vifm from vim. It is |
|
155 |
|
included in the source tarball but it is not installed by default and must |
|
156 |
|
be manually placed in either the default vim/plugin directory or in |
|
157 |
|
~/.vim/plugin/ |
|
158 |
|
To use vifm to load a file into a running vim use the following commands: |
|
159 |
|
:Edit - open a file in the current buffer. |
|
160 |
|
:Split - split the buffer and open a file. |
|
161 |
|
:Vsplit - vertically split a buffer and open a file. |
|
162 |
|
:Diff - open a file to compare to the current file using the vim :diff |
|
163 |
|
command. |
|
164 |
|
You can edit the vifm.vim script to change the command name used if they |
|
165 |
|
conflict with other user commands. |
|
166 |
|
|
|
167 |
|
Starting options: |
|
168 |
|
/full/path/to/directoryone - using vifm /usr/local will start vifm |
|
169 |
|
with the /usr/local directory. The default is to start vifm in |
|
170 |
|
the current directory. |
|
171 |
|
/full/path/to/directorytwo - using two full paths will start vifm with |
|
172 |
|
the first path in the left file list and the second path in the right |
|
173 |
|
file list. |
|
174 |
|
--version - will print the version number and exit. |
|
175 |
|
--help - will show help file. |
|
176 |
|
-f - will run vifm but selecting a file will write the file name to |
|
177 |
|
~/.vifm/vimfiles instead of opening the file. This is used for the |
|
178 |
|
vifm.vim script to load files from vifm into a running vim. |
|
179 |
|
|
|
180 |
|
Menus |
|
181 |
|
bookmarks escape or Ctrl-c to abort j and k to move through |
|
182 |
|
dd on a bookmark to remove. |
|
183 |
|
|
|
184 |
|
sort menu j and k to move - Escape or Ctrl-c to clear - return or l to |
|
185 |
|
select and exit the menu. |
|
186 |
|
|
|
187 |
|
Reserved :commands |
|
188 |
|
! |
|
189 |
|
change |
|
190 |
|
cd |
|
191 |
|
cmap |
|
192 |
|
com |
|
193 |
|
copy |
|
194 |
|
d |
|
195 |
|
delc |
|
196 |
|
e |
|
197 |
|
empty |
|
198 |
|
fi |
|
199 |
|
fil |
|
200 |
|
file |
|
201 |
|
filter |
|
202 |
|
h |
|
203 |
|
help |
|
204 |
|
his |
|
205 |
|
history |
|
206 |
|
in |
|
207 |
|
invert |
|
208 |
|
map |
|
209 |
|
marks |
|
210 |
|
move |
|
211 |
|
nmap |
|
212 |
|
pw |
|
213 |
|
pwd |
|
214 |
|
q |
|
215 |
|
s |
|
216 |
|
screen |
|
217 |
|
sh |
|
218 |
|
sort |
|
219 |
|
unmap |
|
220 |
|
view |
|
221 |
|
vifm |
|
222 |
|
volume |
|
223 |
|
vmap |
|
224 |
|
x |
|
225 |
|
|
File src/vifm.txt added (mode: 100644) (index 0000000..1ce64e9) |
|
1 |
|
*vifm.txt* |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|Filters| Using the file filters. |
|
5 |
|
|Commands| How to use and set :commands. |
|
6 |
|
|Configure| Configuration of vifm. |
|
7 |
|
|Marks| Bookmarking of files. |
|
8 |
|
|Movement| How to move around. |
|
9 |
|
|Normal| Normal mode keys. |
|
10 |
|
|Options| Command line arguments. |
|
11 |
|
|Plugin| Using the vifm.vim plugin. |
|
12 |
|
|Reserved| List of reserved commands. |
|
13 |
|
|Vifm_Ranges| How to use ranges in vifm. |
|
14 |
|
|
|
15 |
|
-------------------------------------------------------------------------------- |
|
16 |
|
*Commands* |
|
17 |
|
|
|
18 |
|
Commands are set with :com command_name command_action<Return> |
|
19 |
|
:com! command_name command_action - will overwrite a previously set command. |
|
20 |
|
:delc[ommand] command_name - will remove the command. |
|
21 |
|
|
|
22 |
|
Commands are executed with :command_name<Return> |
|
23 |
|
Command names do not have to start with a capital letter. |
|
24 |
|
Trying to use a reserved command name will result in an error msg. |
|
25 |
|
See |Reserved| for a list of reserved command names. |
|
26 |
|
|
|
27 |
|
:com<Return> creates a menu of user commands. |
|
28 |
|
|
|
29 |
|
The builtin commands are: |
|
30 |
|
|
|
31 |
|
:!program - shellout and execute program. |
|
32 |
|
:!!program - same as :! but will pause before returning. |
|
33 |
|
This will be changed for compatibility with vim. |
|
34 |
|
:!! - repeat the last command. |
|
35 |
|
:!!program - will pause before returning. |
|
36 |
|
:apropos manpage - will create a menu of items returned by the apropos |
|
37 |
|
command. Selecting an item in the menu will open the corresponding |
|
38 |
|
manpage. |
|
39 |
|
:ch[ange] - create a menu window to alter a files properties. |
|
40 |
|
:cd - change to your home directory. |
|
41 |
|
:cd /usr/local - change directory to /usr/local. |
|
42 |
|
:[range]d[elete][count] - delete selected file or files. |
|
43 |
|
See |Vifm_Ranges| for the ranges implemented. |
|
44 |
|
:delc[ommand] user_command - remove user_command. |
|
45 |
|
:e[dit} - will load the selected file or files into vi. |
|
46 |
|
:em[pty] - permanently remove files from the ~/.vifm/Trash directory. |
|
47 |
|
:f[ilter] regular_expression - will filter files matching the pattern out of |
|
48 |
|
the directory. See |Filters| |
|
49 |
|
:file - popup menu of programs set for the file type of the current file. |
|
50 |
|
:h[elp] - show this help file. |
|
51 |
|
:h argument - is the same as using ':h argument' in vim. |
|
52 |
|
:his[tory] - show directory history. |
|
53 |
|
:invert - invert file name filter. |
|
54 |
|
:jobs - shows menu of current backgrounded processes. |
|
55 |
|
:locate filename - uses the locate command to create a menu of filenames |
|
56 |
|
Selecting a file from the menu will reload the current file list in vifm |
|
57 |
|
to show the selected file. |
|
58 |
|
:marks - menu of bookmarks. |
|
59 |
|
:o[nly] - switch to a one window view. |
|
60 |
|
:pwd - show the present working directory. |
|
61 |
|
:q[uit] or :x - will exit vifm. |
|
62 |
|
:sh[ell] - will start a shell. |
|
63 |
|
:sc[reen] - toggles whether to use the screen program or not. |
|
64 |
|
:s[ort] - menu of different sorting methods. |
|
65 |
|
:sp[lit] - switch to a two window view. |
|
66 |
|
:sy[nc] - change the other panel to the current panels directory. |
|
67 |
|
:vi[ew] - toggle on and off the quick file view. |
|
68 |
|
:x - exit vifm. |
|
69 |
|
|
|
70 |
|
command macros: |
|
71 |
|
%a user arguments. |
|
72 |
|
%f all of the selected files. |
|
73 |
|
%F all of the selected files in the other directory list. |
|
74 |
|
%d current directory name. |
|
75 |
|
%D other file list directory name. |
|
76 |
|
|
|
77 |
|
The command macros may be used in user commands. |
|
78 |
|
:com move mv %f %D - would set the :move command to move all of the files |
|
79 |
|
selected in the current directory to the other directory. |
|
80 |
|
|
|
81 |
|
The %a macro will substitute any arguments given in a command into the |
|
82 |
|
command. All arguments are considered optional. |
|
83 |
|
:com lsl !!ls -l %a - will set the lsl command to execute ls -l with or |
|
84 |
|
without an argument. |
|
85 |
|
|
|
86 |
|
:lsl<Return> will list the directory contents of the current directory. |
|
87 |
|
:lsl filename<Return> will list only the given filename. |
|
88 |
|
|
|
89 |
|
The macros can also be used in directly executing commands. |
|
90 |
|
:!mv %f %D - would move the current directory selected files to the other |
|
91 |
|
directory. |
|
92 |
|
|
|
93 |
|
Appending & to the end of a command will cause it to be executed in the |
|
94 |
|
background. |
|
95 |
|
|
|
96 |
|
:!mv %f %D & |
|
97 |
|
|
|
98 |
|
-------------------------------------------------------------------------------- |
|
99 |
|
*Filters* |
|
100 |
|
|
|
101 |
|
There are two basic file filters. One for dot files and one for file names. |
|
102 |
|
|
|
103 |
|
The basic vim folding key-bindings are used for filters. |
|
104 |
|
za - toggles the showing and hiding of dot files. |
|
105 |
|
zo - show the dot files. |
|
106 |
|
zf - add the selected files to the file name filter. |
|
107 |
|
zm - hide the dot files. |
|
108 |
|
zO - show the hidden file name files. |
|
109 |
|
zM - restore all filters. |
|
110 |
|
zR - remove all filters. |
|
111 |
|
|
|
112 |
|
|
|
113 |
|
-------------------------------------------------------------------------------- |
|
114 |
|
*Marks* |
|
115 |
|
|
|
116 |
|
:marks - will create a menu of the current marks. |
|
117 |
|
m[letter] will set a mark at the current cursor position. |
|
118 |
|
'[letter] will move to a mark. |
|
119 |
|
|
|
120 |
|
-------------------------------------------------------------------------------- |
|
121 |
|
*Movement* |
|
122 |
|
|
|
123 |
|
k is up |
|
124 |
|
j is down |
|
125 |
|
|
|
126 |
|
h is up directory |
|
127 |
|
l is handle file and is the same as Return |
|
128 |
|
|
|
129 |
|
gg will move to the first line of the file list. |
|
130 |
|
|
|
131 |
|
G will move to the last line in the file list. |
|
132 |
|
|
|
133 |
|
Space or Tab to switch file lists. |
|
134 |
|
|
|
135 |
|
Most movement commands also accept a count 12j would move down 12 files. |
|
136 |
|
[count]% move to percent of the file list. |
|
137 |
|
[count]j move down count files. |
|
138 |
|
[count]k move up count files. |
|
139 |
|
[count]G or gg move to list position count. |
|
140 |
|
|
|
141 |
|
-------------------------------------------------------------------------------- |
|
142 |
|
*Normal* |
|
143 |
|
|
|
144 |
|
/regular expression. - select files matching regular expression. |
|
145 |
|
H - move to the first file in the window. |
|
146 |
|
L - move to the last file in the window. |
|
147 |
|
M - move to the file in the middle of the window. |
|
148 |
|
N - previous file matching last search pattern. |
|
149 |
|
cw - change word is used to rename a file. |
|
150 |
|
dd - move selected file or files to ~/.vifm/Trash |
|
151 |
|
yy, Y - yank selected files. |
|
152 |
|
p - put last selected files. |
|
153 |
|
n - next file matching last search pattern. |
|
154 |
|
s - open a shell - this is temporary and will be removed. |
|
155 |
|
t - select or unselect a file. |
|
156 |
|
v, V - start visual selection of files. |
|
157 |
|
|
|
158 |
|
-------------------------------------------------------------------------------- |
|
159 |
|
*Options* |
|
160 |
|
|
|
161 |
|
The vifm executable will start vifm in the current directory unless it is |
|
162 |
|
given a different directory on the command line. |
|
163 |
|
|
|
164 |
|
vifm /path/to/directory/one |
|
165 |
|
or |
|
166 |
|
vifm /path/to/directory/one /path/to/directory/two |
|
167 |
|
|
|
168 |
|
The only other command line arguments are: |
|
169 |
|
-f - only used from the vifm.vim script. The selected files are written |
|
170 |
|
to ~/.vifm/vimfiles and vifm exits. |
|
171 |
|
|
|
172 |
|
--help - show a brief command summary and exit vifm. |
|
173 |
|
--version - show the version number of vifm and exit. |
|
174 |
|
|
|
175 |
|
-------------------------------------------------------------------------------- |
|
176 |
|
*Configure* |
|
177 |
|
|
|
178 |
|
The ~/.vifm/vifmrc file contains all the configurable settings. It is |
|
179 |
|
commented and you must edit it by hand to change the settings. |
|
180 |
|
|
|
181 |
|
The :screen command toggles whether to use the screen program or not. |
|
182 |
|
|
|
183 |
|
The default configuration has the screen option turned off. The screen |
|
184 |
|
program uses pseudo terminals to allow multiple windows to be used in |
|
185 |
|
the console or in a single xterm. Starting vifm from screen with the |
|
186 |
|
screen option turned on will cause vifm to open a new screen window for |
|
187 |
|
each new file edited or program launched from vifm. |
|
188 |
|
|
|
189 |
|
This requires screen version 3.9.9 or newer for the screen -X argument. |
|
190 |
|
|
|
191 |
|
|
|
192 |
|
-------------------------------------------------------------------------------- |
|
193 |
|
*Plugin* Plugin for using vifm in vim as a file selector. |
|
194 |
|
|
|
195 |
|
Commands: |
|
196 |
|
|
|
197 |
|
:EditVifm select a file to open in the current buffer. |
|
198 |
|
:SplitVifm split buffer and select a file to open. |
|
199 |
|
:VsplitVifm vertically split buffer and select a file to open. |
|
200 |
|
:DiffVifm select a file to compare to the current file with :vert diffsplit. |
|
201 |
|
|
|
202 |
|
The plugin does not have any settings. |
|
203 |
|
|
|
204 |
|
To use the plugin copy the vifm.vim file to either the system wide vim/plugin |
|
205 |
|
directory or into ~/.vim/plugin. |
|
206 |
|
|
|
207 |
|
If you would prefer not to use the plugin and it is in the system wide plugin |
|
208 |
|
directory add |
|
209 |
|
|
|
210 |
|
let loaded_vifm=1 |
|
211 |
|
|
|
212 |
|
to your ~/.vimrc file. |
|
213 |
|
-------------------------------------------------------------------------------- |
|
214 |
|
*Vifm_Ranges* |
|
215 |
|
|
|
216 |
|
The ranges implemented include: |
|
217 |
|
Numbers :2,3 |
|
218 |
|
% - the entire directory. |
|
219 |
|
. - the current position in the filelist. |
|
220 |
|
$ - the end of the filelist. |
|
221 |
|
't - the mark position t. |
|
222 |
|
|
|
223 |
|
:%delete would delete all files in the directory. |
|
224 |
|
:2,4delete would delete the files in the list positions 2 through 4. |
|
225 |
|
:.,$delete would delete the files from the current position to the end |
|
226 |
|
of the filelist. |
|
227 |
|
:3delete4 would delete the files in the list positions 3, 4, 5, 6. |
|
228 |
|
|
|
229 |
|
If a backward range is given :4,2delete - an error message is given and |
|
230 |
|
the operation is abandoned. |
|
231 |
|
|
|
232 |
|
The only builtin command that accepts a range is :delete. |
|
233 |
|
|
|
234 |
|
|
|
235 |
|
-------------------------------------------------------------------------------- |
|
236 |
|
*Reserved* |
|
237 |
|
|
|
238 |
|
The following command names are reserved and cannot be used for user commands. |
|
239 |
|
|
|
240 |
|
! - shellout and execute command. |
|
241 |
|
apropos - run the apropos command in a menu window. |
|
242 |
|
cd - change directory |
|
243 |
|
change - alter a files properties |
|
244 |
|
cmap - not used will be used for key mapping. |
|
245 |
|
colorscheme - will be used to set a colorscheme for a directory. |
|
246 |
|
command - show user commands. |
|
247 |
|
delete - delete file. |
|
248 |
|
delcommand - delete command. |
|
249 |
|
edit - edit file. |
|
250 |
|
empty - empty trash directory. |
|
251 |
|
filter - set file name filter. |
|
252 |
|
file - show filetypes menu. |
|
253 |
|
find - not yet implemented. |
|
254 |
|
help - show help file. |
|
255 |
|
history - show directory history. |
|
256 |
|
invert - invert file filter. |
|
257 |
|
locate - run the locate command in a menu window. |
|
258 |
|
map - not used will be used with key mapping. |
|
259 |
|
marks - show marks. |
|
260 |
|
nmap - not used will be used with key mapping. |
|
261 |
|
noh - |
|
262 |
|
pwd - show present working directory. |
|
263 |
|
quit - exit vifm. |
|
264 |
|
screen - toggles use of screen program. |
|
265 |
|
shell - shellout. |
|
266 |
|
sort - show sort menu. |
|
267 |
|
unmap - not used will be used with key mapping. |
|
268 |
|
view - toggle on and off the quick file view. |
|
269 |
|
vifm - not used saved for possible menu. |
|
270 |
|
vmap - not used will be used for key mapping. |
|
271 |
|
x - exit vifm. |
|
272 |
|
|
File src/visual.c added (mode: 100644) (index 0000000..c0a4694) |
|
1 |
|
/* vifm |
|
2 |
|
* Copyright (C) 2001 Ken Steen. |
|
3 |
|
* |
|
4 |
|
* This program is free software; you can redistribute it and/or modify |
|
5 |
|
* it under the terms of the GNU General Public License as published by |
|
6 |
|
* the Free Software Foundation; either version 2 of the License, or |
|
7 |
|
* (at your option) any later version. |
|
8 |
|
* |
|
9 |
|
* This program is distributed in the hope that it will be useful, |
|
10 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
|
* GNU General Public License for more details. |
|
13 |
|
* |
|
14 |
|
* You should have received a copy of the GNU General Public License |
|
15 |
|
* along with this program; if not, write to the Free Software |
|
16 |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
17 |
|
*/ |
|
18 |
|
|
|
19 |
|
#include "commands.h" |
|
20 |
|
#include "config.h" |
|
21 |
|
#include "filelist.h" |
|
22 |
|
#include "fileops.h" |
|
23 |
|
#include "visual.h" |
|
24 |
|
#include "status.h" |
|
25 |
|
#include<string.h> |
|
26 |
|
|
|
27 |
|
/* tbrown |
|
28 |
|
move up one position in the window, adding |
|
29 |
|
to the selection list */ |
|
30 |
|
|
|
31 |
|
void |
|
32 |
|
select_up_one(FileView *view, int start_pos) { |
|
33 |
|
|
|
34 |
|
view->list_pos--; |
|
35 |
|
if(view->list_pos < 0) |
|
36 |
|
{ |
|
37 |
|
if (start_pos == 0) |
|
38 |
|
view->selected_files = 0; |
|
39 |
|
view->list_pos = 0; |
|
40 |
|
} |
|
41 |
|
else if(view->list_pos == 0) |
|
42 |
|
{ |
|
43 |
|
if(start_pos == 0) |
|
44 |
|
{ |
|
45 |
|
view->dir_entry[view->list_pos +1].selected = 0; |
|
46 |
|
view->selected_files = 0; |
|
47 |
|
} |
|
48 |
|
} |
|
49 |
|
else if(view->list_pos < start_pos) |
|
50 |
|
{ |
|
51 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
52 |
|
view->selected_files++; |
|
53 |
|
} |
|
54 |
|
else if(view->list_pos == start_pos) |
|
55 |
|
{ |
|
56 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
57 |
|
view->dir_entry[view->list_pos +1].selected = 0; |
|
58 |
|
view->selected_files = 1; |
|
59 |
|
} |
|
60 |
|
else |
|
61 |
|
{ |
|
62 |
|
view->dir_entry[view->list_pos +1].selected = 0; |
|
63 |
|
view->selected_files--; |
|
64 |
|
} |
|
65 |
|
} |
|
66 |
|
|
|
67 |
|
/*tbrown |
|
68 |
|
move down one position in the window, adding |
|
69 |
|
to the selection list */ |
|
70 |
|
|
|
71 |
|
void |
|
72 |
|
select_down_one(FileView *view, int start_pos) { |
|
73 |
|
|
|
74 |
|
view->list_pos++; |
|
75 |
|
|
|
76 |
|
if(view->list_pos >= view->list_rows) |
|
77 |
|
; |
|
78 |
|
else if(view->list_pos == 0) |
|
79 |
|
{ |
|
80 |
|
if (start_pos == 0) |
|
81 |
|
view->selected_files = 0; |
|
82 |
|
} |
|
83 |
|
else if (view->list_pos == 1 && start_pos != 0) |
|
84 |
|
{ |
|
85 |
|
return; |
|
86 |
|
} |
|
87 |
|
else if(view->list_pos > start_pos) |
|
88 |
|
{ |
|
89 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
90 |
|
view->selected_files++; |
|
91 |
|
} |
|
92 |
|
else if(view->list_pos == start_pos) |
|
93 |
|
{ |
|
94 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
95 |
|
view->dir_entry[view->list_pos -1].selected = 0; |
|
96 |
|
view->selected_files = 1; |
|
97 |
|
} |
|
98 |
|
else |
|
99 |
|
{ |
|
100 |
|
view->dir_entry[view->list_pos -1].selected = 0; |
|
101 |
|
view->selected_files--; |
|
102 |
|
} |
|
103 |
|
} |
|
104 |
|
|
|
105 |
|
|
|
106 |
|
int |
|
107 |
|
visual_key_cb(FileView *view) |
|
108 |
|
{ |
|
109 |
|
int done = 0; |
|
110 |
|
int abort = 0; |
|
111 |
|
int count = 0; |
|
112 |
|
int start_pos = view->list_pos; |
|
113 |
|
char buf[36]; |
|
114 |
|
int save_msg = 0; |
|
115 |
|
|
|
116 |
|
while(!done) |
|
117 |
|
{ |
|
118 |
|
int key; |
|
119 |
|
curr_stats.getting_input = 1; |
|
120 |
|
key = wgetch(view->win); |
|
121 |
|
curr_stats.getting_input = 0; |
|
122 |
|
|
|
123 |
|
switch(key) |
|
124 |
|
{ |
|
125 |
|
case 13: /* ascii Return */ |
|
126 |
|
done = 1; |
|
127 |
|
break; |
|
128 |
|
case 27: /* ascii Escape */ |
|
129 |
|
case 3: /* ascii Ctrl C */ |
|
130 |
|
abort = 1; |
|
131 |
|
break; |
|
132 |
|
case ':': |
|
133 |
|
{ |
|
134 |
|
get_command(view, GET_VISUAL_COMMAND, NULL); |
|
135 |
|
/*abort = 1;*/ |
|
136 |
|
return 0; |
|
137 |
|
} |
|
138 |
|
break; |
|
139 |
|
case 'd': |
|
140 |
|
delete_file(view); |
|
141 |
|
done = 1; |
|
142 |
|
break; |
|
143 |
|
case KEY_DOWN: |
|
144 |
|
case 'j': |
|
145 |
|
{ |
|
146 |
|
select_down_one(view, start_pos); |
|
147 |
|
} |
|
148 |
|
break; |
|
149 |
|
case KEY_UP: |
|
150 |
|
case 'k': |
|
151 |
|
{ |
|
152 |
|
select_up_one(view, start_pos); |
|
153 |
|
} |
|
154 |
|
break; |
|
155 |
|
case 'y': |
|
156 |
|
{ |
|
157 |
|
get_all_selected_files(view); |
|
158 |
|
yank_selected_files(view); |
|
159 |
|
count = view->selected_files; |
|
160 |
|
free_selected_file_array(view); |
|
161 |
|
save_msg = 1; |
|
162 |
|
} |
|
163 |
|
abort = 1; |
|
164 |
|
break; |
|
165 |
|
case 'H': |
|
166 |
|
while (view->list_pos>view->top_line) { |
|
167 |
|
select_up_one(view,start_pos); |
|
168 |
|
} |
|
169 |
|
break; |
|
170 |
|
/*tbrown move to middle of window, selecting from start position to there |
|
171 |
|
*/ |
|
172 |
|
case 'M': |
|
173 |
|
/*window smaller than file list */ |
|
174 |
|
if (view->list_rows < view->window_rows) |
|
175 |
|
{ |
|
176 |
|
/*in upper portion */ |
|
177 |
|
if (view->list_pos < view->list_rows/2) |
|
178 |
|
{ |
|
179 |
|
while (view->list_pos < view->list_rows/2) |
|
180 |
|
{ |
|
181 |
|
select_down_one(view,start_pos); |
|
182 |
|
} |
|
183 |
|
} |
|
184 |
|
/* lower portion */ |
|
185 |
|
else if (view->list_pos > view->list_rows/2) |
|
186 |
|
{ |
|
187 |
|
while (view->list_pos > view->list_rows/2) |
|
188 |
|
{ |
|
189 |
|
select_up_one(view,start_pos); |
|
190 |
|
} |
|
191 |
|
} |
|
192 |
|
} |
|
193 |
|
/* window larger than file list */ |
|
194 |
|
else |
|
195 |
|
{ |
|
196 |
|
/* top half */ |
|
197 |
|
if (view->list_pos < (view->top_line+view->window_rows/2)) |
|
198 |
|
{ |
|
199 |
|
while (view->list_pos < (view->top_line+view->window_rows/2)) |
|
200 |
|
{ |
|
201 |
|
select_down_one(view,start_pos); |
|
202 |
|
} |
|
203 |
|
} |
|
204 |
|
/* bottom half */ |
|
205 |
|
else if (view->list_pos > (view->top_line+view->window_rows/2)) |
|
206 |
|
{ |
|
207 |
|
while (view->list_pos > (view->top_line+view->window_rows/2)) |
|
208 |
|
{ |
|
209 |
|
select_up_one(view,start_pos); |
|
210 |
|
} |
|
211 |
|
} |
|
212 |
|
} |
|
213 |
|
break; |
|
214 |
|
/* tbrown move to last line of window, selecting as we go */ |
|
215 |
|
case 'L': |
|
216 |
|
while (view->list_pos<(view->top_line + view->window_rows)) |
|
217 |
|
{ |
|
218 |
|
select_down_one(view,start_pos); |
|
219 |
|
} |
|
220 |
|
break; |
|
221 |
|
/* tbrown select all files */ |
|
222 |
|
case 1: /* ascii Ctrl A */ |
|
223 |
|
moveto_list_pos(view,1); |
|
224 |
|
while (view->list_pos < view->list_rows) |
|
225 |
|
{ |
|
226 |
|
select_down_one(view,view->list_pos); |
|
227 |
|
} |
|
228 |
|
break; |
|
229 |
|
/* tbrown */ |
|
230 |
|
case 2: /* ascii Ctrl B */ |
|
231 |
|
case KEY_PPAGE: |
|
232 |
|
while (view->list_pos > (view->top_line - view->window_rows -1)) |
|
233 |
|
{ |
|
234 |
|
select_up_one(view,start_pos); |
|
235 |
|
} |
|
236 |
|
break; |
|
237 |
|
/* tbrown */ |
|
238 |
|
case 'G': |
|
239 |
|
while (view->list_pos < view->list_rows) |
|
240 |
|
{ |
|
241 |
|
select_down_one(view,start_pos); |
|
242 |
|
} |
|
243 |
|
break; |
|
244 |
|
/* tbrown */ |
|
245 |
|
case 6: /* ascii Ctrl F */ |
|
246 |
|
case KEY_NPAGE: |
|
247 |
|
while (view->list_pos < (view->top_line+(2*view->window_rows)+1)) |
|
248 |
|
{ |
|
249 |
|
select_down_one(view,start_pos); |
|
250 |
|
} |
|
251 |
|
break; |
|
252 |
|
default: |
|
253 |
|
break; |
|
254 |
|
} |
|
255 |
|
if(abort) |
|
256 |
|
{ |
|
257 |
|
int x; |
|
258 |
|
if(view->selected_files) |
|
259 |
|
{ |
|
260 |
|
for(x = 0; x < view->list_rows; x++) |
|
261 |
|
view->dir_entry[x].selected = 0; |
|
262 |
|
|
|
263 |
|
view->selected_files = 0; |
|
264 |
|
} |
|
265 |
|
done = 1; |
|
266 |
|
} |
|
267 |
|
|
|
268 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
269 |
|
moveto_list_pos(view, view->list_pos); |
|
270 |
|
update_pos_window(view); |
|
271 |
|
|
|
272 |
|
if(abort) |
|
273 |
|
return 0; |
|
274 |
|
|
|
275 |
|
if(count) |
|
276 |
|
{ |
|
277 |
|
status_bar_message(buf); |
|
278 |
|
save_msg = 1; |
|
279 |
|
} |
|
280 |
|
else |
|
281 |
|
{ |
|
282 |
|
char status_buf[64] = ""; |
|
283 |
|
snprintf(status_buf, sizeof(status_buf), " %d %s Selected", |
|
284 |
|
view->selected_files, view->selected_files == 1 ? "File" : |
|
285 |
|
"Files"); |
|
286 |
|
status_bar_message(status_buf); |
|
287 |
|
} |
|
288 |
|
|
|
289 |
|
write_stat_win(" --VISUAL--"); |
|
290 |
|
} |
|
291 |
|
return save_msg; |
|
292 |
|
} |
|
293 |
|
|
|
294 |
|
int |
|
295 |
|
start_visual_mode(FileView *view) |
|
296 |
|
{ |
|
297 |
|
int x; |
|
298 |
|
|
|
299 |
|
for(x = 0; x < view->list_rows; x++) |
|
300 |
|
view->dir_entry[x].selected = 0; |
|
301 |
|
|
|
302 |
|
/* Don't allow the ../ dir to be selected */ |
|
303 |
|
if(strcmp(view->dir_entry[view->list_pos].name, "../")) |
|
304 |
|
{ |
|
305 |
|
view->selected_files = 1; |
|
306 |
|
view->dir_entry[view->list_pos].selected = 1; |
|
307 |
|
} |
|
308 |
|
|
|
309 |
|
draw_dir_list(view, view->top_line, view->list_pos); |
|
310 |
|
moveto_list_pos(view, view->list_pos); |
|
311 |
|
|
|
312 |
|
if(view->list_pos != 0) |
|
313 |
|
status_bar_message(" 1 File Selected"); |
|
314 |
|
else |
|
315 |
|
status_bar_message(""); |
|
316 |
|
|
|
317 |
|
write_stat_win(" --VISUAL--"); |
|
318 |
|
return visual_key_cb(view); |
|
319 |
|
} |