I'd like to use Windows (10) native Emacs (spacemacs) and ledger (both installed via Chocolatey). The finance layer from spacemacs provides integration for it, however when I tried to run a simple register report it gave me the following error:

Report: reg
Command: "ledger" -f "c:/Users/USERNAME/Dropbox/Priv/2018.ledger" reg

Error: Cannot read journal file "/cygdrive/c/Users/USERNAME/Dropbox/Priv/c:/Users/USERNAME/Dropbox/Priv/2018.ledger"

I assume this is because the chocolatey installed package is cygwin based.

Do You have an idea how to get rid of this problem?

  • Do you have cygwin installed? – ctrl-alt-delor Sep 10 '18 at 10:14
  • @ctrl-alt-delor no I'm not (Windows 10 has WSL with which I'm rather happy (but don't want run an X server that's why I'm using native windows emacs). – Zsolt Botykai Sep 11 '18 at 17:59
  • WSL. Is that Windows subsystem for Linux? Does it use /cygdrive? – ctrl-alt-delor Sep 11 '18 at 18:53
  • @ctrl-alt-delor, sorry for the incomplete info, yes, WSL is Windows Subsystem for Linux, and no it doesn't use /cygdrive (I don't have cygwin installed. When You download ledger to Windows, it includes some of the required DLLs from Cygwin to be able to run. – Zsolt Botykai Sep 13 '18 at 7:05
  • According to my analysis and my partial test the method in my solution should work for you. Please test it and give a short report here. Naturally if you don't I must delete it. – Tobias Sep 17 '18 at 22:58

The path you passed (c:/Users/USERNAME/Dropbox/Priv/2018.ledger) is not a valid cygwin file-path, it is a MS-windows file-path:

It will look like a relative file-path to cygwin, so will be appended to the present working directory. I assume that /cygdrive/c/Users/USERNAME/Dropbox/Priv/ | c:/Users/USERNAME/Dropbox/Priv is your present working directory.

If ledger is a cygwin application, then pass it a cygwin file-path. /cygdrive/c/Users/USERNAME/Dropbox/Priv/2018.ledger

After testing the above, if you need to pass MS-windows paths then write a wrapper, possably in bash, to use cygpath to translate the path from MS-windows to cygwin.

  • Thanks for the suggestion, I'm rather sure it is caused by ledger expects a cygwin style path. And You gave me a workaround idea which I'm going to impement soon, however I'm also interested in a real emacs-y solution. – Zsolt Botykai Sep 11 '18 at 17:58
  • Before trying to make a work-around, test it: manually pass it the path /cygdrive/c/Users/USERNAME/Dropbox/Priv/2018.ledger. You can then use the program cygpath to translate the path. Using a regex substitution may also work, however there may be (there are) some subtleties that cygpath knows about. – ctrl-alt-delor Sep 13 '18 at 8:12
  • 1
    c:/Users/USERNAME/Dropbox/Priv/2018.ledger is a special valid cygwin file path. It is parsed by path.cc within cygwin1.dll. The short-circuit code is: if ((isdrive (src) && isdirsep (src[2])) || *src == '\\') goto win32_path; – Tobias Sep 13 '18 at 12:25
  • @Tobias you may be half right. IT is probably not the cygwin.dll. However it is probably not emacs (as OP says this is a native emacs). It probably is Ledger. Therefore the discussion in this answer will still be valid. – ctrl-alt-delor Sep 13 '18 at 12:26
  • If Ledger is compiled as cygwin app and if the misinterpretation of the path as relative path is caused by Ledger then it is a bug of Ledger since it is not properly using the cygwin api. In that case a bug report is in place. – Tobias Sep 13 '18 at 12:31

I don't use ledger-mode but I am pretty sure that the following advice-add will help you. The code is only partially tested (up to make-process in ledger-flymake). Please test whether it is working for you.

It converts the drive specification \`[[:alpha:]]: in buffer-file-name of your ledger buffer selective for function ledger-flymake into /cygdrive/\1 where \1 stands for the drive letter.

(defun run-with-cygwin-file-path (fun &rest args)
  "Let-transform `buffer-file-name' to cygwin-format and run FUN with ARGS."
  (let ((file-name (buffer-file-name)))
    (if (string-match "\\`\\([[:alpha:]]\\):" file-name)
    (let ((buffer-file-name (replace-match "/cygdrive/\\1" nil nil file-name)))
      (apply fun args))
      (apply fun args))))

(advice-add 'ledger-flymake :around #'run-with-cygwin-file-path)
  • According to my analysis and my partial test this method should work for you. Please test it and give a short report here. – Tobias Sep 17 '18 at 22:55
  • Hi @Tobias could You please advise on how to apply it to ledger-mode? I wasn't able to make it work by enabling flymake-mode in my ledger buffer then evaluate Your solution in the scratch buffer. – Zsolt Botykai Sep 18 '18 at 7:27
  • @ZsoltBotykai What happens if you proceed the way you described? Same error message as in the original question? – Tobias Sep 18 '18 at 7:52
  • yes, the very same. – Zsolt Botykai Sep 18 '18 at 19:13
  • @ZsoltBotykai Ready for a short debug session?: chat.stackexchange.com/rooms/83346/… Please join the linked discussion room. – Tobias Sep 18 '18 at 19:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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