💾 Archived View for gemini.rmf-dev.com › repo › Vaati › mz › files › 1ec21aaf2fd9aede2505d143876f72c… captured on 2023-12-28 at 15:52:13. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-09-08)
-=-=-=-=-=-=-
0 /*
1 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
2 *
3 * Permission to use, copy, modify, and distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 */
15 #ifdef __linux__
16 #define _GNU_SOURCE
17 #else
18 #define _BSD_SOURCE
19 #endif
20 #include <dirent.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdint.h>
27 #include <unistd.h>
28 #include "termbox.h"
29 #include "client.h"
30 #include "view.h"
31 #include "file.h"
32 #include "util.h"
33 #include "strlcpy.h"
34 #include "utf8.h"
35 #include "trash.h"
36
37 struct view *view_init(const char *path) {
38 struct view *view = malloc(sizeof(struct view));
39 file_init(view, path);
40 return view;
41 }
42
43 int format_path(const char *str, char *out, size_t length) {
44
45 size_t i = 0, j = 0;
46
47 while (str[i] && j < length - 1) {
48 size_t len = tb_utf8_char_length(str[i]);
49 if (len > 1) {
50 if (j + len > length) return -1;
51 memcpy(&out[j], &str[i], len);
52 i += len; j += len;
53 continue;
54 }
55 if (str[i] == '"') out[j++] = '\\';
56 out[j++] = str[i++];
57 }
58
59 out[j] = '\0';
60 return -(j >= length - 1); /* error if str was not properly copied */
61 }
62
63 void view_open(struct view *view) {
64
65 const char xdg[] = "xdg-open \"%s\" >/dev/null 2>&1 &";
66 char name[PATH_MAX];
67 char buf[sizeof(name) + sizeof(xdg) + 1];
68
69 if (view->length < 1 || view->fd == TRASH_FD)
70 return;
71
72 client.error = 0;
73 switch (view->entries[view->selected].type) {
74 case DT_REG:
75 chdir(view->path);
76 if (format_path(SELECTED(view).name, V(name))) {
77 STRCPY(client.info, "path too long");
78 client.error = 1;
79 break;
80 }
81 snprintf(V(buf), xdg, name);
82 system(buf);
83 break;
84 case DT_DIR:
85 if (file_cd(view, SELECTED(view).name)) {
86 STRCPY(client.info, strerror(errno));
87 client.error = 1;
88 break;
89 }
90 file_ls(view);
91 break;
92 }
93 }
94
95 void view_draw(struct view *view) {
96
97 size_t i = 0, start = TABS;
98
99 if (view->selected + 1 > view->scroll + HEIGHT)
100 view->scroll = view->selected - HEIGHT;
101 if (view->selected < view->scroll)
102 view->scroll = view->selected;
103
104 while (i + view->scroll < view->length) {
105 int selected;
106 struct entry *e;
107 uintattr_t fg, bg;
108
109 if (i > HEIGHT)
110 break;
111
112 fg = bg = TB_DEFAULT;
113
114 selected = view->selected == i + view->scroll;
115 e = &view->entries[i + view->scroll];
116 if (selected) {
117 fg = TB_WHITE;
118 bg = TB_CYAN;
119 }
120 if (e->type == DT_DIR)
121 fg = selected ? TB_BLACK : TB_CYAN;
122 if (e->selected)
123 bg = TB_CYAN;
124 if (e->selected && fg == TB_CYAN)
125 fg = TB_WHITE;
126 if (e->selected && selected)
127 fg = e->type == DT_REG ? TB_BLACK : TB_GREEN;
128 tb_print(0, i + start, fg, bg, e->name);
129 if (e->type == DT_DIR) {
130 tb_set_cell(utf8_width(e->name, PATH_MAX), i + start,
131 '/', fg, bg);
132 }
133 i++;
134 }
135 }
136
137 void view_select(struct view *view, const char *name) {
138 file_select(view, name);
139 if (view->length < HEIGHT) return;
140 if (view->selected >= view->length - HEIGHT / 2) {
141 view->scroll = view->length - HEIGHT - 1;
142 } else if (view->selected > HEIGHT / 2) {
143 view->scroll = view->selected - HEIGHT / 2;
144 }
145 }
146
147 void view_unselect(struct view *view) {
148 size_t i = 0;
149 while (i < view->length) {
150 view->entries[i].selected = 0;
151 i++;
152 }
153 }
154