Hello community, here is the log from the commit of package rofi-calc for openSUSE:Factory checked in at 2019-04-01 12:40:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rofi-calc (Old) and /work/SRC/openSUSE:Factory/.rofi-calc.new.25356 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rofi-calc" Mon Apr 1 12:40:29 2019 rev:3 rq:690267 version:1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rofi-calc/rofi-calc.changes 2019-03-15 10:52:16.908971436 +0100 +++ /work/SRC/openSUSE:Factory/.rofi-calc.new.25356/rofi-calc.changes 2019-04-01 12:40:46.993985051 +0200 @@ -1,0 +2,7 @@ +Mon Apr 1 08:23:56 UTC 2019 - [email protected] + +- Update to 1.1: + * Add -calc-command to specify a shell command (#3) + * Execute with last_result from qalc when Ctrl+Enter is pressed (#3) + +------------------------------------------------------------------- Old: ---- v1.0.tar.gz New: ---- v1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rofi-calc.spec ++++++ --- /var/tmp/diff_new_pack.uzYq2A/_old 2019-04-01 12:40:48.717985887 +0200 +++ /var/tmp/diff_new_pack.uzYq2A/_new 2019-04-01 12:40:48.725985892 +0200 @@ -12,12 +12,12 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# Please submit bugfixes or comments via http://bugs.opensuse.org/ # Name: rofi-calc -Version: 1.0 +Version: 1.1 Release: 0 Summary: Calculator for rofi License: MIT ++++++ v1.0.tar.gz -> v1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.0/.travis.yml new/rofi-calc-1.1/.travis.yml --- old/rofi-calc-1.0/.travis.yml 2019-03-04 15:46:13.000000000 +0100 +++ new/rofi-calc-1.1/.travis.yml 2019-03-30 21:54:07.000000000 +0100 @@ -1,5 +1,5 @@ sudo: required -dist: trusty +dist: xenial language: c compiler: - clang @@ -45,8 +45,9 @@ - make - sudo make install - cd - - - git clone --recursive https://github.com/DaveDavenport/rofi + - git clone --recursive https://github.com/davatorium/rofi - cd rofi + - git checkout 1.5.2 - autoreconf -i - ./configure - make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.0/README.md new/rofi-calc-1.1/README.md --- old/rofi-calc-1.0/README.md 2019-03-04 15:46:13.000000000 +0100 +++ new/rofi-calc-1.1/README.md 2019-03-30 21:54:07.000000000 +0100 @@ -16,6 +16,17 @@ rofi -show calc -modi calc -no-show-match -no-sort +The result of the current input can be selected with `Ctrl+Enter`, and history entries can be selected with `Enter`. By default this will just output the equation/result. + +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 +* `{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): + + rofi -show calc -modi calc -no-show-match -no-sort -calc-command "echo '{result}' | xclip" + It's convenient to bind it to a key combination in i3. For instance, you could use: bindsym $mod+c exec --no-startup-id "rofi -show calc -modi calc -no-show-match -no-sort" @@ -29,7 +40,7 @@ You will also need development headers for `rofi` and `libqalculate`. Depending on your distribution these may be included in different packages: * Arch, Gentoo: included with `rofi`, `libqalculate` -* OpenSUSE: `zypper in rofi rofi-devel qalculate` +* OpenSUSE: `zypper in rofi rofi-devel qalculate` * Debian: `dpkg --install rofi-dev qalc libqalculate-dev` * Ubuntu: `apt install rofi-dev qalc libqalculate-dev` * Solus: `eopkg it rofi-devel libqalculate-devel` @@ -43,7 +54,7 @@ #### Package Manager * [Arch AUR](https://aur.archlinux.org/packages/rofi-calc/) -* [OpenSUSE Leap](https://software.opensuse.org/package/rofi-calc) +* [openSUSE](https://software.opensuse.org/package/rofi-calc) #### From source diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rofi-calc-1.0/src/calc.c new/rofi-calc-1.1/src/calc.c --- old/rofi-calc-1.0/src/calc.c 2019-03-04 15:46:13.000000000 +0100 +++ new/rofi-calc-1.1/src/calc.c 2019-03-30 21:54:07.000000000 +0100 @@ -44,10 +44,35 @@ */ typedef struct { + char* cmd; char* last_result; GPtrArray* history; } CALCModePrivateData; + +/** + * Used in splitting equations into {expression} and {result} + */ +#define PARENS_LEFT '(' +#define PARENS_RIGHT ')' +#define EQUALS_SIGN '=' + + +/** + * Calc command option + */ +#define CALC_COMMAND_OPTION "-calc-command" + + +/** + * 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}" + + static void get_calc(Mode* sw) { /** @@ -57,6 +82,11 @@ CALCModePrivateData* pd = (CALCModePrivateData*)mode_get_private_data(sw); pd->last_result = g_strdup(""); pd->history = g_ptr_array_new(); + + char *cmd = NULL; + if (find_arg_str(CALC_COMMAND_OPTION, &cmd)) { + pd->cmd = g_strdup(cmd); + } } @@ -99,6 +129,68 @@ } +// Split the equation result into the left (expression) and right (result) side +// of the equals sign. +// +// Note that both sides can themselves contain equals sign, consider the simple +// example of `20x + 40 = 100`. This means we cannot naively split on the '=' +// character. +static char** split_equation(char* string) +{ + int index = 0; + int parens_depth = 0; + char* curr = string; + + // Iterate through and track our level of nestedness, stopping when + // we've hit an equals sign not inside other parentheses. + // At this point we can set the NULL character to split the string + // into `string` and `curr + 1`. + while (*curr) { + if (*curr == PARENS_LEFT) { + parens_depth++; + } else if (*curr == PARENS_RIGHT) { + parens_depth--; + } else if (*curr == EQUALS_SIGN && parens_depth == 0) { + break; + } + curr++; + } + *curr = '\0'; + + // 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 + if (cmd == NULL) { + printf("%s\n", entry); + return; + } + + // Otherwise, we will execute -calc-command + char **parts = split_equation(entry); + char *user_cmd = helper_string_replace_if_exists(cmd, + EQUATION_LHS_KEY, parts[0], + EQUATION_RHS_KEY, parts[1], + NULL); + g_free(parts); + + gchar *escaped_cmd = g_strescape(user_cmd, NULL); + gchar *complete_cmd = g_strdup_printf("/bin/sh -c \"%s\"", escaped_cmd); + g_free(user_cmd); + g_free(escaped_cmd); + + helper_execute_command(NULL, complete_cmd, FALSE, NULL); + 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; @@ -109,16 +201,23 @@ retv = PREVIOUS_DIALOG; } else if (menu_entry & MENU_QUICK_SWITCH) { retv = (menu_entry & MENU_LOWER_MASK); - } else if (((menu_entry & MENU_OK) && selected_line == 0) || - ((menu_entry & MENU_CUSTOM_INPUT) && selected_line == -1u)) { + } else if ((menu_entry & MENU_OK) && selected_line == 0) { 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); } retv = RELOAD_DIALOG; } else if ((menu_entry & MENU_OK) && selected_line > 0) { - printf("%s\n", (char*)g_ptr_array_index(pd->history, get_real_history_index(pd->history, selected_line))); + char* entry = g_ptr_array_index(pd->history, get_real_history_index(pd->history, selected_line)); + execsh(pd->cmd, entry); retv = MODE_EXIT; + } else if (menu_entry & MENU_CUSTOM_INPUT) { + if (!is_error_string(pd->last_result) && strlen(pd->last_result) > 0) { + execsh(pd->cmd, pd->last_result); + retv = MODE_EXIT; + } else { + retv = RELOAD_DIALOG; + } } else if (menu_entry & MENU_ENTRY_DELETE) { if (selected_line > 0) { g_ptr_array_remove_index(pd->history, get_real_history_index(pd->history, selected_line));
