title: Bash completion to make 'cd' command complete working directories from other running shells?
body: <p>I'm trying to write a bash completion that will let me complete directory names that other shells are in.</p>
  
  <p>For example, suppose I have another shell open in <code>/very/long/path/name</code>, and I'm currently in a directory that contains subdirs <code>foo</code> and <code>bar</code>. When I type <code>cd &lt;Tab&gt;</code>, I want to see:</p>
  
  <pre><code>$ cd &lt;Tab&gt;
  foo/  bar/  /very/long/path/name
  </code></pre>
  
  <p>I have this command to produce the list of potential completions:</p>
  
  <pre><code>ps -Cbash -opid= | xargs pwdx | cut -d" " -f2 | sort -u | while read; do echo ${REPLY#$PWD/}; done | grep -v "^$"
  </code></pre>
  
  <p>For brevity, I'll write this as <code>...pipeline...</code>.</p>
  
  <p>On my system there's a <code>_cd</code> function that produces the regular completion:</p>
  
  <pre><code>$ complete -p cd
  complete -o nospace -F _cd cd
  </code></pre>
  
  <p>I would like to reuse this <code>_cd</code> function, because it's nontrivial (~30 lines of code, according to <code>type _cd</code>). Bonus points if the solution reuses whatever completion is already defined, whether or not it's based on a function called <code>_cd</code>.</p>
  
  <p>I thought the <code>-C</code> option to <code>complete</code> sounded promising, but I can't get it to work:</p>
  
  <pre><code>$ complete -C '...pipeline...' cd
  $ cd &lt;Tab&gt;grep: cd: No such file or directory
  grep: : No such file or directory
  grep: cd: No such file or directory
  </code></pre>
  
  <p>Writing my own wrapper function for <code>-F</code>, which appends to the <code>COMPREPLY</code> array, also didn't quite work:</p>
  
  <pre><code>$ function _cd2() { _cd; COMPREPLY=( ${COMPREPLY[@]} $(...pipeline...) ); }
  $ cd &lt;Tab&gt;
  foo/  bar/  name/
  </code></pre>
  
  <p>It strips off all the path components except the last. I figure it must be something set up by <code>_cd</code> that does this, but I'm not sure how to counteract it.</p>
  
  <p>If I remove the <code>_cd</code> call from <code>_cd2</code>, I do see the completions, but they don't properly complete partial directory names. If I type <code>cd /ve&lt;Tab&gt;</code>, it still shows the full path, without actually completing my command line.</p>
  
  <p>How can I get this to do what I want?</p>
  
  <hr>
  
  <p>Appendix: the full definition of <code>_cd</code>:</p>
  
  <pre><code>$ type _cd
  _cd is a function
  _cd () 
  { 
      local cur prev words cword;
      _init_completion || return;
      local IFS='
  ' i j k;
      compopt -o filenames;
      if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
          _filedir -d;
          return 0;
      fi;
      local -r mark_dirs=$(_rl_enabled mark-directories &amp;&amp; echo y);
      local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories &amp;&amp; echo y);
      for i in ${CDPATH//:/'
  '};
      do
          k="${#COMPREPLY[@]}";
          for j in $( compgen -d $i/$cur );
          do
              if [[ ( -n $mark_symdirs &amp;&amp; -h $j || -n $mark_dirs &amp;&amp; ! -h $j ) &amp;&amp; ! -d ${j#$i/} ]]; then
                  j+="/";
              fi;
              COMPREPLY[k++]=${j#$i/};
          done;
      done;
      _filedir -d;
      if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
          i=${COMPREPLY[0]};
          if [[ "$i" == "$cur" &amp;&amp; $i != "*/" ]]; then
              COMPREPLY[0]="${i}/";
          fi;
      fi;
      return 0
  }
  </code></pre>