1

when i type on "shell":

c:\Users\TR\Desktop\emacs-27.2-x86_64\bin\GAMES\game3>love .

works fine but when i put

(defun insert-file-name ()
 (interactive)
 (let ((compilation-ask-about-save  nil))
 (compile (concat (file-name-directory (buffer-file-name)) "love ."))))

(global-set-key (kbd "C-c C-v") #'insert-file-name)

in my initialization file using "C-c C-v" gives me the error message:

-- mode: compilation; default-directory: "c:/Users/TR/Desktop/emacs-27.2-x86_64/bin/GAMES/game3/" -- Compilation started at Sun Apr 18 23:30:16 c:/Users/TR/Desktop/emacs-27.2-x86_64/bin/GAMES/game3/love . 'c:/Users/TR/Desktop/emacs-27.2-x86_64/bin/GAMES/game3/love' is not recognized as an internal or external command, operable program or batch file.

Compilation exited abnormally with code 1 at Sun Apr 18 23:30:16

a similar code worked on Ubuntu emacs, but on Windows 7 it does not work!

How can i solve this problem?

4
  • 1
    I do not know, if that is an issue, but have you noticed the use of / vs \ ?
    – jue
    Commented Apr 18, 2021 at 21:07
  • I'm guessing this question is a duplicate...
    – Drew
    Commented Apr 18, 2021 at 23:50
  • Start here.
    – Drew
    Commented Apr 18, 2021 at 23:52
  • And here.
    – Drew
    Commented Apr 19, 2021 at 1:14

2 Answers 2

1

Learn about backslashes in strings. And learn about manipulating file names.

The result of evaluating this is presumably the absolute file name that you want for your program:

(expand-file-name "love" "c:\\Users\\TR\\Desktop\\emacs-27.2-x86_64\\bin\\GAMES\\game3")

That is:

(expand-file-name "love" (file-name-directory (buffer-file-name)))
1

Short answer,

pass the relative file path to the cli. See documentation of file-relative-name.

Long answer,

As I can see in first paragraph. The shell is DOS shell. When current work directory is "c:\Users\TR\Desktop\emacs-27.2-x86_64\bin\GAMES\game3", you can run "love" (note it's relative path) without any problem.

But when you run M-x compile, you pass the whole path "c:/Users/TR/Desktop/emacs-27.2-x86_64/bin/GAMES/game3/love" to the DOS shell.

The DOS shell can't recognise the path.

You can convert the path by replacing the "/" with "" by (replace-regexp-in-string "/" "\\\\" "c:/hello/world.txt").

But it's better to use relative path which is portable on all environments (WSL, Cygwin, macOS, Linux ...)

In your code, instead of using full path (concat (file-name-directory (buffer-file-name)) "love ."), you should use (concat (file-name-relative (file-name-directory (buffer-file-name))) "love .").

Here is the documentation of file-relative-name,

file-relative-name is a compiled Lisp function in ‘files.el’.

(file-relative-name FILENAME &optional DIRECTORY)

Convert FILENAME to be relative to DIRECTORY (default: ‘default-directory’).
This function returns a relative file name that is equivalent to FILENAME
when used with that default directory as the default.
If FILENAME is a relative file name, it will be interpreted as existing in
‘default-directory’.

You might need set default-directory to the right working directory inside your function insert-file-name before calling compile. But looks it's correct according to the error message.

1
  • Please consider elaborating, perhaps summarizing a relevant portion of that doc or providing an example.
    – Drew
    Commented Apr 19, 2021 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.