34 |
StringArray items; |
StringArray items; |
35 |
int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */ |
int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */ |
36 |
int last_index; |
int last_index; |
37 |
char path[1024]; /* current path */ |
char path[MAX_FILENAME_SIZE]; /* current path */ |
38 |
} DiredState; |
} DiredState; |
39 |
|
|
40 |
/* opaque structure for sorting DiredState.items StringArray */ |
/* opaque structure for sorting DiredState.items StringArray */ |
83 |
int is_dir1, is_dir2; |
int is_dir1, is_dir2; |
84 |
|
|
85 |
if (mode & DIRED_SORT_GROUP) { |
if (mode & DIRED_SORT_GROUP) { |
86 |
is_dir1 = !!S_ISDIR(dip1->mode); |
is_dir1 = !!S_ISDIR(dip1->mode); |
87 |
is_dir2 = !!S_ISDIR(dip2->mode); |
is_dir2 = !!S_ISDIR(dip2->mode); |
88 |
if (is_dir1 != is_dir2) |
if (is_dir1 != is_dir2) |
89 |
return is_dir2 - is_dir1; |
return is_dir2 - is_dir1; |
90 |
} |
} |
91 |
for (;;) { |
for (;;) { |
92 |
if (mode & DIRED_SORT_DATE) { |
if (mode & DIRED_SORT_DATE) { |
93 |
if (dip1->mtime != dip2->mtime) { |
if (dip1->mtime != dip2->mtime) { |
94 |
res = (dip1->mtime < dip2->mtime) ? -1 : 1; |
res = (dip1->mtime < dip2->mtime) ? -1 : 1; |
95 |
break; |
break; |
96 |
} |
} |
97 |
} |
} |
98 |
if (mode & DIRED_SORT_SIZE) { |
if (mode & DIRED_SORT_SIZE) { |
99 |
if (dip1->size != dip2->size) { |
if (dip1->size != dip2->size) { |
100 |
res = (dip1->size < dip2->size) ? -1 : 1; |
res = (dip1->size < dip2->size) ? -1 : 1; |
101 |
break; |
break; |
102 |
} |
} |
103 |
} |
} |
104 |
if (mode & DIRED_SORT_EXTENSION) { |
if (mode & DIRED_SORT_EXTENSION) { |
105 |
res = strcmp(extension(dip1->name), extension(dip2->name)); |
res = strcmp(extension(dip1->name), extension(dip2->name)); |
106 |
if (res) |
if (res) |
107 |
break; |
break; |
108 |
} |
} |
109 |
res = strcmp(dip1->name, dip2->name); |
res = strcmp(dip1->name, dip2->name); |
110 |
break; |
break; |
111 |
} |
} |
112 |
return (mode & DIRED_SORT_DESCENDING) ? -res : res; |
return (mode & DIRED_SORT_DESCENDING) ? -res : res; |
113 |
} |
} |
124 |
index = dired_get_index(s); |
index = dired_get_index(s); |
125 |
cur_item = NULL; |
cur_item = NULL; |
126 |
if (index >= 0 && index < hs->items.nb_items) |
if (index >= 0 && index < hs->items.nb_items) |
127 |
cur_item = hs->items.items[index]; |
cur_item = hs->items.items[index]; |
128 |
|
|
129 |
qsort(hs->items.items, hs->items.nb_items, |
qsort(hs->items.items, hs->items.nb_items, |
130 |
sizeof(StringItem *), dired_sort_func); |
sizeof(StringItem *), dired_sort_func); |
135 |
eb_delete(b, 0, b->total_size); |
eb_delete(b, 0, b->total_size); |
136 |
s->offset = 0; |
s->offset = 0; |
137 |
if (DIRED_HEADER) |
if (DIRED_HEADER) |
138 |
eb_printf(b, " %s:\n", hs->path); |
eb_printf(b, " %s:\n", hs->path); |
139 |
for (i = 0; i < hs->items.nb_items; i++) { |
for (i = 0; i < hs->items.nb_items; i++) { |
140 |
item = hs->items.items[i]; |
item = hs->items.items[i]; |
141 |
dip = item->opaque; |
dip = item->opaque; |
142 |
dip->offset = b->total_size; |
dip->offset = b->total_size; |
143 |
if (item == cur_item) |
if (item == cur_item) |
144 |
s->offset = b->total_size; |
s->offset = b->total_size; |
145 |
eb_printf(b, "%c %s\n", dip->mark, item->str); |
eb_printf(b, "%c %s\n", dip->mark, item->str); |
146 |
} |
} |
147 |
b->modified = 0; |
b->modified = 0; |
175 |
const char *p; |
const char *p; |
176 |
|
|
177 |
for (p = sort_order; *p; p++) { |
for (p = sort_order; *p; p++) { |
178 |
switch (tolower(*p)) { |
switch (tolower(*p)) { |
179 |
case 'n': /* name */ |
case 'n': /* name */ |
180 |
hs->sort_mode &= ~DIRED_SORT_MASK; |
hs->sort_mode &= ~DIRED_SORT_MASK; |
181 |
hs->sort_mode |= DIRED_SORT_NAME; |
hs->sort_mode |= DIRED_SORT_NAME; |
182 |
break; |
break; |
183 |
case 'e': /* extension */ |
case 'e': /* extension */ |
184 |
hs->sort_mode &= ~DIRED_SORT_MASK; |
hs->sort_mode &= ~DIRED_SORT_MASK; |
185 |
hs->sort_mode |= DIRED_SORT_EXTENSION; |
hs->sort_mode |= DIRED_SORT_EXTENSION; |
186 |
break; |
break; |
187 |
case 's': /* size */ |
case 's': /* size */ |
188 |
hs->sort_mode &= ~DIRED_SORT_MASK; |
hs->sort_mode &= ~DIRED_SORT_MASK; |
189 |
hs->sort_mode |= DIRED_SORT_SIZE; |
hs->sort_mode |= DIRED_SORT_SIZE; |
190 |
break; |
break; |
191 |
case 'd': /* direct */ |
case 'd': /* direct */ |
192 |
hs->sort_mode &= ~DIRED_SORT_MASK; |
hs->sort_mode &= ~DIRED_SORT_MASK; |
193 |
hs->sort_mode |= DIRED_SORT_DATE; |
hs->sort_mode |= DIRED_SORT_DATE; |
194 |
break; |
break; |
195 |
case 'u': /* ungroup */ |
case 'u': /* ungroup */ |
196 |
hs->sort_mode &= ~DIRED_SORT_GROUP; |
hs->sort_mode &= ~DIRED_SORT_GROUP; |
197 |
break; |
break; |
198 |
case 'g': /* group */ |
case 'g': /* group */ |
199 |
hs->sort_mode |= DIRED_SORT_GROUP; |
hs->sort_mode |= DIRED_SORT_GROUP; |
200 |
break; |
break; |
201 |
case '+': /* ascending */ |
case '+': /* ascending */ |
202 |
hs->sort_mode &= ~DIRED_SORT_DESCENDING; |
hs->sort_mode &= ~DIRED_SORT_DESCENDING; |
203 |
break; |
break; |
204 |
case '-': /* descending */ |
case '-': /* descending */ |
205 |
hs->sort_mode |= DIRED_SORT_DESCENDING; |
hs->sort_mode |= DIRED_SORT_DESCENDING; |
206 |
break; |
break; |
207 |
case 'r': /* reverse */ |
case 'r': /* reverse */ |
208 |
hs->sort_mode ^= DIRED_SORT_DESCENDING; |
hs->sort_mode ^= DIRED_SORT_DESCENDING; |
209 |
break; |
break; |
210 |
} |
} |
211 |
} |
} |
212 |
do_dired_sort(s); |
do_dired_sort(s); |
213 |
} |
} |
218 |
{ |
{ |
219 |
DiredState *hs = s->mode_data; |
DiredState *hs = s->mode_data; |
220 |
FindFileState *ffs; |
FindFileState *ffs; |
221 |
char filename[1024]; |
char filename[MAX_FILENAME_SIZE]; |
222 |
char line[1024], buf[1024]; |
char line[1024], buf[1024]; |
223 |
const char *p; |
const char *p; |
224 |
struct stat st; |
struct stat st; |
239 |
continue; |
continue; |
240 |
p = basename(filename); |
p = basename(filename); |
241 |
|
|
242 |
#if 1 /* CG: bad idea, but causes spurious bugs */ |
#if 1 /* CG: bad idea, but causes spurious bugs */ |
243 |
/* exclude redundant '.' and '..' */ |
/* exclude redundant '.' and '..' */ |
244 |
if (!strcmp(p, ".") || !strcmp(p, "..")) |
if (!strcmp(p, ".") || !strcmp(p, "..")) |
245 |
continue; |
continue; |
292 |
|
|
293 |
item = add_string(&hs->items, line); |
item = add_string(&hs->items, line); |
294 |
if (item) { |
if (item) { |
295 |
DiredItem *dip; |
DiredItem *dip; |
296 |
|
|
297 |
dip = malloc(sizeof(DiredItem) + strlen(p)); |
dip = malloc(sizeof(DiredItem) + strlen(p)); |
298 |
dip->state = hs; |
dip->state = hs; |
299 |
dip->mode = st.st_mode; |
dip->mode = st.st_mode; |
300 |
dip->size = st.st_size; |
dip->size = st.st_size; |
301 |
dip->mtime = st.st_mtime; |
dip->mtime = st.st_mtime; |
302 |
dip->mark = ' '; |
dip->mark = ' '; |
303 |
strcpy(dip->name, p); |
strcpy(dip->name, p); |
304 |
item->opaque = dip; |
item->opaque = dip; |
305 |
} |
} |
306 |
} |
} |
307 |
find_file_close(ffs); |
find_file_close(ffs); |
308 |
do_dired_sort(s); |
do_dired_sort(s); |
309 |
} |
} |
310 |
|
|
311 |
static char *get_dired_filename(EditState *s, |
static char *get_dired_filename(EditState *s, |
312 |
char *buf, int buf_size, int index) |
char *buf, int buf_size, int index) |
313 |
{ |
{ |
314 |
DiredState *hs = s->mode_data; |
DiredState *hs = s->mode_data; |
315 |
const StringItem *item; |
const StringItem *item; |
333 |
static void dired_select(EditState *s) |
static void dired_select(EditState *s) |
334 |
{ |
{ |
335 |
struct stat st; |
struct stat st; |
336 |
char filename[1024]; |
char filename[MAX_FILENAME_SIZE]; |
337 |
EditState *e; |
EditState *e; |
338 |
|
|
339 |
if (!get_dired_filename(s, filename, sizeof(filename), |
if (!get_dired_filename(s, filename, sizeof(filename), |
340 |
dired_get_index(s))) { |
dired_get_index(s))) { |
341 |
return; |
return; |
342 |
} |
} |
343 |
|
|
344 |
/* now we can act */ |
/* now we can act */ |
392 |
e->b = b; |
e->b = b; |
393 |
} |
} |
394 |
/* mark buffer as preview, so that it will get recycled if needed */ |
/* mark buffer as preview, so that it will get recycled if needed */ |
395 |
/* CG: this is wrong if buffer existed already */ |
/* CG: this is wrong if buffer existed already */ |
396 |
b->flags |= BF_PREVIEW; |
b->flags |= BF_PREVIEW; |
397 |
} |
} |
398 |
} |
} |
406 |
static void dired_parent(EditState *s) |
static void dired_parent(EditState *s) |
407 |
{ |
{ |
408 |
DiredState *hs = s->mode_data; |
DiredState *hs = s->mode_data; |
409 |
char filename[1024]; |
char filename[MAX_FILENAME_SIZE]; |
410 |
|
|
411 |
makepath(filename, sizeof(filename), hs->path, ".."); |
makepath(filename, sizeof(filename), hs->path, ".."); |
412 |
|
|
425 |
static void dired_display_hook(EditState *s) |
static void dired_display_hook(EditState *s) |
426 |
{ |
{ |
427 |
DiredState *ds = s->mode_data; |
DiredState *ds = s->mode_data; |
428 |
char filename[1024]; |
char filename[MAX_FILENAME_SIZE]; |
429 |
int index; |
int index; |
430 |
|
|
431 |
/* Prevent point from going beyond list */ |
/* Prevent point from going beyond list */ |
432 |
if (s->offset && s->offset == s->b->total_size) |
if (s->offset && s->offset == s->b->total_size) |
433 |
do_up_down(s, -1); |
do_up_down(s, -1); |
434 |
|
|
435 |
/* open file so that user can see it before it is selected */ |
/* open file so that user can see it before it is selected */ |
436 |
/* XXX: find a better solution (callback) */ |
/* XXX: find a better solution (callback) */ |
440 |
/* Should not rely on last_index! */ |
/* Should not rely on last_index! */ |
441 |
if (index != ds->last_index) { |
if (index != ds->last_index) { |
442 |
ds->last_index = index; |
ds->last_index = index; |
443 |
if (get_dired_filename(s, filename, sizeof(filename), |
if (get_dired_filename(s, filename, sizeof(filename), |
444 |
dired_get_index(s))) { |
dired_get_index(s))) { |
445 |
dired_view_file(s, filename); |
dired_view_file(s, filename); |
446 |
} |
} |
447 |
} |
} |
448 |
} |
} |
449 |
|
|
487 |
EditBuffer *b, *b0; |
EditBuffer *b, *b0; |
488 |
EditState *e, *e1; |
EditState *e, *e1; |
489 |
int width, index, i; |
int width, index, i; |
490 |
char filename[1024], *p; |
char filename[MAX_FILENAME_SIZE], *p; |
491 |
|
|
492 |
/* Should take directory argument with optional switches, |
/* Should take directory argument with optional switches, |
493 |
* find dired window if exists, |
* find dired window if exists, |
517 |
|
|
518 |
e1 = find_window(e, KEY_RIGHT); |
e1 = find_window(e, KEY_RIGHT); |
519 |
if (e1) |
if (e1) |
520 |
b0 = e1->b; |
b0 = e1->b; |
521 |
|
|
522 |
index = 0; |
index = 0; |
523 |
/* CG: target file should be an argument to this command */ |
/* CG: target file should be an argument to this command */ |
524 |
for (i = 0; i < hs->items.nb_items; i++) { |
for (i = 0; i < hs->items.nb_items; i++) { |
525 |
if (get_dired_filename(e, filename, sizeof(filename), i) |
if (get_dired_filename(e, filename, sizeof(filename), i) |
526 |
&& !strcmp(filename, b0->filename)) { |
&& !strcmp(filename, b0->filename)) { |
527 |
index = i; |
index = i; |
528 |
break; |
break; |
529 |
} |
} |
530 |
} |
} |
531 |
e->offset = eb_goto_pos(e->b, index + DIRED_HEADER, 0); |
e->offset = eb_goto_pos(e->b, index + DIRED_HEADER, 0); |
532 |
|
|