poe

Уређивач .po фајлова
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 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:
MTODO | 4++--
Mconfig.def.h | 2++
Mconfig.h | 2++
Mdraw.c | 21++++++++++++++++++---
Mdraw.h | 3+++
Mpo.c | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mpo.h | 10+++++++++-
Mpoe.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;