2

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?

7
  • Do you have cygwin installed? Sep 10, 2018 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). Sep 11, 2018 at 17:59
  • WSL. Is that Windows subsystem for Linux? Does it use /cygdrive? Sep 11, 2018 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. Sep 13, 2018 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, 2018 at 22:58

2 Answers 2

1

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.

7
  • 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. Sep 11, 2018 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. Sep 13, 2018 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, 2018 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. Sep 13, 2018 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, 2018 at 12:31
1

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)
6
  • 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, 2018 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. Sep 18, 2018 at 7:27
  • @ZsoltBotykai What happens if you proceed the way you described? Same error message as in the original question?
    – Tobias
    Sep 18, 2018 at 7:52
  • yes, the very same. Sep 18, 2018 at 19:13
  • @ZsoltBotykai Ready for a short debug session?: chat.stackexchange.com/rooms/83346/… Please join the linked discussion room.
    – Tobias
    Sep 18, 2018 at 19:19

Your Answer

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

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