1 /* Find file command for the Midnight Commander
2 Copyright (C) The Free Software Foundation
3 Written 1995 by Miguel de Icaza
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
37 /* Dialog manager and widgets */
42 #include "panel.h" /* current_panel */
43 #include "main.h" /* do_cd, try_to_select */
45 #include "cmd.h" /* view_file_at_line */
49 /* Size of the find parameters window */
51 static int FIND_X
= 50;
53 /* Size of the find window */
54 #define FIND2_Y (LINES - 4)
56 static int FIND2_X
= 64;
57 #define FIND2_X_USE (FIND2_X - 20)
59 /* A couple of extra messages we need */
74 /* List of directories to be ignored, separated by ':' */
75 char *find_ignore_dirs
= 0;
77 static WInput
*in_start
; /* Start path */
78 static WInput
*in_name
; /* Pattern to search */
79 static WInput
*in_with
; /* Text inside filename */
80 static WCheck
*case_sense
; /* "case sensitive" checkbox */
81 static WCheck
*find_regex_cbox
; /* [x] find regular expression */
83 static int running
= 0; /* nice flag */
84 static char *find_pattern
; /* Pattern to search */
85 static char *content_pattern
; /* pattern to search inside files; if
86 find_regex_flag is true, it contains the
87 regex pattern, else the search string. */
88 static int count
; /* Number of files displayed */
89 static int matches
; /* Number of matches */
90 static int is_start
; /* Status of the start/stop toggle button */
93 /* Where did we stop */
98 static Dlg_head
*find_dlg
; /* The dialog */
100 static WButton
*stop_button
; /* pointer to the stop button */
101 static WLabel
*status_label
; /* Finished, Searching etc. */
102 static WListbox
*find_list
; /* Listbox with the file list */
104 /* This keeps track of the directory stack */
105 typedef struct dir_stack
{
107 struct dir_stack
*prev
;
110 static dir_stack
*dir_stack_base
= 0;
114 int len
; /* length including space and brackets */
117 { N_("&Suspend"), 11, 29 },
118 { N_("Con&tinue"), 12, 29 },
119 { N_("&Chdir"), 11, 3 },
120 { N_("&Again"), 9, 17 },
121 { N_("&Quit"), 8, 43 },
122 { N_("Pane&lize"), 12, 3 },
123 { N_("&View - F3"), 13, 20 },
124 { N_("&Edit - F4"), 13, 38 }
127 static inline char * add_to_list (const char *text
, void *data
) {
128 return listbox_add_item (find_list
, 0, 0, text
, data
);
130 static inline void stop_idle (void *data
) {
131 set_idle_proc (data
, 0);
133 static inline void status_update (const char *text
) {
134 label_set_text (status_label
, text
);
136 static void get_list_info (char **file
, char **dir
) {
137 listbox_get_current (find_list
, file
, dir
);
140 /* FIXME: r should be local variable */
141 static regex_t
*r
; /* Pointer to compiled content_pattern */
143 static int case_sensitive
= 1;
144 static gboolean find_regex_flag
= TRUE
;
145 static int find_recursively
= 1;
148 * Callback for the parameter dialog.
149 * Validate regex, prevent closing the dialog if it's invalid.
152 find_parm_callback (struct Dlg_head
*h
, dlg_msg_t msg
, int parm
)
158 if ((h
->ret_value
!= B_ENTER
) || !in_with
->buffer
[0]
159 || !(find_regex_cbox
->state
& C_BOOL
))
162 flags
= REG_EXTENDED
| REG_NOSUB
;
164 if (!(case_sense
->state
& C_BOOL
))
167 if (regcomp (r
, in_with
->buffer
, flags
)) {
168 message (1, MSG_ERROR
, _(" Malformed regular expression "));
169 dlg_select_widget (in_with
);
170 h
->running
= 1; /* Don't stop the dialog */
175 return default_dlg_callback (h
, msg
, parm
);
180 * find_parameters: gets information from the user
182 * If the return value is true, then the following holds:
184 * START_DIR and PATTERN are pointers to char * and upon return they
185 * contain the information provided by the user.
187 * CONTENT holds a strdup of the contents specified by the user if he
188 * asked for them or 0 if not (note, this is different from the
189 * behavior for the other two parameters.
193 find_parameters (char **start_dir
, char **pattern
, char **content
)
197 static const char *case_label
= N_("case &Sensitive");
198 static const char *recurs_label
= N_("find Re&cursively");
200 WCheck
*recursively_cbox
;
202 static char *in_contents
= NULL
;
203 static char *in_start_dir
= NULL
;
204 static char *in_start_name
= NULL
;
206 static const char *labs
[] =
207 { N_("Start at:"), N_("Filename:"), N_("Content: ") };
208 static const char *buts
[] = { N_("&OK"), N_("&Tree"), N_("&Cancel") };
209 static int ilen
= 30, istart
= 14;
210 static int b0
= 3, b1
= 16, b2
= 36;
213 static int i18n_flag
= 0;
216 register int i
= sizeof (labs
) / sizeof (labs
[0]);
220 l1
= strlen (labs
[i
] = _(labs
[i
]));
224 i
= maxlen
+ ilen
+ 7;
228 for (i
= sizeof (buts
) / sizeof (buts
[0]), l1
= 0; i
--;) {
229 l1
+= strlen (buts
[i
] = _(buts
[i
]));
235 ilen
= FIND_X
- 7 - maxlen
; /* for the case of very long buttons :) */
236 istart
= FIND_X
- 3 - ilen
;
238 b1
= b0
+ strlen (buts
[0]) + 7;
239 b2
= FIND_X
- (strlen (buts
[2]) + 6);
242 case_label
= _(case_label
);
243 recurs_label
= _(recurs_label
);
245 #endif /* ENABLE_NLS */
249 in_start_dir
= g_strdup (".");
251 in_start_name
= g_strdup (easy_patterns
? "*" : ".");
253 in_contents
= g_strdup ("");
256 create_dlg (0, 0, FIND_Y
, FIND_X
, dialog_colors
,
257 find_parm_callback
, "[Find File]", _("Find File"),
258 DLG_CENTER
| DLG_REVERSE
);
260 add_widget (find_dlg
,
261 button_new (12, b2
, B_CANCEL
, NORMAL_BUTTON
, buts
[2], 0));
262 add_widget (find_dlg
,
263 button_new (12, b1
, B_TREE
, NORMAL_BUTTON
, buts
[1], 0));
264 add_widget (find_dlg
,
265 button_new (12, b0
, B_ENTER
, DEFPUSH_BUTTON
, buts
[0], 0));
268 check_new (6, istart
, find_recursively
, recurs_label
);
270 find_regex_cbox
= check_new (10, istart
, find_regex_flag
, _("&Regular expression"));
271 add_widget (find_dlg
, find_regex_cbox
);
273 case_sense
= check_new (9, istart
, case_sensitive
, case_label
);
274 add_widget (find_dlg
, case_sense
);
277 input_new (8, istart
, INPUT_COLOR
, ilen
, in_contents
, "content");
278 add_widget (find_dlg
, in_with
);
280 add_widget (find_dlg
, recursively_cbox
);
282 input_new (5, istart
, INPUT_COLOR
, ilen
, in_start_name
, "name");
283 add_widget (find_dlg
, in_name
);
286 input_new (3, istart
, INPUT_COLOR
, ilen
, in_start_dir
, "start");
287 add_widget (find_dlg
, in_start
);
289 add_widget (find_dlg
, label_new (8, 3, labs
[2]));
290 add_widget (find_dlg
, label_new (5, 3, labs
[1]));
291 add_widget (find_dlg
, label_new (3, 3, labs
[0]));
293 dlg_select_widget (in_name
);
297 switch (find_dlg
->ret_value
) {
303 temp_dir
= g_strdup (in_start
->buffer
);
304 case_sensitive
= case_sense
->state
& C_BOOL
;
305 find_regex_flag
= find_regex_cbox
->state
& C_BOOL
;
306 find_recursively
= recursively_cbox
->state
& C_BOOL
;
307 destroy_dlg (find_dlg
);
308 g_free (in_start_dir
);
309 if (strcmp (temp_dir
, ".") == 0) {
311 temp_dir
= g_strdup (current_panel
->cwd
);
313 in_start_dir
= tree_box (temp_dir
);
317 in_start_dir
= temp_dir
;
318 /* Warning: Dreadful goto */
323 g_free (in_contents
);
324 if (in_with
->buffer
[0]) {
325 *content
= g_strdup (in_with
->buffer
);
326 in_contents
= g_strdup (*content
);
328 *content
= in_contents
= NULL
;
332 case_sensitive
= case_sense
->state
& C_BOOL
;
333 find_regex_flag
= find_regex_cbox
->state
& C_BOOL
;
334 find_recursively
= recursively_cbox
->state
& C_BOOL
;
336 *start_dir
= g_strdup (in_start
->buffer
);
337 *pattern
= g_strdup (in_name
->buffer
);
339 g_free (in_start_dir
);
340 in_start_dir
= g_strdup (*start_dir
);
341 g_free (in_start_name
);
342 in_start_name
= g_strdup (*pattern
);
345 destroy_dlg (find_dlg
);
351 push_directory (const char *dir
)
355 new = g_new (dir_stack
, 1);
356 new->name
= concat_dir_and_file (dir
, "");
357 new->prev
= dir_stack_base
;
358 dir_stack_base
= new;
368 name
= dir_stack_base
->name
;
369 next
= dir_stack_base
->prev
;
370 g_free (dir_stack_base
);
371 dir_stack_base
= next
;
378 insert_file (const char *dir
, const char *file
)
381 static char *dirname
;
383 while (dir
[0] == PATH_SEP
&& dir
[1] == PATH_SEP
)
387 if (strcmp (old_dir
, dir
)){
389 old_dir
= g_strdup (dir
);
390 dirname
= add_to_list (dir
, NULL
);
393 old_dir
= g_strdup (dir
);
394 dirname
= add_to_list (dir
, NULL
);
397 tmp_name
= g_strconcat (" ", file
, (char *) NULL
);
398 add_to_list (tmp_name
, dirname
);
403 find_add_match (Dlg_head
*h
, const char *dir
, const char *file
)
405 int p
= ++matches
& 7;
409 insert_file (dir
, file
);
413 listbox_select_last (find_list
, 1);
415 listbox_select_last (find_list
, 0);
416 /* Updates the current listing */
417 send_message (&find_list
->widget
, WIDGET_DRAW
, 0);
425 * Returns malloced null-terminated line from file file_fd.
426 * Input is buffered in buf_size long buffer.
427 * Current pos in buf is stored in pos.
428 * n_read - number of read chars.
429 * has_newline - is there newline ?
432 get_line_at (int file_fd
, char *buf
, int *pos
, int *n_read
, int buf_size
,
441 if (*pos
>= *n_read
) {
443 if ((*n_read
= mc_read (file_fd
, buf
, buf_size
)) <= 0)
449 /* skip possible leading zero(s) */
456 if (i
>= buffer_size
- 1) {
457 buffer
= g_realloc (buffer
, buffer_size
+= 80);
466 *has_newline
= ch
? 1 : 0;
475 static FindProgressStatus
476 check_find_events(Dlg_head
*h
)
481 c
= get_event (&event
, h
->mouse_status
== MOU_REPEAT
, 0);
483 dlg_process_event (h
, c
, &event
);
484 if (h
->ret_value
== B_ENTER
485 || h
->ret_value
== B_CANCEL
486 || h
->ret_value
== B_AGAIN
487 || h
->ret_value
== B_PANELIZE
) {
488 /* dialog terminated */
491 if (!(h
->flags
& DLG_WANT_IDLE
)) {
492 /* searching suspended */
503 * Search the global (FIXME) regexp compiled content_pattern string in the
504 * DIRECTORY/FILE. It will add the found entries to the find listbox.
506 * returns 0 if do_search should look for another file
507 * 1 if do_search should exit and proceed to the event handler
510 search_content (Dlg_head
*h
, const char *directory
, const char *filename
)
513 char buffer
[BUF_SMALL
];
518 fname
= concat_dir_and_file (directory
, filename
);
520 if (mc_stat (fname
, &s
) != 0 || !S_ISREG (s
.st_mode
)){
525 file_fd
= mc_open (fname
, O_RDONLY
);
531 g_snprintf (buffer
, sizeof (buffer
), _("Grepping in %s"), name_trunc (filename
, FIND2_X_USE
));
533 status_update (buffer
);
536 enable_interrupt_key ();
546 typedef const char * (*search_fn
) (const char *, const char *);
547 search_fn search_func
;
550 /* We've been previously suspended, start from the previous position */
556 search_func
= (case_sensitive
) ? cstrstr
: cstrcasestr
;
558 while ((p
= get_line_at (file_fd
, buffer
, &pos
, &n_read
, sizeof (buffer
), &has_newline
)) && (ret_val
== 0)){
559 if (found
== 0){ /* Search in binary line once */
560 if (find_regex_flag
) {
561 if (regexec (r
, p
, 1, 0, 0) == 0){
563 p
= g_strdup_printf ("%d:%s", line
, filename
);
564 find_add_match (h
, directory
, p
);
568 if (search_func (p
, content_pattern
) != NULL
) {
569 char *match
= g_strdup_printf("%d:%s", line
, filename
);
570 find_add_match (h
, directory
, match
);
581 if ((line
& 0xff) == 0) {
582 FindProgressStatus res
;
583 res
= check_find_events(h
);
602 disable_interrupt_key ();
608 do_search (struct Dlg_head
*h
)
610 static struct dirent
*dp
= 0;
611 static DIR *dirp
= 0;
612 static char *directory
;
613 struct stat tmp_stat
;
615 static int subdirs_left
= 0;
617 if (!h
) { /* someone forces me to close dirp */
638 attrset (REVERSE_COLOR
);
640 tmp
= pop_directory ();
643 status_update (_("Finished"));
647 if (find_ignore_dirs
){
649 char *temp_dir
= g_strconcat (":", tmp
, ":", (char *) NULL
);
651 found
= strstr (find_ignore_dirs
, temp_dir
) != 0;
665 char buffer
[BUF_SMALL
];
667 g_snprintf (buffer
, sizeof (buffer
), _("Searching %s"),
668 name_trunc (directory
, FIND2_X_USE
));
669 status_update (buffer
);
671 /* mc_stat should not be called after mc_opendir
672 because vfs_s_opendir modifies the st_nlink
674 if (!mc_stat (directory
, &tmp_stat
))
675 subdirs_left
= tmp_stat
.st_nlink
- 2;
678 /* Commented out as unnecessary
679 if (subdirs_left < 0)
680 subdirs_left = MAXINT;
682 dirp
= mc_opendir (directory
);
683 } /* while (!dirp) */
684 dp
= mc_readdir (dirp
);
687 if (strcmp (dp
->d_name
, ".") == 0 ||
688 strcmp (dp
->d_name
, "..") == 0){
689 dp
= mc_readdir (dirp
);
693 if (subdirs_left
&& find_recursively
&& directory
) { /* Can directory be NULL ? */
694 char *tmp_name
= concat_dir_and_file (directory
, dp
->d_name
);
695 if (!mc_lstat (tmp_name
, &tmp_stat
)
696 && S_ISDIR (tmp_stat
.st_mode
)) {
697 push_directory (tmp_name
);
703 if (regexp_match (find_pattern
, dp
->d_name
, match_file
)){
704 if (content_pattern
) {
705 if (search_content (h
, directory
, dp
->d_name
)) {
709 find_add_match (h
, directory
, dp
->d_name
);
712 dp
= mc_readdir (dirp
);
714 /* Displays the nice dot */
717 /* For nice updating */
718 const char *rotating_dash
= "|/-\\";
722 attrset (DLG_NORMALC (h
));
723 dlg_move (h
, FIND2_Y
-6, FIND2_X
- 4);
724 addch (rotating_dash
[pos
]);
728 goto do_search_begin
;
733 init_find_vars (void)
742 /* Remove all the items in the stack */
743 while ((dir
= pop_directory ()) != NULL
)
748 find_do_view_edit (int unparsed_view
, int edit
, char *dir
, char *file
)
751 const char *filename
;
754 if (content_pattern
){
755 filename
= strchr (file
+ 4, ':') + 1;
756 line
= atoi (file
+ 4);
761 if (dir
[0] == '.' && dir
[1] == 0)
762 fullname
= g_strdup (filename
);
763 else if (dir
[0] == '.' && dir
[1] == PATH_SEP
)
764 fullname
= concat_dir_and_file (dir
+2, filename
);
766 fullname
= concat_dir_and_file (dir
, filename
);
769 do_edit_at_line (fullname
, line
);
771 view_file_at_line (fullname
, unparsed_view
, use_internal_view
, line
);
776 view_edit_currently_selected_file (int unparsed_view
, int edit
)
778 WLEntry
*entry
= find_list
->current
;
782 return MSG_NOT_HANDLED
;
786 if (!entry
->text
|| !dir
)
787 return MSG_NOT_HANDLED
;
789 find_do_view_edit (unparsed_view
, edit
, dir
, entry
->text
);
794 find_callback (struct Dlg_head
*h
, dlg_msg_t msg
, int parm
)
798 if (parm
== KEY_F (3) || parm
== KEY_F (13)) {
799 int unparsed_view
= (parm
== KEY_F (13));
800 return view_edit_currently_selected_file (unparsed_view
, 0);
802 if (parm
== KEY_F (4)) {
803 return view_edit_currently_selected_file (0, 1);
805 return MSG_NOT_HANDLED
;
812 return default_dlg_callback (h
, msg
, parm
);
816 /* Handles the Stop/Start button in the find window */
818 start_stop (int button
)
823 set_idle_proc (find_dlg
, running
);
824 is_start
= !is_start
;
826 status_update (is_start
? _("Stopped") : _("Searching"));
827 button_set_text (stop_button
, fbuts
[is_start
].text
);
832 /* Handle view command, when invoked as a button */
834 find_do_view_file (int button
)
838 view_edit_currently_selected_file (0, 0);
842 /* Handle edit command, when invoked as a button */
844 find_do_edit_file (int button
)
848 view_edit_currently_selected_file (0, 1);
856 static int i18n_flag
= 0;
858 register int i
= sizeof (fbuts
) / sizeof (fbuts
[0]);
860 fbuts
[i
].len
= strlen (fbuts
[i
].text
= _(fbuts
[i
].text
)) + 3;
861 fbuts
[2].len
+= 2; /* DEFPUSH_BUTTON */
864 #endif /* ENABLE_NLS */
867 * Dynamically place buttons centered within current window size
870 int l0
= max (fbuts
[0].len
, fbuts
[1].len
);
871 int l1
= fbuts
[2].len
+ fbuts
[3].len
+ l0
+ fbuts
[4].len
;
872 int l2
= fbuts
[5].len
+ fbuts
[6].len
+ fbuts
[7].len
;
877 /* Check, if both button rows fit within FIND2_X */
878 if (l1
+ 9 > FIND2_X
)
880 if (l2
+ 8 > FIND2_X
)
883 /* compute amount of space between buttons for each row */
884 r1
= (FIND2_X
- 4 - l1
) % 5;
885 l1
= (FIND2_X
- 4 - l1
) / 5;
886 r2
= (FIND2_X
- 4 - l2
) % 4;
887 l2
= (FIND2_X
- 4 - l2
) / 4;
889 /* ...and finally, place buttons */
890 fbuts
[2].x
= 2 + r1
/ 2 + l1
;
891 fbuts
[3].x
= fbuts
[2].x
+ fbuts
[2].len
+ l1
;
892 fbuts
[0].x
= fbuts
[3].x
+ fbuts
[3].len
+ l1
;
893 fbuts
[4].x
= fbuts
[0].x
+ l0
+ l1
;
894 fbuts
[5].x
= 2 + r2
/ 2 + l2
;
895 fbuts
[6].x
= fbuts
[5].x
+ fbuts
[5].len
+ l2
;
896 fbuts
[7].x
= fbuts
[6].x
+ fbuts
[6].len
+ l2
;
900 create_dlg (0, 0, FIND2_Y
, FIND2_X
, dialog_colors
, find_callback
,
901 "[Find File]", _("Find File"), DLG_CENTER
| DLG_REVERSE
);
903 add_widget (find_dlg
,
904 button_new (FIND2_Y
- 3, fbuts
[7].x
, B_VIEW
, NORMAL_BUTTON
,
905 fbuts
[7].text
, find_do_edit_file
));
906 add_widget (find_dlg
,
907 button_new (FIND2_Y
- 3, fbuts
[6].x
, B_VIEW
, NORMAL_BUTTON
,
908 fbuts
[6].text
, find_do_view_file
));
909 add_widget (find_dlg
,
910 button_new (FIND2_Y
- 3, fbuts
[5].x
, B_PANELIZE
,
911 NORMAL_BUTTON
, fbuts
[5].text
, 0));
913 add_widget (find_dlg
,
914 button_new (FIND2_Y
- 4, fbuts
[4].x
, B_CANCEL
,
915 NORMAL_BUTTON
, fbuts
[4].text
, 0));
917 button_new (FIND2_Y
- 4, fbuts
[0].x
, B_STOP
, NORMAL_BUTTON
,
918 fbuts
[0].text
, start_stop
);
919 add_widget (find_dlg
, stop_button
);
920 add_widget (find_dlg
,
921 button_new (FIND2_Y
- 4, fbuts
[3].x
, B_AGAIN
,
922 NORMAL_BUTTON
, fbuts
[3].text
, 0));
923 add_widget (find_dlg
,
924 button_new (FIND2_Y
- 4, fbuts
[2].x
, B_ENTER
,
925 DEFPUSH_BUTTON
, fbuts
[2].text
, 0));
927 status_label
= label_new (FIND2_Y
- 6, 4, _("Searching"));
928 add_widget (find_dlg
, status_label
);
931 listbox_new (2, 2, FIND2_X
- 4, FIND2_Y
- 9, 0);
932 add_widget (find_dlg
, find_list
);
939 set_idle_proc (find_dlg
, 1);
941 return find_dlg
->ret_value
;
947 set_idle_proc (find_dlg
, 0);
948 destroy_dlg (find_dlg
);
952 find_file (char *start_dir
, char *pattern
, char *content
, char **dirname
,
955 int return_value
= 0;
957 char *dir_tmp
, *file_tmp
;
961 /* FIXME: Need to cleanup this, this ought to be passed non-globaly */
962 find_pattern
= pattern
;
963 content_pattern
= content
;
966 push_directory (start_dir
);
968 return_value
= run_process ();
970 /* Remove all the items in the stack */
971 while ((dir
= pop_directory ()) != NULL
)
974 get_list_info (&file_tmp
, &dir_tmp
);
977 *dirname
= g_strdup (dir_tmp
);
979 *filename
= g_strdup (file_tmp
);
981 if (return_value
== B_PANELIZE
&& *filename
) {
982 int status
, link_to_dir
, stale_link
;
986 WLEntry
*entry
= find_list
->list
;
987 dir_list
*list
= ¤t_panel
->dir
;
990 for (i
= 0; entry
&& i
< find_list
->count
;
991 entry
= entry
->next
, i
++) {
992 const char *filename
;
994 if (!entry
->text
|| !entry
->data
)
998 filename
= strchr (entry
->text
+ 4, ':') + 1;
1000 filename
= entry
->text
+ 4;
1003 if (dir
[0] == '.' && dir
[1] == 0)
1004 name
= g_strdup (filename
);
1005 else if (dir
[0] == '.' && dir
[1] == PATH_SEP
)
1006 name
= concat_dir_and_file (dir
+ 2, filename
);
1008 name
= concat_dir_and_file (dir
, filename
);
1010 handle_path (list
, name
, &st
, next_free
, &link_to_dir
,
1021 /* don't add files more than once to the panel */
1022 if (content_pattern
&& next_free
> 0) {
1023 if (strcmp (list
->list
[next_free
- 1].fname
, name
) == 0) {
1029 if (!next_free
) /* first turn i.e clean old list */
1030 panel_clean_dir (current_panel
);
1031 list
->list
[next_free
].fnamelen
= strlen (name
);
1032 list
->list
[next_free
].fname
= name
;
1033 list
->list
[next_free
].f
.marked
= 0;
1034 list
->list
[next_free
].f
.link_to_dir
= link_to_dir
;
1035 list
->list
[next_free
].f
.stale_link
= stale_link
;
1036 list
->list
[next_free
].f
.dir_size_computed
= 0;
1037 list
->list
[next_free
].st
= st
;
1039 if (!(next_free
& 15))
1043 current_panel
->count
= next_free
;
1044 current_panel
->is_panelized
= 1;
1045 /* Done by panel_clean_dir a few lines above
1046 current_panel->dirs_marked = 0;
1047 current_panel->marked = 0;
1048 current_panel->total = 0;
1049 current_panel->top_file = 0;
1050 current_panel->selected = 0; */
1052 if (start_dir
[0] == PATH_SEP
) {
1053 strcpy (current_panel
->cwd
, PATH_SEP_STR
);
1054 chdir (PATH_SEP_STR
);
1060 do_search (0); /* force do_search to release resources */
1064 return return_value
;
1070 char *start_dir
= NULL
, *pattern
= NULL
, *content
= NULL
;
1071 char *filename
, *dirname
;
1072 int v
, dir_and_file_set
;
1073 regex_t rx
; /* Compiled content_pattern to search inside files */
1075 for (r
= &rx
; find_parameters (&start_dir
, &pattern
, &content
); r
= &rx
){
1077 dirname
= filename
= NULL
;
1079 v
= find_file (start_dir
, pattern
, content
, &dirname
, &filename
);
1082 if (find_regex_flag
&& r
)
1086 if (dirname
|| filename
){
1088 do_cd (dirname
, cd_exact
);
1090 try_to_select (current_panel
, filename
+ (content
?
1091 (strchr (filename
+ 4, ':') - filename
+ 1) : 4) );
1092 } else if (filename
)
1093 do_cd (filename
, cd_exact
);
1094 select_item (current_panel
);
1101 dir_and_file_set
= dirname
&& filename
;
1107 if (v
== B_PANELIZE
){
1108 if (dir_and_file_set
){
1109 try_to_select (current_panel
, NULL
);
1110 panel_re_sort (current_panel
);