Well, it turns out that cleaning really *is* that boring. I got to thinking about what could be done to fix the find(1) problems and ended up with the attached patch. This threw away two thirds of the code in `...-file-name-all-completions', so I am actually quite happy 'bout it. Could you give this a try (along with anyone else who feels enthused) and see if it does what you want? FWIW, it passed the test of running under bash, pdksh and ash[1] locally, so I feel pretty confident that the remote sh would have to be pretty stupid to fall over on this one. Um, if it *does* fail, could you work out the command by hand and run it in the shell? Then I can know exactly what is broken. Hrm. The only other issue is that this patch /does/ introduce a limit to the number of files offered for completion, because it uses shell globing into ls. Of course, this is only when the list is filtered somewhat so, I hope, it should be fine. If anyone actually hits the limit, we can rewrite it. :) Daniel
Index: tramp.el =================================================================== RCS file: /services/emacs-rcp/cvsroot/tramp/lisp/tramp.el,v retrieving revision 1.385 diff -u -u -p -r1.385 tramp.el --- tramp.el 2000/06/05 10:54:06 1.385 +++ tramp.el 2000/06/05 13:00:18 @@ -1489,52 +1489,28 @@ is initially created and is kept cached (tramp-barf-unless-okay "tramp-handle-file-name-all-completions: Couldn't `cd %s'" (tramp-shell-quote-argument path)) - ;; Get list of file names by calling ls. + + ;; Get a list of directories and files, including reliably tagging + ;; the directories with a trailing '/'. Because I rock. [EMAIL PROTECTED] (tramp-send-command multi-method method user host - (format "find . \\( \\! -name . -prune \\) %s -print" + (format (concat "%s -a %s | while read f; do if test -d $f; " + "then echo \"$f/\"; else echo \"$f\"; fi; done") + (tramp-get-ls-command multi-method method user host) (if (zerop (length filename)) "" - (format "-a \\( -name %s\\* -prune \\)" - (tramp-shell-quote-argument filename))))) + (format "-d %s*" (tramp-shell-quote-argument filename))))) + + ;; Now grab the output. (tramp-wait-for-output) (goto-char (point-max)) (while (zerop (forward-line -1)) - (push (buffer-substring (+ 2 (point)) + (push (buffer-substring (point) (tramp-line-end-position)) result)) - ;; Now get a list of directories in a similar way. - ;; I think this should not by using find(1) [EMAIL PROTECTED] - (tramp-send-command - multi-method method user host - (format "find . \\( \\! -name . -prune \\) -a \\( %s -type d -prune \\) -print" - (if (zerop (length filename)) "" - (format "-name %s\\*" (tramp-shell-quote-argument filename))))) - (tramp-wait-for-output) - (goto-char (point-max)) - (while (zerop (forward-line -1)) - (push (buffer-substring (+ 2 (point)) - (tramp-line-end-position)) - dirs))) - ;; Now annotate all dirs in list of file names with a slash, - ;; at the same time checking for - (mapcar - (function (lambda (x) - (if (member x dirs) - (file-name-as-directory x) - x))) - (save-match-data - (all-completions - filename (mapcar 'list result) - (lambda (x) - (and (not (string= (car x) ".")) - (not (string= (car x) "..")) - (not (string-match - (concat "\\(" - (mapconcat 'regexp-quote - completion-ignored-extensions - "\\|") - "\\)\\'") - (car x)))))))))) + + ;; Return the list. + result))) + ;; The following isn't needed for Emacs 20 but for 19.34? (defun tramp-handle-file-name-completion (filename directory)
Footnotes: [1] The single most brain-dead shell that I have ever had the misfortune to deal with, but at least it doesn't have any of those nasty 'features' to get in the way of the frustration. :) -- They always say time changes things, but you actually have to change them yourself. -- Andy Warhol