Commit 943efd4ba5391914fd373f2ff8b2348b9162d357

Initial Setup
Author: ksteen
Author date (UTC): 2009-01-28 19:42
Committer name: ksteen
Committer date (UTC): 2009-01-28 19:42
Parent(s):
Signing key:
Tree: 3543f6310ca347725da1b59aab95303755ee6b18
File Lines added Lines deleted
AUTHORS 31 0
COPYING 339 0
ChangeLog 114 0
INSTALL 30 0
NEWS 0 0
README 15 0
TODO 20 0
src/Makefile 27 0
src/background.c 252 0
src/background.h 44 0
src/bookmarks.c 208 0
src/bookmarks.h 62 0
src/color_scheme.c 488 0
src/color_scheme.h 58 0
src/commands.c 1630 0
src/commands.h 39 0
src/config.c 489 0
src/config.h 60 0
src/file_info.c 248 0
src/file_info.h 24 0
src/filelist.c 1004 0
src/filelist.h 46 0
src/fileops.c 1041 0
src/fileops.h 47 0
src/filetype.c 151 0
src/filetype.h 30 0
src/keys.c 1281 0
src/keys.h 46 0
src/menus.c 1707 0
src/menus.h 43 0
src/pauseme 8 0
src/registers.c 101 0
src/registers.h 42 0
src/rline.c 573 0
src/rline.h 23 0
src/search.c 141 0
src/search.h 23 0
src/signals.c 54 0
src/signals.h 19 0
src/sort.c 213 0
src/sort.h 22 0
src/status.h 47 0
src/ui.c 314 0
src/ui.h 122 0
src/utils.c 127 0
src/utils.h 29 0
src/vifm-help.txt 225 0
src/vifm.c 279 0
src/vifm.txt 272 0
src/vifm.vim 81 0
src/vifmrc 119 0
src/visual.c 319 0
src/visual.h 27 0
File AUTHORS added (mode: 100644) (index 0000000..6065938)
1 All suggestions or complaints should be sent to ksteen@users.sourceforge.net.
2
3 The pauseme script is from the tkdesk program.
4
5 Some of the code is from emelfm by Michael Clark.
6
7 The screen-open-region-with-program and screen-ren-program-in-region were
8 written by Miciah Dashiel Butler Masters.
9
10 The file sorting function is from the git program by Tudor Hulubei
11 and Andrei Pitis.
12
13 A patch for filetypes detection was written by Stefan Walter.
14
15 FreeBSD and NetBSD ports by Stefan Walter.
16
17 Debian package by Edelhard Becker.
18
19 Terry Brown wrote part of the keybinding code.
20
21 Gentoo package by Peter Johanson.
22
23 Ralf Arens added the configurable color code and rewrote the bookmarks
24 code.
25
26 Dmitry Suzdalev fixed the :!<Enter> bug.
27
28 MacOSX Fink package by Damien Ferrand
29
30 Karsten Schoelzel - submitted a patch to fix the handling of files with
31 a % in the name.
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 ChangeLog added (mode: 100644) (index 0000000..e875b4a)
1 0.4 to 0.5
2 Initial port to win32
3 :move
4 :copy
5
6 0.3a to 0.4
7 Color schemes added - required a change to the vifmrc file.
8
9 UTF-8 support
10
11 Quick view of current file with :view command.
12
13 Hopefully fixed bug when starting vifm with a directory on the command
14 line.
15
16 Changed executable file to check for filetypes. If you have vifm set to
17 not run executable files, it will now first check for a filetype setting
18 and if present will use the program you set to open the file. If no
19 filetype is set it will open the file in vi.
20
21 Fixed delete command when dd in :com window.
22
23 0.3 to 0.3a
24
25 Files with % in the name should work now.
26
27 The symlinks in the tarball were replaced with the actual scripts.
28
29 0.2 to 0.3
30
31 Added error message for shell commands that are too long.
32
33 Added :split, :only for one window view.
34
35 Added :ls command for screen and %s macro.
36
37 Added . to repeat last command. This currently only works with :commands.
38
39 When deleting or putting files the process is backgrounded but it now
40 waits for the process to return so that the changes show up quicker
41 in the file lists.
42
43 Removed the code to change the xterm title.
44
45 User commands and the builtin commands now work with <Tab> expansion.
46
47 :! and :!! now work with tab expansion.
48
49 Changed waitpid to a loop.
50
51 Removed the timing thread.
52
53 Redirected error messages of processes run in the background.
54
55 :jobs command shows menu of backgrounded processes.
56
57 :!! segfault fixed by Dmitry Suzdalev.
58
59 Readline like expansion of files now escapes the filename.
60
61 Fixed menu scrolling bug when the menu list was the same size as window rows.
62
63 0.1 to 0.2
64
65 File names are now escaped before going to the shell.
66
67 The menus are now searchable with / or ? and basic commands :45 or :quit.
68
69 The current position was changed to a solid bar instead of an arrow.
70
71 Basic readline file completion.
72
73 Command and pattern history.
74
75 Colors are now configurable.
76
77 cw can be used to rename files.
78
79 Added a keys pressed window in the status bar to show the first d of dd,
80 numbers for 12G or 33j movement commands, and first y of yy.
81
82 User commands are now sorted in alphabetical order so that they may be
83 used in the shortest form that does not match another command.
84
85 The :command parsing was rewritten.
86
87 The default action on an executable file was changed to a configurable
88 option. The default is now to view the file instead of executing it.
89
90 New :commands
91 :locate command uses locate.
92 :apropos command - shows list of man pages in menu window.
93 :sync command - changes the other panel to the same directory as the
94 current panel.
95
96 New Key bindings
97 Normal mode:
98 M - move to the middle of the window.
99 L - move to the bottom of the window.
100 H - move to the top of the window.
101 V - switch to visual mode.
102 Y - yank the currently selected files.
103
104 Visual mode:
105 M - select from the current position to the middle of the list.
106 L - select from the current position to the bottom of the list.
107 H - select from the current position to the top of the list.
108
109 The bookmarks code was rewritten.
110
111 The automatic updating of the file lists was rewritten.
112
113
114
File INSTALL added (mode: 100644) (index 0000000..b1b4542)
1 Installation
2 ~~~~~~~~~~~~
3 You need:
4
5 If you want to compile the source code you will need:
6 Mingw
7 Pdcurses for Mingw
8 Regex for Mingw
9
10
11
12 Vim Specific Options:
13
14 If you use vim, copy the vifm.txt file in the vifm/src directory to
15 your ~/.vim/doc directory or the system vim/doc directory.
16 Then launch vim ahd give the command
17 :helptags ~/.vim/doc
18 or
19 :helptags path/to/system/vim/doc
20 depending on where you installed the vifm.txt file.
21
22 You will also need to change the USE_VIM_HELP
23 in ~/.vifm/vifmrc as the default setting is to use the plain text file.
24
25 If you want to use the vifm.vim plugin, copy the vifm.vim plugin script to
26 either the system wide vim/plugin or to ~/.vim/plugin/. The vifm.vim script
27 allows you to use vifm from vim to select files. The vifm.vim script is not
28 installed by default and must be manually copied to the plugin directory.
29
30
File NEWS added (mode: 100644) (index 0000000..e69de29)
File README added (mode: 100644) (index 0000000..9f59c42)
1 See the INSTALL file for building instructions and the TODO file for what
2 still needs to be implemented.
3
4 If you are interested in playing with the source code.
5
6 vifm.c contains main() - which does basic initialization,
7 ui.c - setup_ncurses_interface()
8 signals.c - setup_signals()
9 keys.c - main_key_press_cb() - the main loop.
10
11
12
13
14
15
File TODO added (mode: 100644) (index 0000000..d2cb091)
1 Basic things that need to be done.
2 Backgrounding of commands with job control.
3 Fix window resizing.
4 Better documentation.
5 Handle commands that are too long to be passed directly to the shell.
6
7 Vi specific features that need to be added.
8 Finish implementing range and count for user commands.
9 Fix '' to go back to all jumps G gg links.
10 Key mapping :nmap s :sh<Return>
11 Change file list filters to use fold levels instead of just
12 the dot filter and regular expression filter.
13 Named registers for yanked or deleted files.
14
15
16 Possible things to add.
17 Use system wide mimetypes file.
18 Virtual File System
19
20
File src/Makefile added (mode: 100644) (index 0000000..7f5a6c9)
1
2 CC=gcc
3
4 CFLAGS=-c -Wall
5
6 LDFLAGS= -all-static
7
8 LIBS=-lpdcurses -lregex
9 #c:/MinGW/lib/libgnurx.dll.a
10
11 SOURCES=background.c bookmarks.c color_scheme.c commands.c config.c\
12 file_info.c filelist.c fileops.c filetype.c keys.c menus.c registers.c\
13 rline.c search.c signals.c sort.c ui.c utils.c vifm.c visual.c
14
15 OBJECTS=$(SOURCES:.c=.o)
16
17 EXECUTABLE=vifm.exe
18
19 all: $(SOURCES) $(EXECUTABLE)
20
21 $(EXECUTABLE): $(OBJECTS)
22 $(CC) $(OBJECTS) -o $@ $(LDFLAGS) $(LIBS)
23 .c.o:
24 $(CC) $(CFLAGS) $< -o $@
25
26 clean:
27 rm *.o
File src/background.c added (mode: 100644) (index 0000000..baa0132)
1 /* vifm Copyright (C) 2001 Ken Steen.
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation; either version 2 of the License, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307, USA
16 */
17
18 #include<string.h>
19 #include<unistd.h>
20 #include<time.h>
21 #include<signal.h>
22 #include<sys/types.h>
23 #include<sys/stat.h>
24 //#include<sys/wait.h>
25 #include<fcntl.h>
26 #include<windows.h>
27
28 #include"background.h"
29 #include"menus.h"
30 #include"status.h"
31 #include"utils.h"
32
33 struct Jobs_List *jobs = NULL;
34 struct Finished_Jobs *fjobs = NULL;
35
36 /*
37 static void
38 add_background_job(int pid, char *cmd, int fd)
39 {
40 Jobs_List *new;
41
42 new = (Jobs_List *)malloc(sizeof(Jobs_List));
43 new->pid = pid;
44 new->cmd = strdup(cmd);
45 new->next = jobs;
46 new->fd = fd;
47 new->error_buf = (char *)calloc(1, sizeof(char));
48 new->running = 1;
49 jobs = new;
50 }
51 */
52
53 void
54 add_finished_job(int pid, int status)
55 {
56 Finished_Jobs *new;
57
58 new = (Finished_Jobs *)malloc(sizeof(Finished_Jobs));
59 new->pid = pid;
60 new->remove = 0;
61 new->next = fjobs;
62 fjobs = new;
63 }
64
65 void
66 check_background_jobs(void)
67 {
68 /*
69 Jobs_List *p = jobs;
70 Jobs_List *prev = 0;
71 Finished_Jobs *fj = NULL;
72 sigset_t new_mask;
73 fd_set ready;
74 int maxfd;
75 int nread;
76 struct timeval ts;
77
78
79 if (!p)
80 return;
81 */
82
83 /*
84 * SIGCHLD needs to be blocked anytime the Finished_Jobs list
85 * is accessed from anywhere except the received_sigchld().
86 */
87 /*
88 sigemptyset(&new_mask);
89 sigaddset(&new_mask, SIGCHLD);
90 sigprocmask(SIG_BLOCK, &new_mask, NULL);
91
92 fj = fjobs;
93
94 ts.tv_sec = 0;
95 ts.tv_usec = 1000;
96
97 while (p)
98 {
99 */
100 /* Mark any finished jobs */
101 /*
102 while (fj)
103 {
104 if (p->pid == fj->pid)
105 {
106 p->running = 0;
107 fj->remove = 1;
108 }
109 fj = fj->next;
110 }
111 */
112
113 /* Setup pipe for reading */
114
115 /*
116 FD_ZERO(&ready);
117 maxfd = 0;
118 FD_SET(p->fd, &ready);
119 maxfd = (p->fd > maxfd ? p->fd : maxfd);
120
121 if ((select(maxfd +1, &ready, NULL, NULL, &ts) > 0))
122 {
123 char buf[256];
124
125 nread = read(p->fd, buf, sizeof(buf) -1);
126
127 if (nread)
128 {
129 p->error_buf = (char *) realloc(p->error_buf,
130 sizeof(buf));
131
132 strncat(p->error_buf, buf, sizeof(buf) - 1);
133 }
134 if (strlen(p->error_buf) > 1)
135 {
136 show_error_msg(" Background Process Error ", p->error_buf);
137 my_free(p->error_buf);
138 p->error_buf = (char *) calloc(1, sizeof(char));
139 }
140 }
141 */
142
143 /* Remove any finished jobs. */
144 /*
145 if (!p->running)
146 {
147 Jobs_List *j = p;
148 if (prev)
149 prev->next = p->next;
150 else
151 jobs = p->next;
152
153 p = p->next;
154 my_free(j->cmd);
155
156 if (strlen(j->error_buf))
157 my_free(j->error_buf);
158
159 my_free(j);
160 }
161 else
162 {
163 prev = p;
164 p = p->next;
165 }
166 }
167
168 */
169 /* Clean up Finished Jobs list */
170 /*
171 fj = fjobs;
172 if (fj)
173 {
174 Finished_Jobs *prev = 0;
175 while (fj)
176 {
177 if (fj->remove)
178 {
179 Finished_Jobs *j = fj;
180
181 if (prev)
182 prev->next = fj->next;
183 else
184 fjobs = fj->next;
185
186 fj = fj->next;
187 my_free(j);
188 }
189 else
190 {
191 prev = fj;
192 fj = fj->next;
193 }
194 }
195 }
196 */
197
198 /* Unblock SIGCHLD signal */
199 // sigprocmask(SIG_UNBLOCK, &new_mask, NULL);
200 }
201
202 /* Only used for deleting and putting of files so that the changes show
203 * up immediately in the file lists.
204 */
205 int
206 background_and_wait_for_errors(char *cmd)
207 {
208 STARTUPINFO si;
209 PROCESS_INFORMATION pi;
210 int retval = 1;
211 memset(&pi, 0, sizeof(pi));
212 memset(&pi, 0, sizeof(si));
213 si.cb = sizeof(si);
214
215 retval = CreateProcess(NULL, cmd, 0, 0, 0, 0, 0, 0, &si, &pi);
216 CloseHandle(pi.hThread);
217 WaitForSingleObject(pi.hProcess, 0);
218 CloseHandle(pi.hProcess);
219
220 if(!retval)
221 {
222 DWORD dw = GetLastError();
223 char buf[256];
224
225 snprintf(buf, 256, "error is %d -",(int) dw);
226 show_error_msg("error in delete", buf);
227
228 }
229
230
231 return 0;
232
233 }
234
235 int
236 start_background_job(char *cmd)
237 {
238 STARTUPINFO si;
239 PROCESS_INFORMATION pi;
240 int retval = 1;
241 memset(&pi, 0, sizeof(pi));
242 memset(&pi, 0, sizeof(si));
243 si.cb = sizeof(si);
244
245 retval = CreateProcess(NULL, cmd, 0, 0, 0, 0, 0, 0, &si, &pi);
246 CloseHandle(pi.hThread);
247 WaitForSingleObject(pi.hProcess, 0);
248 CloseHandle(pi.hProcess);
249
250
251 return 0;
252 }
File src/background.h added (mode: 100644) (index 0000000..5787eb5)
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<sys/types.h>
20
21 typedef struct Jobs_List {
22 int fd;
23 int pid;
24 char *cmd;
25 char *error_buf;
26 int running;
27 struct Jobs_List *next;
28 } Jobs_List;
29
30 typedef struct Finished_Jobs {
31 int pid;
32 int remove;
33 struct Finished_Jobs *next;
34 } Finished_Jobs;
35
36 extern struct Jobs_List *jobs;
37 extern struct Finished_Jobs *fjobs;
38
39 int start_background_job(char *cmd);
40 int background_and_wait_for_errors(char *cmd);
41 void add_finished_job(int pid, int status);
42 void check_background_jobs(void);
43 void update_jobs_list(void);
44
File src/bookmarks.c added (mode: 100644) (index 0000000..7b6eef7)
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<string.h>
20 #include<ctype.h> /* isalnum() */
21 #include<sys/types.h>
22
23 #include "bookmarks.h"
24 #include "config.h"
25 #include "filelist.h"
26 #include "keys.h"
27 #include "status.h"
28 #include "ui.h"
29 #include "utils.h"
30
31
32 /*
33 * transform a mark to an index
34 * (0=48->0, 9=57->9, A=65->10,...,Z=90->35, a=97 -> 36,..., z=122 -> 61
35 */
36 int
37 mark2index(const char mark)
38 {
39 if ((int) mark > 96)
40 return (int) mark - 61;
41 else if ((int) mark < 65)
42 return (int) mark - 48;
43 else
44 return (int) mark - 55;
45 }
46
47
48 /*
49 * transform an index to a mark
50 */
51 char
52 index2mark(const int x)
53 {
54 if (x > 35)
55 return (char) (x + 61);
56 else if (x < 10)
57 return (char) (x + 48);
58 else
59 return (char) (x + 55);
60 }
61
62 /*
63 * test if a bookmark already exists
64 */
65 int
66 is_bookmark(const int x)
67 {
68
69 /* the bookmark is valid if the file and the directory exists.
70 * (i know, checking both is a bit paranoid, one should be enough.) */
71 if (bookmarks[x].directory == NULL || bookmarks[x].file == NULL)
72 return 0;
73 else if (is_dir(bookmarks[x].directory))
74 return 1;
75 else
76 return 0;
77 }
78
79
80 /*
81 * low-level function without safety checks
82 */
83 void
84 silent_remove_bookmark(const int x)
85 {
86 my_free(bookmarks[x].directory);
87 my_free(bookmarks[x].file);
88 bookmarks[x].directory = NULL;
89 bookmarks[x].file = NULL;
90 /* decrease number of active bookmarks */
91 cfg.num_bookmarks--;
92 }
93
94
95 void
96 remove_bookmark(const int x)
97 {
98
99 if (is_bookmark(x))
100 silent_remove_bookmark(x);
101 else
102 status_bar_message("Could not find mark");
103 }
104
105
106 void
107 add_bookmark(const char mark, const char *directory, const char *file)
108 {
109 int x ;
110
111 if(!isalnum(mark))
112 {
113 status_bar_message("Invalid mark");
114 return;
115 }
116
117 x = mark2index(mark);
118
119 /* The mark is already being used. Free pointers first! */
120 if (is_bookmark(x))
121 silent_remove_bookmark(x);
122
123 bookmarks[x].directory = strdup(directory);
124 bookmarks[x].file = strdup(file);
125 /* increase number of active bookmarks */
126 cfg.num_bookmarks++;
127 }
128
129
130 int
131 move_to_bookmark(FileView *view, char mark)
132 {
133 int x = mark2index(mark);
134 int file_pos = -1;
135
136 if(x != -1 && is_bookmark(x))
137 {
138
139 change_directory(view, bookmarks[x].directory);
140
141 load_dir_list(view, 1);
142 file_pos = find_file_pos_in_list(view, bookmarks[x].file);
143 if(file_pos != -1)
144 moveto_list_pos(view, file_pos);
145 else
146 moveto_list_pos(view, 0);
147 }
148 else
149 {
150 if(!isalnum(mark))
151 status_bar_message("Invalid mark");
152 else
153 status_bar_message("Mark is not set.");
154
155 moveto_list_pos(view, view->list_pos);
156 return 1;
157 }
158 return 0;
159 }
160
161 int
162 check_mark_directory(FileView *view, char mark)
163 {
164 int x = mark2index(mark);
165 int file_pos = -1;
166
167 if(strcmp(view->curr_dir, bookmarks[x].directory) == 0)
168 file_pos = find_file_pos_in_list(view, bookmarks[x].file);
169
170 return file_pos;
171
172 }
173
174 int
175 get_bookmark(FileView *view)
176 {
177 int key;
178
179 wtimeout(curr_view->win, -1);
180
181 key = wgetch(view->win);
182
183 wtimeout(curr_view->win, 1000);
184
185 if (key == ERR)
186 return 0;
187
188 switch(key)
189 {
190 case '\'':
191 {
192 change_directory(view, view->last_dir);
193 load_dir_list(view, 0);
194 moveto_list_pos(view, view->list_pos);
195 return 0;
196 }
197 break;
198 case 27: /* ascii Escape */
199 case 3: /* ascii ctrl c */
200 moveto_list_pos(view, view->list_pos);
201 return 0;
202 break;
203 default:
204 return move_to_bookmark(view, key);
205 break;
206 }
207 return 0;
208 }
File src/bookmarks.h added (mode: 100644) (index 0000000..b0515c5)
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 #ifndef __BOOKMARKS_H__
20 #define __BOOKMARKS_H__
21
22 #include"ui.h"
23
24 #define NUM_BOOKMARKS 62
25
26 typedef struct
27 {
28 /*
29 * 'mark' is unnecessary, we already reserve all possible bookmarks,
30 * therfore we can use the mark as an index:
31 * 0: 0 ( 0=48, ascii)
32 * 9: 9 ( 9=57 )
33 * A: 10 ( A=65 )
34 * ...
35 * Z: 35
36 * a: 36 ( a=97 )
37 * ...
38 * z: 61
39 char mark;
40 */
41 /* use pointers instead of fixed length char arrays -> save space!
42 char file[NAME_MAX];
43 char directory[PATH_MAX];
44 */
45 char *file;
46 char *directory;
47 } bookmarks_t;
48
49 bookmarks_t bookmarks[NUM_BOOKMARKS];
50
51 /* array of active bookmarks, populated in menu.c: init_active_bookmarks() */
52 int active_bookmarks[NUM_BOOKMARKS];
53
54 char index2mark(const int x);
55 int is_bookmark(const int x);
56 void add_bookmark(const char mark, const char *directory, const char *file);
57 int get_bookmark(FileView *view);
58 int move_to_bookmark(FileView *view, const char mark);
59 void remove_bookmark(const int x);
60 int check_mark_directory(FileView *view, char mark);
61
62 #endif
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/color_scheme.h added (mode: 100644) (index 0000000..1e573cc)
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 #ifndef __COLOR_SCHEME_H__
20 #define __COLOR_SCHEME_H__
21
22 #include<limits.h>
23 #include "ui.h"
24 #define MAXNUM_COLOR 11
25
26 #define MENU_COLOR 0
27 #define BORDER_COLOR 1
28 #define WIN_COLOR 2
29 #define STATUS_BAR_COLOR 3
30 #define CURR_LINE_COLOR 4
31 #define DIRECTORY_COLOR 5
32 #define FIFO_COLOR 6
33 #define DEVICE_COLOR 7
34 #define EXECUTABLE_COLOR 8
35 #define SELECTED_COLOR 9
36 #define CURRENT_COLOR 10
37
38 typedef struct _Col_attr {
39 int name;
40 int fg;
41 int bg;
42 } Col_attr;
43
44
45 typedef struct _Col_Scheme {
46 char name[PATH_MAX];
47 char dir[PATH_MAX];
48 Col_attr color[11];
49 } Col_scheme;
50
51 extern Col_scheme col_schemes[8];;
52
53 void read_color_scheme_file();
54 void write_color_scheme_file();
55 int check_directory_for_color_scheme(const char *);
56 void load_color_scheme(char *name, char *dir);
57
58 #endif
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/commands.h added (mode: 100644) (index 0000000..a7b4822)
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 "ui.h"
20
21 typedef struct
22 {
23 char *action;
24 char *name;
25 }command_t;
26
27 extern char *reserved_commands[];
28
29 command_t *command_list;
30
31 int get_command(FileView *view, int type, void *ptr);
32 void shellout(char *command, int pause);
33 void add_command(char *name, char *action);
34 int execute_command(FileView *view, char *action);
35 int sort_this(const void *one, const void *two);
36 int is_user_command(char *command);
37 int command_is_reserved(char *command);
38 char * expand_macros(FileView *view, char *command, char *args, int *menu);
39 void remove_command(char *name);
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/config.h added (mode: 100644) (index 0000000..f37e2b4)
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 #ifndef __CONFIG_H__
20 #define __CONFIG_H__
21
22 #include<limits.h>
23 #include<curses.h>
24
25 typedef struct _Config {
26 char config_dir[PATH_MAX];
27 char trash_dir[PATH_MAX];
28 char *vi_command;
29 char *shell_cmd;
30 int num_bookmarks;
31 int use_trash;
32 int vim_filter;
33 int use_vim_help;
34 int command_num;
35 int filetypes_num;
36 int history_len;
37 int nmapped_num;
38 int screen_num;
39 int timer;
40 char **search_history;
41 int search_history_len;
42 int search_history_num;
43 char **cmd_history;
44 int cmd_history_len;
45 int cmd_history_num;
46 int auto_execute;
47 int color_scheme_num;
48 int color_pairs_num;
49 int show_one_window;
50 long max_args;
51 } Config;
52
53 extern Config cfg;
54
55 int read_config_file(void);
56 void write_config_file(void);
57 void set_config_dir(void);
58 void init_config(void);
59
60 #endif
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/file_info.h added (mode: 100644) (index 0000000..5d58ae4)
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 "ui.h"
20
21 void describe_file_size(char *buf, int buf_size, FileView *view);
22 void get_perm_string(char *buf, int len, mode_t mode);
23 void show_full_file_properties(FileView *view);
24
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/filelist.h added (mode: 100644) (index 0000000..8540ed3)
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 #ifndef __FILELIST_H__
20 #define __FILELIST_H__
21
22
23 #include "ui.h"
24
25 enum
26 {
27 DIRECTORY,
28 DEVICE,
29 NORMAL,
30 EXECUTABLE,
31 FIFO,
32 UNKNOWN
33 };
34
35 void quick_view_file(FileView * view);
36 void change_directory(FileView *view, char *directory);
37 void load_dir_list(FileView *view, int reload);
38 void draw_dir_list(FileView *view, int top, int pos);
39 char * get_current_file_name(FileView *view);
40 void moveto_list_pos(FileView *view, int pos);
41 int find_file_pos_in_list(FileView *view, char *file);
42 void get_all_selected_files(FileView *view);
43 void free_selected_file_array(FileView *view);
44 void erase_current_line_bar(FileView *view);
45
46 #endif
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/fileops.h added (mode: 100644) (index 0000000..fa17d6f)
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 #ifndef __FILEOPS_H__
19 #define __FILEOPS_H__
20
21 #include"ui.h"
22
23 #define FILE_CHANGE 1
24 #define FILE_NAME 2
25 #define FILE_OWNER 4
26 #define FILE_GROUP 6
27 #define FILE_PERMISSIONS 8
28
29 typedef struct
30 {
31 char *dir;
32 char *file;
33 }yank_t;
34
35 yank_t *yanked_file;
36
37 void handle_file(FileView *view);
38 void delete_file(FileView *view);
39 int my_system(char *command);
40 void yank_selected_files(FileView *view);
41 int pipe_and_capture_errors(char *command);
42 int file_exec(char *command);
43 void show_change_window(FileView *view, int type);
44 void move_files(FileView *view);
45 void copy_files(FileView *view);
46
47 #endif
File src/filetype.c added (mode: 100644) (index 0000000..e665002)
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<curses.h>
20 #include<string.h>
21 #include<stdlib.h>
22
23 #include "config.h"
24 #include "filetype.h"
25
26 int
27 get_filetype_number(char *file)
28 {
29 char *strptr;
30 char *ptr;
31 char ext[24];
32 int x;
33
34 /* Stefan Walter fixed this to catch tar.gz extensions */
35 strptr = file;
36 while((ptr = strchr(strptr, '.')) != NULL)
37 {
38 ptr++;
39 snprintf(ext, sizeof(ext), "%s", ptr);
40
41 for(x = 0; x < cfg.filetypes_num; x++)
42 {
43 char *exptr = NULL;
44
45 /* Only one extension */
46 if((exptr = strchr(filetypes[x].ext, ',')) == NULL)
47 {
48 if(!strcasecmp(filetypes[x].ext, ext))
49 return x;
50 }
51 else
52 {
53 char *ex_copy = strdup(filetypes[x].ext);
54 char *free_this = ex_copy;
55 char *exptr2 = NULL;
56 while((exptr = exptr2= strchr(ex_copy, ',')) != NULL)
57 {
58 *exptr = '\0';
59 exptr2++;
60
61 if(!strcasecmp(ext, ex_copy))
62 {
63 free(free_this);
64 return x;
65 }
66
67 ex_copy = exptr2;
68 }
69 if(!strcasecmp(ext, ex_copy))
70 {
71 free(free_this);
72 return x;
73 }
74 free(free_this);
75 }
76 }
77 strptr = ptr;
78 }
79 return -1;
80 }
81
82 char *
83 get_default_program_for_file(char *file)
84 {
85 int x = get_filetype_number(file);
86 char *strptr = NULL;
87 char *ptr = NULL;
88 char *program_name = NULL;
89
90 if(x < 0)
91 return NULL;
92
93 strptr = strdup(filetypes[x].programs);
94
95 /* Only one program */
96 if((ptr = strchr(strptr, ',')) == NULL)
97 {
98 program_name = strdup(strptr);
99 }
100 else
101 {
102 *ptr = '\0';
103 program_name = strdup(strptr);
104 }
105 free(strptr);
106 return program_name;
107 }
108
109
110 char *
111 get_all_programs_for_file(char *file)
112 {
113 int x = get_filetype_number(file);
114
115 if(x > -1)
116 return filetypes[x].programs;
117
118 return NULL;
119 }
120
121 void
122 clear_filetypes(void)
123 {
124 int x;
125
126 for(x = 0; x < cfg.filetypes_num; x++)
127 {
128 if(filetypes[x].type)
129 free(filetypes[x].type);
130 if(filetypes[x].ext)
131 free(filetypes[x].ext);
132 if(filetypes[x].programs)
133 free(filetypes[x].programs);
134 }
135 cfg.filetypes_num = 0;
136 }
137
138 void
139 add_filetype(char *description, char *extension, char *program)
140 {
141
142 filetypes = (filetype_t *)realloc(filetypes,
143 (cfg.filetypes_num +1) * sizeof(filetype_t));
144
145 filetypes[cfg.filetypes_num].type = strdup(description);
146
147 filetypes[cfg.filetypes_num].ext = strdup(extension);
148 filetypes[cfg.filetypes_num].programs = strdup(program);
149 cfg.filetypes_num++;
150 }
151
File src/filetype.h added (mode: 100644) (index 0000000..e479a93)
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 typedef struct
20 {
21 char *type;
22 char *ext;
23 char *programs;
24 }filetype_t;
25
26 filetype_t *filetypes;
27 char * get_default_program_for_file(char *file);
28 void add_filetype(char *description, char *extension, char *program);
29 char * get_all_programs_for_file(char *file);
30 void clear_filetypes(void);
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), "