5

In Windows paths are (unreasonably) long, so it is common to drag and drop from some links to the terminal or copy and paste paths from file managers. It is possible to put in the shell init file a function like

cdw() { cd "`cygpath -u $1`"  }

Now we have a Windows version of cd. Assuming that "C:\Program Files" is in your clip, you can type:

cdw "CTRL+V"

and CD there. I agree with you, quoting is boring: cdw CTRL+V (no double quotes) would be the killer cd.
This is easy in Bash exploiting the history command, as shown here. But I use zsh, where issuing history does not return the very last command (i.e. history itself). By trial and errors I came up with this function:

cdw(){
  print -s 
  set $(fc -l -1 | tail -2 | head  -1)
  shift 2
  p=`cygpath -u "$*"`
  cd "$p"
}

It works but seems too convoluted. I wonder if you can find a solution more elegant than mine.

3 Answers 3

5

That history hack is a really strange way to solve this problem, and it's pretty fragile. It won't work with some characters that are valid in Windows file names such as parentheses.

There's a much easier way to use to a pasted Windows path. Instead of pasting it into the line editor, call the getclip utility (which is in cygutils-extra in recent versions of Cygwin).

cdw () {
  cd -- "$(getclip)"
}
cd -- "`getclip`"/../foo

You can get away without the double quotes if the dir path contains no characters of $IFS (space, tab, newline and NUL by default).

If you want to be able to edit the path, bind a key to expand-or-complete-prefix, e.g. type "`getclip`" and press Esc Tab:

bindkey '\e\t' expand-or-complete-prefix

Another approach is to bind a key to insert the quoted content of the clipboard.

insert-quoted-clipboard-content () {
  LBUFFER+=${(q)$(getclip)}
}
zle -N insert-quoted-clipboard-content
bindkey '^X^V' insert-quoted-clipboard-content
3
  • @Nathan It's a zsh builtin command. Commented Oct 18, 2021 at 18:32
  • I could not find bindkey in Cygwin. I found bind instead.
    – Nathan
    Commented Oct 18, 2021 at 18:33
  • @Nathan Bash has a builtin called bind. Zsh has a builtin with a similar purpose called bindkey. It's a difference between bash and zsh. It has nothing to do with Cygwin. Commented Oct 18, 2021 at 18:37
1

Gilles answer is for Zsh since the question is about Zsh. Google dropped me on this page, but I use Bash. The following works on Bash when added to .bashrc.

# Convert Windows paths to Cygwin paths and add " if necessary.  Then paste to the command buffer.
paste()
{
   local prefix=${READLINE_LINE:0:${READLINE_POINT}}
   local suffix=${READLINE_LINE:${READLINE_POINT}}
   local text=$(getclip)

   # Does the clipboard contents look like a Windows path (e.g., C:\Program Files)?
   if [[ ${text} =~ [A-Z]:\\.* ]]; then
      text=$(cygpath --mixed "${text}")

      # Add quotes if there are any spaces in the path
      if [[ ${text} == *" "* ]]; then
         text='"'${text}'"'
      fi
   fi

   # Insert the clipboard contents at the current cursor position
   READLINE_LINE=${prefix}${text}${suffix}

   # Move the cursor to the end of the inserted text
   ((READLINE_POINT += ${#text}))
}

# Remove Ctrl+V binding
stty lnext undef

# Change Control+v to execute paste()
bind -x '"\C-v":"paste"'
3
  • With your approach and without it, my paths are pasted using /mnt instead of using /cygdrive and I have to type it every time. Any ideas why? Thanks!
    – Metafaniel
    Commented Feb 10, 2022 at 18:07
  • @Metafaniel I suggest adding some printfs to debug what is happening at the various steps. This will probably reveal where /mnt.
    – Nathan
    Commented Feb 11, 2022 at 19:21
  • A little bit later, I found an answer. I needed to add -cur_console:pm:/cygdrive to the command that launches the CygWin terminal using ConEmu under its task configuration. Thank you for the follow-up! Here's the URL where I found the answer: github.com/Maximus5/ConEmu/issues/2082
    – Metafaniel
    Commented Feb 15, 2022 at 0:03
1

I don't know if I'm misunderstanding the question but, worst case scenario, I figure this could help someone else. There is no need1 to create a function like cdw to cd to Windows paths. Cygwin's cd already accepts them, so long as you wrap them in quotes.

e.g., cd 'C:\Program Files' will Change your Directory to /cygdrive/c/Program Files.


1: I'm intentionally using the word "need." There still may be a legitimate reasonable desire to create cdw.

2
  • 1
    Note that cd is a builtin of each shell, there's no such thing as a cygwin cd. Here the point is that pathname resolution in POSIX system calls emulated by cygwin including chdir() support both Unix-style and Windows style paths. See cygwin.com/cygwin-ug-net/using.html#using-pathnames Commented Dec 21, 2023 at 9:54
  • @StéphaneChazelas Thanks for the information! For someone as inexperienced as me, I kept the wording the same because I think it might be easier for the typical cygwin user to understand. Obviously, I'm coming from a place of ignorance, so if you disagree, don't hesitate to edit my answer! :) Commented Dec 21, 2023 at 21:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .