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), "x is %d y is %d ", x, y);
862 show_error_msg("cursor curr_win", buf);
863
864 wmove(stdscr, y + 2, 0);
865 wrefresh(stdscr);
866
867 getyx(stdscr, y, x);
868 snprintf(buf, sizeof(buf), "x is %d y is %d ", x, y);
869 show_error_msg("stdscr win", buf);
870 */
871 }
872
873 /* This point down gets called only when a key is actually pressed */
874
875 curr_stats.save_msg = 0;
876
877 if (curr_stats.use_register && !curr_stats.register_saved)
878 {
879 if (is_valid_register(key))
880 {
881 curr_stats.curr_register = key;
882 curr_stats.register_saved = 1;
883 save_reg = 1;
884 continue;
885 }
886 else
887 {
888 status_bar_message("Invalid Register Key");
889 curr_stats.save_msg = 1;
890 wrefresh(status_bar);
891 curr_stats.use_register = 0;
892 curr_stats.curr_register = -1;
893 curr_stats.register_saved = 0;
894 save_reg = 0;
895 continue;
896 }
897 }
898 else if((key > 47) && (key < 58)) /* ascii 0 - 9 */
899 {
900 if (count > 62)
901 {
902 show_error_msg(" Number is too large ",
903 "Vifm cannot handle that large of a number as a count. ");
904 clear_num_window();
905 continue;
906 }
907
908 count_buf[count] = key;
909 count++;
910 count_buf[count] = '\0';
911 update_num_window(count_buf);
912 continue;
913 }
914 else
915 clear_num_window();
916
917 switch(key)
918 {
919 case '"': /* "register */
920 curr_stats.use_register = 1;
921 break;
922 case 2: /* ascii Ctrl B */
923 case KEY_PPAGE:
924 view->list_pos = view->list_pos - view->window_rows;
925 moveto_list_pos(view, view->list_pos);
926 break;
927 case 3: /* ascii Ctrl C */
928 case 27: /* ascii Escape */
929 {
930 int x;
931
932 for(x = 0; x < view->list_rows; x++)
933 view->dir_entry[x].selected = 0;
934
935 view->selected_files = 0;
936 load_dir_list(curr_view, 1);// redraw_window();
937 curs_set(0);
938 }
939 break;
940 case 6: /* ascii Ctrl F */
941 case KEY_NPAGE:
942 view->list_pos = view->list_pos + view->window_rows;
943 moveto_list_pos(view, view->list_pos);
944 break;
945 case 7: /* ascii Ctrl G */
946 if(!curr_stats.show_full)
947 curr_stats.show_full = 1;
948 break;
949 case 9: /* ascii Tab */
950 case 32: /* ascii Spacebar */
951 change_window(&view);
952 break;
953 case 12: /* ascii Ctrl L - clear screen and redraw */
954 redraw_window();
955 curs_set(0);
956 break;
957 case 13: /* ascii Return */
958 handle_file(view);
959 break;
960 case 23: /* ascii Ctrl W - change windows */
961 {
962 int letter;
963 curr_stats.getting_input = 1;
964 letter = wgetch(view->win);
965 curr_stats.getting_input = 0;
966
967 if((letter == 'h') && (view->win == rwin.win))
968 change_window(&view);
969 else if((letter == 'l') && (view->win == lwin.win))
970 change_window(&view);
971 }
972 break;
973 case '.': /* repeat last change */
974 repeat_last_command(view);
975 break;
976 case ':': /* command */
977 curr_stats.save_msg = get_command(view, GET_COMMAND, NULL);
978 break;
979 case '/': /* search */
980 curr_stats.save_msg = get_command(view, GET_SEARCH_PATTERN, NULL);
981 break;
982 case '?': /* search backwards */
983 break;
984 case '\'': /* mark */
985 curr_stats.save_msg = get_bookmark(view);
986 break;
987 case '%': /* Jump to percent of file. */
988 if(count)
989 {
990 int percent = atoi(count_buf);
991 int line = (percent * (view->list_rows)/100);
992 moveto_list_pos(view, line -1);
993 reset_last_char = 1;
994 }
995 break;
996 case 'G': /* Jump to bottom of list. */
997 {
998 if(count)
999 moveto_list_pos(view, atoi(count_buf) -1);
1000 else
1001 moveto_list_pos(view, view->list_rows - 1);
1002 reset_last_char = 1;
1003 }
1004 break;
1005 /* tbrown */
1006 case 'H': /* go to first file in window */
1007 view->list_pos = view->top_line;
1008 moveto_list_pos(view, view->list_pos);
1009 reset_last_char =1;
1010 break;
1011 /* tbrown */
1012 case 'L': /* go to last file in window */
1013 view->list_pos = view->top_line + view->window_rows;
1014 moveto_list_pos(view, view->list_pos);
1015 reset_last_char =1;
1016 break;
1017 case 'M': /* zM Restore filename filter and hide dot files. */
1018 if(curr_stats.last_char == 'z')
1019 {
1020 restore_filename_filter(view);
1021 hide_dot_files(view);
1022 reset_last_char = 1;
1023 }
1024 else
1025 { /* tbrown go to middle of window */
1026 if (view->list_rows<view->window_rows)
1027 {
1028 view->list_pos = view->list_rows/2;
1029 }
1030 else
1031 {
1032 view->list_pos = view->top_line + (view->window_rows/2);
1033 }
1034 moveto_list_pos(view, view->list_pos);
1035 reset_last_char = 1;
1036 }
1037 break;
1038 case 'N':
1039 find_previous_pattern(view);
1040 break;
1041 case 'O': /* zO Remove filename filter. */
1042 if(curr_stats.last_char == 'z')
1043 remove_filename_filter(view);
1044 reset_last_char = 1;
1045 break;
1046 case 'R': /* zR Show all hidden files */
1047 {
1048 if(curr_stats.last_char == 'z')
1049 {
1050 remove_filename_filter(view);
1051 show_dot_files(view);
1052 }
1053 reset_last_char = 1;
1054 }
1055 break;
1056 case 'a': /* zo Show dot files */
1057 if(curr_stats.last_char == 'z')
1058 toggle_dot_files(view);
1059 reset_last_char = 1;
1060 break;
1061 case 'c': /* cw change word */
1062 {
1063 save_count = 1;
1064 update_num_window("c");
1065 }
1066 break;
1067 case 'd': /* dd delete file */
1068 {
1069 save_count = 1;
1070 update_num_window("d");
1071 if(curr_stats.last_char == 'd')
1072 {
1073 clear_num_window();
1074 if(view->selected_files)
1075 delete_file(view);
1076 else if(count)
1077 {
1078 int x;
1079 int y = view->list_pos;
1080 for(x = 0; x < atoi(count_buf); x++)
1081 {
1082 view->dir_entry[y].selected = 1;
1083 y++;
1084 }
1085 delete_file(view);
1086 }
1087 else
1088 delete_file(view);
1089 reset_last_char = 1;
1090 }
1091 }
1092 break;
1093 case 'f': /* zf filter selected files */
1094 if(curr_stats.last_char == 'z')
1095 filter_selected_files(view);
1096 break;
1097 case 'g': /* gg Jump to top of the list. */
1098 {
1099 save_count = 1;
1100 if(curr_stats.last_char == 'g')
1101 {
1102 if(count)
1103 moveto_list_pos(view, atoi(count_buf) -1);
1104 else
1105 moveto_list_pos(view, 0);
1106
1107 reset_last_char = 1;
1108 }
1109 }
1110 break;
1111 case KEY_LEFT:
1112 case 'h': /* updir */
1113 {
1114 change_directory(view, "../");
1115 load_dir_list(view, 0);
1116 moveto_list_pos(view, view->list_pos);
1117 }
1118 break;
1119 case KEY_DOWN:
1120 case 'j': /* Move down one line */
1121 {
1122 if(count)
1123 view->list_pos += atoi(count_buf);
1124 else
1125 view->list_pos++;
1126
1127 moveto_list_pos(view, view->list_pos);
1128 reset_last_char =1;
1129 }
1130 break;
1131 case KEY_UP:
1132 case 'k': /* Move up one line */
1133 {
1134 if(count)
1135 view->list_pos -= atoi(count_buf);
1136 else
1137 view->list_pos--;
1138
1139 moveto_list_pos(view, view->list_pos);
1140 reset_last_char = 1;
1141 }
1142 break;
1143 case KEY_RIGHT:
1144 case 'l':
1145 handle_file(view);
1146 break;
1147 case 'm': /* 'm' set mark and 'zm' hide dot files */
1148 {
1149 if(curr_stats.last_char == 'z')
1150 {
1151 hide_dot_files(view);
1152 reset_last_char = 1;
1153 }
1154 else
1155 {
1156 int mark;
1157 curr_stats.getting_input = 1;
1158
1159 wtimeout(curr_view->win, -1);
1160 mark = wgetch(view->win);
1161 wtimeout(curr_view->win, 1000);
1162 curr_stats.getting_input = 0;
1163 if(key == ERR)
1164 continue;
1165 add_bookmark(mark, view->curr_dir,
1166 get_current_file_name(view));
1167 }
1168 }
1169 break;
1170 case 'n':
1171 find_next_pattern(view);
1172 break;
1173 case 'o': /* zo Show dot files */
1174 if(curr_stats.last_char == 'z')
1175 show_dot_files(view);
1176 reset_last_char = 1;
1177 break;
1178 case 'p': /* put files */
1179 curr_stats.save_msg = put_files(view);
1180 break;
1181 case 's': /* tmp shellout **** This should be done with key mapping */
1182 shellout(NULL, 0);
1183 break;
1184 case 't': /* Tag file. */
1185 tag_file(view);
1186 break;
1187 /* tbrown */
1188 case 'V':
1189 case 'v': /* Visual selection of files. */
1190 curr_stats.save_msg = start_visual_mode(view);
1191 break;
1192 case 'w': /* cw change word */
1193 {
1194 if (curr_stats.last_char == 'c')
1195 rename_file(view);
1196 }
1197 break;
1198 /* tbrown */
1199 case 'Y': /* Y yank file */
1200 yank_files(view, count, count_buf);
1201 reset_last_char++;
1202 curr_stats.save_msg = 1;
1203 break;
1204
1205 case 'y': /* yy yank file */
1206 {
1207 if(curr_stats.last_char == 'y')
1208 {
1209 yank_files(view, count, count_buf);
1210 reset_last_char++;
1211 curr_stats.save_msg = 1;
1212 save_reg = 0;
1213 }
1214 else
1215 {
1216 update_num_window("y");
1217 save_reg = 1;
1218 }
1219 save_count = 1;
1220 }
1221 break;
1222 case 'z': /* zz redraw with file in center of list */
1223 if(curr_stats.last_char == 'z')
1224 {
1225
1226 }
1227 break;
1228 default:
1229 break;
1230 } /* end of switch(key) */
1231
1232 curr_stats.last_char = key;
1233
1234 if(!save_count)
1235 count = 0;
1236
1237 if(reset_last_char)
1238 {
1239 curr_stats.last_char = 0;
1240 reset_last_char = 0;
1241 count = 0;
1242 }
1243
1244 if(curr_stats.show_full)
1245 show_full_file_properties(view);
1246 else
1247 update_stat_window(view);
1248
1249 if(view->selected_files)
1250 {
1251 static int number = 0;
1252 if(number != view->selected_files)
1253 {
1254 snprintf(status_buf, sizeof(status_buf), "%d %s Selected",
1255 view->selected_files, view->selected_files == 1 ? "File" :
1256 "Files");
1257 status_bar_message(status_buf);
1258 curr_stats.save_msg = 1;
1259 }
1260 }
1261
1262 else if(!curr_stats.save_msg)
1263 clean_status_bar(view);
1264
1265 if (curr_stats.use_register && curr_stats.register_saved)
1266 {
1267 if (!save_reg)
1268 {
1269 curr_stats.use_register = 0;
1270 curr_stats.curr_register = -1;
1271 curr_stats.register_saved = 0;
1272 }
1273 }
1274
1275 if(curr_stats.need_redraw)
1276 load_dir_list(curr_view, 1);// redraw_window();
1277
1278 update_all_windows();
1279
1280 } /* end of while(!done) */
1281 }
File src/keys.h added (mode: 100644) (index 0000000..1e25179)
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 __KEYS_H__
20 #define __KEYS_H__
21
22 #include "ui.h"
23
24 enum {
25 CHANGE_WINDOWS,
26 GET_COMMAND,
27 GET_BOOKMARK,
28 GET_SEARCH_PATTERN,
29 GET_VISUAL_COMMAND,
30 START_VISUAL_MODE,
31 MAPPED_COMMAND,
32 MAPPED_SEARCH,
33 MENU_SEARCH,
34 MENU_COMMAND
35 };
36
37
38 void main_key_press_cb(FileView *view);
39 void update_all_windows(void);
40 void show_dot_files(FileView *view);
41 void remove_filename_filter(FileView *view);
42 void rename_file(FileView *view);
43 void switch_views(void);
44 #endif
45
46
File src/menus.c added (mode: 100644) (index 0000000..c7db01a)
1 /* vifm
2 * Copyright (C) 2001 Ken Steen.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17 */
18 #define _WIN32_WINNT 0x0501
19
20 #include<sys/types.h>
21 #include<regex.h>
22 #include<ctype.h> /* isspace() */
23 #include<string.h> /* strchr() */
24 #include<unistd.h> /* access() */
25 //#include<termios.h> /* struct winsize */
26 //#include<sys/ioctl.h>
27 #include<signal.h>
28 #include<windows.h>
29 #include<tchar.h>
30
31 #include "background.h"
32 #include "bookmarks.h"
33 #include "color_scheme.h"
34 #include "commands.h"
35 #include "config.h"
36 #include "filelist.h"
37 #include "fileops.h"
38 #include "filetype.h"
39 #include "keys.h"
40 #include "registers.h"
41 #include "status.h"
42 #include "ui.h"
43 #include "utils.h"
44
45 typedef struct menu_info
46 {
47 int top;
48 int current;
49 int len;
50 int pos;
51 int win_rows;
52 int type;
53 int match_dir;
54 int matching_entries;
55 char *regexp;
56 char *title;
57 char *args;
58 char **data;
59 /* For user menus only */
60 char *get_info_script; /* program + args to fill in menu. */
61 }menu_info;
62
63 enum {
64 APROPOS,
65 BOOKMARK,
66 COMMAND,
67 FILETYPE,
68 HISTORY,
69 JOBS,
70 LOCATE,
71 REGISTER,
72 USER,
73 VIFM,
74 VOLUME
75 };
76
77 enum {
78 NONE,
79 UP,
80 DOWN
81 };
82
83 static void draw_menu(FileView *view, menu_info *m);
84
85 void
86 show_progress(void)
87 {
88 static int count = 0;
89 static int pause = 1;
90
91 pause++;
92
93 if ((pause % 1000) == 0)
94 {
95 pause = 1;
96
97 switch(count)
98 {
99 case 0:
100 status_bar_message("Loading Menu |");
101 break;
102 case 1:
103 status_bar_message("Loading Menu /");
104 break;
105 case 2:
106 status_bar_message("Loading Menu -");
107 break;
108 case 3:
109 status_bar_message("Loading Menu \\");
110 count = -1;
111 break;
112 default:
113 count = -1;
114 break;
115 }
116 }
117 else
118 return;
119
120 wrefresh(status_bar);
121
122 count++;
123 }
124
125 static void
126 show_position_in_menu(menu_info *m)
127 {
128 char pos_buf[14];
129 snprintf(pos_buf, sizeof(pos_buf), " %d-%d ", m->pos + 1, m->len);
130 werase(pos_win);
131 mvwaddstr(pos_win, 0, 13 - strlen(pos_buf), pos_buf);
132 wrefresh(pos_win);
133 }
134
135 static void
136 clean_menu_position(menu_info *m)
137 {
138 int x, y, z;
139 char * buf = (char *)NULL;
140
141 getmaxyx(menu_win, y, x);
142
143 buf = (char *)malloc(x + 2);
144
145
146 snprintf(buf, x, " %s", m->data[m->pos]);
147
148 for (z = strlen(buf); z < x; z++)
149 buf[z] = ' ';
150
151 buf[x] = ' ';
152 buf[x + 1] = '\0';
153
154 wattron(menu_win, COLOR_PAIR(WIN_COLOR));
155
156 mvwaddnstr(menu_win, m->current, 1, buf, x - 2);
157
158 wattroff(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD);
159
160 my_free(buf);
161 }
162
163 void
164 show_error_msg(char *title, char *message)
165 {
166 int x, y;
167 int key;
168 int done = 0;
169 int z = 0;
170 char *dup = strdup(message);
171
172 curr_stats.freeze = 1;
173 curs_set(0);
174 werase(error_win);
175
176 getmaxyx(error_win, y, x);
177
178 if(strlen(dup) > x -2)
179 dup[x -2] = '\0';
180
181 while ((z < strlen(dup) -1) && isprint(dup[z]))
182 z++;
183
184 dup[z] = '\0';
185
186 mvwaddstr(error_win, 2, (x - strlen(dup))/2, dup);
187
188 box(error_win, 0, 0);
189 mvwaddstr(error_win, 0, (x - strlen(title))/2, title);
190
191 mvwaddstr(error_win, y -2, (x - 25)/2, "Press Return to continue");
192
193 while(!done)
194 {
195 key = wgetch(error_win);
196 if(key == 13 || key == 3) /* ascii Return ascii Ctrl-c */
197 done = 1;
198 }
199
200 my_free(dup);
201
202 curr_stats.freeze = 0;
203
204 werase(error_win);
205 wrefresh(error_win);
206
207 touchwin(stdscr);
208
209 update_all_windows();
210
211 if(curr_stats.need_redraw)
212 redraw_window();
213 }
214
215 void
216 reset_popup_menu(menu_info *m)
217 {
218 int z;
219
220 if (m->args)
221 my_free(m->args);
222
223 for (z = 0; z < m->len; z++)
224 {
225 if (m->data[z])
226 my_free(m->data[z]);
227 }
228 if (m->regexp)
229 my_free(m->regexp);
230 if (m->data)
231 my_free(m->data);
232 if (m->title)
233 my_free(m->title);
234
235 werase(menu_win);
236 curr_stats.menu = 0;
237 redraw_window();
238 }
239
240 void
241 setup_menu(FileView *view)
242 {
243 scrollok(menu_win, FALSE);
244 curr_stats.menu = 1;
245 curs_set(0);
246 werase(menu_win);
247 werase(status_bar);
248 werase(pos_win);
249 wrefresh(status_bar);
250 wrefresh(pos_win);
251 }
252
253 void
254 init_active_bookmarks(void)
255 {
256 int i, x;
257
258 i = 0;
259 for (x = 0; x < NUM_BOOKMARKS; ++x)
260 {
261 if (is_bookmark(x))
262 active_bookmarks[i++] = x;
263 }
264 }
265
266 static void
267 moveto_menu_pos(FileView *view, int pos, menu_info *m)
268 {
269 int redraw = 0;
270 int x, y, z;
271 char * buf = (char *)NULL;
272
273 getmaxyx(menu_win, y, x);
274
275
276 if(pos < 1)
277 pos = 0;
278
279 if(pos > m->len -1)
280 pos = m->len -1;
281
282 if((m->top <= pos) && (pos <= (m->top + m->win_rows +1)))
283 {
284 m->current = pos - m->top +1;
285 }
286 if((pos >= (m->top + m->win_rows -2)))
287 {
288 while(pos >= (m->top + m->win_rows -2))
289 m->top++;
290
291 m->current = m->win_rows -2;
292 redraw = 1;
293 }
294 else if(pos < m->top)
295 {
296 while(pos < m->top)
297 m->top--;
298 m->current = 1;
299 redraw = 1;
300 }
301 if(redraw)
302 draw_menu(view, m);
303
304
305 buf = (char *)malloc((x + 2));
306 if (!buf)
307 return;
308 snprintf(buf, x, " %s", m->data[pos]);
309
310 for (z = strlen(buf); z < x; z++)
311 buf[z] = ' ';
312
313 buf[x] = ' ';
314 buf[x + 1] = '\0';
315
316 wattron(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD);
317
318 mvwaddnstr(menu_win, m->current, 1, buf, x - 2);
319
320 wattroff(menu_win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD);
321
322 m->pos = pos;
323 my_free(buf);
324 show_position_in_menu(m);
325 }
326
327 static void
328 redraw_menu(FileView *view, menu_info *m)
329 {
330 /*
331 int screen_x, screen_y;
332 //struct winsize ws;
333
334 curr_stats.freeze = 1;
335 curr_stats.redraw_menu = 0;
336
337 //ioctl(0, TIOCGWINSZ, &ws);
338 //changed for pdcurses
339 //resizeterm(ws.ws_row, ws.ws_col);
340 getmaxyx(stdscr, screen_y, screen_x);
341
342 wclear(stdscr);
343 wclear(menu_win);
344 wclear(status_bar);
345 wclear(pos_win);
346
347 wresize(menu_win, screen_y - 1, screen_x);
348 wresize(status_bar, 1, screen_x -19);
349 mvwin(status_bar, screen_y -1, 0);
350 wresize(pos_win, 1, 13);
351 mvwin(pos_win, screen_y -1, screen_x -13);
352 box(menu_win, 0, 0);
353 wrefresh(status_bar);
354 wrefresh(pos_win);
355 wrefresh(menu_win);
356 curr_stats.freeze = 0;
357 draw_menu(view, m);
358 moveto_menu_pos(view, m->pos, m);
359 */
360 }
361
362 int
363 search_menu_forwards(FileView *view, menu_info *m, int start_pos)
364 {
365 int match_up = -1;
366 int match_down = -1;
367 int x;
368 regex_t re;
369 m->matching_entries = 0;
370
371 for(x = 0; x < m->len; x++)
372 {
373 if(regcomp(&re, m->regexp, REG_EXTENDED) == 0)
374 {
375 if(regexec(&re, m->data[x], 0, NULL, 0) == 0)
376 {
377 if(match_up < 0)
378 {
379 if (x < start_pos)
380 match_up = x;
381 }
382 if(match_down < 0)
383 {
384 if (x >= start_pos)
385 match_down = x;
386 }
387 m->matching_entries++;
388 }
389 }
390 regfree(&re);
391 }
392
393 if((match_up > -1) || (match_down > -1))
394 {
395 char buf[64];
396 int pos;
397
398 if (match_down > -1)
399 pos = match_down;
400 else
401 pos = match_up;
402
403 clean_menu_position(m);
404 moveto_menu_pos(view, pos, m);
405 snprintf(buf, sizeof(buf), "%d %s", m->matching_entries,
406 m->matching_entries == 1 ? "match" : "matches");
407 status_bar_message(buf);
408 wrefresh(status_bar);
409 }
410 else
411 {
412 char buf[48];
413 snprintf(buf, sizeof(buf), "No matches for %s", m->regexp);
414 status_bar_message(buf);
415 wrefresh(status_bar);
416 return 1;
417 }
418 return 0;
419
420 }
421
422 int
423 search_menu_backwards(FileView *view, menu_info *m, int start_pos)
424 {
425 int match_up = -1;
426 int match_down = -1;
427 int x;
428 regex_t re;
429 m->matching_entries = 0;
430
431 for(x = m->len - 1; x > -1; x--)
432 {
433 if(regcomp(&re, m->regexp, REG_EXTENDED) == 0)
434 {
435 if(regexec(&re, m->data[x], 0, NULL, 0) == 0)
436 {
437 if(match_up < 0)
438 {
439 if (x <= start_pos)
440 match_up = x;
441 }
442 if(match_down < 0)
443 {
444 if (x > start_pos)
445 match_down = x;
446 }
447 m->matching_entries++;
448 }
449 }
450 regfree(&re);
451 }
452
453 if ((match_up > -1) || (match_down > -1))
454 {
455 char buf[64];
456 int pos;
457
458 if (match_up > - 1)
459 pos = match_up;
460 else
461 pos = match_down;
462
463 clean_menu_position(m);
464 moveto_menu_pos(view, pos, m);
465 snprintf(buf, sizeof(buf), "%d %s", m->matching_entries,
466 m->matching_entries == 1 ? "match" : "matches");
467 status_bar_message(buf);
468 wrefresh(status_bar);
469 }
470 else
471 {
472 char buf[48];
473 snprintf(buf, sizeof(buf), "No matches for %s", m->regexp);
474 status_bar_message(buf);
475 wrefresh(status_bar);
476 return 1;
477 }
478 return 0;
479 }
480
481 int
482 search_menu_list(FileView *view, char * pattern, menu_info *m)
483 {
484 int save = 0;
485
486 if (pattern)
487 m->regexp = strdup(pattern);
488
489 switch (m->match_dir)
490 {
491 case NONE:
492 save = search_menu_forwards(view, m, m->pos);
493 break;
494 case UP:
495 save = search_menu_backwards(view, m, m->pos - 1);
496 break;
497 case DOWN:
498 save = search_menu_forwards(view, m, m->pos + 1);
499 break;
500 default:
501 break;
502 }
503 return save;
504 }
505
506 static void
507 execute_jobs_cb(FileView *view, menu_info *m)
508 {
509
510 }
511
512 static void
513 execute_apropos_cb(FileView *view, menu_info *m)
514 {
515 char *line = NULL;
516 char *man_page = NULL;
517 char *free_this = NULL;
518 char *num_str = NULL;
519 char command[256];
520 int z = 0;
521
522 free_this = man_page = line = strdup(m->data[m->pos]);
523
524 if((num_str = strchr(line, '(')))
525 {
526 num_str++;
527 while(num_str[z] != ')')
528 {
529 z++;
530 if(z > 40)
531 return;
532 }
533
534 num_str[z] = '\0';
535 line = strchr(line, ' ');
536 line[0] = '\0';
537
538 snprintf(command, sizeof(command), "man %s %s", num_str,
539 man_page);
540
541 shellout(command, 0);
542 my_free(free_this);
543 }
544 else
545 my_free(free_this);
546 }
547
548
549 static void
550 execute_locate_cb(FileView *view, menu_info *m)
551 {
552 char *dir = NULL;
553 char *file = NULL;
554 char *free_this = NULL;
555 int isdir = 0;
556
557 free_this = file = dir = strdup(m->data[m->pos]);
558 chomp(file);
559
560 /* :locate -h will show help message */
561 if(!access(file, R_OK))
562 {
563 if(is_dir(file))
564 isdir = 1;
565
566 file = strrchr(dir, '/');
567 *file = '\0';
568 file++;
569
570 change_directory(view, dir);
571
572 status_bar_message("Finding the correct directory.");
573
574 wrefresh(status_bar);
575 load_dir_list(view, 1);
576
577
578 if(find_file_pos_in_list(view, file) < 0)
579 {
580 if(isdir)
581 {
582 strcat(file, "/");
583 }
584
585 if(file[0] == '.')
586 show_dot_files(view);
587
588 if(find_file_pos_in_list(view, file) < 0)
589 remove_filename_filter(view);
590
591 moveto_list_pos(view, find_file_pos_in_list(view, file));
592 }
593 else
594 moveto_list_pos(view, find_file_pos_in_list(view, file));
595 }
596
597 my_free(free_this);
598 }
599
600 static void
601 execute_volume_cb(FileView *view, menu_info *m)
602 {
603 char buf[4];
604 snprintf(buf, 4, "%s", m->data[m->pos]);
605
606 change_directory(view, buf);
607 load_dir_list(view, 0);
608 moveto_list_pos(view, 0);
609
610 }
611
612 static void
613 execute_filetype_cb(FileView *view, menu_info *m)
614 {
615 /*
616 char *filename = get_current_file_name(view);
617 char *prog_str = get_all_programs_for_file(filename);
618 char command[PATH_MAX];
619 char *ptr = NULL;
620
621
622 if((ptr = strchr(prog_str, ',')) == NULL)
623 {
624 if(strchr(prog_str, '%'))
625 {
626 int m = 0;
627 char *expanded_command = expand_macros(view, prog_str, NULL, &m, 0);
628 shellout(expanded_command, 0);
629 my_free(expanded_command);
630 return;
631 }
632 else
633 {
634 snprintf(command, sizeof(command), "%s %s", prog_str, filename);
635 shellout(command, 0);
636 return;
637 }
638 }
639 else
640 {
641 char *prog_copy = strdup(prog_str);
642 char *free_this = prog_copy;
643 char *ptr1 = NULL;
644 int x = 1;
645
646 while((ptr = ptr1 = strchr(prog_copy, ',')) != NULL)
647 {
648 *ptr = '\0';
649 ptr1++;
650
651 if(x == m->pos +1)
652 {
653 if(strchr(prog_str, '%'))
654 {
655 int m = 0;
656 char *expanded_command = expand_macros(view, prog_copy, NULL, &m, 0);
657 shellout(expanded_command, 0);
658 my_free(expanded_command);
659 free(free_this);
660 return;
661 }
662 else
663 {
664 snprintf(command, sizeof(command), "%s %s",
665 prog_copy, filename);
666 shellout(command, 0);
667 free(free_this);
668 return;
669 }
670 }
671 prog_copy = ptr1;
672 x++;
673 }
674 if(strchr(prog_str, '%'))
675 {
676 int m = 0;
677 char *expanded_command = expand_macros(view, prog_copy, NULL, &m, 0);
678 shellout(expanded_command, 0);
679 my_free(expanded_command);
680 free(free_this);
681 return;
682 }
683 else
684 {
685 snprintf(command, sizeof(command), "%s %s", prog_copy, filename);
686 shellout(command, 0);
687 free(free_this);
688 return;
689 }
690 }
691 */
692 }
693
694 static void
695 execute_menu_cb(FileView *view, menu_info *m)
696 {
697 switch(m->type)
698 {
699 case APROPOS:
700 execute_apropos_cb(view, m);
701 break;
702 case BOOKMARK:
703 move_to_bookmark(view, index2mark(active_bookmarks[m->pos]));
704 break;
705 case COMMAND:
706 execute_command(view, command_list[m->pos].name);
707 break;
708 case FILETYPE:
709 execute_filetype_cb(view, m);
710 break;
711 case HISTORY:
712 {
713 change_directory(view, view->history[m->pos].dir);
714 load_dir_list(view, 1);
715 moveto_list_pos(view, find_file_pos_in_list(view,
716 view->history[m->pos].file));
717 }
718 break;
719 case JOBS:
720 execute_jobs_cb(view, m);
721 break;
722 case LOCATE:
723 execute_locate_cb(view, m);
724 break;
725 case VIFM:
726 break;
727 case VOLUME:
728 execute_volume_cb(view, m);
729 break;
730 default:
731 break;
732 }
733 }
734
735 static void
736 reload_bookmarks_menu_list(menu_info *m)
737 {
738 int x, i, z, len, j;
739 char buf[PATH_MAX];
740
741 getmaxyx(menu_win, z, len);
742
743
744 for (z = 0; z < m->len; z++)
745 {
746 if (m->data[z])
747 my_free(m->data[z]);
748 }
749
750 init_active_bookmarks();
751 m->len = cfg.num_bookmarks;
752 x = 0;
753
754 for(i = 1; x < m->len; i++)
755 {
756 j = active_bookmarks[x];
757 if (!strcmp(bookmarks[j].directory, "/"))
758 snprintf(buf, sizeof(buf), " %c /%s", index2mark(j), bookmarks[j].file);
759 else if (!strcmp(bookmarks[j].file, "../"))
760 snprintf(buf, sizeof(buf), " %c %s", index2mark(j),
761 bookmarks[j].directory);
762 else
763 snprintf(buf, sizeof(buf), " %c %s/%s", index2mark(j),
764 bookmarks[j].directory, bookmarks[j].file);
765
766 m->data = (char **)realloc(m->data, sizeof(char *) * (x + 1));
767 m->data[x] = (char *)malloc(sizeof(buf) + 2);
768 snprintf(m->data[x], sizeof(buf), "%s", buf);
769
770 x++;
771 }
772 m->len = x;
773 }
774
775 static void
776 reload_command_menu_list(menu_info *m)
777 {
778
779 int x, i, z, len;
780
781 getmaxyx(menu_win, z, len);
782
783 for (z = 0; z < m->len; z++)
784 {
785 if (m->data[z])
786 my_free(m->data[z]);
787 }
788
789 m->len = cfg.command_num;
790
791 qsort(command_list, cfg.command_num, sizeof(command_t),
792 sort_this);
793
794 x = 0;
795
796 for (i = 1; x < m->len; i++)
797 {
798 m->data = (char **)realloc(m->data, sizeof(char *) * (x + 1));
799 m->data[x] = (char *)malloc(len + 2);
800 snprintf(m->data[x], len, " %-*s %s ", 10, command_list[x].name,
801 command_list[x].action);
802
803 x++;
804 /* This will show the expanded command instead of the macros
805 * char *expanded = expand_macros(view, command_list[x].action, NULL);
806 * my_free(expanded);
807 */
808 }
809 }
810
811 static void
812 menu_key_cb(FileView *view, menu_info *m)
813 {
814 int done = 0;
815 int abort = 0;
816 int save_msg = 0;
817 int y, len;
818
819 getmaxyx(menu_win, y, len);
820 keypad(menu_win, TRUE);
821 werase(status_bar);
822 wtimeout(menu_win, 1000);
823
824 while(!done)
825 {
826 int key = wgetch(menu_win);
827
828 switch(key)
829 {
830 case '/':
831 {
832 m->match_dir = NONE;
833 if (m->regexp)
834 my_free(m->regexp);
835
836 get_command(view, MENU_SEARCH, m);
837 }
838 break;
839 case ':':
840 {
841 save_msg = get_command(view, MENU_COMMAND, m);
842 if (save_msg < 0)
843 {
844 done = 1;
845 abort = 1;
846 }
847 }
848 break;
849 case '?':
850 {
851 m->match_dir = UP;
852
853 if (m->regexp)
854 my_free(m->regexp);
855
856 get_command(view, MENU_SEARCH, m);
857 }
858 break;
859 case 2: /* ascii Ctrl B */
860 case KEY_PPAGE:
861 clean_menu_position(m);
862 moveto_menu_pos(view, m->top - m->win_rows + 2, m);
863 break;
864 case 3: /* ascii Ctrl C */
865 case 27: /* ascii Escape */
866 done = 1;
867 abort = 1;
868 break;
869 case 6: /* ascii Ctrl F */
870 {
871 clean_menu_position(m);
872 m->pos = m->pos + m->win_rows;
873 moveto_menu_pos(view, m->pos, m);
874 }
875 break;
876 case KEY_NPAGE:
877 break;
878 case 'l':
879 case 13: /* ascii Return */
880 done = 1;
881 break;
882 case 'G':
883 clean_menu_position(m);
884 moveto_menu_pos(view, m->len -1, m);
885 break;
886 case 'N':
887 {
888 if (m->regexp != NULL)
889 {
890 m->match_dir = UP;
891 m->matching_entries = 0;
892 search_menu_list(view, NULL, m);
893 }
894 else
895 {
896 status_bar_message("No search pattern set.");
897 wrefresh(status_bar);
898 }
899 }
900 break;
901 case 'g':
902 {
903 key = wgetch(menu_win);
904 if(key == 'g')
905 {
906 clean_menu_position(m);
907 moveto_menu_pos(view, 0, m);
908 }
909 }
910 break;
911 case 'd':
912 {
913 key = wgetch(menu_win);
914
915 if(key != 'd')
916 break;
917
918 if(m->type == COMMAND)
919 {
920 clean_menu_position(m);
921 remove_command(command_list[m->pos].name);
922
923 reload_command_menu_list(m);
924 draw_menu(view, m);
925
926 if(m->pos -1 >= 0)
927 moveto_menu_pos(view, m->pos -1, m);
928 else
929 moveto_menu_pos(view, 0, m);
930 }
931 else if(m->type == BOOKMARK)
932 {
933 clean_menu_position(m);
934 remove_bookmark(active_bookmarks[m->pos]);
935
936 reload_bookmarks_menu_list(m);
937 draw_menu(view, m);
938
939 if(m->pos -1 >= 0)
940 moveto_menu_pos(view, m->pos -1, m);
941 else
942 moveto_menu_pos(view, 0, m);
943 }
944 }
945 break;
946 case 'j':
947 case KEY_DOWN:
948 {
949 clean_menu_position(m);
950 m->pos++;
951 moveto_menu_pos(view, m->pos, m);
952 }
953 break;
954 case 'k':
955 case KEY_UP:
956 {
957 clean_menu_position(m);
958 m->pos--;
959 moveto_menu_pos(view, m->pos, m);
960 wrefresh(menu_win);
961 }
962 break;
963 case 'n':
964 {
965 if (m->regexp != NULL)
966 {
967 m->match_dir = DOWN;
968 m->matching_entries = 0;
969 search_menu_list(view, NULL, m);
970 }
971 else
972 {
973 status_bar_message("No search pattern set>");
974 wrefresh(status_bar);
975 }
976 }
977 break;
978 default:
979 break;
980 }
981 if (curr_stats.redraw_menu)
982 redraw_menu(view, m);
983
984 } /* end of while(!done) */
985
986 if (abort)
987 return;
988
989 execute_menu_cb(view, m);
990 }
991
992 static void
993 draw_menu(FileView *view, menu_info *m)
994 {
995 int i;
996 int x, y;
997 int len;
998
999 getmaxyx(menu_win, y, x);
1000 len = x;
1001 werase(menu_win);
1002
1003 box(menu_win, 0, 0);
1004
1005 if(m->win_rows - 2 >= m->len)
1006 {
1007 m->top = 0;
1008 }
1009 x = m->top;
1010
1011 wattron(menu_win, A_BOLD);
1012 mvwaddstr(menu_win, 0, 3, m->title);
1013 wattroff(menu_win, A_BOLD);
1014
1015 for(i = 1; x < m->len; i++)
1016 {
1017 char *ptr = NULL;
1018 chomp(m->data[x]);
1019 if ((ptr = strchr(m->data[x], '\n')) || (ptr = strchr(m->data[x], '\r')))
1020 *ptr = '\0';
1021 mvwaddnstr(menu_win, i, 2, m->data[x], len - 4);
1022 x++;
1023
1024 if(i +3 > y)
1025 break;
1026 }
1027 }
1028
1029 void
1030 show_apropos_menu(FileView *view, char *args)
1031 {
1032 int x = 0;
1033 char buf[256];
1034 FILE *file;
1035 int len = 0;
1036
1037 menu_info m;
1038 m.top = 0;
1039 m.current = 1;
1040 m.len = 0;
1041 m.pos = 0;
1042 m.win_rows = 0;
1043 m.type = APROPOS;
1044 m.matching_entries = 0;
1045 m.match_dir = NONE;
1046 m.regexp = NULL;
1047 m.title = NULL;
1048 m.args = strdup(args);
1049 m.data = NULL;
1050
1051 getmaxyx(menu_win, m.win_rows, len);
1052
1053 m.title = (char *)malloc((strlen(args) + 12) * sizeof(char));
1054 snprintf(m.title, strlen(args) + 11, " Apropos %s ", args);
1055 snprintf(buf, sizeof(buf), "apropos %s", args);
1056 file = popen(buf, "r");
1057
1058 if(!file)
1059 {
1060 show_error_msg("Trouble opening a file", "Unable to open file");
1061 return ;
1062 }
1063 x = 0;
1064
1065 curr_stats.search = 1;
1066 while(fgets(buf, sizeof(buf), file))
1067 {
1068 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1069 m.data[x] = (char *)malloc(len);
1070
1071 snprintf(m.data[x], len - 2, "%s", buf);
1072
1073 x++;
1074 }
1075 pclose(file);
1076 m.len = x;
1077 curr_stats.search = 0;
1078
1079 setup_menu(view);
1080 draw_menu(view, &m);
1081 moveto_menu_pos(view, 0, &m);
1082 menu_key_cb(view, &m);
1083 reset_popup_menu(&m);
1084 }
1085
1086 void
1087 show_bookmarks_menu(FileView *view)
1088 {
1089 int i, j, x;
1090 char buf[PATH_MAX];
1091
1092 menu_info m;
1093 m.top = 0;
1094 m.current = 1;
1095 m.len = cfg.num_bookmarks;
1096 m.pos = 0;
1097 m.win_rows = 0;
1098 m.type = BOOKMARK;
1099 m.matching_entries = 0;
1100 m.match_dir = NONE;
1101 m.regexp = NULL;
1102 m.title = NULL;
1103 m.args = NULL;
1104 m.data = NULL;
1105
1106 getmaxyx(menu_win, m.win_rows, x);
1107
1108 init_active_bookmarks();
1109
1110 m.title = (char *)malloc((strlen(" Mark -- File ") + 1) * sizeof(char));
1111 snprintf(m.title, strlen(" Mark -- File "), " Mark -- File ");
1112
1113 x = 0;
1114
1115 for(i = 1; x < m.len; i++)
1116 {
1117 j = active_bookmarks[x];
1118 if (!strcmp(bookmarks[j].directory, "/"))
1119 snprintf(buf, sizeof(buf), " %c /%s", index2mark(j), bookmarks[j].file);
1120 else if (!strcmp(bookmarks[j].file, "../"))
1121 snprintf(buf, sizeof(buf), " %c %s", index2mark(j),
1122 bookmarks[j].directory);
1123 else
1124 snprintf(buf, sizeof(buf), " %c %s/%s", index2mark(j),
1125 bookmarks[j].directory, bookmarks[j].file);
1126
1127 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1128 m.data[x] = (char *)malloc(sizeof(buf) + 2);
1129 snprintf(m.data[x], sizeof(buf), "%s", buf);
1130
1131 x++;
1132 }
1133 m.len = x;
1134
1135 setup_menu(view);
1136 draw_menu(view, &m);
1137 moveto_menu_pos(view, 0, &m);
1138 menu_key_cb(view, &m);
1139 reset_popup_menu(&m);
1140 }
1141
1142 void
1143 show_commands_menu(FileView *view)
1144 {
1145 int len, i, x;
1146
1147 menu_info m;
1148 m.top = 0;
1149 m.current = 1;
1150 m.len = cfg.command_num;
1151 m.pos = 0;
1152 m.win_rows = 0;
1153 m.type = COMMAND;
1154 m.matching_entries = 0;
1155 m.match_dir = NONE;
1156 m.regexp = NULL;
1157 m.title = NULL;
1158 m.args = NULL;
1159 m.data = NULL;
1160
1161 if (cfg.command_num < 1)
1162 {
1163 show_error_msg("No commands set", "No commands are set.");
1164 return;
1165 }
1166
1167 getmaxyx(menu_win, m.win_rows, len);
1168 qsort(command_list, cfg.command_num, sizeof(command_t),
1169 sort_this);
1170
1171 m.title = (char *)malloc((strlen(" Command ------ Action ") + 1)
1172 * sizeof(char));
1173 snprintf(m.title, strlen(" Command ------ Action "),
1174 " Command ------ Action ");
1175
1176 x = 0;
1177
1178 for (i = 1; x < m.len; i++)
1179 {
1180 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1181 m.data[x] = (char *)malloc(len + 2);
1182 snprintf(m.data[x], len, " %-*s %s ", 10, command_list[x].name,
1183 command_list[x].action);
1184
1185 x++;
1186 /* This will show the expanded command instead of the macros
1187 * char *expanded = expand_macros(view, command_list[x].action, NULL);
1188 * my_free(expanded);
1189 */
1190 }
1191
1192 setup_menu(view);
1193 draw_menu(view, &m);
1194 moveto_menu_pos(view, 0, &m);
1195 menu_key_cb(view, &m);
1196 reset_popup_menu(&m);
1197 }
1198
1199 void
1200 show_filetypes_menu(FileView *view)
1201 {
1202 char *filename = get_current_file_name(view);
1203 char *prog_str = get_all_programs_for_file(filename);
1204 if (prog_str == NULL)
1205 {
1206 show_error_msg(" Filetype is not set. ",
1207 "No programs set for this filetype.");
1208 return;
1209 }
1210 else
1211 {
1212 int x = 0;
1213 int len = 0;
1214 char *ptr = NULL;
1215
1216 menu_info m;
1217 m.top = 0;
1218 m.current = 1;
1219 m.len = 0;
1220 m.pos = 0;
1221 m.win_rows = 0;
1222 m.type = FILETYPE;
1223 m.matching_entries = 0;
1224 m.match_dir = NONE;
1225 m.regexp = NULL;
1226 m.title = NULL;
1227 m.args = NULL;
1228 m.data = NULL;
1229
1230 getmaxyx(menu_win, m.win_rows, len);
1231
1232 if ((ptr = strchr(prog_str, ',')) == NULL)
1233 {
1234 m.len = 1;
1235 m.data = (char **)realloc(m.data, sizeof(char *) * (len + 1));
1236 m.data[0] = strdup(prog_str);
1237 }
1238 else
1239 {
1240 char *prog_copy = strdup(prog_str);
1241 char *free_this = prog_copy;
1242 char *ptr1 = NULL;
1243
1244 while ((ptr = ptr1 = strchr(prog_copy, ',')) != NULL)
1245 {
1246 *ptr = '\0';
1247 ptr1++;
1248 m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1));
1249 m.data[x] = strdup(prog_copy);
1250 prog_copy = ptr1;
1251 x++;
1252 m.len = x;
1253 }
1254 m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1));
1255 m.data[x] = (char *)malloc((len + 1) * sizeof(char));
1256 snprintf(m.data[x], len, "%s", prog_copy);
1257 m.len++;
1258
1259 free(free_this);
1260 }
1261 setup_menu(view);
1262 draw_menu(view, &m);
1263 moveto_menu_pos(view, 0, &m);
1264 menu_key_cb(view, &m);
1265 reset_popup_menu(&m);
1266 }
1267 }
1268
1269 void
1270 show_history_menu(FileView *view)
1271 {
1272 int x;
1273 menu_info m;
1274
1275 if (view->history_num < 2)
1276 return;
1277
1278 m.top = 0;
1279 m.current = 1;
1280 m.len = view->history_num + 1;
1281 m.pos = 0;
1282 m.win_rows = 0;
1283 m.type = HISTORY;
1284 m.matching_entries = 0;
1285 m.match_dir = NONE;
1286 m.regexp = NULL;
1287 m.title = strdup("History");
1288 m.args = NULL;
1289 m.data = NULL;
1290
1291 getmaxyx(menu_win, m.win_rows, x);
1292
1293 for(x = 0; x < view->history_num + 1; x++)
1294 {
1295 if(strlen(view->history[x].dir) < 1)
1296 break;
1297
1298 /* Change the current dir to reflect the current file. */
1299 if(!strcmp(view->history[x].dir, view->curr_dir))
1300 snprintf(view->history[x].file, sizeof(view->history[x].file),
1301 "%s", view->dir_entry[view->list_pos].name);
1302
1303 if(!strcmp(view->history[x].dir, "/"))
1304 {
1305 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1306 m.data[x] = (char *)malloc((strlen(view->history[x].file) + 1)
1307 * sizeof(char));
1308 snprintf(m.data[x], strlen(view->history[x].file),
1309 "%s", view->history[x].file);
1310 }
1311 else
1312 {
1313 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1314 m.data[x] = (char *)malloc((strlen(view->history[x].file) +
1315 strlen(view->history[x].dir) + 2) * sizeof(char));
1316 snprintf(m.data[x], strlen(view->history[x].file) +
1317 strlen(view->history[x].dir) + 1, "%s/%s",
1318 view->history[x].dir, view->history[x].file);
1319 }
1320 m.len = x;
1321 }
1322 setup_menu(view);
1323 draw_menu(view, &m);
1324 moveto_menu_pos(view, 0, &m);
1325 menu_key_cb(view, &m);
1326 reset_popup_menu(&m);
1327 }
1328
1329 void
1330 show_locate_menu(FileView *view, char *args)
1331 {
1332 int x = 0;
1333 char buf[256];
1334 FILE *file;
1335
1336 menu_info m;
1337 m.top = 0;
1338 m.current = 1;
1339 m.len = 0;
1340 m.pos = 0;
1341 m.win_rows = 0;
1342 m.type = LOCATE;
1343 m.matching_entries = 0;
1344 m.match_dir = NONE;
1345 m.regexp = NULL;
1346 m.title = NULL;
1347 m.args = strdup(args);
1348 m.data = NULL;
1349
1350 getmaxyx(menu_win, m.win_rows, x);
1351
1352 snprintf(buf, sizeof(buf), "locate %s", args);
1353 m.title = strdup(buf);
1354 file = popen(buf, "r");
1355
1356 if(!file)
1357 {
1358 show_error_msg("Trouble opening a file", "Unable to open file");
1359 return ;
1360 }
1361 x = 0;
1362
1363 curr_stats.search = 1;
1364
1365 while(fgets(buf, sizeof(buf), file))
1366 {
1367 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1368 m.data[x] = (char *)malloc(sizeof(buf) + 2);
1369 snprintf(m.data[x], sizeof(buf), "%s", buf);
1370
1371 x++;
1372 }
1373
1374 pclose(file);
1375 m.len = x;
1376 curr_stats.search = 0;
1377
1378 if(m.len < 1)
1379 {
1380 char buf[256];
1381
1382 reset_popup_menu(&m);
1383 snprintf(buf, sizeof(buf), "No files found matching \"%s\"", args);
1384 status_bar_message(buf);
1385 wrefresh(status_bar);
1386 return;
1387 }
1388
1389 setup_menu(view);
1390 draw_menu(view, &m);
1391 moveto_menu_pos(view, 0, &m);
1392 menu_key_cb(view, &m);
1393 reset_popup_menu(&m);
1394 }
1395
1396 void
1397 show_user_menu(FileView *view, char *command)
1398 {
1399 int x;
1400 char buf[256];
1401 FILE *file;
1402
1403 menu_info m;
1404 m.top = 0;
1405 m.current = 1;
1406 m.len = 0;
1407 m.pos = 0;
1408 m.win_rows = 0;
1409 m.type = USER;
1410 m.matching_entries = 0;
1411 m.match_dir = NONE;
1412 m.regexp = NULL;
1413 m.title = NULL;
1414 m.args = NULL;
1415 m.data = NULL;
1416 m.get_info_script = command;
1417
1418
1419 for ( x = 0; x < strlen(command); x++)
1420 {
1421 if (command[x] == ',')
1422 {
1423 command[x] = '\0';
1424 break;
1425 }
1426 }
1427
1428 getmaxyx(menu_win, m.win_rows, x);
1429
1430 snprintf(buf, sizeof(buf), " %s ", m.get_info_script);
1431 m.title = strdup(buf);
1432 file = popen(buf, "r");
1433
1434 if(!file)
1435 {
1436 reset_popup_menu(&m);
1437 show_error_msg("Trouble opening a file", "Unable to open file");
1438 return ;
1439 }
1440 x = 0;
1441
1442 curr_stats.search = 1;
1443
1444 while(fgets(buf, sizeof(buf), file))
1445 {
1446 show_progress();
1447 m.data = (char **)realloc(m.data, sizeof(char *) * (x + 1));
1448 m.data[x] = (char *)malloc(sizeof(buf) + 2);
1449 snprintf(m.data[x], sizeof(buf), "%s", buf);
1450
1451 x++;
1452 }
1453
1454 pclose(file);
1455 m.len = x;
1456 curr_stats.search = 0;
1457
1458 if(m.len < 1)
1459 {
1460 char buf[256];
1461
1462 reset_popup_menu(&m);
1463 snprintf(buf, sizeof(buf), "No results found");
1464 status_bar_message(buf);
1465 wrefresh(status_bar);
1466 return;
1467 }
1468
1469 setup_menu(view);
1470 draw_menu(view, &m);
1471 moveto_menu_pos(view, 0, &m);
1472 menu_key_cb(view, &m);
1473 reset_popup_menu(&m);
1474 }
1475
1476 void
1477 show_register_menu(FileView *view)
1478 {
1479 int x;
1480
1481 menu_info m;
1482 m.top = 0;
1483 m.current = 1;
1484 m.len = 0;
1485 m.pos = 0;
1486 m.win_rows = 0;
1487 m.type = REGISTER;
1488 m.matching_entries = 0;
1489 m.match_dir = NONE;
1490 m.regexp = NULL;
1491 m.title = strdup(" Registers ");
1492 m.args = NULL;
1493 m.data = NULL;
1494
1495 getmaxyx(menu_win, m.win_rows, x);
1496
1497 for (x = 0; x < NUM_REGISTERS; x++)
1498 {
1499 if (reg[x].num_files > 0)
1500 {
1501 char buf[56];
1502 int y = reg[x].num_files;
1503 snprintf(buf, sizeof(buf), "\"%c", reg[x].name);
1504 m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1));
1505 m.data[m.len] = strdup(buf);
1506 m.len++;
1507
1508 while (y)
1509 {
1510
1511 y--;
1512 m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1));
1513 m.data[m.len] = strdup(reg[x].files[y]);
1514
1515 m.len++;
1516 }
1517 }
1518 }
1519
1520 if (!m.len)
1521 {
1522 m.data = (char **)realloc(m.data, sizeof(char *) * 1);
1523 m.data[0] = strdup(" Registers are empty ");
1524 m.len = 1;
1525 }
1526
1527 setup_menu(view);
1528 draw_menu(view, &m);
1529 moveto_menu_pos(view, 0, &m);
1530 menu_key_cb(view, &m);
1531 reset_popup_menu(&m);
1532 }
1533
1534 void
1535 show_vifm_menu(FileView *view)
1536 {
1537 int x;
1538
1539 menu_info m;
1540 m.top = 0;
1541 m.current = 1;
1542 m.len = 0;
1543 m.pos = 0;
1544 m.win_rows = 0;
1545 m.type = VIFM;
1546 m.matching_entries = 0;
1547 m.match_dir = NONE;
1548 m.regexp = NULL;
1549 m.title = NULL;
1550 m.args = NULL;
1551 m.data = NULL;
1552
1553 getmaxyx(menu_win, m.win_rows, x);
1554
1555 setup_menu(view);
1556 draw_menu(view, &m);
1557 moveto_menu_pos(view, 0, &m);
1558 menu_key_cb(view, &m);
1559 reset_popup_menu(&m);
1560 }
1561
1562 void
1563 show_volume_menu(FileView *view)
1564 {
1565 menu_info m;
1566 int retVal;
1567 int x;
1568 TCHAR Drive[] = TEXT("c:\\");
1569 TCHAR I;
1570 TCHAR volName[MAX_PATH];
1571 TCHAR fileBuf[MAX_PATH];
1572
1573 m.top = 0;
1574 m.current = 1;
1575 m.len = 0;
1576 m.pos = 0;
1577 m.win_rows = 0;
1578 m.type = VOLUME;
1579 m.matching_entries = 0;
1580 m.match_dir = NONE;
1581 m.regexp = NULL;
1582 m.title = strdup(" Mounted Volumes ");
1583 m.args = NULL;
1584 m.data = NULL;
1585
1586 getmaxyx(menu_win, m.win_rows, x);
1587
1588 for(I = TEXT('a'); I < TEXT('z'); I++)
1589 {
1590 Drive[0] = I;
1591 retVal = GetDriveType(Drive);
1592
1593 switch(retVal)
1594 {
1595 case DRIVE_CDROM:
1596
1597 case DRIVE_REMOTE:
1598
1599 case DRIVE_RAMDISK:
1600
1601 case DRIVE_REMOVABLE:
1602
1603 case DRIVE_FIXED:
1604 break;
1605
1606 case DRIVE_UNKNOWN:
1607 case DRIVE_NO_ROOT_DIR:
1608 default:
1609 retVal = 0;
1610 break;
1611 }
1612 if(retVal)
1613 {
1614 if(GetVolumeInformation(Drive, volName, MAX_PATH, NULL,
1615 NULL, NULL, fileBuf, MAX_PATH))
1616 {
1617 m.data = (char **)realloc(m.data, sizeof(char *) * (m.len + 1));
1618 m.data[m.len] = (char *)malloc((MAX_PATH + 5) * sizeof(char));
1619
1620 snprintf(m.data[m.len], MAX_PATH, "%s %s ", Drive, volName);
1621 m.len++;
1622
1623 }
1624 }
1625 }
1626
1627 setup_menu(view);
1628 draw_menu(view, &m);
1629 moveto_menu_pos(view, 0, &m);
1630 menu_key_cb(view, &m);
1631 reset_popup_menu(&m);
1632 moveto_list_pos(view, view->list_pos);
1633 }
1634
1635 int
1636 show_overwrite_file_menu(char *file)
1637 {
1638 int x, y;
1639 int key;
1640 int done = 0;
1641 int answer = 0;
1642 char buf[MAX_PATH];
1643
1644 curr_stats.freeze = 1;
1645 curs_set(0);
1646 werase(error_win);
1647
1648 getmaxyx(error_win, y, x);
1649
1650 snprintf(buf, sizeof(buf), " \'%s\' exists would you like to overwrite it? ", file);
1651
1652
1653 mvwaddstr(error_win, 2, (x - strlen(buf))/2, buf);
1654
1655 box(error_win, 0, 0);
1656 mvwaddstr(error_win, 0, (x - strlen(" File Exists "))/2, " File Exists ");
1657 mvwaddstr(error_win, 4, (x - strlen(" [Y]es [N]o [A]ll "))/2, " [Y]es [N]o [A]ll ");
1658
1659 while(!done)
1660 {
1661 key = wgetch(error_win);
1662
1663 switch (key)
1664 {
1665 case 'a':
1666 case 'A':
1667 answer = 1;
1668 done = 1;
1669 break;
1670 case 'n':
1671 case 'N':
1672 answer = 2;
1673 done = 1;
1674 break;
1675 case 'y':
1676 case 'Y':
1677 answer = 3;
1678 done = 1;
1679 break;
1680 default:
1681 break;
1682 }
1683
1684 }
1685
1686
1687 curr_stats.freeze = 0;
1688
1689 werase(error_win);
1690 wrefresh(error_win);
1691
1692 touchwin(stdscr);
1693
1694 update_all_windows();
1695
1696 if(curr_stats.need_redraw)
1697 redraw_window();
1698
1699 return answer;
1700
1701 }
1702
1703
1704
1705
1706
1707
File src/menus.h added (mode: 100644) (index 0000000..5cbf791)
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 __MENUS_H__
20 #define __MENUS_H__
21
22 #include "ui.h"
23
24 void show_bookmarks_menu(FileView *view);
25 void show_commands_menu(FileView *view);
26 void show_history_menu(FileView *view);
27 void show_vifm_menu(FileView *view);
28 void show_filetypes_menu(FileView *view);
29 void show_jobs_menu(FileView *view);
30 void show_locate_menu(FileView *view, char *args);
31 void show_apropos_menu(FileView *view, char *args);
32 void show_user_menu(FileView *view, char *command);
33 void show_register_menu(FileView *view);
34 void show_volume_menu(FileView *view);
35 void reset_popup_menu(void);
36 int show_overwrite_file_menu(char *file);
37 void setup_menu(FileView *view);
38 void show_error_msg(char * title, char *message);
39 int search_menu_list(FileView *view, char * command, void * ptr);
40 int execute_menu_command(FileView *view, char * command, void * ptr);
41
42
43 #endif
File src/pauseme added (mode: 100644) (index 0000000..a62a7f7)
1 #!/bin/sh
2
3 PROG=$1
4 shift
5 $PROG "$@"
6
7 echo "Press return ..."
8 read dummy
File src/registers.c added (mode: 100644) (index 0000000..81abb9c)
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<unistd.h>
20 #include<string.h>
21
22 #include"menus.h"
23 #include"registers.h"
24 #include"utils.h"
25
26 char valid_registers[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
27 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
28 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
29 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
30
31 int
32 is_valid_register(int key)
33 {
34 int x = 0;
35
36 for (x = 0; x < strlen(valid_registers); x++)
37 {
38 if (key == (int)valid_registers[x])
39 return 1;
40 }
41
42 return 0;
43 }
44
45 static int
46 check_for_duplicate_file_names(int pos, char *file)
47 {
48 int z;
49 int x = 0;
50 for (z = 0; z < reg[pos].num_files; z++)
51 {
52 if (!strcmp(file, reg[pos].files[z]))
53 return ++x;
54 }
55 return x;
56 }
57
58 void
59 append_to_register(int key, char *file)
60 {
61 int i = 0;
62
63 if (access(file, F_OK))
64 return;
65
66 for (i = 0; i < NUM_REGISTERS; i++)
67 {
68 if (reg[i].name == key)
69 {
70 if (check_for_duplicate_file_names(i, file))
71 break;
72 reg[i].num_files++;
73 reg[i].files = (char **)realloc(reg[i].files,
74 reg[i].num_files * sizeof(char *));
75 reg[i].files[reg[i].num_files - 1] = strdup(file);
76 break;
77 }
78
79 }
80 }
81
82 void
83 clear_register(int key)
84 {
85 int i = 0;
86
87 for (i = 0; i < NUM_REGISTERS; i++)
88 {
89 if (reg[i].name == key)
90 {
91 int y = reg[i].num_files;
92 while (y)
93 {
94 y--;
95 my_free(reg[i].files[y]);
96 }
97 reg[i].num_files = 0;
98 break;
99 }
100 }
101 }
File src/registers.h added (mode: 100644) (index 0000000..d118f2b)
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 __REGISTERS_H_
20 #define __REGISTERS_H_
21
22 #define NUM_REGISTERS 26
23
24 typedef struct _Registers
25 {
26 int name;
27 int num_files;
28 char ** files;
29 int deleted;
30
31 }registers_t;
32
33 registers_t reg[NUM_REGISTERS];
34 extern char valid_registers[];
35
36
37 int is_valid_register(int key);
38 void load_register(int reg, char *file);
39 void append_to_register(int reg, char *file);
40 void clear_register(int reg);
41
42 #endif
File src/rline.c added (mode: 100644) (index 0000000..5c7c3d2)
1 /* vifm
2 * Copyright (C) 2001 Ken Steen.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17 */
18
19 #include<ctype.h>
20 #include<sys/types.h> /* Needed for Fink with Mac OS X */
21 #include<dirent.h> /* DIR */
22 #include<curses.h>
23 #include<signal.h>
24 #include<string.h>
25
26 #include"commands.h"
27 #include"config.h"
28 #include"keys.h"
29 #include"menus.h"
30 #include"status.h"
31 #include"utils.h"
32
33 static char *
34 check_for_command(char *string)
35 {
36 int pos = -1;
37 char *command = (char *)NULL;
38
39 if ((pos = command_is_reserved(string)) > -1)
40 command = strdup(reserved_commands[pos]);
41
42 else if ((pos = is_user_command(string)) > -1)
43 command = strdup(command_list[pos].name);
44
45 return command;
46 }
47
48 static char *
49 check_for_executable(char *string)
50 {
51 char *temp = (char *)NULL;
52
53 if (!string)
54 return NULL;
55
56 if (string[0] == '!')
57 {
58 if (strlen(string) > 2)
59 {
60 if (string[1] == '!')
61 temp = strdup(string + 2);
62 else
63 temp = strdup(string + 1);
64 }
65 else if (strlen(string) > 1)
66 temp = strdup(string + 1);
67 }
68 return temp;
69 }
70
71 static char *
72 get_last_word(char * string)
73 {
74
75 char * temp = (char *)NULL;
76
77 if (!string)
78 return NULL;
79
80 /*:command filename */
81 temp = strrchr(string, ' ');
82
83 if(temp)
84 {
85 temp++;
86 return temp;
87 }
88 /* :!filename or :!!filename */
89 temp = check_for_executable(string);
90 if (temp)
91 return temp;
92
93 return NULL;
94 }
95
96 /* This is from the taken mainly from the readline program it just
97 * returns the first file name in the directory that matches
98 * the string passed to the function. I couldn't get readline to handle
99 * the Ctrl-c or Esc keys correctly so we are doing this the hard way.
100 */
101 static char *
102 filename_completion(char *string)
103 {
104
105 DIR *dir;
106 int x = 0;
107 struct dirent *d;
108 char * dirname = (char *)NULL;
109 char * filename = (char *)NULL;
110 char * temp = (char *)NULL;
111 int found = 0;
112 int filename_len = 0;
113
114 if (!string)
115 return NULL;
116
117 if (!strncmp(string, "~/", 2))
118 {
119 char * homedir = getenv("HOME");
120
121 dirname = (char *)malloc((strlen(homedir) + strlen(string) + 1));
122
123 if (dirname == NULL)
124 return NULL;
125
126 snprintf(dirname, strlen(homedir) + strlen(string) + 1, "%s/%s",
127 homedir, string + 2);
128
129 filename = strdup(dirname);
130 }
131 else
132 {
133 dirname = strdup(string);
134 filename = strdup(string);
135 }
136
137 temp = strrchr(dirname, '/');
138
139 if (temp)
140 {
141 strcpy(filename, ++temp);
142 *temp = '\0';
143 }
144 else
145 {
146 dirname[0] = '.';
147 dirname[1] = '\0';
148 }
149
150
151 dir = opendir(dirname);
152 filename_len = strlen(filename);
153
154 if(dir == NULL)
155 {
156 my_free(filename);
157 my_free(dirname);
158 return NULL;
159 }
160
161 for (x = 0; (d = readdir(dir)); x++)
162 {
163 if (!strncmp(d->d_name, filename, filename_len))
164 {
165 found++;
166 break;
167 }
168 }
169
170 closedir(dir);
171
172
173 if (found)
174 {
175 int isdir = 0;
176 if (is_dir(d->d_name))
177 {
178 isdir = 1;
179 }
180 else if (strcmp(dirname, "."))
181 {
182 char * tempfile = (char *)NULL;
183 int len = strlen(dirname) + strlen(d->d_name) + 1;
184 tempfile = (char *)malloc((len) * sizeof(char));
185 if (!tempfile)
186 return NULL;
187 snprintf(tempfile, len, "%s%s", dirname, d->d_name);
188 if (is_dir(tempfile))
189 isdir = 1;
190 else
191 temp = strdup(d->d_name);
192
193 my_free(tempfile);
194 }
195 else
196 temp = strdup(d->d_name);
197
198 if (isdir)
199 {
200 char * tempfile = (char *)NULL;
201 tempfile = (char *) malloc((strlen(d->d_name) + 2) * sizeof(char));
202 if (!tempfile)
203 return NULL;
204 snprintf(tempfile, strlen(d->d_name) + 2, "%s/", d->d_name);
205 temp = strdup(tempfile);
206
207 my_free(tempfile);
208 }
209
210 my_free(filename);
211 my_free(dirname);
212
213 return temp;
214 }
215 else
216 {
217 my_free(filename);
218 my_free(dirname);
219 return NULL;
220 }
221 }
222
223 char *
224 my_rl_gets(int type)
225 {
226 static char *line_read = (char *)NULL;
227 int key;
228 int pos;
229 int index = 0;
230 int done = 0;
231 int abort = 0;
232 int len = 0;
233 int cmd_pos = -1;
234 int prompt_len;
235 char prompt[8];
236
237 /* If the buffer has already been allocated, free the memory. */
238 if (line_read)
239 {
240 my_free(line_read);
241 line_read = (char *)NULL;
242 }
243
244 if (type == GET_VISUAL_COMMAND)
245 prompt_len = pos = 6;
246 else
247 prompt_len = pos = 1;
248
249 curs_set(1);
250 werase(status_bar);
251
252 if (type == GET_COMMAND || type == MENU_COMMAND)
253 snprintf(prompt, sizeof(prompt), ":");
254 else if (type == GET_SEARCH_PATTERN || type == MENU_SEARCH)
255 snprintf(prompt, sizeof(prompt), "/");
256 /*
257 else if (type == MAPPED_COMMAND || type == MAPPED_SEARCH)
258 {
259 snprintf(buf, sizeof(buf), "%s", string);
260 mvwaddstr(status_bar, 0, 0, string);
261 pos = strlen(string);
262 index = pos -1;
263 len = index;
264 }
265 */
266 else if (type == GET_VISUAL_COMMAND)
267 snprintf(prompt, sizeof(prompt), ":'<,'>");
268
269 mvwaddstr(status_bar, 0, 0, prompt);
270
271 while (!done)
272 {
273 if(curr_stats.freeze)
274 continue;
275
276 curs_set(1);
277 flushinp();
278 curr_stats.getting_input = 1;
279 key = wgetch(status_bar);
280
281 switch (key)
282 {
283 case 27: /* ascii Escape */
284 case 3: /* ascii Ctrl C */
285 done = 1;
286 abort = 1;
287 break;
288 case 13: /* ascii Return */
289 done = 1;
290 break;
291 case 9: /* ascii Tab */
292 {
293 char *last_word = (char *)NULL;
294 char *raw_name = (char *)NULL;
295 char *filename = (char *)NULL;
296
297 if (type == MENU_SEARCH || type == MENU_COMMAND)
298 break;
299
300 if(! line_read)
301 break;
302
303 last_word = get_last_word(line_read);
304
305 if (last_word)
306 {
307 raw_name = filename_completion(last_word);
308 if (raw_name)
309 filename = escape_filename(raw_name, 1);
310 }
311 /* :partial_command */
312 else
313 {
314 char *complete_command = check_for_command(line_read);
315
316 if (complete_command)
317 {
318 line_read = strdup(complete_command);
319
320 mvwaddstr(status_bar, 0, prompt_len, line_read);
321 pos = index = strlen(line_read);
322 pos++;
323
324 my_free(complete_command);
325 break;
326 }
327 else
328 break;
329 }
330
331 if (filename)
332 {
333 char *temp = (char *)NULL;
334
335 /* :command /some/directory/partial_filename */
336 if ((temp = strrchr(line_read, '/')))
337 {
338 temp++;
339 *temp = '\0';
340
341 line_read = (char *)realloc(line_read, (strlen(line_read) +
342 strlen(filename) + 1) * sizeof(char));
343
344 if (!line_read)
345 {
346 my_free(raw_name);
347 my_free(filename);
348 break;
349 }
350
351 strcat(line_read, filename);
352 my_free(filename);
353 my_free(raw_name);
354
355 }
356 /* :command partial_filename */
357 else if ((temp = strrchr(line_read, ' ')))
358 {
359 temp++;
360 *temp = '\0';
361
362 line_read = (char *)realloc(line_read, (strlen(line_read) +
363 strlen(filename) + 1) * sizeof(char));
364 if (!line_read)
365 {
366 my_free(filename);
367 break;
368 }
369
370 strcat(line_read, filename);
371 my_free(raw_name);
372 my_free(filename);
373 }
374 /* :!partial_filename or :!!partial_filename */
375 else if ((temp = strrchr(line_read, '!')))
376 {
377 temp++;
378 *temp = '\0';
379
380 line_read = (char *)realloc(line_read, (strlen(line_read) +
381 strlen(filename) + 1) * sizeof(char));
382
383 if (!line_read)
384 {
385 my_free(raw_name);
386 my_free(filename);
387 break;
388 }
389
390 strcat(line_read, filename);
391 my_free(raw_name);
392 my_free(filename);
393 }
394 /* error */
395 else
396 {
397 show_error_msg(" Debug Error ",
398 "Harmless error in rline.c line 388");
399 my_free(raw_name);
400 my_free(filename);
401 break;
402 }
403
404 mvwaddstr(status_bar, 0, prompt_len, line_read);
405 pos = index = strlen(line_read);
406 pos++;
407 }
408 else
409 break;
410 }
411 break;
412 case KEY_UP:
413 {
414 if (type == GET_COMMAND)
415 {
416 if (0 > cfg.cmd_history_num)
417 break;
418
419 cmd_pos++;
420
421 if(cmd_pos > cfg.cmd_history_num)
422 cmd_pos = 0;
423
424 werase(status_bar);
425 mvwaddch(status_bar, 0, 0, ':');
426 mvwaddstr(status_bar, 0, 1, cfg.cmd_history[cmd_pos]);
427 pos = strlen(cfg.cmd_history[cmd_pos]) + 1;
428 line_read = (char *)realloc(line_read,
429 strlen(cfg.cmd_history[cmd_pos]) + 1);
430 strcpy(line_read, cfg.cmd_history[cmd_pos]);
431 index = strlen(line_read);
432
433 if (cmd_pos >= cfg.cmd_history_len - 1)
434 cmd_pos = cfg.cmd_history_len - 1;
435 }
436 else if (type == GET_SEARCH_PATTERN)
437 {
438 if (0 > cfg.search_history_num)
439 break;
440
441 cmd_pos++;
442
443 if(cmd_pos > cfg.search_history_num)
444 cmd_pos = 0;
445
446 werase(status_bar);
447 mvwaddch(status_bar, 0, 0, '/');
448 mvwaddstr(status_bar, 0, 1, cfg.search_history[cmd_pos]);
449 pos = strlen(cfg.search_history[cmd_pos]) + 1;
450 line_read = (char *)realloc(line_read,
451 strlen(cfg.search_history[cmd_pos]) + 1);
452 strcpy(line_read, cfg.search_history[cmd_pos]);
453 index = strlen(line_read);
454
455 if (cmd_pos >= cfg.search_history_len - 1)
456 cmd_pos = cfg.search_history_len - 1;
457 }
458 }
459 break;
460 case KEY_DOWN:
461 {
462 if(type == GET_COMMAND)
463 {
464 if (0 > cfg.cmd_history_num)
465 break;
466
467 cmd_pos--;
468
469 if (cmd_pos < 0)
470 cmd_pos = cfg.cmd_history_num;
471
472 werase(status_bar);
473 mvwaddch(status_bar, 0, 0, ':');
474 mvwaddstr(status_bar, 0, 1, cfg.cmd_history[cmd_pos]);
475 pos = strlen(cfg.cmd_history[cmd_pos]) + 1;
476
477 line_read = (char *)realloc(line_read,
478 strlen(cfg.cmd_history[cmd_pos]) + 1);
479 strcpy(line_read, cfg.cmd_history[cmd_pos]);
480 index = strlen(line_read);
481
482 }
483 else if (type == GET_SEARCH_PATTERN)
484 {
485 if (0 > cfg.search_history_num)
486 break;
487
488 cmd_pos--;
489
490 if (cmd_pos < 0)
491 cmd_pos = cfg.search_history_num;
492
493 werase(status_bar);
494 mvwaddch(status_bar, 0, 0, '/');
495 mvwaddstr(status_bar, 0, 1, cfg.search_history[cmd_pos]);
496 pos = strlen(cfg.search_history[cmd_pos]) + 1;
497
498 line_read = (char *)realloc(line_read,
499 strlen(cfg.search_history[cmd_pos]) + 1);
500 strcpy(line_read, cfg.search_history[cmd_pos]);
501 index = strlen(line_read);
502
503 }
504 }
505 break;
506 /* This needs to be changed to a value that is read from
507 * the termcap file.
508 */
509 case 127: /* ascii Delete */
510 case 8: /* ascii Backspace ascii Ctrl H */
511 case KEY_BACKSPACE: /* ncurses BACKSPACE KEY */
512 {
513 pos--;
514 index--;
515 len--;
516 if (type == GET_VISUAL_COMMAND)
517 {
518 if (pos < 6)
519 pos = 6;
520 if (index < 0)
521 index = 0;
522 }
523 else
524 {
525 if (pos < 1)
526 pos = 1;
527 if (index < 0)
528 index = 0;
529 }
530 mvwdelch(status_bar, 0, pos);
531 if (line_read)
532 line_read[index] = '\0';
533 }
534 break;
535 default:
536 if (key > 31 && key < 127)
537 {
538 line_read = (char *)realloc(line_read, (index + 2) * (sizeof(char)));
539
540 if (line_read == NULL)
541 return NULL;
542
543 mvwaddch(status_bar, 0, pos, key);
544 line_read[index] = key;
545 index++;
546 line_read[index] = '\0';
547 if (index > 62)
548 {
549 abort = 1;
550 done = 1;
551 }
552 pos++;
553 len++;
554 }
555 break;
556 }
557 curr_stats.getting_input = 0;
558 }
559 curs_set(0);
560 werase(status_bar);
561 wnoutrefresh(status_bar);
562
563 if (abort)
564 return NULL;
565
566 /*
567 if (line_read && * line_read)
568 add_to_command_history(type, line_read);
569 */
570
571 return line_read;
572 }
573
File src/rline.h added (mode: 100644) (index 0000000..6a572bc)
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 __RLINE_H__
20 #define __RLINE_H__
21
22 char * my_rl_gets(int type);
23 #endif
File src/search.c added (mode: 100644) (index 0000000..7f762e2)
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 #include<sys/types.h>
23
24 #include<curses.h>
25 #include<regex.h>
26
27 #include"filelist.h"
28 #include"keys.h"
29 #include"ui.h"
30
31 enum
32 {
33 PREVIOUS,
34 NEXT
35 };
36
37 static int
38 find_next_pattern_match(FileView *view, int start, int direction)
39 {
40 int found = 0;
41 int x;
42
43 if(direction == PREVIOUS)
44 {
45 for(x = start -1; x > 0; x--)
46 {
47 if(view->dir_entry[x].selected)
48 {
49 found = 1;
50 view->list_pos = x;
51 break;
52 }
53 }
54 }
55 else if(direction == NEXT)
56 {
57 for(x = start +1; x < view->list_rows; x++)
58 {
59 if(view->dir_entry[x].selected)
60 {
61 found = 1;
62 view->list_pos = x;
63 break;
64 }
65 }
66 }
67 return found;
68 }
69
70 void
71 find_previous_pattern(FileView *view)
72 {
73 if(find_next_pattern_match(view, view->list_pos, PREVIOUS))
74 moveto_list_pos(view, view->list_pos);
75 else if(find_next_pattern_match(view, view->list_rows, PREVIOUS))
76 moveto_list_pos(view, view->list_pos);
77
78 }
79
80 void
81 find_next_pattern(FileView *view)
82 {
83 if(find_next_pattern_match(view, view->list_pos, NEXT))
84 moveto_list_pos(view, view->list_pos);
85 else if(find_next_pattern_match(view, 0, NEXT))
86 moveto_list_pos(view, view->list_pos);
87 }
88
89 int
90 find_pattern(FileView *view, char *pattern)
91 {
92 int found = 0;
93 regex_t re;
94 int x;
95 int first_match = 0;
96 int first_match_pos = 0;
97
98 view->selected_files = 0;
99
100 for(x = 0; x < view->list_rows; x++)
101 {
102 if(regcomp(&re, pattern, REG_EXTENDED) == 0)
103 {
104 if(regexec(&re, view->dir_entry[x].name, 0, NULL, 0) == 0)
105 {
106 if(!first_match)
107 {
108 first_match++;
109 first_match_pos = x;
110 }
111 view->dir_entry[x].selected = 1;
112 view->selected_files++;
113 found++;
114 }
115 else
116 view->dir_entry[x].selected = 0;
117 }
118 regfree(&re);
119 }
120
121
122 /* Need to redraw the list so that the matching files are highlighted */
123 draw_dir_list(view, view->top_line, view->curr_line);
124
125 if(found)
126 {
127 draw_dir_list(view, view->top_line, view->curr_line);
128 moveto_list_pos(view, first_match_pos);
129 return 0;
130 }
131 else
132 {
133 char buf[48];
134 moveto_list_pos(view, view->list_pos);
135 snprintf(buf, sizeof(buf), "No matching files for %s", view->regexp);
136 status_bar_message(buf);
137 return 1;
138 }
139 }
140
141
File src/search.h added (mode: 100644) (index 0000000..2af4eb9)
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 int find_pattern(FileView *view, char *pattern);
22 void find_next_pattern(FileView *view);
23 void find_previous_pattern(FileView *view);
File src/signals.c added (mode: 100644) (index 0000000..b46aa37)
1 /* vifm
2 * Copyright (C) 2001 Ken Steen.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17 */
18
19 #define _WIN32_WINNT 0x0500
20 #include<windows.h>
21
22 #include "menus.h"
23
24
25 void
26 check_messages()
27 {
28 MSG msg;
29 HWND console_win = GetConsoleWindow();
30
31
32 if(console_win == NULL)
33 show_error_msg("Console win", "console window handle error ");
34
35 while(PeekMessage(&msg, console_win, 0, 0, PM_NOREMOVE))
36 {
37 switch(msg.message)
38 {
39 case WM_SIZE:
40 show_error_msg("size changed", "size changed");
41 break;
42 case WM_CLOSE:
43 show_error_msg("close", "close");
44 break;
45 case WM_DESTROY:
46 show_error_msg("destroy", "destroy");
47 break;
48 default:
49 show_error_msg("error", "message received ");
50 return;
51 }
52 }
53
54 }
File src/signals.h added (mode: 100644) (index 0000000..26b5010)
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 void check_messages();
File src/sort.c added (mode: 100644) (index 0000000..0f2ebe5)
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> /* strrchr */
21 #include<windows.h>
22
23 #include "color_scheme.h"
24 #include "config.h"
25 #include "filelist.h"
26 #include "keys.h"
27 #include "status.h"
28 #include "ui.h"
29
30 /*
31 * This function is from the git program written by Tudor Hulubei and
32 * Andrei Pitis
33 */
34 int
35 sort_dir_list(const void *one, const void *two)
36 {
37 int retval;
38 char *pfirst, *psecond;
39 const dir_entry_t *first = (const dir_entry_t *) one;
40 const dir_entry_t *second = (const dir_entry_t *) two;
41 int first_is_dir = first->type == DIRECTORY;
42 int second_is_dir = second->type == DIRECTORY;
43
44 if(first_is_dir != second_is_dir)
45 return first_is_dir ? -1 : 1;
46 switch(curr_view->sort_type)
47 {
48 case SORT_BY_NAME:
49 break;
50
51 case SORT_BY_EXTENSION:
52 pfirst = strrchr(first->name, '.');
53 psecond = strrchr(second->name, '.');
54
55 if (pfirst && psecond)
56 {
57 retval = strcmp(++pfirst, ++psecond);
58 if (retval != 0)
59 return retval;
60 }
61 else
62 if (pfirst || psecond)
63 return (pfirst ? -1 : 1);
64 break;
65
66 case SORT_BY_SIZE:
67 if (first->size == second->size)
68 break;
69 return first->size - second->size;
70
71 case SORT_BY_TIME_MODIFIED:
72 if (first->mtime == second->mtime)
73 break;
74 return first->mtime - second->mtime;
75
76 case SORT_BY_TIME_ACCESSED:
77 if (first->atime == second->atime)
78 break;
79 return first->atime - second->atime;
80
81 case SORT_BY_TIME_CHANGED:
82 if (first->ctime == second->ctime)
83 break;
84 return first->ctime - second->ctime;
85
86 default:
87 break;
88 }
89
90 return strcmp(first->name, second->name);
91 }
92
93 static void
94 reset_sort_menu(void)
95 {
96 curs_set(0);
97 werase(sort_win);
98 update_all_windows();
99 if(curr_stats.need_redraw)
100 redraw_window();
101 }
102
103 static void
104 sort_key_cb(FileView *view)
105 {
106 int done = 0;
107 int abort = 0;
108 int top = 2;
109 int bottom = 12;
110 int curr = view->sort_type + 2;
111 int col = 6;
112 char filename[PATH_MAX];
113
114 snprintf(filename, sizeof(filename), "%s",
115 view->dir_entry[view->list_pos].name);
116
117 curs_set(0);
118 wmove(sort_win, curr, col);
119 wrefresh(sort_win);
120
121 while(!done)
122 {
123 int key = wgetch(sort_win);
124
125 switch(key)
126 {
127 case 'j':
128 {
129 mvwaddch(sort_win, curr, col, ' ');
130 curr++;
131 if(curr > bottom)
132 curr--;
133
134 mvwaddch(sort_win, curr, col, '*');
135 wmove(sort_win, curr, col);
136 wrefresh(sort_win);
137 }
138 break;
139 case 'k':
140 {
141
142 mvwaddch(sort_win, curr, col, ' ');
143 curr--;
144 if(curr < top)
145 curr++;
146
147 mvwaddch(sort_win, curr, col, '*');
148 wmove(sort_win, curr, col);
149 wrefresh(sort_win);
150 }
151 break;
152 case 3: /* ascii Ctrl C */
153 case 27: /* ascii Escape */
154 done = 1;
155 abort = 1;
156 break;
157 case 'l':
158 case 13: /* ascii Return */
159 view->sort_type = curr - 2;
160 done = 1;
161 break;
162 default:
163 break;
164 }
165 }
166
167 if(abort)
168 {
169 reset_sort_menu();
170 moveto_list_pos(view, find_file_pos_in_list(view, filename));
171 return;
172 }
173
174 reset_sort_menu();
175 load_dir_list(view, 1);
176 moveto_list_pos(view, find_file_pos_in_list(view, filename));
177 }
178
179
180 void
181 show_sort_menu(FileView *view)
182 {
183 int x, y;
184
185 wattroff(view->win, COLOR_PAIR(CURR_LINE_COLOR) | A_BOLD);
186 mvwaddstr(view->win, view->curr_line, 0, " ");
187 curs_set(0);
188 update_all_windows();
189 //doupdate();
190 werase(sort_win);
191 box(sort_win, ACS_VLINE, ACS_HLINE);
192
193
194 getmaxyx(sort_win, y, x);
195 curs_set(1);
196 mvwaddstr(sort_win, 0, (x - 6)/2, " Sort ");
197 mvwaddstr(sort_win, 1, 2, " Sort files by:");
198 mvwaddstr(sort_win, 2, 4, " [ ] File Extenstion");
199 mvwaddstr(sort_win, 3, 4, " [ ] File Name");
200 mvwaddstr(sort_win, 4, 4, " [ ] Group ID");
201 mvwaddstr(sort_win, 5, 4, " [ ] Group Name");
202 mvwaddstr(sort_win, 6, 4, " [ ] Mode");
203 mvwaddstr(sort_win, 7, 4, " [ ] Owner ID");
204 mvwaddstr(sort_win, 8, 4, " [ ] Owner Name");
205 mvwaddstr(sort_win, 9, 4, " [ ] Size");
206 mvwaddstr(sort_win, 10, 4, " [ ] Time Accessed");
207 mvwaddstr(sort_win, 11, 4, " [ ] Time Changed");
208 mvwaddstr(sort_win, 12, 4, " [ ] Time Modified");
209 mvwaddch(sort_win, view->sort_type + 2, 6, '*');
210 sort_key_cb(view);
211 }
212
213
File src/sort.h added (mode: 100644) (index 0000000..6b570fc)
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 show_sort_menu(FileView *view);
22 int sort_dir_list(const void *one, const void *tow);
File src/status.h added (mode: 100644) (index 0000000..8a7004d)
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 <sys/stat.h>
21
22 typedef struct
23 {
24 int num_yanked_files;
25 char yanked_files_dir[PATH_MAX];
26 char **yanked_files;
27 int need_redraw;
28 volatile int freeze;
29 volatile int getting_input;
30 volatile int menu;
31 int redraw_menu;
32 int is_updir;
33 int last_char;
34 char updir_file[PATH_MAX];
35 int is_console;
36 time_t config_file_mtime;
37 int search;
38 int save_msg;
39 int use_register;
40 int curr_register;
41 int register_saved;
42 int number_of_windows;
43 int view;
44 int show_full;
45 }Status;
46
47 extern Status curr_stats;
File src/ui.c added (mode: 100644) (index 0000000..957e7cc)
1 /* vifm
2 * Copyright (C) 2001 Ken Steen.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17 */
18
19 #define _WIN32_WINNT 0x0500
20 #include<signal.h> /* signal() */
21 #include<stdlib.h> /* malloc */
22 #include<sys/stat.h> /* stat */
23 //#include<dirent.h> /* DIR */
24 //#include<pwd.h> /* getpwent() */
25 #include<string.h>
26 #include<time.h>
27 #include<windows.h>
28 //#include<termios.h> /* struct winsize */
29 //#include<sys/ioctl.h>
30
31 #include "color_scheme.h"
32 #include "config.h" /* for menu colors */
33 #include "file_info.h"
34 #include "filelist.h"
35 #include "keys.h"
36 #include "menus.h"
37 #include "status.h"
38 #include "ui.h"
39 #include "utils.h"
40
41 static void
42 finish(char *message)
43 {
44 endwin();
45 write_config_file();
46 system("clear");
47 printf("%s", message);
48 exit(0);
49 }
50
51 void
52 update_pos_window(FileView *view)
53 {
54 char buf[13];
55
56 if(curr_stats.freeze)
57 return;
58 werase(pos_win);
59 snprintf(buf, sizeof(buf), "%d-%d ", view->list_pos +1, view->list_rows);
60 mvwaddstr(pos_win, 0, 13 - strlen(buf), buf);
61 wnoutrefresh(pos_win);
62 }
63
64 void
65 write_stat_win(char *message)
66 {
67 werase(stat_win);
68 wprintw(stat_win, "%s", message);
69 wnoutrefresh(stat_win);
70 }
71
72 void
73 update_stat_window(FileView *view)
74 {
75 char name_buf[20];
76 // char perm_buf[26];
77 char size_buf[56];
78 // char uid_buf[26];
79 //struct passwd *pwd_buf;
80 int x, y;
81
82 getmaxyx(stat_win, y, x);
83 snprintf(name_buf, sizeof(name_buf), "%s", get_current_file_name(view));
84 describe_file_size(size_buf, sizeof(size_buf), view);
85
86 /*
87 if((pwd_buf = getpwuid(view->dir_entry[view->list_pos].uid)) == NULL)
88 {
89 snprintf (uid_buf, sizeof(uid_buf), " %d",
90 (int) view->dir_entry[view->list_pos].uid);
91 }
92 else
93 {
94 snprintf(uid_buf, sizeof(uid_buf), " %s", pwd_buf->pw_name);
95 }
96 get_perm_string(perm_buf, sizeof(perm_buf),
97 view->dir_entry[view->list_pos].mode);
98 */
99 werase(stat_win);
100
101 mvwaddstr(stat_win, 0, 2, name_buf);
102 mvwaddstr(stat_win, 0, 20, size_buf);
103 // mvwaddstr(stat_win, 0, 36, perm_buf);
104 // mvwaddstr(stat_win, 0, 46, uid_buf);
105 snprintf(name_buf, sizeof(name_buf), "%d %s filtered",
106 view->filtered, view->filtered == 1 ? "file" : "files");
107
108
109 if(view->filtered > 0)
110 mvwaddstr(stat_win, 0, x - (strlen(name_buf) +2) , name_buf);
111
112 wnoutrefresh(stat_win);
113 update_pos_window(view);
114 }
115
116 void
117 status_bar_message(char *message)
118 {
119 werase(status_bar);
120 wprintw(status_bar, "%s", message);
121 wnoutrefresh(status_bar);
122 }
123
124
125 int
126 setup_ncurses_interface()
127 {
128 int screen_x, screen_y;
129 int i, x, y;
130
131 initscr();
132 noecho();
133 nonl();
134 raw();
135
136 getmaxyx(stdscr, screen_y, screen_x);
137 /* screen is too small to be useful*/
138 if(screen_y < 10)
139 finish("Terminal is too small to run vifm\n");
140 if(screen_x < 30)
141 finish("Terminal is too small to run vifm\n");
142
143 if(! has_colors())
144 finish("Vifm requires a console that can support color.\n");
145
146 start_color();
147
148 x = 0;
149
150 for (i = 0; i < cfg.color_scheme_num; i++)
151 {
152 for(x = 0; x < 12; x++)
153 init_pair(col_schemes[i].color[x].name,
154 col_schemes[i].color[x].fg, col_schemes[i].color[x].bg);
155 }
156
157 werase(stdscr);
158
159 menu_win = newwin(screen_y - 1, screen_x , 0, 0);
160 wbkgdset(menu_win, COLOR_PAIR(WIN_COLOR));
161 werase(menu_win);
162
163 sort_win = newwin(14, 30, (screen_y -12)/2, (screen_x -30)/2);
164 wbkgdset(sort_win, COLOR_PAIR(WIN_COLOR));
165 werase(sort_win);
166
167 change_win = newwin(20, 30, (screen_y -20)/2, (screen_x -30)/2);
168 wbkgdset(change_win, COLOR_PAIR(WIN_COLOR));
169 werase(change_win);
170
171 error_win = newwin(10, screen_x -2, (screen_y -10)/2, 1);
172 wbkgdset(error_win, COLOR_PAIR(WIN_COLOR));
173 werase(error_win);
174
175 lborder = newwin(screen_y - 2, 1, 0, 0);
176
177 wbkgdset(lborder, COLOR_PAIR(BORDER_COLOR));
178
179 werase(lborder);
180
181 if (curr_stats.number_of_windows == 1)
182 lwin.title = newwin(0, screen_x -2, 0, 1);
183 else
184 lwin.title = newwin(0, screen_x/2 -1, 0, 1);
185
186 wattrset(lwin.title, A_BOLD);
187 wbkgdset(lwin.title, COLOR_PAIR(BORDER_COLOR));
188
189 werase(lwin.title);
190
191 if (curr_stats.number_of_windows == 1)
192 lwin.win = newwin(screen_y - 3, screen_x -2, 1, 1);
193 else
194 lwin.win = newwin(screen_y - 3, screen_x/2 -2, 1, 1);
195
196 keypad(lwin.win, TRUE);
197 wbkgdset(lwin.win, COLOR_PAIR(WIN_COLOR));
198 wattrset(lwin.win, A_BOLD);
199 wattron(lwin.win, A_BOLD);
200 werase(lwin.win);
201 getmaxyx(lwin.win, y, x);
202 lwin.window_rows = y -1;
203 lwin.window_width = x -1;
204
205 mborder = newwin(screen_y, 2, 0, screen_x/2 -1);
206
207 wbkgdset(mborder, COLOR_PAIR(BORDER_COLOR));
208
209 werase(mborder);
210
211 if (curr_stats.number_of_windows == 1)
212 rwin.title = newwin(0, screen_x -2 , 0, 1);
213 else
214 rwin.title = newwin(1, screen_x/2 -1 , 0, screen_x/2 +1);
215
216 wbkgdset(rwin.title, COLOR_PAIR(BORDER_COLOR));
217 wattrset(rwin.title, A_BOLD);
218 wattroff(rwin.title, A_BOLD);
219
220 werase(rwin.title);
221
222 if (curr_stats.number_of_windows == 1)
223 rwin.win = newwin(screen_y - 3, screen_x -2 , 1, 1);
224 else
225 rwin.win = newwin(screen_y - 3, screen_x/2 -2 , 1, screen_x/2 +1);
226
227 keypad(rwin.win, TRUE);
228 wattrset(rwin.win, A_BOLD);
229 wattron(rwin.win, A_BOLD);
230 wbkgdset(rwin.win, COLOR_PAIR(WIN_COLOR));
231 werase(rwin.win);
232 getmaxyx(rwin.win, y, x);
233 rwin.window_rows = y - 1;
234 rwin.window_width = x -1;
235
236 rborder = newwin(screen_y - 2, 1, 0, screen_x -1);
237
238 wbkgdset(rborder, COLOR_PAIR(BORDER_COLOR));
239
240 werase(rborder);
241
242 stat_win = newwin(1, screen_x, screen_y -2, 0);
243
244 wbkgdset(stat_win, COLOR_PAIR(BORDER_COLOR));
245
246 werase(stat_win);
247
248 status_bar = newwin(1, screen_x - 19, screen_y -1, 0);
249 keypad(status_bar, TRUE);
250 wattrset(status_bar, A_BOLD);
251 wattron(status_bar, A_BOLD);
252 wbkgdset(status_bar, COLOR_PAIR(STATUS_BAR_COLOR));
253 werase(status_bar);
254
255 pos_win = newwin(1, 13, screen_y - 1, screen_x -13);
256 wattrset(pos_win, A_BOLD);
257 wattron(pos_win, A_BOLD);
258 wbkgdset(pos_win, COLOR_PAIR(STATUS_BAR_COLOR));
259 werase(pos_win);
260
261 num_win = newwin(1, 6, screen_y - 1, screen_x -19);
262 wattrset(num_win, A_BOLD);
263 wattron(num_win, A_BOLD);
264 wbkgdset(num_win, COLOR_PAIR(STATUS_BAR_COLOR));
265 werase(num_win);
266
267
268 wnoutrefresh(lwin.title);
269 wnoutrefresh(lwin.win);
270 wnoutrefresh(rwin.win);
271 wnoutrefresh(rwin.title);
272 wnoutrefresh(stat_win);
273 wnoutrefresh(status_bar);
274 wnoutrefresh(pos_win);
275 wnoutrefresh(num_win);
276 wnoutrefresh(lborder);
277 wnoutrefresh(mborder);
278 wnoutrefresh(rborder);
279
280 return 1;
281 }
282
283 void
284 redraw_window(void)
285 {
286 int color_scheme = 0;
287
288 endwin();
289
290 resize_term(0, 0);
291
292
293 //setup_ncurses_interface();
294 color_scheme = check_directory_for_color_scheme(lwin.curr_dir);
295 wbkgdset(lwin.title, COLOR_PAIR(BORDER_COLOR + color_scheme));
296 wbkgdset(lwin.win, COLOR_PAIR(WIN_COLOR + color_scheme));
297
298 color_scheme = check_directory_for_color_scheme(rwin.curr_dir);
299 wbkgdset(rwin.title, COLOR_PAIR(BORDER_COLOR + color_scheme));
300 wbkgdset(rwin.win, COLOR_PAIR(WIN_COLOR + color_scheme));
301
302 curs_set(0);
303
304 doupdate();
305
306 load_dir_list(other_view, 0);
307 load_dir_list(curr_view, 0);
308
309 curr_stats.freeze = 0;
310 curr_stats.need_redraw = 0;
311
312 }
313
314
File src/ui.h added (mode: 100644) (index 0000000..f99ac6c)
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 __UI_H__
20 #define __UI_H__
21
22 #define VERSION 0.4
23
24 #include<limits.h> /* PATH_MAX */
25 #include<curses.h>
26 #include<stdlib.h> /* off_t mode_t... */
27 #include<sys/types.h>
28 enum {
29 SORT_BY_EXTENSION,
30 SORT_BY_NAME,
31 SORT_BY_GROUP_ID,
32 SORT_BY_GROUP_NAME,
33 SORT_BY_MODE,
34 SORT_BY_OWNER_ID,
35 SORT_BY_OWNER_NAME,
36 SORT_BY_SIZE,
37 SORT_BY_TIME_ACCESSED,
38 SORT_BY_TIME_CHANGED,
39 SORT_BY_TIME_MODIFIED
40 };
41
42 typedef struct
43 {
44 char dir[PATH_MAX];
45 char file[PATH_MAX];
46 }history_t;
47
48
49 typedef struct
50 {
51 char *name;
52 int size;
53 //mode_t mode;
54 //uid_t uid;
55 //gid_t gid;
56 time_t mtime;
57 time_t atime;
58 time_t ctime;
59 char *owner;
60 char *group;
61 char date[16];
62 char type;
63 int selected;
64 char executable;
65 int list_num;
66 char ext[24];
67 }dir_entry_t;
68
69 typedef struct _FileView
70 {
71 WINDOW *win;
72 WINDOW *title;
73 char curr_dir[PATH_MAX];
74 time_t dir_mtime;
75 char last_dir[PATH_MAX];
76 char regexp[256]; /* regular expression pattern for / searching */
77 char * prev_filter;
78 char * filename_filter; /* regexp for filtering files in dir list */
79 char sort_type;
80 int hide_dot;
81 int prev_invert;
82 int history_num;
83 bool invert; /* whether to invert the filename pattern */
84 int curr_line; /* current line # of the window */
85 int top_line; /* # of the list position that is the top line in window */
86 int list_pos; /* actual position in the file list */
87 int list_rows; /* size of the file list */
88 int window_rows; /* number of rows shown in window */
89 int window_width;
90 int filtered; /* number of files filtered out and not shown in list */
91 int selected_files;
92 int color_scheme; /* current color scheme being used */
93 dir_entry_t *dir_entry;
94 history_t history[15];
95 char ** selected_filelist;
96 }FileView;
97
98
99 FileView lwin;
100 FileView rwin;
101 FileView *other_view;
102 FileView *curr_view;
103
104 WINDOW *status_bar;
105 WINDOW *stat_win;
106 WINDOW *pos_win;
107 WINDOW *num_win;
108 WINDOW *menu_win;
109 WINDOW *sort_win;
110 WINDOW *change_win;
111 WINDOW *error_win;
112 WINDOW *lborder;
113 WINDOW *mborder;
114 WINDOW *rborder;
115
116 int setup_ncurses_interface();
117 void status_bar_message(char *message);
118 void update_stat_window(FileView *view);
119 void redraw_window();
120 void write_stat_win(char *message);
121 void update_pos_window(FileView *view);
122 #endif
File src/utils.c added (mode: 100644) (index 0000000..08eab71)
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<stdio.h>
21 //#include<sys/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 "ui.h"
29 #include "status.h"
30
31
32 /* Checks for a NULL pointer before calling free() */
33 void
34 my_free(void *stuff)
35 {
36 if(stuff != NULL)
37 free(stuff);
38 }
39
40 int
41 is_dir(char *file)
42 {
43 struct stat statbuf;
44 stat(file, &statbuf);
45
46 if(S_ISDIR(statbuf.st_mode))
47 return 1;
48 else
49 return 0;
50 }
51
52 void *
53 duplicate (void *stuff, int size)
54 {
55 void *new_stuff = (void *) malloc (size);
56 memcpy (new_stuff, stuff, size);
57 return new_stuff;
58 }
59
60 /*
61 * Escape the filename for the purpose of inserting it into the shell.
62 */
63 char *
64 escape_filename(const char *string, int quote_percent)
65 {
66 char *ret, *dup;
67
68 dup = ret = (char *)malloc (strlen (string) * 2 + 2 + 1);
69
70 if (*string == '-')
71 {
72 *dup++ = '.';
73 *dup++ = '/';
74 }
75
76 for (; *string; string++, dup++)
77 {
78 switch (*string)
79 {
80 case '%':
81 if (quote_percent)
82 *dup++ = '%';
83 break;
84 case '\'':
85 case '\\':
86 case '\r':
87 case '\n':
88 case '\t':
89 case '"':
90 case ';':
91 case ' ':
92 case '?':
93 case '|':
94 case '[':
95 case ']':
96 case '{':
97 case '}':
98 case '<':
99 case '>':
100 case '`':
101 case '!':
102 case '$':
103 case '&':
104 case '*':
105 case '(':
106 case ')':
107 *dup++ = '\\';
108 break;
109 case '~':
110 case '#':
111 if (dup == ret)
112 *dup++ = '\\';
113 break;
114 }
115 *dup = *string;
116 }
117 *dup = '\0';
118 return ret;
119 }
120
121 void
122 chomp(char *text)
123 {
124 if(text[strlen(text) -1] == '\n')
125 text[strlen(text) -1] = '\0';
126 }
127
File src/utils.h added (mode: 100644) (index 0000000..7eb039a)
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 __UTILS_H__
20 #define __UTILS_H__
21
22 #include "ui.h"
23
24 void chomp(char *text);
25 void * duplicate(void *stuff, int size);
26 void my_free(void *);
27 int is_dir(char *file);
28 char * escape_filename(const char *string, int quote_percent);
29 #endif
File src/vifm-help.txt added (mode: 100644) (index 0000000..b889ee9)
1 The basic vi key bindings are used to move through the files and popup
2 windows.
3
4 k is up
5 j is down
6
7 h is updir
8 l is handle file and is the same as Return.
9
10 Ctrl-c or the Escape key will cancel most operations.
11 Ctrl-l will clear and redraw the screen.
12
13 gg top of list
14 G bottom of list
15 cw change word is used to rename a file.
16 m [a-z][A-Z][0-9] to set bookmark
17 ' letter to goto bookmark
18 v start or stop visualy selecting files. This works with the j and k keys
19 for movement. This is different then in vi in that v in visual mode will
20 leave the selected files highlighted. If you want to clear the selected
21 files Ctrl-c or Esc will unselect the files.
22 dd - the default setting is to move the selected files to the trash
23 directory.
24 yy - will yank the selected files.
25 p - will copy the yanked files to the current directory or move the files
26 to the current directory if they were deleted with dd or :d or if the
27 files were yanked 'yy' from the Trash directory.
28
29 Space or Tab to switch lists.
30
31 Most movement commands also accept a count 12j would move down 12 lines.
32 [count] % percent of file list
33 [count] j or k
34 [count] G or gg
35 [count] dd or yy the count is from the current file downward.
36 :[count] user command is not yet implemented.
37 :[count] command
38 The only builtin :[count] command is :[count]d[elete]. :3d would delete
39 three files starting at the current file position moving down.
40
41 :number - move to the line number :12 would move to the 12th line.
42 :0 move to the top of the list.
43 :$ move to the bottom of the list.
44
45 Return or l - handle file
46 Default file type program or if on a directory enter the directory
47
48 Ctrl-g toggles full file information window.
49 Ctrl-b - jump back one page.
50 Ctrl-f - jump forward one page.
51
52 /regular expression pattern - will highlight all files matching the pattern
53 in the current file list. /\.c$ would highlight all the .c files.
54 N find previous match.
55 n find next match.
56
57 Files can also be tagged or selected with 't'. Pressing 't' on a selected
58 file will unselect it. This can be used by itself to select files or with a
59 /search pattern or with visually selected files.
60
61 :commands
62 :com is a menu of user commands
63 :com name action - will set a new user command
64 Unlike vim user commands do not have to start with a capital letter.
65 User commands are run in a shell by default. To run a command in
66 the background you must set it as a background command with & at the end
67 of the commands action.
68 :com rm rm %f &
69
70 :com! name action - will overwrite a preciously set command.
71 :delc command_name will remove the command_name user command
72 :fil regular_expression pattern will filter the files out of the directory
73 listing that match the regular expression.
74 :fil \.o$ - would filter all files ending in .o from the filelist.
75 :empty will permanently remove 'rm -fr' files from the Trash directory.
76 :sh will start a shell
77 :q or :x will exit vifm
78 :! program will execute the program in a shell
79 :!command & will run the process in the background.
80 programs that write to stdout like ls will create an error message
81 showing partial output of the command.
82 :!! same as :! but will pause the screen before returning to vifm.
83 :!!ls -l
84 :e load file into vi
85 :pwd - show the present working directory
86 :ch[ange] - create a menu window to alter a files properties.
87 :cd - change directory
88 :cd ~/bin
89 :s[ort] - popup menu of different sorting methods
90 :sp[lit] - switch to a two window view.
91 :his[tory] - popup menu of directories visited
92 :view - toggle on and off the quick file view.
93 :h[elp] - this crude help file
94 :marks - popup menu of bookmarks
95 :screen toggles whether to use the screen program or not.
96 :sync - change the other panel to the current panel directory.
97
98 :copy - copy selected file or files to other directory - win32 only
99 :move - move selected file or files to other directory - win32 only
100 :volume - show mounted volumes - win32 only
101
102
103 command macros
104 %a user arguments
105 %f all of the selected files
106 %F all of the selected files in the other directory list.
107 %d current directory name
108 %D other file list directory name
109 :com mv mv %f %D
110 would set the mv command to mv all of the selected files to the other
111 directory.
112
113 If you want a command to accept arguments you must use %a.
114 :com mkdir mkdir %a &
115 :com mygrep vim "+grep %a"
116 %a is simply replaced with the user arguments and the arguments are
117 considered to be optional.
118 :com lsl ls -l %a | less - would run ls -l | less with or without
119 an argument being given.
120
121 search patterns can be set with :com name /pattern
122 :com backup /~$
123
124
125 file filters
126 The basic vim folding key bindings are used for filtering files.
127 zO show the filtered files
128 zM Filter the files matching the filename filter.
129 zo show all the dot files
130 zm filter all the .dot files
131 zf filter all the selected files
132 This will work with all selecting methods. Visually selecting files,
133 using a / search pattern or in combination with 't'.
134 :fil[ter] regular expression
135 :in[vert] invert the filter
136 All directorys will show the ../ file no matter what the filter setting is
137 with the exception of the / directory.
138 Each file list has its own filter.
139 filtered files are not checked in / search or :commands
140
141 file name filters can be set with :com name fil pattern
142 :com ofiles fil \.o$
143
144 Configuration.
145
146 The default configuration file is %APPDATA\Vifm\vifmrc
147 If you want to change any settings vifm must not be running when you edit
148 the file as it will overwrite any changes you make when it exits.
149
150
151 Misc.
152 Ctrl-c or Escape to clear all selected files
153
154 vifm.vim is a vim plugin that allows the use of vifm from vim. It is
155 included in the source tarball but it is not installed by default and must
156 be manually placed in either the default vim/plugin directory or in
157 ~/.vim/plugin/
158 To use vifm to load a file into a running vim use the following commands:
159 :Edit - open a file in the current buffer.
160 :Split - split the buffer and open a file.
161 :Vsplit - vertically split a buffer and open a file.
162 :Diff - open a file to compare to the current file using the vim :diff
163 command.
164 You can edit the vifm.vim script to change the command name used if they
165 conflict with other user commands.
166
167 Starting options:
168 /full/path/to/directoryone - using vifm /usr/local will start vifm
169 with the /usr/local directory. The default is to start vifm in
170 the current directory.
171 /full/path/to/directorytwo - using two full paths will start vifm with
172 the first path in the left file list and the second path in the right
173 file list.
174 --version - will print the version number and exit.
175 --help - will show help file.
176 -f - will run vifm but selecting a file will write the file name to
177 ~/.vifm/vimfiles instead of opening the file. This is used for the
178 vifm.vim script to load files from vifm into a running vim.
179
180 Menus
181 bookmarks escape or Ctrl-c to abort j and k to move through
182 dd on a bookmark to remove.
183
184 sort menu j and k to move - Escape or Ctrl-c to clear - return or l to
185 select and exit the menu.
186
187 Reserved :commands
188 !
189 change
190 cd
191 cmap
192 com
193 copy
194 d
195 delc
196 e
197 empty
198 fi
199 fil
200 file
201 filter
202 h
203 help
204 his
205 history
206 in
207 invert
208 map
209 marks
210 move
211 nmap
212 pw
213 pwd
214 q
215 s
216 screen
217 sh
218 sort
219 unmap
220 view
221 vifm
222 volume
223 vmap
224 x
225
File src/vifm.c added (mode: 100644) (index 0000000..bef1fef)
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 #define _WIN32_WINNT 0x0500
21
22 #include<curses.h>
23 #include<unistd.h> /* getcwd & sysconf */
24 #include<string.h> /* strncpy */
25 #include<sys/stat.h> /* stat */
26 #include<unistd.h> /* stat */
27 #include<locale.h> /* setlocale */
28
29 #include<windows.h>
30
31 #include"bookmarks.h"
32 #include"color_scheme.h"
33 #include"commands.h"
34 #include"config.h"
35 #include"filelist.h"
36 #include"filetype.h"
37 #include"keys.h"
38 #include"status.h"
39 #include"ui.h"
40 #include"utils.h"
41
42
43 Config cfg;
44 Status curr_stats;
45 Col_scheme col_schemes[8];
46
47 static void
48 show_help_msg(void)
49 {
50 system("clear");
51 printf("vifm usage:\n\n");
52 printf(" To start in a specific directory give the directory path.\n\n");
53 printf(" vifm /path/to/start/dir/one\n");
54 printf(" or\n");
55 printf(" vifm /path/to/start/dir/one /path/to/start/dir/two\n\n");
56 printf(" If no path is given vifm will start in the current working directory.\n\n");
57 printf(" vifm --version \n");
58 printf(" show version number and quit.\n\n");
59 printf(" vifm --help\n");
60 printf(" show this help message and quit.\n\n");
61
62 }
63
64 int
65 main(int argc, char *argv[])
66 {
67 char dir[PATH_MAX];
68 char config_dir[PATH_MAX];
69 char *console = NULL;
70 int x;
71 int rwin_args = 0;
72 int lwin_args = 0;
73 struct stat stat_buf;
74
75 setlocale(LC_ALL, "");
76 getcwd(dir, sizeof(dir));
77
78 SetConsoleTitle("Vifm");
79
80 /* Window initializations */
81 rwin.curr_line = 0;
82 rwin.top_line = 0;
83 rwin.list_rows = 0;
84 rwin.list_pos = 0;
85 rwin.selected_filelist = NULL;
86 rwin.history_num = 0;
87 rwin.invert = 0;
88 rwin.color_scheme = 0;
89
90 lwin.curr_line = 0;
91 lwin.top_line = 0;
92 lwin.list_rows = 0;
93 lwin.list_pos = 0;
94 lwin.selected_filelist = NULL;
95 lwin.history_num = 0;
96 lwin.invert = 0;
97 lwin.color_scheme = 0;
98
99 /* These need to be initialized before reading the configuration file */
100 cfg.command_num = 0;
101 cfg.filetypes_num = 0;
102 cfg.nmapped_num = 0;
103 cfg.vim_filter = 0;
104 cfg.show_one_window = 0;
105 command_list = NULL;
106 filetypes = NULL;
107
108 cfg.search_history_len = 15;
109 cfg.search_history_num = -1;
110 cfg.search_history = (char **)calloc(cfg.search_history_len, sizeof(char*));
111 cfg.cmd_history_len = 15;
112 cfg.cmd_history_num = -1;
113 cfg.cmd_history = (char **)calloc(cfg.cmd_history_len, sizeof(char *));
114 cfg.auto_execute = 0;
115 cfg.color_scheme_num = 0;
116 //col_schemes = (Col_scheme *)calloc(1, sizeof(Col_scheme*));
117 cfg.shell_cmd = strdup("cmd");
118
119 /* Maximum argument length to pass to the shell */
120 cfg.max_args = 4096; /* POSIX MINIMUM */
121
122
123 init_config();
124 set_config_dir();
125
126 read_config_file();
127
128 /* Misc configuration */
129
130 lwin.prev_invert = lwin.invert;
131 lwin.hide_dot = 1;
132 strncpy(lwin.regexp, "\\..~$", sizeof(lwin.regexp));
133 rwin.prev_invert = rwin.invert;
134 rwin.hide_dot = 1;
135 strncpy(rwin.regexp, "\\..~$", sizeof(rwin.regexp));
136 cfg.timer = 10;
137 curr_stats.yanked_files = NULL;
138 curr_stats.num_yanked_files = 0;
139 curr_stats.need_redraw = 0;
140 curr_stats.getting_input = 0;
141 curr_stats.menu = 0;
142 curr_stats.redraw_menu = 0;
143 curr_stats.is_updir = 0;
144 curr_stats.last_char = 0;
145 curr_stats.is_console = 0;
146 curr_stats.search = 0;
147 curr_stats.save_msg = 0;
148 curr_stats.use_register = 0;
149 curr_stats.curr_register = -1;
150 curr_stats.register_saved = 0;
151 curr_stats.show_full = 0;
152 curr_stats.view = 0;
153
154
155 if (cfg.show_one_window)
156 curr_stats.number_of_windows = 1;
157 else
158 curr_stats.number_of_windows = 2;
159
160 if(stat(config_dir, &stat_buf) == 0)
161 curr_stats.config_file_mtime = stat_buf.st_mtime;
162 else
163 curr_stats.config_file_mtime = 0;
164
165
166 /* Check if running in X */
167 console = getenv("DISPLAY");
168 if(!console || !*console)
169 curr_stats.is_console = 1;
170
171
172 /* Setup the ncurses interface. */
173 if(!setup_ncurses_interface())
174 return -1;
175
176 /* Load the initial directory */
177 snprintf(rwin.curr_dir, sizeof(rwin.curr_dir), "%s", dir);
178 snprintf(lwin.curr_dir, sizeof(lwin.curr_dir), "%s", dir);
179 rwin.dir_entry = (dir_entry_t *)malloc(sizeof(dir_entry_t));
180 lwin.dir_entry = (dir_entry_t *)malloc(sizeof(dir_entry_t));
181 rwin.dir_entry[0].name = malloc(sizeof("../") +1);
182 lwin.dir_entry[0].name = malloc(sizeof("../") +1);
183 strcpy(rwin.dir_entry[0].name, "../");
184 strcpy(lwin.dir_entry[0].name, "../");
185 change_directory(&rwin, dir);
186 change_directory(&lwin, dir);
187 other_view = &lwin;
188 curr_view = &rwin;
189
190 /* Get Command Line Arguments */
191 for(x = 1; x < argc; x++)
192 {
193 if(argv[x] != NULL)
194 {
195 if(!strcmp(argv[x], "-f"))
196 {
197 cfg.vim_filter = 1;
198 }
199 else if(!strcmp(argv[x], "--version"))
200 {
201 endwin();
202 system("clear");
203 printf("vifm %.1f\n\n", VERSION);
204 exit(0);
205 }
206 else if(!strcmp(argv[x], "--help"))
207 {
208 endwin();
209 show_help_msg();
210 exit(0);
211 }
212 else if(is_dir(argv[x]))
213 {
214 if(lwin_args)
215 {
216 snprintf(rwin.curr_dir, sizeof(rwin.curr_dir),
217 "%s", argv[x]);
218
219 rwin_args++;
220
221 }
222 else
223 {
224 snprintf(lwin.curr_dir, sizeof(lwin.curr_dir),
225 "%s", argv[x]);
226
227
228 lwin_args++;
229 }
230 }
231 else
232 {
233 endwin();
234 show_help_msg();
235 exit(0);
236 }
237 }
238 }
239
240
241 load_dir_list(&rwin, 0);
242
243 if (rwin_args)
244 {
245 change_directory(&rwin, rwin.curr_dir);
246 load_dir_list(&rwin, 0);
247 }
248
249 mvwaddstr(rwin.win, rwin.curr_line, 0, "*");
250 wrefresh(rwin.win);
251
252 /* This is needed for the sort_dir_list() which uses curr_view */
253 switch_views();
254
255 load_dir_list(&lwin, 0);
256
257 if (lwin_args)
258 {
259 change_directory(&lwin, lwin.curr_dir);
260 load_dir_list(&lwin, 0);
261 }
262
263 moveto_list_pos(&lwin, 0);
264 update_all_windows();
265
266 werase(status_bar);
267 wnoutrefresh(status_bar);
268
269
270 if(cfg.vim_filter)
271 curr_stats.number_of_windows = 1;
272
273
274 /* Enter the main loop. */
275 main_key_press_cb(curr_view);
276
277 return 0;
278 }
279
File src/vifm.txt added (mode: 100644) (index 0000000..1ce64e9)
1 *vifm.txt*
2
3
4 |Filters| Using the file filters.
5 |Commands| How to use and set :commands.
6 |Configure| Configuration of vifm.
7 |Marks| Bookmarking of files.
8 |Movement| How to move around.
9 |Normal| Normal mode keys.
10 |Options| Command line arguments.
11 |Plugin| Using the vifm.vim plugin.
12 |Reserved| List of reserved commands.
13 |Vifm_Ranges| How to use ranges in vifm.
14
15 --------------------------------------------------------------------------------
16 *Commands*
17
18 Commands are set with :com command_name command_action<Return>
19 :com! command_name command_action - will overwrite a previously set command.
20 :delc[ommand] command_name - will remove the command.
21
22 Commands are executed with :command_name<Return>
23 Command names do not have to start with a capital letter.
24 Trying to use a reserved command name will result in an error msg.
25 See |Reserved| for a list of reserved command names.
26
27 :com<Return> creates a menu of user commands.
28
29 The builtin commands are:
30
31 :!program - shellout and execute program.
32 :!!program - same as :! but will pause before returning.
33 This will be changed for compatibility with vim.
34 :!! - repeat the last command.
35 :!!program - will pause before returning.
36 :apropos manpage - will create a menu of items returned by the apropos
37 command. Selecting an item in the menu will open the corresponding
38 manpage.
39 :ch[ange] - create a menu window to alter a files properties.
40 :cd - change to your home directory.
41 :cd /usr/local - change directory to /usr/local.
42 :[range]d[elete][count] - delete selected file or files.
43 See |Vifm_Ranges| for the ranges implemented.
44 :delc[ommand] user_command - remove user_command.
45 :e[dit} - will load the selected file or files into vi.
46 :em[pty] - permanently remove files from the ~/.vifm/Trash directory.
47 :f[ilter] regular_expression - will filter files matching the pattern out of
48 the directory. See |Filters|
49 :file - popup menu of programs set for the file type of the current file.
50 :h[elp] - show this help file.
51 :h argument - is the same as using ':h argument' in vim.
52 :his[tory] - show directory history.
53 :invert - invert file name filter.
54 :jobs - shows menu of current backgrounded processes.
55 :locate filename - uses the locate command to create a menu of filenames
56 Selecting a file from the menu will reload the current file list in vifm
57 to show the selected file.
58 :marks - menu of bookmarks.
59 :o[nly] - switch to a one window view.
60 :pwd - show the present working directory.
61 :q[uit] or :x - will exit vifm.
62 :sh[ell] - will start a shell.
63 :sc[reen] - toggles whether to use the screen program or not.
64 :s[ort] - menu of different sorting methods.
65 :sp[lit] - switch to a two window view.
66 :sy[nc] - change the other panel to the current panels directory.
67 :vi[ew] - toggle on and off the quick file view.
68 :x - exit vifm.
69
70 command macros:
71 %a user arguments.
72 %f all of the selected files.
73 %F all of the selected files in the other directory list.
74 %d current directory name.
75 %D other file list directory name.
76
77 The command macros may be used in user commands.
78 :com move mv %f %D - would set the :move command to move all of the files
79 selected in the current directory to the other directory.
80
81 The %a macro will substitute any arguments given in a command into the
82 command. All arguments are considered optional.
83 :com lsl !!ls -l %a - will set the lsl command to execute ls -l with or
84 without an argument.
85
86 :lsl<Return> will list the directory contents of the current directory.
87 :lsl filename<Return> will list only the given filename.
88
89 The macros can also be used in directly executing commands.
90 :!mv %f %D - would move the current directory selected files to the other
91 directory.
92
93 Appending & to the end of a command will cause it to be executed in the
94 background.
95
96 :!mv %f %D &
97
98 --------------------------------------------------------------------------------
99 *Filters*
100
101 There are two basic file filters. One for dot files and one for file names.
102
103 The basic vim folding key-bindings are used for filters.
104 za - toggles the showing and hiding of dot files.
105 zo - show the dot files.
106 zf - add the selected files to the file name filter.
107 zm - hide the dot files.
108 zO - show the hidden file name files.
109 zM - restore all filters.
110 zR - remove all filters.
111
112
113 --------------------------------------------------------------------------------
114 *Marks*
115
116 :marks - will create a menu of the current marks.
117 m[letter] will set a mark at the current cursor position.
118 '[letter] will move to a mark.
119
120 --------------------------------------------------------------------------------
121 *Movement*
122
123 k is up
124 j is down
125
126 h is up directory
127 l is handle file and is the same as Return
128
129 gg will move to the first line of the file list.
130
131 G will move to the last line in the file list.
132
133 Space or Tab to switch file lists.
134
135 Most movement commands also accept a count 12j would move down 12 files.
136 [count]% move to percent of the file list.
137 [count]j move down count files.
138 [count]k move up count files.
139 [count]G or gg move to list position count.
140
141 --------------------------------------------------------------------------------
142 *Normal*
143
144 /regular expression. - select files matching regular expression.
145 H - move to the first file in the window.
146 L - move to the last file in the window.
147 M - move to the file in the middle of the window.
148 N - previous file matching last search pattern.
149 cw - change word is used to rename a file.
150 dd - move selected file or files to ~/.vifm/Trash
151 yy, Y - yank selected files.
152 p - put last selected files.
153 n - next file matching last search pattern.
154 s - open a shell - this is temporary and will be removed.
155 t - select or unselect a file.
156 v, V - start visual selection of files.
157
158 --------------------------------------------------------------------------------
159 *Options*
160
161 The vifm executable will start vifm in the current directory unless it is
162 given a different directory on the command line.
163
164 vifm /path/to/directory/one
165 or
166 vifm /path/to/directory/one /path/to/directory/two
167
168 The only other command line arguments are:
169 -f - only used from the vifm.vim script. The selected files are written
170 to ~/.vifm/vimfiles and vifm exits.
171
172 --help - show a brief command summary and exit vifm.
173 --version - show the version number of vifm and exit.
174
175 --------------------------------------------------------------------------------
176 *Configure*
177
178 The ~/.vifm/vifmrc file contains all the configurable settings. It is
179 commented and you must edit it by hand to change the settings.
180
181 The :screen command toggles whether to use the screen program or not.
182
183 The default configuration has the screen option turned off. The screen
184 program uses pseudo terminals to allow multiple windows to be used in
185 the console or in a single xterm. Starting vifm from screen with the
186 screen option turned on will cause vifm to open a new screen window for
187 each new file edited or program launched from vifm.
188
189 This requires screen version 3.9.9 or newer for the screen -X argument.
190
191
192 --------------------------------------------------------------------------------
193 *Plugin* Plugin for using vifm in vim as a file selector.
194
195 Commands:
196
197 :EditVifm select a file to open in the current buffer.
198 :SplitVifm split buffer and select a file to open.
199 :VsplitVifm vertically split buffer and select a file to open.
200 :DiffVifm select a file to compare to the current file with :vert diffsplit.
201
202 The plugin does not have any settings.
203
204 To use the plugin copy the vifm.vim file to either the system wide vim/plugin
205 directory or into ~/.vim/plugin.
206
207 If you would prefer not to use the plugin and it is in the system wide plugin
208 directory add
209
210 let loaded_vifm=1
211
212 to your ~/.vimrc file.
213 --------------------------------------------------------------------------------
214 *Vifm_Ranges*
215
216 The ranges implemented include:
217 Numbers :2,3
218 % - the entire directory.
219 . - the current position in the filelist.
220 $ - the end of the filelist.
221 't - the mark position t.
222
223 :%delete would delete all files in the directory.
224 :2,4delete would delete the files in the list positions 2 through 4.
225 :.,$delete would delete the files from the current position to the end
226 of the filelist.
227 :3delete4 would delete the files in the list positions 3, 4, 5, 6.
228
229 If a backward range is given :4,2delete - an error message is given and
230 the operation is abandoned.
231
232 The only builtin command that accepts a range is :delete.
233
234
235 --------------------------------------------------------------------------------
236 *Reserved*
237
238 The following command names are reserved and cannot be used for user commands.
239
240 ! - shellout and execute command.
241 apropos - run the apropos command in a menu window.
242 cd - change directory
243 change - alter a files properties
244 cmap - not used will be used for key mapping.
245 colorscheme - will be used to set a colorscheme for a directory.
246 command - show user commands.
247 delete - delete file.
248 delcommand - delete command.
249 edit - edit file.
250 empty - empty trash directory.
251 filter - set file name filter.
252 file - show filetypes menu.
253 find - not yet implemented.
254 help - show help file.
255 history - show directory history.
256 invert - invert file filter.
257 locate - run the locate command in a menu window.
258 map - not used will be used with key mapping.
259 marks - show marks.
260 nmap - not used will be used with key mapping.
261 noh -
262 pwd - show present working directory.
263 quit - exit vifm.
264 screen - toggles use of screen program.
265 shell - shellout.
266 sort - show sort menu.
267 unmap - not used will be used with key mapping.
268 view - toggle on and off the quick file view.
269 vifm - not used saved for possible menu.
270 vmap - not used will be used for key mapping.
271 x - exit vifm.
272
File src/vifm.vim added (mode: 100644) (index 0000000..ade6e7f)
1 " Vim plugin for running vifm from vim.
2
3 " Maintainer: Ken Steen <ksteen@users.sourceforge.net>
4 " Last Change: 2001 November 29
5
6 " vifm and vifm.vim can be found at http://vifm.sf.net
7
8 """"""""""""""""""""""""""""""""""""""""""""""""""""""""
9
10
11 if exists("loaded_vifm")
12 finish
13 endif
14 let loaded_vifm=1
15
16 "Setup commands to run vifm.
17
18 ":EditVifm - open file in current buffer.
19 ":SplitVifm - split buffer and open file.
20 ":VsplitVifm - vertically split buffer and open file.
21 ":DiffVifm - load file for :vert diffsplit.
22
23 " If the commands clash with your other user commands you can change the
24 " command name.
25
26 " if !exists(":Insert_Your_Command_Name_Here")
27 " command Insert_Your_Command_Name_Here :call s:StartVifm("edit ")
28
29 if !exists(':EditVifm')
30 command EditVifm :call s:StartVifm("edit ")
31 endif
32 if !exists(':VsplitVifm')
33 command VsplitVifm :call s:StartVifm("vs ")
34 endif
35 if !exists(':SplitVifm')
36 command SplitVifm :call s:StartVifm("split ")
37 endif
38 if !exists(':DiffVifm')
39 command DiffVifm :call s:StartVifm("diff ")
40 endif
41
42 function! s:StartVifm(editcmd)
43
44 "Gvim cannot handle ncurses so run vifm in an xterm.
45 if has("gui_running")
46 silent !xterm -e vifm -f
47 else
48 silent !vifm -f
49 endif
50
51 redraw!
52
53 "The selected files are written and read from a file instead of using
54 "vim's clientserver so that it will work in the console without a X server
55 "running.
56 "let s:r =system("cat ~/.vifm/vimfiles")
57 let [s:r; s:rest] =readfile("c:\Program\ Files\Vifm\vimfiles", 1)
58
59 "User exits vifm without selecting a file."
60 if s:r =~"NULL"
61 echohl WarningMsg | echo "No file selected" | echohl None
62 else
63 if a:editcmd =~"edit "
64 let s:cmd ="edit "
65 exe s:cmd . s:r
66 elseif a:editcmd =~"vs"
67 let s:cmd ="vsplit "
68 exe s:cmd . s:r
69 elseif a:editcmd =~"split"
70 let s:cmd ="split "
71 exe s:cmd . s:r
72 elseif a:editcmd =~"diff"
73 let s:cmd ="vert diffsplit "
74 exe s:cmd . s:r
75 endif
76 endif
77
78 endfunction
79
80
81
File src/vifmrc added (mode: 100644) (index 0000000..2cfd56c)
1 # You can edit this file by hand. If you have vifm running
2 # it will overwrite any changes you make when it quits.
3 # The # character at the beginning of a line comments out the line.
4 # Blank lines are ignored.
5 # The basic format for each item is shown with an example.
6 # The '=' character is used to separate fields within a single line.
7 # Most settings are true = 1 or false = 0.
8
9 # This is the actual command used to start vi. The default is vi.
10 # If you would like to use another vi clone such as Vim, Elvis, or Vile
11 # you will need to change this setting.
12
13 VI_COMMAND=vim
14 # VI_COMMAND=vi
15 # VI_COMMAND=elvis -G termcap
16 # VI_COMMAND=vile
17
18 # Trash Directory
19 # The default is to move files that are deleted with dd or :d to
20 # the trash directory. 1 means use the trash directory 0 means
21 # just use rm. If you change this you will not be able to move
22 # files by deleting them and then using p to put the file in the new location.
23 # I recommend not changing this until you are familiar with vifm.
24
25 USE_TRASH=1
26
27 # Screen configuration. If you would like to use vifm with
28 # the screen program set this to 1.
29
30 USE_SCREEN=0
31
32
33 # This is how many files to show in the directory history menu.
34
35 HISTORY_LENGTH=15
36
37
38 # The sort type is how the files will be sorted in the file listing.
39 # Sort by File Extension = 0
40 # Sort by File Name = 1
41 # Sort by Group ID = 2
42 # Sort by Group Name = 3
43 # Sort by Mode = 4
44 # Sort by Owner ID = 5
45 # Sort by Owner Name = 6
46 # Sort by Size = 7
47 # Sort by Time Accessed =8
48 # Sort by Time Changed =9
49 # Sort by Time Modified =10
50 # This can be set with the :sort command in vifm.
51
52 LEFT_WINDOW_SORT_TYPE=1
53
54 RIGHT_WINDOW_SORT_TYPE=1
55
56 # The regular expression used to filter files out of
57 # the directory listings.
58 # LWIN_FILTER=\.o$ and LWIN_INVERT=1 would filter out all
59 # of the .o files from the directory listing. LWIN_INVERT=0
60 # would show only the .o files
61
62 LWIN_FILTER=\.o$
63 LWIN_INVERT=1
64 RWIN_FILTER=\.o$
65 RWIN_INVERT=1
66
67 # Show the full file information in a window
68 # Ctrl G will toggle this value in vifm.
69 # 1 will show the file information in a window
70 # 0 will show the file information on the status bar.
71
72 SHOW_FULL=0
73
74 # If you installed the vim.txt help file change this to 1.
75 # If would rather use a plain text help file set this to 0.
76
77 USE_VIM_HELP=0
78
79 # If you would like to run an executable file when you
80 # press return on the file name set this to 1.
81
82 RUN_EXECUTABLE=0
83
84
85 # BOOKMARKS=mark=/full/directory/path=filename
86
87 BOOKMARKS=R=/=
88 BOOKMARKS=U=/usr=../
89 BOOKMARKS=L=/usr/local=../
90 BOOKMARKS=S=/usr/local/share=../
91
92 # COMMAND=command_name=action
93 # The following macros can be used in a command
94 # %a is replaced with the user arguments.
95 # %f the current selected file, or files.
96 # %F the current selected file, or files in the other directoy.
97 # %d the current directory name.
98 # %D the other window directory name.
99
100 COMMAND=mv=mv %f %D &
101 COMMAND=cp=cp %f %D &
102 COMMAND=floppy=mount /dev/fd0
103 COMMAND=run=!! ./%f
104 COMMAND=make=!!make
105 COMMAND=grep=vim \"+grep %a\"
106
107 # The file type is for the default programs to be used with
108 # a file extension.
109 # FILETYPE=description=extension1,extension2=defaultprogram, program2
110 # FILETYPE=Web=html,htm,shtml=links,mozilla,elvis
111 # would set links as the default program for .html .htm .shtml files
112 # The other programs for the file type can be accessed with the :file command
113 # The command macros %f, %F, %d, %F may be used in the commands.
114 # The %a macro is ignored. To use a % you must put %%.
115
116 FILETYPE=Web=html,htm=links,mozilla
117 FILETYPE=Object=o=nm %f | less
118 FILETYPE=Image=jpg,jpeg,png,gif=eog,xv,gimp
119 FILETYPE=Archive=tar.gz,tgz=tar -tzf %f | less,tar -zxvf %f
File src/visual.c added (mode: 100644) (index 0000000..c0a4694)
1 /* vifm
2 * Copyright (C) 2001 Ken Steen.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17 */
18
19 #include "commands.h"
20 #include "config.h"
21 #include "filelist.h"
22 #include "fileops.h"
23 #include "visual.h"
24 #include "status.h"
25 #include<string.h>
26
27 /* tbrown
28 move up one position in the window, adding
29 to the selection list */
30
31 void
32 select_up_one(FileView *view, int start_pos) {
33
34 view->list_pos--;
35 if(view->list_pos < 0)
36 {
37 if (start_pos == 0)
38 view->selected_files = 0;
39 view->list_pos = 0;
40 }
41 else if(view->list_pos == 0)
42 {
43 if(start_pos == 0)
44 {
45 view->dir_entry[view->list_pos +1].selected = 0;
46 view->selected_files = 0;
47 }
48 }
49 else if(view->list_pos < start_pos)
50 {
51 view->dir_entry[view->list_pos].selected = 1;
52 view->selected_files++;
53 }
54 else if(view->list_pos == start_pos)
55 {
56 view->dir_entry[view->list_pos].selected = 1;
57 view->dir_entry[view->list_pos +1].selected = 0;
58 view->selected_files = 1;
59 }
60 else
61 {
62 view->dir_entry[view->list_pos +1].selected = 0;
63 view->selected_files--;
64 }
65 }
66
67 /*tbrown
68 move down one position in the window, adding
69 to the selection list */
70
71 void
72 select_down_one(FileView *view, int start_pos) {
73
74 view->list_pos++;
75
76 if(view->list_pos >= view->list_rows)
77 ;
78 else if(view->list_pos == 0)
79 {
80 if (start_pos == 0)
81 view->selected_files = 0;
82 }
83 else if (view->list_pos == 1 && start_pos != 0)
84 {
85 return;
86 }
87 else if(view->list_pos > start_pos)
88 {
89 view->dir_entry[view->list_pos].selected = 1;
90 view->selected_files++;
91 }
92 else if(view->list_pos == start_pos)
93 {
94 view->dir_entry[view->list_pos].selected = 1;
95 view->dir_entry[view->list_pos -1].selected = 0;
96 view->selected_files = 1;
97 }
98 else
99 {
100 view->dir_entry[view->list_pos -1].selected = 0;
101 view->selected_files--;
102 }
103 }
104
105
106 int
107 visual_key_cb(FileView *view)
108 {
109 int done = 0;
110 int abort = 0;
111 int count = 0;
112 int start_pos = view->list_pos;
113 char buf[36];
114 int save_msg = 0;
115
116 while(!done)
117 {
118 int key;
119 curr_stats.getting_input = 1;
120 key = wgetch(view->win);
121 curr_stats.getting_input = 0;
122
123 switch(key)
124 {
125 case 13: /* ascii Return */
126 done = 1;
127 break;
128 case 27: /* ascii Escape */
129 case 3: /* ascii Ctrl C */
130 abort = 1;
131 break;
132 case ':':
133 {
134 get_command(view, GET_VISUAL_COMMAND, NULL);
135 /*abort = 1;*/
136 return 0;
137 }
138 break;
139 case 'd':
140 delete_file(view);
141 done = 1;
142 break;
143 case KEY_DOWN:
144 case 'j':
145 {
146 select_down_one(view, start_pos);
147 }
148 break;
149 case KEY_UP:
150 case 'k':
151 {
152 select_up_one(view, start_pos);
153 }
154 break;
155 case 'y':
156 {
157 get_all_selected_files(view);
158 yank_selected_files(view);
159 count = view->selected_files;
160 free_selected_file_array(view);
161 save_msg = 1;
162 }
163 abort = 1;
164 break;
165 case 'H':
166 while (view->list_pos>view->top_line) {
167 select_up_one(view,start_pos);
168 }
169 break;
170 /*tbrown move to middle of window, selecting from start position to there
171 */
172 case 'M':
173 /*window smaller than file list */
174 if (view->list_rows < view->window_rows)
175 {
176 /*in upper portion */
177 if (view->list_pos < view->list_rows/2)
178 {
179 while (view->list_pos < view->list_rows/2)
180 {
181 select_down_one(view,start_pos);
182 }
183 }
184 /* lower portion */
185 else if (view->list_pos > view->list_rows/2)
186 {
187 while (view->list_pos > view->list_rows/2)
188 {
189 select_up_one(view,start_pos);
190 }
191 }
192 }
193 /* window larger than file list */
194 else
195 {
196 /* top half */
197 if (view->list_pos < (view->top_line+view->window_rows/2))
198 {
199 while (view->list_pos < (view->top_line+view->window_rows/2))
200 {
201 select_down_one(view,start_pos);
202 }
203 }
204 /* bottom half */
205 else if (view->list_pos > (view->top_line+view->window_rows/2))
206 {
207 while (view->list_pos > (view->top_line+view->window_rows/2))
208 {
209 select_up_one(view,start_pos);
210 }
211 }
212 }
213 break;
214 /* tbrown move to last line of window, selecting as we go */
215 case 'L':
216 while (view->list_pos<(view->top_line + view->window_rows))
217 {
218 select_down_one(view,start_pos);
219 }
220 break;
221 /* tbrown select all files */
222 case 1: /* ascii Ctrl A */
223 moveto_list_pos(view,1);
224 while (view->list_pos < view->list_rows)
225 {
226 select_down_one(view,view->list_pos);
227 }
228 break;
229 /* tbrown */
230 case 2: /* ascii Ctrl B */
231 case KEY_PPAGE:
232 while (view->list_pos > (view->top_line - view->window_rows -1))
233 {
234 select_up_one(view,start_pos);
235 }
236 break;
237 /* tbrown */
238 case 'G':
239 while (view->list_pos < view->list_rows)
240 {
241 select_down_one(view,start_pos);
242 }
243 break;
244 /* tbrown */
245 case 6: /* ascii Ctrl F */
246 case KEY_NPAGE:
247 while (view->list_pos < (view->top_line+(2*view->window_rows)+1))
248 {
249 select_down_one(view,start_pos);
250 }
251 break;
252 default:
253 break;
254 }
255 if(abort)
256 {
257 int x;
258 if(view->selected_files)
259 {
260 for(x = 0; x < view->list_rows; x++)
261 view->dir_entry[x].selected = 0;
262
263 view->selected_files = 0;
264 }
265 done = 1;
266 }
267
268 draw_dir_list(view, view->top_line, view->list_pos);
269 moveto_list_pos(view, view->list_pos);
270 update_pos_window(view);
271
272 if(abort)
273 return 0;
274
275 if(count)
276 {
277 status_bar_message(buf);
278 save_msg = 1;
279 }
280 else
281 {
282 char status_buf[64] = "";
283 snprintf(status_buf, sizeof(status_buf), " %d %s Selected",
284 view->selected_files, view->selected_files == 1 ? "File" :
285 "Files");
286 status_bar_message(status_buf);
287 }
288
289 write_stat_win(" --VISUAL--");
290 }
291 return save_msg;
292 }
293
294 int
295 start_visual_mode(FileView *view)
296 {
297 int x;
298
299 for(x = 0; x < view->list_rows; x++)
300 view->dir_entry[x].selected = 0;
301
302 /* Don't allow the ../ dir to be selected */
303 if(strcmp(view->dir_entry[view->list_pos].name, "../"))
304 {
305 view->selected_files = 1;
306 view->dir_entry[view->list_pos].selected = 1;
307 }
308
309 draw_dir_list(view, view->top_line, view->list_pos);
310 moveto_list_pos(view, view->list_pos);
311
312 if(view->list_pos != 0)
313 status_bar_message(" 1 File Selected");
314 else
315 status_bar_message("");
316
317 write_stat_win(" --VISUAL--");
318 return visual_key_cb(view);
319 }
File src/visual.h added (mode: 100644) (index 0000000..89a67c8)
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 __VISUAL_MODE_H__
20 #define __VISUAL_MODE_H__
21
22 #include "ui.h"
23 #include "keys.h"
24
25 int start_visual_mode(FileView *view);
26
27 #endif
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm-w32

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm-w32

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master