Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any reason of adding . at the end of command on Windows? #169

Open
chansey97 opened this issue May 17, 2024 · 2 comments
Open

Any reason of adding . at the end of command on Windows? #169

chansey97 opened this issue May 17, 2024 · 2 comments

Comments

@chansey97
Copy link

chansey97 commented May 17, 2024

I saw in rg.el there are the following lines

(when (member system-type '(darwin windows-nt))
  (list ".")))))

Anyone know why need this . thing on Windows (and Mac OS)?

First of all, it seems that at the moment we have to use the . on Windows, otherwise rg.el won't display anything. It has little to do with rg.el though, I still want to discuss.

Let's do some experiments via clean Emacs interface:

  1. Try the following three commands (no .) in Windows standard console

    ...> "C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe" SomeTextInFiles
    ...> "cmd.exe" /c "C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe SomeTextInFiles"
    ...> "C:/green/emacs/libexec/emacs/28.2/x86_64-w64-mingw32/cmdproxy.exe" -c "C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe SomeTextInFiles"
    

    All work, i.e. they can display results in the console.

  2. Try the same command (no .) in Emacs with start-process

    (apply 'start-process "rg" "newbuffer123"
           "C:/green/emacs/libexec/emacs/28.2/x86_64-w64-mingw32/cmdproxy.exe"
           (list "-c" "\"C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe\" SomeTextInFiles"))

    This doesn't work, i.e. it displayed nothing in "newbuffer123" (also for rg.exe only and cmd.exe /c).

  3. The way to fix this problem is adding . at the end of command, i.e.

    (apply 'start-process "rg" "newbuffer123"
           "C:/green/emacs/libexec/emacs/28.2/x86_64-w64-mingw32/cmdproxy.exe"
           (list "-c" "\"C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe\" SomeTextInFiles ."))

    Then works, but why?

  4. Not all of the ripgrep commands can't display, -h can do for example:

    (apply 'start-process "rg" "newbuffer123"
           "C:/green/emacs/libexec/emacs/28.2/x86_64-w64-mingw32/cmdproxy.exe"
           (list  "-c" "\"C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe\" -h"))

    This can display help information in "newbuffer123"

I found this patch was added by @drvink from #10 but no explanation. Also, there are two related commits 842452c and 89343e9.

Nevertheless, the . solution works fine, until someone want to add rg-command-line-flags to rg.el.

For example, suppose I'd like to search only two specific directories under the current directory (multiple directories search):

(defun test-rg ()
  (interactive)
  (let ((rg-command-line-flags '("\"./folder1\" \"./folder2\"")))
    (call-interactively 'rg)))

In the current rg.el implementation, these two directories will be combined with the current directory (i.e. .), which causes these two flags meaningless, i.e. it still searches the entire current directory.

Of course, this problem can be workaround via deleting (list ".") in the code above, but that breaks the code.

So anyone know why we have to add . on Windows (and Mac)? Is this related to Emacs or ripgrep?

Thanks.

@chansey97
Copy link
Author

chansey97 commented May 17, 2024

I think I know what happened here:

When the command-line arguments did not explicitly indicate the search path (e.g. . or ./), ripgrep would use a heuristic to guess users' intention, i.e. whether searching in the current directory or in stdin via a pipe, see hiargs.rs#L1104 and lib.rs#L170. Unfortunately, on Windows (might be also on Mac), ripgrep guesses "users want to search in stdin via a pipe", so Emacs process hangs.

A simple experiment to make the above process code work:

(let ((p (apply 'start-process "rg" "newbuffer123"
                "C:/env/ripgrep/ripgrep-14.1.0-x86_64-pc-windows-msvc/rg.exe"
                (list "SomeTextInFiles"))))
  (process-send-string p "1. SomeTextInFiles1\nxxxxxx\n2. SomeTextInFiles2\nyyyyy\n3. SomeTextInFiles3\n")
  (process-send-eof p))

This code work, Emacs can display the result.

1. SomeTextInFiles1
2. SomeTextInFiles2
3. SomeTextInFiles3

Process rg<1> finished

However as you see that, ripgrep searched "SomeTextInFiles" in the string content, i.e. "1. SomeTextInFiles1\nxxxxxx\n2. SomeTextInFiles2\nyyyyy\n3. SomeTextInFiles3\n" instead of directory.


Some suggestions:

  1. Make the command-line consistent on Windows, Linux and Mac OS, i.e. explicitly provide the search path instead of leaving ripgrep to guess. Remove (member system-type '(darwin windows-nt)) condition.
  2. The search path (or "multiple directories search") should be implemented as a separate feature instead of hardcoded as . or added through rg-command-line-flags.

@drvink
Copy link
Contributor

drvink commented May 18, 2024

Yes, @chansey97's description is what my fix was for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants