Hello community, here is the log from the commit of package rofi-calc for openSUSE:Factory checked in at 2019-04-23 14:36:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rofi-calc (Old) and /work/SRC/openSUSE:Factory/.rofi-calc.new.5536 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rofi-calc" Tue Apr 23 14:36:58 2019 rev:5 rq:696928 version:1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/rofi-calc/rofi-calc.changes 2019-04-03 09:28:03.711816562 +0200 +++ /work/SRC/openSUSE:Factory/.rofi-calc.new.5536/rofi-calc.changes 2019-04-23 14:37:06.493514978 +0200 @@ -1,0 +2,7 @@ +Tue Apr 23 05:54:33 UTC 2019 - [email protected] + +- Update to 1.4: + * Fix parsing result with -terse + * Add history feature (#6) + +------------------------------------------------------------------- Old: ---- v1.3.tar.gz New: ---- v1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rofi-calc.spec ++++++ --- /var/tmp/diff_new_pack.HsAmdY/_old 2019-04-23 14:37:09.213516578 +0200 +++ /var/tmp/diff_new_pack.HsAmdY/_new 2019-04-23 14:37:09.217516581 +0200 @@ -17,7 +17,7 @@ Name: rofi-calc -Version: 1.3 +Version: 1.4 Release: 0 Summary: Calculator for rofi License: MIT ++++++ v1.3.tar.gz -> v1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.3/.gitignore new/rofi-calc-1.4/.gitignore --- old/rofi-calc-1.3/.gitignore 2019-04-02 00:36:35.000000000 +0200 +++ new/rofi-calc-1.4/.gitignore 2019-04-23 00:30:54.000000000 +0200 @@ -11,3 +11,4 @@ configure config.* build/ +compile_commands.json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.3/README.md new/rofi-calc-1.4/README.md --- old/rofi-calc-1.3/README.md 2019-04-02 00:36:35.000000000 +0200 +++ new/rofi-calc-1.4/README.md 2019-04-23 00:30:54.000000000 +0200 @@ -22,7 +22,7 @@ Use the `-calc-command` option to specify a shell command to execute which will be interpolated with the following keys: -* `{expression}`: the left-side of the equation +* `{expression}`: the left-side of the equation (currently not available when using `-terse`) * `{result}`: the right of the equation The following example copies the result to the clipboard (NOTE: `{result}` should be quoted since it may contain characters that your shell would otherwise interpret): @@ -37,6 +37,10 @@ rofi -show calc -modi calc -no-show-match -no-sort -no-bold +To disable the history: + + rofi -show calc -modi calc -no-show-match -no-sort -no-history + ## Compilation ### Dependencies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.3/src/calc.c new/rofi-calc-1.4/src/calc.c --- old/rofi-calc-1.3/src/calc.c 2019-04-02 00:36:35.000000000 +0200 +++ new/rofi-calc-1.4/src/calc.c 2019-04-23 00:30:54.000000000 +0200 @@ -1,28 +1,27 @@ -/** - * rofi-calc - * - * MIT/X11 License - * Copyright (c) 2018 Sven-Hendrik Haase <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +// rofi-calc +// +// MIT/X11 License +// Copyright (c) 2018 Sven-Hendrik Haase <[email protected]> +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + #include <stdlib.h> #include <stdio.h> #include <unistd.h> @@ -39,9 +38,7 @@ G_MODULE_EXPORT Mode mode; -/** - * The internal data structure holding the private data of the TEST Mode. - */ +// The internal data structure holding the private data of the TEST Mode. typedef struct { char* cmd; @@ -50,47 +47,102 @@ } CALCModePrivateData; -/** - * Used in splitting equations into {expression} and {result} - */ +// Used in splitting equations into {expression} and {result}. #define PARENS_LEFT '(' #define PARENS_RIGHT ')' #define EQUALS_SIGN '=' -/** - * Calc command option - */ +// Calc command option #define CALC_COMMAND_OPTION "-calc-command" -/** - * Option to disable bold results - */ +// Option to disable bold results #define NO_BOLD_OPTION "-no-bold" -/** - * Terse option - */ +// Terse option #define TERSE_OPTION "-terse" -/** - * The following keys can be specified in `CALC_COMMAND_FLAG` and - * will be replaced with the left-hand side and right-hand side of - * the equation. - */ +// The following keys can be specified in `CALC_COMMAND_FLAG` and +// will be replaced with the left-hand side and right-hand side of +// the equation. #define EQUATION_LHS_KEY "{expression}" #define EQUATION_RHS_KEY "{result}" +// History stuff +#define NO_HISTORY_OPTION "-no-history" +#define HISTORY_LENGTH 100 + + +// Limit `str` to at most `limit` new lines. +// Returns a new string of either the limited length or the length length. +// However, in both cases, it's a new string. +static gchar* limit_to_n_newlines(gchar* str, uint32_t limit) { + uint32_t newlines = 0; + uint32_t last_index = 0; + uint32_t string_length = strlen(str); + + while (last_index < string_length) { + if (str[last_index] == '\n') { + newlines++; + } + + if (newlines >= limit) { + gchar* limited_str = g_strndup(str, last_index); + return limited_str; + } + + last_index++; + } + + return g_strdup(str); +} + + +// Append `input` to history. +static void append_str_to_history(gchar* input) { + GError *error = NULL; + gchar* history_file = g_build_filename(g_get_user_data_dir(), "rofi", "rofi_calc_history", NULL); + gchar* history_contents; + + if (g_file_test(history_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + g_file_get_contents(history_file, &history_contents, NULL, &error); + + if (error != NULL) { + g_error("Error while reading the history file: %s", error->message); + g_error_free(error); + } + } else { + // Empty history, initialize it. + history_contents = ""; + } + + gchar* new_history = g_strjoin("\n", history_contents, input, NULL); + g_strstrip(new_history); + + gchar* limited_str = g_strreverse(limit_to_n_newlines(g_strreverse(new_history), HISTORY_LENGTH)); + + g_file_set_contents(history_file, limited_str, -1, &error); + + if (error != NULL) { + g_error("Error while writing the history file: %s", error->message); + g_error_free(error); + } + + g_free(limited_str); + g_free(new_history); + g_free(history_contents); + g_free(history_file); +} + + +// Get the entries to display. +// This gets called on plugin initialization. static void get_calc(Mode* sw) { - /** - * Get the entries to display. - * this gets called on plugin initialization. - */ CALCModePrivateData* pd = (CALCModePrivateData*)mode_get_private_data(sw); pd->last_result = g_strdup(""); pd->history = g_ptr_array_new(); @@ -99,20 +151,45 @@ if (find_arg_str(CALC_COMMAND_OPTION, &cmd)) { pd->cmd = g_strdup(cmd); } + + if (find_arg(NO_HISTORY_OPTION) == -1) { + // Load old history if it exists. + GError *error = NULL; + gchar* history_file = g_build_filename(g_get_user_data_dir(), "rofi", "rofi_calc_history", NULL); + gchar* history_contents; + + if (g_file_test(history_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + g_file_get_contents(history_file, &history_contents, NULL, &error); + + if (error != NULL) { + g_error("Error while reading the history file: %s", error->message); + g_error_free(error); + } + + char* newline = strtok(history_contents, "\n"); + + while(newline != NULL) { + g_ptr_array_add(pd->history, newline); + + newline = strtok(NULL, "\n"); + } + } + + g_free(history_file); + } } +// Called on startup when enabled (in modi list) static int calc_mode_init(Mode* sw) { - /** - * Called on startup when enabled (in modi list) - */ if (mode_get_private_data(sw) == NULL) { CALCModePrivateData* pd = g_malloc0(sizeof(*pd)); mode_set_private_data(sw, (void*)pd); // Load content. get_calc(sw); } + return TRUE; } @@ -135,6 +212,7 @@ return FALSE; } + static int get_real_history_index(GPtrArray* history, unsigned int selected_line) { return history->len - selected_line; @@ -149,6 +227,14 @@ // character. static char** split_equation(char* string) { + char** result = malloc(2 * sizeof(char*)); + + if (find_arg(TERSE_OPTION) > -1) { + result[0] = NULL; + result[1] = g_strdup(string); // with -terse, string _is_ the result + return result; + } + int parens_depth = 0; char* curr = string; @@ -170,13 +256,13 @@ // Strip trailing whitespace with `g_strchomp()` from the left. // Strip leading whitespace with `g_strchug()` from the right. - char** result = malloc(2 * sizeof(char*)); result[0] = g_strchomp(string); result[1] = g_strchug(curr + 1); return result; } + static void execsh(char* cmd, char* entry) { // If no command was provided, simply print the entry @@ -202,6 +288,7 @@ g_free(complete_cmd); } + static ModeMode calc_mode_result(Mode* sw, int menu_entry, G_GNUC_UNUSED char** input, unsigned int selected_line) { ModeMode retv = MODE_EXIT; @@ -216,6 +303,9 @@ if (!is_error_string(pd->last_result) && strlen(pd->last_result) > 0) { char* history_entry = g_strdup_printf("%s", pd->last_result); g_ptr_array_add(pd->history, (gpointer) history_entry); + if (find_arg(NO_HISTORY_OPTION) == -1) { + append_str_to_history(history_entry); + } } retv = RELOAD_DIALOG; } else if ((menu_entry & MENU_OK) && selected_line > 0) { @@ -274,6 +364,7 @@ return g_strdup(g_ptr_array_index(pd->history, real_index)); } + static int calc_token_match(G_GNUC_UNUSED const Mode* sw, G_GNUC_UNUSED rofi_int_matcher** tokens, G_GNUC_UNUSED unsigned int index) { return TRUE; @@ -282,6 +373,7 @@ // It's a hacky way of making rofi show new window titles. extern void rofi_view_reload(void); + static void process_cb(GObject* source_object, GAsyncResult* res, gpointer user_data) { GError *error = NULL; @@ -307,14 +399,17 @@ unsigned int line_length = strcspn(stdout_buf, "\n"); *last_result = g_strndup(stdout_buf, line_length); + rofi_view_reload(); } + static char* calc_preprocess_input(Mode* sw, const char* input) { GError *error = NULL; CALCModePrivateData* pd = (CALCModePrivateData*)mode_get_private_data(sw); + // Build array of strings that is later fed into a subprocess to actually start qalc with proper parameters. GPtrArray *argv = g_ptr_array_new(); g_ptr_array_add(argv, "qalc"); g_ptr_array_add(argv, "+u8");
