чување 1b488738b7455a16a0ac5707dabc7d3eed7b1850
родитељ 289d06d7f45a635bc76c3a776f96d32091fb1dc4
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sun, 4 Jul 2021 16:24:02 +0200
Info display with msgid_plural and Plural-Forms
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | TODO | | | 4 | ++-- |
| M | config.def.h | | | 2 | ++ |
| M | config.h | | | 2 | ++ |
| M | draw.c | | | 21 | ++++++++++++++++++--- |
| M | draw.h | | | 3 | +++ |
| M | po.c | | | 70 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
| M | po.h | | | 10 | +++++++++- |
| M | poe.c | | | 111 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
измењених датотека: 8, додавања: 192(+), брисања: 31(-)
diff --git a/TODO b/TODO
@@ -13,9 +13,9 @@
[ ] Yank/paste (entire current msgstr)
- [~] Multiline msgid display
+ [x] Multiline msgid display
[x] Also msgid_plural
- [ ] Also Plural-Forms
+ [x] Also Plural-Forms
[x] (Multiline) comment display; ~key binding: "?"~
[x] Toggle msgid/msgstr focus with F6; when msgid is focused,
arrow keys scroll the msgid area
diff --git a/config.def.h b/config.def.h
@@ -5,6 +5,8 @@
#define EDIT_MSGID_BG TB_WHITE
#define EDIT_MSGID_FOCUS_FG TB_BLACK
#define EDIT_MSGID_FOCUS_BG TB_WHITE
+#define EDIT_MSGID_HEADING_FG TB_WHITE | TB_BOLD
+#define EDIT_MSGID_HEADING_BG TB_WHITE
#define EDIT_MSGSTR_FG TB_BLACK | TB_BOLD
#define EDIT_MSGSTR_BG TB_BLACK
#define EDIT_MSGSTR_FOCUS_FG TB_YELLOW | TB_BOLD
diff --git a/config.h b/config.h
@@ -5,6 +5,8 @@
#define EDIT_MSGID_BG TB_WHITE
#define EDIT_MSGID_FOCUS_FG TB_BLACK
#define EDIT_MSGID_FOCUS_BG TB_WHITE
+#define EDIT_MSGID_HEADING_FG TB_WHITE | TB_BOLD
+#define EDIT_MSGID_HEADING_BG TB_WHITE
#define EDIT_MSGSTR_FG TB_BLACK | TB_BOLD
#define EDIT_MSGSTR_BG TB_BLACK
#define EDIT_MSGSTR_FOCUS_FG TB_YELLOW | TB_BOLD
diff --git a/draw.c b/draw.c
@@ -48,6 +48,8 @@ init_bufferline(struct BufferLine* bl)
return;
bl->text = NULL;
bl->length = 0;
+ bl->fg = 0;
+ bl->bg = 0;
}
void
@@ -61,6 +63,8 @@ free_bufferline(struct BufferLine* bl)
bl->text = NULL;
}
bl->length = 0;
+ bl->fg = 0;
+ bl->bg = 0;
}
void
@@ -259,11 +263,20 @@ draw_editbox(const struct DrawState* state)
if (!curline || !curline->text)
return NULL;
if (curline->length > state->info_first_shown_column)
- u32_draw_string(startx+1, starty+1+i, fg,
- bg, curline->text +
- state->info_first_shown_column,
+ u32_draw_string(startx+1, starty+1+i,
+ curline->fg == 0 ? fg : curline->fg,
+ curline->bg == 0 ? bg : curline->bg,
+ curline->text +
+ state->info_first_shown_column,
w-3, w-3, 1, 1, LEFT);
}
+
+ if (state->info_first_shown_row > 0)
+ u32_draw_string(endx-2, starty+1, fg, bg, (uint32_t*)L"\u2191",
+ 1, 1, 0, 0, LEFT);
+ if (state->info_first_shown_row + (h-3)/2 + 2 <= state->info_rows_count)
+ u32_draw_string(endx-2, h/2+1, fg, bg, (uint32_t*)L"\u2193",
+ 1, 1, 0, 0, LEFT);
/*
*u32_draw_string(startx+1, starty+1, EDIT_MSGID_FG, EDIT_MSGID_BG,
* state->entries[state->msgid_number-1].msgid, w-2,
@@ -360,6 +373,8 @@ draw_status(const struct DrawState* state)
else
strncpy(buf, pseg->format, MAXBUFLINE);
buf[MAXBUFLINE-1] = 0;
+ if (pseg == status_segments + LEN(status_segments)-1)
+ seg_size = state->maxx-1 - current_start;
if (!draw_string(current_start, state->maxy-1, pseg->fg,
pseg->bg, buf, seg_size, seg_size, 1, 1,
pseg->alignment))
diff --git a/draw.h b/draw.h
@@ -25,6 +25,8 @@ typedef enum {
struct BufferLine {
uint32_t* text;
size_t length;
+ uint16_t fg;
+ uint16_t bg;
};
struct DrawState {
@@ -44,6 +46,7 @@ struct DrawState {
int info_first_shown_column;
int info_first_shown_row;
int info_rows_count;
+ int info_rows_maxlen;
struct PoEntry* entries;
void (*prompt_callback)(struct DrawState*, struct tb_event*);
int running;
diff --git a/po.c b/po.c
@@ -22,7 +22,7 @@ init_po_entry(struct PoEntry* entry)
entry->flags = FL_NONE;
entry->msgid = NULL;
entry->msgid_plural = NULL;
- entry->nplural = 0;
+ entry->plural_forms = NULL;
entry->msgstr = NULL;
entry->msgstr_count = 0;
entry->comments = NULL;
@@ -45,6 +45,8 @@ free_po_entry(struct PoEntry* entry)
}
if (entry->msgid_plural)
free(entry->msgid_plural);
+ if (entry->plural_forms)
+ free(entry->plural_forms);
if (entry->comments)
{
@@ -83,6 +85,26 @@ set_msgid(struct PoEntry* entry, const char* msgid, int append)
}
struct PoEntry*
+set_msgid_plural(struct PoEntry* entry, const char* msgid_plural, int append)
+{
+ uint32_t umsgid_plural[MAXMSG];
+ if (!entry)
+ return NULL;
+ u8_string_to_unicode(umsgid_plural, msgid_plural);
+ return u32_set_msgid_plural(entry, umsgid_plural, append);
+}
+
+struct PoEntry*
+set_plural_forms(struct PoEntry* entry, const char* plural_forms, int append)
+{
+ uint32_t uplural_forms[MAXMSG];
+ if (!entry)
+ return NULL;
+ u8_string_to_unicode(uplural_forms, plural_forms);
+ return u32_set_plural_forms(entry, uplural_forms, append);
+}
+
+struct PoEntry*
set_msgstr(struct PoEntry* entry, const char* msgstr, int msgstr_index,
int append)
{
@@ -112,6 +134,44 @@ u32_set_msgid(struct PoEntry* entry, const uint32_t* msgid, int append)
}
struct PoEntry*
+u32_set_msgid_plural(struct PoEntry* entry, const uint32_t* msgid_plural,
+ int append)
+{
+ if (!entry)
+ return NULL;
+ if (!entry->msgid_plural)
+ {
+ entry->msgid_plural = calloc(MAXMSG, sizeof(uint32_t));
+ if (!entry->msgid_plural)
+ return NULL;
+ }
+ if (append)
+ u32_strncat(entry->msgid_plural, msgid_plural, MAXMSG);
+ else
+ u32_strncpy(entry->msgid_plural, msgid_plural, MAXMSG);
+ return entry;
+}
+
+struct PoEntry*
+u32_set_plural_forms(struct PoEntry* entry, const uint32_t* plural_forms,
+ int append)
+{
+ if (!entry)
+ return NULL;
+ if (!entry->plural_forms)
+ {
+ entry->plural_forms = calloc(MAXMSG, sizeof(uint32_t));
+ if (!entry->plural_forms)
+ return NULL;
+ }
+ if (append)
+ u32_strncat(entry->plural_forms, plural_forms, MAXMSG);
+ else
+ u32_strncpy(entry->plural_forms, plural_forms, MAXMSG);
+ return entry;
+}
+
+struct PoEntry*
u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr, int msgstr_index,
int append)
{
@@ -466,8 +526,16 @@ parse_po_line(const char* line, struct PoEntry** entries, size_t* entries_size,
if (*state & PS_MSGID)
set_msgid(*current_entry, token, 1);
+ else if (*state & PS_MSGID_PLURAL)
+ set_msgid_plural(*current_entry, token, 1);
else if (*state & PS_MSGSTR)
+ {
+ if (*current_entry == *entries && starts_with(token,
+ "Plural-Forms: "))
+ set_plural_forms(*current_entry, token +
+ strlen("Plural-Forms: "), 0);
set_msgstr(*current_entry, token, 0, 1);
+ }
else if (*state & PS_MSGSTR_ARRAY)
set_msgstr(*current_entry, token, *msgstr_index, 1);
else if (*state & PS_COMMENT_DESC)
diff --git a/po.h b/po.h
@@ -54,7 +54,7 @@ struct PoEntry {
Flags flags;
uint32_t* msgid;
uint32_t* msgid_plural;
- size_t nplural;
+ uint32_t* plural_forms;
uint32_t** msgstr;
int msgstr_count;
uint32_t** comments;
@@ -69,10 +69,18 @@ void free_po_entry(struct PoEntry* entry);
struct PoEntry* set_flags(struct PoEntry* entry, const Flags flags);
struct PoEntry* set_msgid(struct PoEntry* entry, const char* msgid,
int append);
+struct PoEntry* set_msgid_plural(struct PoEntry* entry,
+ const char* msgid_plural, int append);
+struct PoEntry* set_plural_forms(struct PoEntry* entry,
+ const char* plural_forms, int append);
struct PoEntry* set_msgstr(struct PoEntry* entry, const char* msgstr,
int msgstr_index, int append);
struct PoEntry* u32_set_msgid(struct PoEntry* entry, const uint32_t* msgid,
int append);
+struct PoEntry* u32_set_msgid_plural(struct PoEntry* entry,
+ const uint32_t* msgid_plural, int append);
+struct PoEntry* u32_set_plural_forms(struct PoEntry* entry,
+ const uint32_t* plural_forms, int append);
struct PoEntry* u32_set_msgstr(struct PoEntry* entry, const uint32_t* msgstr,
int msgstr_index, int append);
struct PoEntry* u32_add_comment(struct PoEntry* entry, const uint32_t* comment);
diff --git a/poe.c b/poe.c
@@ -120,6 +120,7 @@ struct DrawState* join_lines(struct DrawState* state, size_t first_line);
struct BufferLine*
load_info(struct DrawState* state)
{
+ struct PoEntry* first = &state->entries[0];
struct PoEntry* current = &state->entries[state->msgid_number-1];
size_t msgid_num_lines = u32_lines_in_string(current->msgid);
size_t msgid_plural_num_lines = u32_lines_in_string(
@@ -128,15 +129,20 @@ load_info(struct DrawState* state)
struct BufferLine* newbuf = NULL;
struct BufferLine* pnewbuf = NULL;
+ state->info_rows_maxlen = 0;
+
if (current->msgid)
- num_lines += 1 + msgid_num_lines + 1;
- num_lines += 3; /* Plural-Forms */
+ num_lines += msgid_num_lines + 1;
if (current->msgid_plural)
- num_lines += 1 + msgid_plural_num_lines + 1;
+ {
+ num_lines += msgid_plural_num_lines + 1;
+ if (first->plural_forms)
+ num_lines += 3;
+ }
if (current->comments)
- num_lines += 1 + current->comment_lines + 1;
+ num_lines += current->comment_lines + 1;
if (current->ref_comments)
- num_lines += 1 + current->ref_comment_lines + 1;
+ num_lines += current->ref_comment_lines + 1;
newbuf = calloc(num_lines, sizeof(struct BufferLine));
if (!newbuf)
return NULL;
@@ -163,6 +169,10 @@ load_info(struct DrawState* state)
newlen = u32_u8_strncpy(pnewbuf->text, "msgid:",
MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
pnewbuf++;
for (size_t i = 0; i < msgid_num_lines; i++)
{
@@ -172,28 +182,26 @@ load_info(struct DrawState* state)
MAXBUFLINE));
newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
pumsgid += len+(pumsgid[len] ? 2 : 0);
pnewbuf++;
}
- pnewbuf->text[0] = 0;
- pnewbuf->length = 0;
- pnewbuf++;
+ /*
+ *pnewbuf->text[0] = 0;
+ *pnewbuf->length = 0;
+ *pnewbuf++;
+ */
}
- /* TODO: Parse first msgid for Plural-Forms */
- newlen = u32_u8_strncpy(pnewbuf->text, "Plural-Forms:", MAXBUFLINE);
- pnewbuf->length = newlen;
- pnewbuf++;
- newlen = u32_u8_strncpy(pnewbuf->text, "<Reserved>", MAXBUFLINE);
- pnewbuf->length = newlen;
- pnewbuf++;
- pnewbuf->text[0] = 0;
- pnewbuf->length = 0;
- pnewbuf++;
if (current->msgid_plural)
{
newlen = u32_u8_strncpy(pnewbuf->text, "msgid_plural:",
MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
pnewbuf++;
pumsgid = current->msgid_plural;
for (size_t i = 0; i < msgid_plural_num_lines; i++)
@@ -204,18 +212,48 @@ load_info(struct DrawState* state)
MAXBUFLINE));
newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
pumsgid += len+(pumsgid[len] ? 2 : 0);
pnewbuf++;
}
- pnewbuf->text[0] = 0;
- pnewbuf->length = 0;
- pnewbuf++;
+ /*
+ *pnewbuf->text[0] = 0;
+ *pnewbuf->length = 0;
+ *pnewbuf++;
+ */
+ if (first->plural_forms)
+ {
+ newlen = u32_u8_strncpy(pnewbuf->text, "Plural forms:",
+ MAXBUFLINE);
+ pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
+ pnewbuf++;
+ newlen = u32_strncpy(pnewbuf->text, first->plural_forms,
+ MAXBUFLINE);
+ pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf++;
+ /*
+ *pnewbuf->text[0] = 0;
+ *pnewbuf->length = 0;
+ *pnewbuf++;
+ */
+ }
}
if (current->comments)
{
newlen = u32_u8_strncpy(pnewbuf->text, "Comments:",
MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
pnewbuf++;
for (size_t i = 0; i < current->comment_lines; i++)
{
@@ -224,17 +262,25 @@ load_info(struct DrawState* state)
newlen = u32_strncpy(pnewbuf->text, comment,
MIN(len+1, MAXBUFLINE));
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
pnewbuf++;
}
- pnewbuf->text[0] = 0;
- pnewbuf->length = 0;
- pnewbuf++;
+ /*
+ *pnewbuf->text[0] = 0;
+ *pnewbuf->length = 0;
+ *pnewbuf++;
+ */
}
if (current->ref_comments)
{
newlen = u32_u8_strncpy(pnewbuf->text, "References:",
MAXBUFLINE);
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
pnewbuf++;
for (size_t i = 0; i < current->ref_comment_lines; i++)
{
@@ -243,6 +289,8 @@ load_info(struct DrawState* state)
newlen = u32_u8_strncpy(pnewbuf->text, ref_comment,
MIN(len+1, MAXBUFLINE));
pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
pnewbuf++;
}
}
@@ -442,6 +490,13 @@ move_start(struct DrawState* state)
void
move_left(struct DrawState* state)
{
+ if (state->edit_info_focused)
+ {
+ if (state->info_first_shown_column > 0)
+ state->info_first_shown_column--;
+ return;
+ }
+
if (state->input_column == 0)
return;
@@ -460,6 +515,14 @@ move_left(struct DrawState* state)
void
move_right(struct DrawState* state)
{
+ if (state->edit_info_focused)
+ {
+ if (state->info_first_shown_column + EDIT_WIDTH-3 <
+ state->info_rows_maxlen + 1)
+ state->info_first_shown_column++;
+ return;
+ }
+
size_t len = state->input_buffer[state->input_row].length;
if (state->input_column == len)
return;