Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Don't append slash when auto completing a symbolic link pointing to a directory



Alan wrote on Thu, 28 May 2020 17:56 -0400:
> On Thu, May 28, 2020 at 4:53 PM Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
> > On 5/28/20, Alan <8fvebtoeq87@xxxxxxxxx> wrote:  
> > > $ ls sym<TAB>
> > >
> > > At this point, in bash, you would get:
> > > $ ls symblink
> > >
> > > In zsh, I'm getting:
> > > $ ls symblink/
> > >
> > > Also, in bash, hitting a <TAB> when the full symbolic link is already
> > > present would then append the slash to the symbolic link:
> > > $ ls symblink<TAB>
> > > $ ls symblink/
> > >
> > > Is there anyway to get this behavior with zsh? I looked through "man
> > > zshoptions" this time and couldn't find anything specific to this.  
> >
> > If it makes you feel better, hitting enter will remove the / and just
> > run "ls symblink". (Although this makes no difference to ls unless you
> > also give -l). The / is just inserted temporarily in case you want to
> > continue typing/completing things inside the directory, but a space,
> > enter or movement etc will remove it again. This should be indicated
> > by a bold/standout font.
> >  
> 
> Unfortunately, I have autoremoveslash disabled (i.e. 'unsetopt
> autoremoveslash'), and prefer it that way for other things, so the trailing
> slash isn't removed when pressing enter.

It's possible to achieve this with a custom widget:

[[[
expand-or-complete()
{
	local old=$LBUFFER
	{
		zle .$WIDGET -- "$@"
	} always {
		[[ ${LBUFFER} == */ && $LBUFFER != ${old}/ && -L ${${(z)LBUFFER}[-1]%/} ]] && LBUFFER=${LBUFFER%/}
	}
}
zle -N expand-or-complete
]]]

I realize this isn't exactly an obvious solution.  I suspect there's
a simpler solution that I'm overlooking.

In English, what it does is wrap the «expand-or-complete» widget (which
handles <TAB> presses — see `bindkey $'\t'`) with a function that, after
the built-in widget does its thing, removes the slash if the word before
the cursor is a symlink with slash appended.  The second conjunct is to
let «symlink<TAB>» complete to «symlink/».

You might want to add a «$old != $LBUFFER» and/or «$? -eq 0» to the list
of conditions so it doesn't remove the slash when trying to complete
filenames in an empty directory.

s/(z)/(zZ+c+)/ if you set the INTERACTIVE_COMMENTS option.

Cheers,

Daniel



Messages sorted by: Reverse Date, Date, Thread, Author