poe

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

чување 4cd6e1ac30dc31e4bcaa7d5faabe4ff31b7aa0c7
родитељ f35c2cc0a498199805e239864ecc3829a52956d9
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sun, 11 Jul 2021 19:16:59 +0200

Handle #~ (obsolete messages) and show their number in statusline

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 2+-
Mconfig.def.h | 2+-
Mconfig.h | 2+-
Mdraw.c | 3++-
Mdraw.h | 4+++-
Mpo.c | 42+++++++++++++++++++++++++++++++++++++-----
Mpo.h | 20+++++++++++---------
Mpoe.1.in | 10++++++++++
Mpoe.c | 13+++++++------
Mutil.c | 13+++++++++++++
Mutil.h | 1+
измењених датотека: 11, додавања: 87(+), брисања: 25(-)

diff --git a/TODO b/TODO @@ -11,7 +11,7 @@ [ ] Yank msgstr to paste buffer [ ] Paste paste buffer to msgstr - [ ] Handle #~ (Don't show; flag? But write to file) + [x] Handle #~ (Don't show; flag? But write to file) [x] Search (highlight=/, then navigate with next/prev) [x] Search input diff --git a/config.def.h b/config.def.h @@ -58,7 +58,7 @@ void format_msgs(char* result, size_t result_size, const char* format, static const struct StatusSegment status_segments[] = { { .format = "%s%s", .callback = format_filename, .fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT }, - { .format = "%ld/%ld (%ld unt %ld fuzzy)", + { .format = "%ld/%ld (%ldu/%ldf/%ldo)", .callback = format_msgs, .fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER }, { .format = "H=HELP, q=QUIT", .callback = NULL, diff --git a/config.h b/config.h @@ -58,7 +58,7 @@ void format_msgs(char* result, size_t result_size, const char* format, static const struct StatusSegment status_segments[] = { { .format = "%s%s", .callback = format_filename, .fg = TB_BLACK, .bg = TB_WHITE, .alignment = LEFT }, - { .format = "%ld/%ld (%ld unt %ld fuzzy)", + { .format = "%ld/%ld (%ldu/%ldf/%ldo)", .callback = format_msgs, .fg = TB_WHITE | TB_BOLD, .bg = TB_BLUE, .alignment = CENTER }, { .format = "H=HELP, q=QUIT", .callback = NULL, diff --git a/draw.c b/draw.c @@ -114,6 +114,7 @@ init_drawstate(struct DrawState* state, char* error, char* filename, state->msgid_number = state->msgid_count > 0 ? 1 : 0; state->fuzzy_count = 0; state->untranslated_count = 0; + state->obsolete_count = 0; state->msgstr_index = 0; state->first_shown_msgid = state->msgid_number; } @@ -148,7 +149,7 @@ free_drawstate(struct DrawState* state) } if (state->entries) { - for (i = 0; i < state->msgid_count; i++) + for (i = 0; i < state->real_msgid_count; i++) { current_entry = state->entries+i; free_po_entry(current_entry); diff --git a/draw.h b/draw.h @@ -79,7 +79,9 @@ struct DrawState { size_t msgid_size; size_t fuzzy_count; size_t untranslated_count; - int msgstr_index; /* with msgstr[] */ + size_t obsolete_count; + size_t real_msgid_count; /* msgid_count + obsolete_count */ + int msgstr_index; /* with msgstr[] */ size_t first_shown_msgid; }; diff --git a/po.c b/po.c @@ -26,6 +26,7 @@ void init_po_entry(struct PoEntry* entry) { entry->flags = FL_NONE; + entry->obsolete = 0; entry->msgid = NULL; entry->msgid_plural = NULL; entry->plural_forms = NULL; @@ -382,11 +383,13 @@ load_file(struct DrawState* dstate, long* lineno, long* col) if (msgid_counter > 0) return LOAD_ERR_NOT_PO_FILE; + dstate->real_msgid_count = dstate->msgid_count + dstate->obsolete_count; + return LOAD_ERR_NONE; } int -save_file(const struct PoEntry* entries, const size_t msgid_count, +save_file(const struct PoEntry* entries, const size_t real_msgid_count, const char* filename) { const struct PoEntry* current = entries; @@ -405,7 +408,7 @@ save_file(const struct PoEntry* entries, const size_t msgid_count, backup_filename[len+1] = 0; - while (current < entries + msgid_count) + while (current < entries + real_msgid_count) { if (current->comment_lines > 0) { @@ -867,6 +870,20 @@ parse_po_line(const char* line, struct DrawState* dstate, (*col)++; } break; + case '~': + if (*col == 2 && *pstate & PS_COMMENT_TRAN) + { + *pstate &= ~PS_COMMENT_TRAN; + *pstate |= PS_COMMENT_OBSO; + pline++; + (*col)++; + } + else + { + *ptoken++ = *pline++; + (*col)++; + } + break; case '"': /* skip beginning and end quote */ if ((ptoken == token || *(pline+1) == 0) @@ -890,9 +907,17 @@ parse_po_line(const char* line, struct DrawState* dstate, if (*pstate == PS_NONE) { struct PoEntry* newchunk = NULL; + if ((*current_entry)->obsolete) + dstate->obsolete_count++; + else + { + /* don't count obsolete towards the msgid count or + * untranslated count */ + dstate->untranslated_count++; + dstate->msgid_count++; + } + (*current_entry)++; - dstate->msgid_count++; - dstate->untranslated_count++; if (*current_entry == dstate->entries + dstate->msgid_size) { dstate->msgid_size += ALLOC_DELTA; @@ -985,6 +1010,13 @@ parse_po_line(const char* line, struct DrawState* dstate, } else if (*pstate & PS_COMMENT_REFN) add_ref_comment(*current_entry, token); + else if (*pstate & PS_COMMENT_OBSO) + { + uint32_t u32_token[MAXCOMMENTLINE]; + u8_string_to_unicode(u32_token, token, MAXCOMMENTLINE); + u32_add_comment(*current_entry, u32_token); + (*current_entry)->obsolete = 1; + } *token = 0; } else if (*pstate & PS_COMMENT_TRAN) @@ -994,7 +1026,7 @@ parse_po_line(const char* line, struct DrawState* dstate, /* one-line states */ *pstate &= ~(PS_COMMENT_TRAN | PS_COMMENT_EXTR | PS_COMMENT_FLAG | - PS_COMMENT_REFN); + PS_COMMENT_REFN | PS_COMMENT_OBSO); return PARSE_ERR_NONE; } diff --git a/po.h b/po.h @@ -39,14 +39,15 @@ enum { typedef enum { PS_NONE = 0, - PS_COMMENT_TRAN = 1, /* "translator-comments" */ - PS_COMMENT_EXTR = 1 << 1, /* "extracted-comments" */ - PS_COMMENT_FLAG = 1 << 2, /* "flag" */ - PS_COMMENT_REFN = 1 << 3, /* "reference" */ - PS_MSGID = 1 << 4, - PS_MSGID_PLURAL = 1 << 5, - PS_MSGSTR = 1 << 6, - PS_MSGSTR_ARRAY = 1 << 7 + PS_COMMENT_TRAN = 1, /* "translator-comments" : # */ + PS_COMMENT_EXTR = 1 << 1, /* "extracted-comments" : #. */ + PS_COMMENT_FLAG = 1 << 2, /* "flag" : #, */ + PS_COMMENT_REFN = 1 << 3, /* "reference" : #: */ + PS_COMMENT_OBSO = 1 << 4, /* obsolete (undocumented) : #~ */ + PS_MSGID = 1 << 5, + PS_MSGID_PLURAL = 1 << 6, + PS_MSGSTR = 1 << 7, + PS_MSGSTR_ARRAY = 1 << 8 } ParseState; /* Complete list at: @@ -68,6 +69,7 @@ typedef enum { struct PoEntry { Flags flags; + int obsolete; uint32_t* msgid; uint32_t* msgid_plural; uint32_t* plural_forms; @@ -106,7 +108,7 @@ struct PoEntry* u32_add_trans_comment(struct PoEntry* entry, const uint32_t* trans_comment); struct PoEntry* add_ref_comment(struct PoEntry* entry, const char* comment); int load_file(struct DrawState* state, long* lineno, long* col); -int save_file(const struct PoEntry* entries, const size_t msgid_count, +int save_file(const struct PoEntry* entries, const size_t real_msgid_count, const char* filename); int parse_po_line(const char* line, struct DrawState* dstate, struct PoEntry** current_entry, ParseState* pstate, long* col, diff --git a/poe.1.in b/poe.1.in @@ -138,6 +138,16 @@ When the search box is open, relevant text editing and movement commands from the edit box also apply. For example, \fCC-R\fP moves one word backwards, and \fCC-W\fP deletes one word backwards. . +.SH "STATUS LINE" +. +.LP +Status line is comprised of a number of segments, by default three. The central +segment displays the current message number, the total messages count, then in +parentheses: number of untranslated messages, number of fuzzy messages and the +number of obsolete messages. Obsolete messages are messages whose msgid doesn't +match any msgid in the message catalog anymore, and are commented out in the .po +file using \fC#~\fP comments. +. .SH "MESSAGE FLAGS" . .LP diff --git a/poe.c b/poe.c @@ -118,8 +118,7 @@ format_filename(char* result, size_t result_size, const char* format, { if (!result) return; - - snprintf(result, result_size, format, state->filename, + snprintf(result, result_size, format, u8_basename(state->filename), state->dirty ? "*" : ""); } @@ -132,9 +131,10 @@ format_msgs(char* result, size_t result_size, const char* format, snprintf(result, result_size, format, state ? state->msgid_number : 0, - state ? state->msgid_count : 0, + state ? state->msgid_count: 0, state ? state->untranslated_count : 0, - state ? state->fuzzy_count : 0); + state ? state->fuzzy_count : 0, + state ? state->obsolete_count : 0); } void @@ -145,7 +145,8 @@ quit_callback(struct DrawState* state, struct tb_event* ev) if (ev->ch == 'y') { int result = save_file(state->entries, - state->msgid_count, state->filename); + state->real_msgid_count, + state->filename); switch (result) { case SAVE_ERR_CANT_ALLOC: @@ -1820,7 +1821,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) { if (!state->dirty) return; - int result = save_file(state->entries, state->msgid_count, + int result = save_file(state->entries, state->real_msgid_count, state->filename); switch (result) { diff --git a/util.c b/util.c @@ -300,6 +300,19 @@ u32_starts_with(const uint32_t* s, const uint32_t* with) return *with == 0; } +const char* +u8_basename(const char* path) +{ + if (!path) + return NULL; + const char* ppath = path + strlen(path); + while (ppath != path && *ppath != '/') + ppath--; + if (*ppath == '/') + ppath++; + return ppath; +} + void poe_log(const char* msg, ...) { diff --git a/util.h b/util.h @@ -38,5 +38,6 @@ size_t u8_lines_in_string(const char* s); size_t u32_lines_in_string(const uint32_t* s); int starts_with(const char* s, const char* with); int u32_starts_with(const uint32_t* s, const uint32_t* with); +const char* u8_basename(const char* path); void poe_log(const char* msg, ...);