Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Absolute path tab completion on Windows
- X-seq: zsh-workers 53225
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: Ram Rachum <ram@xxxxxxxxxx>
- Cc: zsh workers <zsh-workers@xxxxxxx>
- Subject: Re: Absolute path tab completion on Windows
- Date: Thu, 7 Nov 2024 16:18:13 -0800
- Archived-at: <https://zsh.org/workers/53225>
- In-reply-to: <CANXboVb_D=DMFHFK9SBDXWctXVmTJz-keS030wMWZsCZ+RC0Gw@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CANXboVbJ0mv5sD_PAVe=ESkjymJs1YuAEKF8T=4QMCNpD8460g@mail.gmail.com> <CAH+w=7a13BXHRj6XD0RNnPVfpET9mcJxYCO8Gp4ser8PZwSj=Q@mail.gmail.com> <CANXboVZoDGi8BCHn0CPitYAR_R4yH2Vc3BiQ0c18A0Wy=9NHKg@mail.gmail.com> <CAHYJk3QnXGawgxBrsMVCG4gBLEKK6qNY-Z_y7YvU+71CJi_mMA@mail.gmail.com> <CANXboVYsxTOcQ+ms2voHiRQd70GQWq0fGe73-3dCGm2C5SpNBA@mail.gmail.com> <CAH+w=7aPdJ1JiHsWSVz-u98j9=rB3Xshq2-aR1qB0jQBpGT9eA@mail.gmail.com> <CANXboVb_D=DMFHFK9SBDXWctXVmTJz-keS030wMWZsCZ+RC0Gw@mail.gmail.com>
On Thu, Nov 7, 2024 at 1:25 PM Ram Rachum <ram@xxxxxxxxxx> wrote:
>
> I used Claude to extend this code to apply to all drive letters, code below.
Hm. Not entirely terrible code, but could be optimized.
> One problem with this code is that it only autocompletes the paths when they are an argument to a command, and not when they are the first thing that's typed in the shell, like you might do to `cd` into a folder without typing `cd`. If anyone knows how to fix that, let me know.
I've been testing (the original formulation) by pretending that /tmp/
is a drive mount, and the big drawback for AUTO_CD seems to be that it
offers command names as well as the directories under /tmp/. That's
difficult to fix without breaking command completion.
> get_drive_letters() {
> mount | grep -i '^[a-z]:' | cut -d':' -f1 | tr '[:upper:]' '[:lower:]' | sort -u
> }
Clever enough to create that function but then it didn't use it where
it would make sense. In any case that pipeline is functional but
wasteful.
${${(M)${(fL)"$(mount)"}:#[a-z]:*}%%:*}
I left out the "sort -u" because (a) the order shouldn't matter and
(b) if "mount" isn't already returning each drive uniquely I think
something is wrong.
> # Store the original completion function
> functions -c -- _normal _normal@original
OK, interesting if Claude figured that out itself.
> # Create completion functions for each drive
This isn't necessary. Just re-use _normal@original every time. You
only need a new function if you're going to change the operation, and
"functions -c" changes nothing but the name. I just threw the drive
letter in when creating the first copy to make the suffix part after
the @ more distinctive.
> _normal () {
> for drive in $(mount | grep -i '^[a-z]:' | cut -d':' -f1 | tr '[:upper:]' '[:lower:]' | sort -u); do
local drive
for drive in ${${(M)${(fL)"$(mount)"}:#[a-z]:*}%%:*}; do
> if compset -P "/${drive}/"
> then
> local opwd=$PWD ret
> cd /${drive} || return 1
> _normal@${drive}:drive "$@"
_normal@original "$@"
> ret=$?
> cd $opwd
> return ret
> fi
> done
> _normal@original "$@"
> }
I think we can fix the autocd problem in two steps:
1. Don't do the whole compset+cd dance if we already know a directory
name under the drive name
2. If we pass that hurdle and are in command position with autocd,
jump straight to _cd
"compset -P" accepts a pattern, so we can remove the loop from the
foregoing by turning the list of drive names into a pattern, which
just means joining them with (j:|:). That puts the name matched by
the pattern into $IPREFIX, so we don't need the $drive local.
That gives (harder for me to test with no windows environment, so may
need tweaking) --
_normal () {
if [[ $PREFIX != /*/*/* ]] && compset -P
"/(${(j:|:)${(M)${(fL)"$(mount)"}:#[a-z]:*}%%:*})/"
then
local opwd=$PWD ret
cd $IPREFIX || return 1
if [[ -o autocd && $compstate[context] = command ]]
then
_cd "$@"
else
_normal@original "$@"
fi
ret=$?
cd $opwd
return ret
else
_normal@original "$@"
fi
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author