v1cont / yad

Yet Another Dialog
GNU General Public License v3.0
654 stars 58 forks source link

feature: form symbolic ID #213

Closed step- closed 9 months ago

step- commented 1 year ago

FORM SYMBOLIC ID

The main idea is to add support for symbolic IDs, such as @name, where one can already use ordinal IDs, such as %N, in a form. Similarly for command output redirection: add support for @name: where %N: can be used.

This commit adds two new features to forms:

    --form --use-output-prefix[=PREFIX] --field=label!tooltip:type@ID

Example:

--form --use-output-prefix --field=Number:num@NUMBER 10

Output:

NUMBER=10|

Can be combined with --quoted-output

--form --quoted-output --separator="; " --use-output-prefix="%@ <- " \
    --field="R string:@r_string" "hello" --field= ""

Output:

r_string <- 'hello'; nul=''

Fixed string "nul" is used automatically for any undeclared @ID.

yad --form --use-output-prefix --separator=" " --field=:@name test > /tmp/data.sh &&
        . /tmp/data.sh && echo "name=$name"

yad --form --use-output-prefix --separator=$'\n' \
        --field='code:ro' 'declare -A a' \
        --field=':@a[ka]' A --field=':@a[kb]' B \
        --field='code:ro' 'printf %s\\n "${a[@]}"' |
        bash -x
--form --field=label!tooltip:type[@ID]

Example:

--form --field='+1:fbtn@B' '@echo @N:$((@N+1))' --field=':num@N' 1 --use-interp

Can be escaped with \@ID to avoid expansion Can be mixed with %N and ^N: but not recommended; better use one or the other

Wherever the use of symbolic references (@ID) vs ordinal references (%N) simplifies coding or maintaining the code.

Form options
    --field=LABEL[!TOOLTIP][:TYPE[@ID]]
...
    --use-output-prefix[=PREFIX]
           Prefix output field value with PREFIX. Default PREFIX is %@=. If %@ is included
           in PREFIX, it will be replaced by the field's @ID (without the leading "@") if
           defined, otherwise by fixed string "nul".
...
           BTN - button field. Label text may be formatted as LABEL[!ICON[!TOOLTIP]]
           where `!' is an item separator. LABEL is the text of button label or yad stock
           id. ICON is a button icon (stock id or file name). TOOLTIP is the text of an
           optional help popup tooltip. Initial value is a command which is started when
           the button is clicked. Special symbols %N (percent followed by a number) in
           command will be replaced by the value of the Nth field. If command starts with
           @, the output of com‐ mand will be parsed and lines that start with M: (a
           number followed by colon) will set the new value of the Mth field.  @ID can
           be used instead of %N and M:.  A quoting style for value when sh -c is used -
           single quotes around command and double quotes around -c argument.

In option.c, setting the default output prefix was similar to setting the default interpreter, so I followed that example. The setter function and the new options are:

static gboolean set_form_output_prefix (const gchar *, const gchar *, gpointer, GError **);

options.form_data.use_output_prefix = FALSE;
options.form_data.output_prefix = "%@=";

Modifications of existing functions:

Field ID is stored in struct YadFields as member atid. Mind that atid stores "@ID" not "ID".

typedef struct {
  gchar *name;
  gchar *tip;
  YadFieldType type;
  gchar *atid;
} YadField;

IDs, if any, are expanded into their corresponding %N and ^N: forms, which are then processed as usual with the existing code. Two new functions in form.c perform ID expansion: preprocess_atid() and preprocess_cb() (callback). Expansion is based on regular expressions.

Function preprocess_atid() is called twice. First in expand_action() before the latter expands %N into field value:

  gboolean needs_free = preprocess_atid (command, "\\\\%1$s|%1$s\\b:?", &cmd);

Second in parse_cmd_output() before the latter expands ^N: into output redirection:

  gboolean needs_free = preprocess_atid (text, "\\\\%1$s|^%1$s:", &data);

This trace shows it all, @ID => %N value expansion, @ID: => N: redirection expansion, \@ID escaping.

INCREMENT BY 1 AND REPROGRAM BUTTON ACTION

export YAD_OPTIONS="--use-interp='dash -xc \"%s\"'"
yad=src/yad

$yad --form --field='+1:fbtn@B' '@echo @N:$((@N+1)); '"echo '@B:@echo @N:\$((\@N+1))'" --field=res:num@N 1

$yad --form --field='+1:fbtn@B' '@echo @N:$((@N+1)); '"printf '@'; printf 'B:@echo '; printf @; printf 'N:\$((\@N+1))'; echo" --field=res:num@N 1

command and cmd refer to before/after the call to preprocess_atid() in expand_action(). text and data refer to before/after the call to preprocess_atid() in parse_cmd_output().

┌─────────────────────────────────────────────────────────┐  ·  ┌─────────────────────────────────────────────────────────┐
│  FIRST MOUSE CLICK 1+1                                  │  ·  │  FIRST MOUSE CLICK 1+1                                  │
└─────────────────────────────────────────────────────────┘  ·  └─────────────────────────────────────────────────────────┘
command( echo @N:$((@N+1)); echo '@B:@echo @N:$((\@N+1))' )  !  command( echo @N:$((@N+1)); printf '@'; printf 'B:@echo '; printf @; printf 'N:$((\@N+1))'; echo )
cmd    ( echo @N:$((%2+1)); echo '@B:@echo @N:$((@N+1))' )   !  cmd    ( echo @N:$((%2+1)); printf '@'; printf 'B:@echo '; printf @; printf 'N:$((@N+1))'; echo )
+ echo @N:2                                                  ·  + echo @N:2
+ echo @B:@echo @N:$((@N+1))                                 !  + printf @
                                                             >  + printf 'B:@echo '
                                                             >  + printf @
                                                             >  + printf N:$((@N+1))
                                                             >  + echo
text   ( @N:2                                                ·  text   ( @N:2
@B:@echo @N:$((@N+1))                                        ·  @B:@echo @N:$((@N+1))
 )                                                           ·   )
data   ( 2:2                                                 ·  data   ( 2:2
1:@echo @N:$((@N+1))                                         ·  1:@echo @N:$((@N+1))
 )                                                           ·   )
┌─────────────────────────────────────────────────────────┐  ·  ┌─────────────────────────────────────────────────────────┐
│  SECOND MOUSE CLICK 2+1                                 │  ·  │  SECOND MOUSE CLICK 2+1                                 │
└─────────────────────────────────────────────────────────┘  ·  └─────────────────────────────────────────────────────────┘
command( echo @N:$((@N+1)) )                                 ·  command( echo @N:$((@N+1)) )
cmd    ( echo @N:$((%2+1)) )                                 ·  cmd    ( echo @N:$((%2+1)) )
+ echo @N:3                                                  ·  + echo @N:3
text   ( @N:3                                                ·  text   ( @N:3
 )                                                           ·   )
data   ( 2:3                                                 ·  data   ( 2:3
 )                                                           ·   )
step- commented 1 year ago

highlighted diff of the trace

Diff

and a version of Frontend-for-find script (with #212 included) where I modified %N and N: with symbolic IDs, just for testing.

Frontend-for-find.sh.txt

step- commented 1 year ago

FYI, I don't have any more PRs to submit.