How about using shell-quote-argument (to quote any possibly funky characters) on the result of expand-file-name (to expand the ~, before it is quoted).
(let ((path "~/Foo Bar/file.tex"))
(shell-quote-argument (expand-file-name path)))
If the ~ is not already part of the string before it gets to you, you could add if after using shell-quote-argument so that the shell will expand ~ for you instead of Emacs:
(let ((path-in-home "Foo Bar/file.tex"))
(concat "~/" (shell-quote-argument path-in-home)))
The answer to your referenced question shows using (buffer-file-name) to get the filename. In that case, just use (shell-quote-argument (buffer-file-name)) instead. There will not be a ~ involved.
Apparently your errors are coming from texcount.pl. It does not properly handle spaces in the filenames it is given. Internally, it is using the given filenames as glob patterns instead of actual filenames. Unix shells normally handle globbing for the user so programs do not often include this functionality themselves. Maybe this bit of functionality was for
Windows users (where the shell does not expand file patterns).
Anyway, you might be able to work around the problem by wrapping quotes around your filename:
(defun latex-word-count ()
(interactive)
(shell-command (concat "/path/to/texcount.pl "
(shell-quote-argument (concat "'" (buffer-file-name) "'")))))
Or you could rip the globbing functionality out of texcount.pl:
diff --git i/texcount.pl w/texcount.pl
index 96fac5c..aa96eb4 100755
--- i/texcount.pl
+++ w/texcount.pl
@@ -360,7 +360,7 @@ sub parse_options_output {
sub parse_file_list {
my @filelist=@_;
my $listtotalcount=new_count("TOTAL COUNT");
- for my $file (<@filelist>) {
+ for my $file (@filelist) {
my $filetotalcount=parse_file($file);
add_count($listtotalcount,$filetotalcount);
}
And use more reasonable code on the elisp side:
(defun latex-word-count ()
(interactive)
(shell-command (concat "/path/to/texcount.pl "
(shell-quote-argument (buffer-file-name)))))