tpapp / julia-repl

Run an inferior Julia REPL in a terminal inside Emacs
Other
170 stars 35 forks source link

Add rewrite rules for Cygwin. #76

Closed tpapp closed 4 years ago

tpapp commented 4 years ago

Fixes #74.

tpapp commented 4 years ago

@PetrKryslUCSD: please kindly test this code and report back, a review would also be welcome.

PetrKryslUCSD commented 4 years ago

Something is a bit off.

  1. I had to install s.el manually. I had to use a different computer this time, and for some reason when I installed cygwin s.el was not found.
  2. No key bindings from julia-repl work (C-c C-z, for instance. Or, C-c C-b.)
  3. Using M-x julia-repl-includet-buffer yields
    julia> Revise.includet("/cygdrive/c/Users/PetrKrysl/Documents/work/tmp/play.jl");
    ERROR: \cygdrive\c\Users\PetrKrysl\Documents\work\tmp\play.jl is not a file
    Stacktrace:
    [1] error(::String, ::String) at .\error.jl:42
    [2] #track#74(::Base.Iterators.Pairs{Symbol,Bool,Tuple{Symbol,Symbol},NamedTuple{(:define, :skip_include),Tuple{Bool,Bool}}}, ::typeof(Revise.track), ::Module, ::String) at C:\Users\PetrKrysl\.julia\packages\Revise\0KQ7U\src\Revise.jl:670
    [3] includet(::Module, ::String) at .\none:0
    [4] includet(::String) at C:\Users\PetrKrysl\.julia\packages\Revise\0KQ7U\src\Revise.jl:732

    I believe the correct form should have been Revise.includet("c:/Users/PetrKrysl/Documents/work/tmp/play.jl"); (which worked, as I checked).

PetrKryslUCSD commented 4 years ago

The rewriting of the path does not work. The weird thing is, if I load this file then suddenly the include refers to the correct path.

(defcustom julia-repl-path-cygwin-prefix "c:/cygwin64"
  "Prepended to paths by some Cygwin rewrite rules when no other information is available."
  :type 'string
  :group 'julia-repl)

(defun julia-repl--cygwin-replace-cygdrive (path)
  "Rewrite ‘/cygdrive/c/something’ to ‘c:/something’."
  (let ((m (s-match-strings-all "^/cygdrive/\\([A-Za-z]\\)\\(/.*\\)$" path)))
    (when m
      (let ((m1 (first m)))
        (s-concat (second m1) ":" (third m1))))))

(defun julia-repl--cygwin-add-drive (path)
  "When the path does not start with a Windows drive letter,
prepend ‘julia-repl-path-cygwin-prefix’."
  (unless (s-matches? "^[A-Za-z]:/" path)
    (s-concat julia-repl-path-cygwin-prefix path)))

(defconst julia-repl-cygwin-path-rewrite-rules
  (list #'julia-repl--cygwin-replace-cygdrive
        #'julia-repl--cygwin-add-drive)
  "Default list of rewrite rules for Cygwin. Use as a starting
  point, you may need to copy and modify this. See
  ‘julia-repl-path-cygwin-prefix’.")

(defun julia-repl--path-rewrite (path rules)
  "Call each rule (function) in ‘rules’ with ‘path’. When the
result is non-nil, return that and terminate, when all rules are
tested return ‘path’ unchanged."
  (let ((result nil))
    (while (and (not result) rules)
      (setf result (funcall (car rules) path)
            rules (cdr rules)))
    (if result
        result
      path)))

(setq julia-repl-path-rewrite-rules julia-repl-cygwin-path-rewrite-rules)
(julia-repl--path-rewrite "/cygdrive/c/Users/PetrKrysl/Documents/work/tmp/play.jl" julia-repl-path-rewrite-rules)
PetrKryslUCSD commented 4 years ago

The problem appears to be that the variable julia-repl-path-rewrite-rules is nil upon starting Emacs and running julia-repl.

PetrKryslUCSD commented 4 years ago

I think I found the reason the path wasn't being modified. It appears I was supposed to set the rewrite rules. I included the following in my init file

(require 'julia-mode)
(require 'julia-repl)
(setq julia-repl-path-rewrite-rules julia-repl-cygwin-path-rewrite-rules)

and now the rewrite rules appear to work..

There is still the problem of the shortcuts not being in effect. Unfortunately I don't have access at the moment to the laptop in which I installed Emacs last time. The key bindings were working then. This time I installed Emacs 26.3. Perhaps that is a mistake? I will try with version 25.

PetrKryslUCSD commented 4 years ago

The julia-repl-mode minor mode is not set automatically. (Which would explain the missing keyboard bindings.) Not sure why would that be. Any ideas?

EDIT: I forgot to add (add-hook 'julia-mode-hook 'julia-repl-mode) ;; always use minor mode. Sorry.

PetrKryslUCSD commented 4 years ago

It seems that the following code might also incorporate the rewrite rules:

(defun julia-repl-cd ()
  "Change directory to the directory of the current buffer (if applicable)."
  (interactive)
  (if-let ((directory (file-name-directory (buffer-file-name))))
      (progn
    (julia-repl--send-string (concat "cd(\"" (julia-repl--path-rewrite directory julia-repl-path-rewrite-rules) "\")"))
    (with-current-buffer (julia-repl-inferior-buffer) (cd directory)))
    (warn "buffer not associated with a file")))
tpapp commented 4 years ago

Thanks for the feedback. Yes, the minor mode should be activated in a hook, and then configured. I pushed a fix for the cd and the dependency.

Please keep evaluating this and let me know if there are any open issues.

PetrKryslUCSD commented 4 years ago

Excellent. Thank you very much!

tpapp commented 4 years ago

The dependency resolution is still hacky, leaving this open while waiting for some advice here:

https://emacs.stackexchange.com/questions/53961/install-dependencies-for-emacs-package-in-a-ci-environment

tpapp commented 4 years ago

@PetrKryslUCSD: I am under the impression that this is working well for you, so I am merging.

If you encounter further problems or need some extra features for Windows, please do not hesitate to open an issue.