чување 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:
измењених датотека: 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, ...);