чување e38446b14d1e32981b0f5ac0805e5eea2cba03f8
родитељ 926a54d9a727abd6d86da7b1f78e4f44e8a6f14b
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sun, 10 Mar 2024 17:00:54 +0100
Deal with long filenames (add ... at the end and leave space for *)
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 7, додавања: 55(+), брисања: 17(-)
diff --git a/TODO b/TODO
@@ -1,8 +1,6 @@
TODO
====
-[ ] Deal with long filenames (add ... at the end and leave space for *)
-
[~] Code optimization (struct coord...)
diff --git a/TODO.done b/TODO.done
@@ -1,6 +1,8 @@
Done or canceled todos
======================
+[x] Deal with long filenames (add ... at the end and leave space for *)
+
[x] Switch to strlcpy, strlcat; check u8_*/u32_*
[x] Change the backup method, as `crontab -e` doesn't like inode changes
diff --git a/config.def.h b/config.def.h
@@ -288,11 +288,11 @@ static const struct Key command_keys[] = {
#endif /* SLED_C_GLOBALS */
void format_filename(char* result, size_t result_size, const char* format,
- const struct DrawState* state);
+ const int seg_size, const struct DrawState* state);
void format_mode(char* result, size_t result_size, const char* format,
- const struct DrawState* state);
+ const int seg_size, const struct DrawState* state);
void format_position(char* result, size_t result_size, const char* format,
- const struct DrawState* state);
+ const int seg_size, const struct DrawState* state);
/* clang-format off */
static const struct StatusSegment status_segments[] = {
diff --git a/draw.c b/draw.c
@@ -174,17 +174,32 @@ assign_coord(struct Coord* dest, const struct Coord src)
void
format_filename(char* result, size_t result_size, const char* format,
- const struct DrawState* state)
+ const int seg_size, const struct DrawState* state)
{
- if (!result)
+ char* basename = NULL;
+ if (!result || seg_size < 2)
return;
- snprintf(result, result_size, format, u8_basename(state->filename),
- state->dirty ? "*" : "");
+
+ basename = strdup(u8_basename(state->filename));
+
+ if (u8_strlen(basename) >= seg_size - 2)
+ {
+ if (state->dirty)
+ basename[seg_size - 4] = 0;
+ else
+ basename[seg_size - 3] = 0;
+ snprintf(result, result_size, format, basename,
+ state->dirty ? "…*" : "…");
+ }
+ else
+ snprintf(result, result_size, format, basename,
+ state->dirty ? "*" : "");
+ free(basename);
}
void
format_mode(char* result, size_t result_size, const char* format,
- const struct DrawState* state)
+ const int seg_size, const struct DrawState* state)
{
const char* mode_label = mode_labels[UNKNOWN_MODE];
if (!result)
@@ -207,7 +222,7 @@ format_mode(char* result, size_t result_size, const char* format,
void
format_position(char* result, size_t result_size, const char* format,
- const struct DrawState* state)
+ const int seg_size, const struct DrawState* state)
{
if (!result)
return;
@@ -715,13 +730,16 @@ draw_screen(const struct DrawState* state)
const struct DrawState*
draw_status(const struct DrawState* state)
{
+ char buf[MAXBUFLINE];
+ int seg_size;
+ int current_start = 0;
+ const struct StatusSegment* pseg;
+
if (!state)
return NULL;
- char buf[MAXBUFLINE];
- int seg_size = state->maxx / LEN(status_segments);
- int current_start = 0;
- const struct StatusSegment* pseg = status_segments;
+ seg_size = state->maxx / LEN(status_segments);
+ pseg = status_segments;
if (IN(state->mode, M_PROMPT) && *state->prompt)
{
@@ -754,7 +772,7 @@ draw_status(const struct DrawState* state)
buf[0] = 0;
if (pseg->callback)
pseg->callback(buf, MAXBUFLINE, pseg->format,
- state);
+ seg_size, state);
else
strncpy(buf, pseg->format, MAXBUFLINE - 1);
buf[MAXBUFLINE - 1] = 0;
diff --git a/draw.h b/draw.h
@@ -102,7 +102,8 @@ struct Key {
struct StatusSegment {
const char* format;
- void (*callback)(char*, size_t, const char*, const struct DrawState*);
+ void (*callback)(char*, size_t, const char*, const int,
+ const struct DrawState*);
uint16_t fg;
uint16_t bg;
Alignment alignment;
diff --git a/util.c b/util.c
@@ -71,6 +71,24 @@ unicode_string_to_u8(char* s, const uint32_t* us, const size_t max)
}
size_t
+u8_strlen(const char* s)
+{
+ const char* ps = s;
+ uint32_t uc;
+ size_t len;
+ size_t result = 0;
+ if (!s)
+ return 0;
+ while (*ps)
+ {
+ len = tb_utf8_char_to_unicode(&uc, ps);
+ result += len;
+ ps++;
+ }
+ return result;
+}
+
+size_t
u32_strlen(const uint32_t* s)
{
const uint32_t* ps = s;
diff --git a/util.h b/util.h
@@ -72,6 +72,7 @@ size_t strlcat(char* dst, const char* src, size_t dsize);
size_t u8_string_to_unicode(uint32_t* us, const char* s, const size_t max);
size_t unicode_string_to_u8(char* s, const uint32_t* us, const size_t max);
+size_t u8_strlen(const char* s);
size_t u32_strlen(const uint32_t* s);
const uint32_t* u32_strstr(const uint32_t* haystack, const uint32_t* needle);
const uint32_t* u32_strrstr(const uint32_t* haystack, const uint32_t* needle,