Subject: Re: _history-complete-older problems with $(
From: Bart Schaefer <[email-masked]>
To: Zsh hackers list <[email-masked]>
Date: Tue, 12 Jan 2016 11:39:28 -0800
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Jan 12,  2:09pm, Sebastian Gniazdowski wrote:
} Subject: Re: _history-complete-older problems with $(
}
} I think the hacks are acceptable if the code will be used only by
} Alt-/ (_history-complete-older). How to accomplish this, btw?

You would need to change the _history_complete_word_gen_matches
function in the _history_complete_word file to replace

    _main_complete _history

with

    _main_complete _widen_for_history

} Are this expected values? Because despite proposing $(( 0 + 1 ))
} correctly after $(<TAB>  (btw., not after $(<Alt-/>), the completer
} behaves weird. For "ls <TAB>" it doesn't propose any files.

I can't reproduce this.  There may need to be some tests for success
of the calls to "builtin compadd" in the substitute compadd function;
given

    zstyle ':completion:*' completer _widen_for_history _complete

(the _complete at the end is important) there will only be completions
generated by _complete when _widen_for_history returns nonzero.  It is
possible you've found some circumstance in which it returns 0 but does
not add any actual matches.

I'm not trivally able to reproduce that.

} > This needs some work around the issue of empty words, i.e., when
} > completing in empty parens such as $(<TAB>) then $words[CURRENT] is
} > empty and the trailing paren must be copied from $RBUFFER to SUFFIX.
} > I haven't dived into that detail.
} 
} I would gladly perform the work but the code is quite difficult. Could
} you state in one sentence what it is doing? Variables $CURRENT, $word
} aren't documented in zshzle.1.

They're documented in "man zshcompwid".

} What does the {} always {} block of code do?

 { TRY-LIST } always { ALWAYS-LIST }
     First execute TRY-LIST.  Regardless of errors, or break, continue,
     or return commands encountered within TRY-LIST, execute
     ALWAYS-LIST.  Execution then continues from the result of the
     execution of TRY-LIST; in other words, any error, or break,
     continue, or return command is treated in the normal way, as if
     ALWAYS-LIST were not present.  The two chunks of code are referred
     to as the `try block' and the `always block'.

} Next, I would guess that "builtin compadd -O found "$@""
} performs one run of matching, is this correct?

    -O ARRAY
          If this option is given, the WORDS are _not_ added to the set
          of possible completions.  Instead, matching is done as usual
          and all of the WORDS given as arguments that match the string
          on the command line will be stored in the array parameter
          whose name is given as ARRAY.

} Why second comadd, and
} what does "${(@)${(@)found#$PREFIX}%$SUFFIX}" do?

Suppose you have "$(" on the line, and the completion is $((1+2)).  The
$found array will contain "$((1+2))" (and possibly other elements).  In
the setup to at the beginning of _widen_for_history, PREFIX="$(" was
assigned (that $left[-1]).  So now we need to remove "$(" from the
values in $found to get the actual string to insert to finish the word,
i.e., "(1+2))".  Similarly we would need to remove $SUFFIX (taken from
$right) from the end of the values if there were one.

${...#$PREFIX} removes from the left and ${...%$SUFFIX} removes from
the right.

Normally "builtin compadd" would handle this for us, but internally it
still thinks it is populating command words that must follow the open
paren; so we have to fix things up before we make the final call.

(That's not an entirely accurate description of the "internally" part
but it suffices to explain why we must trim the prefix/suffix.)