zsh-workers
 help / color / mirror / code / Atom feed
From: Sebastian Gniazdowski <sgniazdowski@gmail.com>
To: Bart Schaefer <schaefer@brasslantern.com>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: Re: _history-complete-older problems with $(
Date: Wed, 13 Jan 2016 17:40:55 +0100	[thread overview]
Message-ID: <CAKc7PVBz1nNueRmEfyz3157kvJjEgHW3wmSXraKM+-9P-i5Atw@mail.gmail.com> (raw)
In-Reply-To: <160112180141.ZM9984@torch.brasslantern.com>

[-- Attachment #1: Type: text/plain, Size: 2837 bytes --]

On 13 January 2016 at 03:01, Bart Schaefer <schaefer@brasslantern.com> wrote:
> True.  Anyone who wants to fix these issues and post an update is more
> than welcome.  I already spent way more time on it than I intended.

Thanks for the explanations and pointing the manual, this allowed me
to move onward with the code. I didn't use $LBUFFER, but say manually
detected active shell word, and point of break to left and right part
in that word. This will allow to nicely handle COMPLETE_IN_WORD. I
must say it's quite exhausting to handle which word is active. Setting
cursor to "|" in terminal application clarifies few things. Block
cursor highlights a letter, but $CURSOR points before it, where "|"
cursor would stand. Zsh doesn't make following word active, i.e. "ls
|/Users/user_na" with the cursor where "|" is will not complete the
"user_name". I have chosen different approach, in such case I treat
what's after "|" as right part of current shell word. The same I do
for zew-transpose-shell-words (former transpose-segments), block
cursor on first letter of word makes the word active, selected for
transposition.

I do other tricks in the code, e.g. trim left "$((   " out of spaces,
because in case of syntax error (Z+n+) will put spaces in returned
shell word. All this is quite hackish I think. But something could
clarify out of this, and most of all robust Alt-/ is on the horizon.

I have one problem. First compadd returns $found array
populated with matches:

A CURRENT: 3, words: >git,add,wid<
B CURRENT: 3, words: >git,add,wid<
C CURRENT: 3, CURSR: 11, lft: |wid|, rght: ||, words: >git,add,wid<
PREFIX: |wid|, SUFFIX: ||
Calling _history
widen_for_history widen_for_history widen_for_history
widen_for_history widen_for_history widen_for_history
widen_for_history widen_for_history

But nothing is displayed below the prompt, "en" replaces "wid" at
prompt and that's all, while $(<TAB> does:

A CURRENT: 1, words: ><
B CURRENT: 1, words: >$( <
C CURRENT: 1, CURSR: 2, lft: |$(|, rght: ||, words: >$(<
PREFIX: |$(|, SUFFIX: ||
Calling _history
$(( 0 + 1 )) $(( 0 + 1 )) $(( 試句相當長 ""  $(( 0 + 1 )) $( ( echo b ))
$(( echo b ) ) $(( echo a ) ) $(( 0 + 1 )) $(( 0 + 1 )) $(( i + 1 ))
$(( i + 1 )) $(( i + 1 )) $(( i+1 )) $(( i+1 )) $(( i+1 )) $(( i+1 ))
$(( i+1 ))

And below the prompt it's shown:
 ( echo b ))      ( 0 + 1 ))        ( echo a ) )      ( echo b ) )
 ( i + 1 ))        ( i+1 ))          ( 試句相當長 ""

The same problem is with "ls" about which I wrote to you earlier. So
it seems that the second compadd isn't fully working.

The code is here (and also attached):

https://raw.githubusercontent.com/psprint/zsh-editing-workbench/657d6a591bea5d26fbed88176ac7de80e8d73927/widen_for_history

Best regards,
Sebastian Gniazdowski

[-- Attachment #2: widen_for_history --]
[-- Type: application/octet-stream, Size: 2493 bytes --]

echo -e "\nA CURRENT: $CURRENT, words: >${(j:,:)words}<" >> /tmp/wfhistory

words="${(Z+n+)BUFFER}"
integer nwords="${#words}"
local buf="$BUFFER"

echo -e "B CURRENT: $CURRENT, words: >${(j:,:)words}<" >> /tmp/wfhistory

# Remove words one by one, counting characters,
# computing beginning of each word, to find
# place to break the word into 2 halves (for
# complete_in_word option)
# If would use $LBUFFER, then would have to be able
# to parse shell words, to extract word's halves

local i word
integer char_count=0
typeset -a word_beginnings
CURRENT="-1"

for (( i=1; i<=nwords; i++ )); do
    # Remove trailing spaces from $word - they may
    # appear in case of syntax error, like "$((   <TAB>"
    words[i]="${words[i]%% ##}"

    word="${words[i]}"

    # Remove white spaces
    buf="${buf##(#m)[^$word[1]]#}"
    # Count them
    char_count=char_count+"$#MATCH"
    # This is the beginning of current word
    word_beginnings[i]="$char_count"

    # Remove the word
    MATCH=""
    buf="${buf#(#m)$word}"

    # If shell word not found, return. This shoudln't happen
    [ -z "$MATCH" ] && { echo "Aborting" >> /tmp/wfhistory; return 0 }

    # Spaces point to previous shell word
    [[ "$CURRENT" -eq "-1" && "$char_count" -gt "$CURSOR" ]] && CURRENT=i-1

    # Actual characters point to current shell word
    char_count=char_count+"$#word"
    [[ "$CURRENT" -eq "-1" && "$char_count" -ge "$CURSOR" ]] && CURRENT=i
done 

# What's left in $buf can be only white spaces
char_count=char_count+"$#buf"
[[ "$CURRENT" -eq -1 && "$char_count" -ge "$CURSOR" ]] && CURRENT=i-1

# Divide words[CURRENT] into two halves
integer diff=$(( CURSOR - word_beginnings[CURRENT] ))
word="${words[CURRENT]}"
local left="${word[1,diff]}"
local right="${word[diff+1,-1]}"

echo "C CURRENT: $CURRENT, CURSR: $CURSOR, lft: |$left[*]|, rght: |$right|, words: >${(j:,:)words}<" >> /tmp/wfhistory

# History is searched for words that start with $PREFIX
PREFIX="${left}"
IPREFIX=''
# ... and end with $SUFFIX
SUFFIX="${right}"
ISUFFIX=''

echo "PREFIX: |$PREFIX|, SUFFIX: |$SUFFIX|" >> /tmp/wfhistory

{
    compadd () {
        local -a found
        builtin compadd -O found "$@"
        [[ "$#found" -eq 0 ]] && echo -n "_empty_ " >> /tmp/wfhistory || echo "${found[@]}" >> /tmp/wfhistory
        builtin compadd -Q -U "${(@)${(@)found#$PREFIX}%$SUFFIX}"
    }
    echo "Calling _history" >> /tmp/wfhistory
    _history
    echo >> /tmp/wfhistory
} always {
    unfunction compadd
}

# vim:ft=zsh

  reply	other threads:[~2016-01-13 16:41 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-10 19:35 Sebastian Gniazdowski
2016-01-11 16:21 ` Sebastian Gniazdowski
2016-01-12  0:15   ` Bart Schaefer
2016-01-12 13:09     ` Sebastian Gniazdowski
2016-01-12 19:39       ` Bart Schaefer
2016-01-13  1:01         ` Daniel Shahaf
2016-01-13  2:01           ` Bart Schaefer
2016-01-13 16:40             ` Sebastian Gniazdowski [this message]
2016-01-14  4:48               ` Bart Schaefer
2016-01-14 11:30                 ` Sebastian Gniazdowski
2016-01-14 11:37                   ` Sebastian Gniazdowski
2016-01-14 11:59                     ` Sebastian Gniazdowski
2016-01-15  3:18                   ` Bart Schaefer
2016-01-15  5:07                     ` Sebastian Gniazdowski
2016-01-15  6:26                     ` Daniel Shahaf
2016-01-14 18:55                 ` Sebastian Gniazdowski
2016-01-14  9:52               ` Sebastian Gniazdowski
2016-01-14 10:14                 ` Sebastian Gniazdowski
2016-01-14 10:55                   ` Sebastian Gniazdowski
2016-01-15  3:05                     ` Bart Schaefer
2016-01-15  6:26                 ` Daniel Shahaf
2016-01-13  1:01       ` Daniel Shahaf
2016-01-13  1:59         ` Bart Schaefer
2016-01-12  7:57 ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAKc7PVBz1nNueRmEfyz3157kvJjEgHW3wmSXraKM+-9P-i5Atw@mail.gmail.com \
    --to=sgniazdowski@gmail.com \
    --cc=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).