Signed-off-by: Lars Øyvind Hagland <lar...@gmail.com>
---
 src/pacman/util.c | 55 ++++++++++++++++++++++++++++++++++++++++++-----
 src/pacman/util.h |  2 ++
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/pacman/util.c b/src/pacman/util.c
index e9187529..d3c89ecb 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -531,7 +531,12 @@ static void table_print_line(const alpm_list_t *line, 
short col_padding,
                if(cell->mode & CELL_TITLE) {
                        printf("%s%*s%s", config->colstr.title, cell_width, 
str, config->colstr.nocolor);
                } else {
-                       printf("%*s", cell_width, str);
+                       // printf includes ANSI control chars in width, pad 
manually with actual width
+                       if (cell_width > 0) {
+                               printf("%*s%s", cell_width - (int)cell->len, 
"", str);
+                       } else {
+                               printf("%s%*s", str, -cell_width - 
(int)cell->len, "");
+                       }
                }
                need_padding = 1;
        }
@@ -860,8 +865,10 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
                        target->remove != NULL ? 
alpm_pkg_get_version(target->remove) : "");
        add_table_cell(&ret, str, CELL_NORMAL | CELL_FREE);
 
-       pm_asprintf(&str, "%s",
-                       target->install != NULL ? 
alpm_pkg_get_version(target->install) : "");
+       str = version_colorize_diff(
+                       target->install ? alpm_pkg_get_version(target->install) 
: "",
+                       target->remove ? alpm_pkg_get_version(target->remove) : 
"",
+                       config->colstr.title);
        add_table_cell(&ret, str, CELL_NORMAL | CELL_FREE);
 
        /* and size */
@@ -886,7 +893,7 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
 /* prepare a list of pkgs to display */
 static void _display_targets(alpm_list_t *targets, int verbose)
 {
-       char *str;
+       char *str, *version;
        off_t isize = 0, rsize = 0, dlsize = 0;
        unsigned short cols;
        alpm_list_t *i, *names = NULL, *header = NULL, *rows = NULL;
@@ -918,8 +925,12 @@ static void _display_targets(alpm_list_t *targets, int 
verbose)
                }
 
                if(target->install) {
+                       version = 
version_colorize_diff(alpm_pkg_get_version(target->install),
+                                       target->remove ? 
alpm_pkg_get_version(target->remove) : "",
+                                       config->colstr.nocolor);
                        pm_asprintf(&str, "%s%s-%s%s", 
alpm_pkg_get_name(target->install), config->colstr.faint,
-                                       alpm_pkg_get_version(target->install), 
config->colstr.nocolor);
+                                       version, config->colstr.nocolor);
+                       free(version);
                } else if(isize == 0) {
                        pm_asprintf(&str, "%s%s-%s%s", 
alpm_pkg_get_name(target->remove), config->colstr.faint,
                                        alpm_pkg_get_version(target->remove), 
config->colstr.nocolor);
@@ -1676,6 +1687,40 @@ int colon_printf(const char *fmt, ...)
        return ret;
 }
 
+/** Highlight the changed part of the version string
+ *
+ * Inserts an ANSI color tag before the first changed version part and a
+ * no-color tag at the end.
+ *
+ * @param version The new version string
+ * @param old_version The old version string
+ * @param color The color of the highlighted part
+ * @return Pointer to the new string
+ */
+char *version_colorize_diff(const char *version, const char *old_version, 
const char *color)
+{
+       char *ret;
+       char start[strlen(version)], end[strlen(version)];
+       unsigned long pos = 0;
+
+       while ((pos < strlen(version))
+                       && (pos < strlen(old_version))
+                       && (version[pos] == old_version[pos]))
+               pos++;
+       while (pos > 0
+                       && version[pos] != '.'
+                       && version[pos] != '-')
+               pos--;
+       if (pos != 0)
+               pos++;
+
+       strncpy(start, version, pos);
+       start[pos] = '\0';      // strncpy does not add delimiter
+       strcpy(end, &version[pos]);
+       pm_asprintf(&ret, "%s%s%s%s", start, color, end, 
config->colstr.nocolor);
+       return ret;
+}
+
 int pm_printf(alpm_loglevel_t level, const char *format, ...)
 {
        int ret;
diff --git a/src/pacman/util.h b/src/pacman/util.h
index c97048fb..7597da40 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -81,6 +81,8 @@ int yesno(const char *format, ...) 
__attribute__((format(printf, 1, 2)));
 int noyes(const char *format, ...) __attribute__((format(printf, 1, 2)));
 char *arg_to_string(int argc, char *argv[]);
 char *safe_fgets_stdin(char *s, int size);
+char *version_colorize_diff(const char *version, const char *old_version, 
const char *color);
+
 void console_cursor_hide(void);
 void console_cursor_show(void);
 void console_cursor_move_up(unsigned int lines);
-- 
2.27.0

Reply via email to