I added an embark config from: https://karthinks.com/software/fifteen-ways-to-use-embark/#open-any-buffer-by-splitting-any-window, which works really good, the only problem is that if a file is opened with project-find-file-in, it doesn’t respect its own directory.

Steps:

  1. When the default-directory set to ~/, M-x browse-emacs-config to open a file list of ~/.config/emacs in the minibuffer
  2. embark-act on a file lisp/init-lib.el
  3. o and b to open the selected file horizontally
  4. A buffer opened on the right side, but the directory is still using the default-directory in step 1 instead of the buffer’s directory, causing the buffer to visit ~/lisp/init-lib.el instead of ~/.config/emacs/lisp/init-lib.el.

Config:

(defun find-file-in-project (&optional dir)
  (interactive)
  (let ((project (project-current nil dir)))
    (project-find-file-in nil nil project)))

(defun browse-emacs-config ()
  (interactive)
  (find-file-in-project "~/.config/emacs"))

(eval-when-compile
  (defmacro my/embark-aw-action (fn)
    `(defun ,(intern (concat "my/embark-aw-" (symbol-name fn))) ()
       ,(format "Open %s buffer selected with ace-window" (symbol-name fn))
       (interactive)
       (with-demoted-errors "%s"
         (require 'ace-window)
         (let ((aw-dispatch-always t))
           (aw-switch-to-window (aw-select nil))
           (call-interactively (symbol-function ',fn)))))))

(define-key embark-file-map (kbd "o") (my/embark-aw-action find-file))
  • vm7_69@alien.topB
    link
    fedilink
    English
    arrow-up
    1
    ·
    10 months ago

    Hey there! It looks like you might need to adjust the default-directory when using embark-act. Have you considered using with-current-buffer to set the directory to the one of the selected file before invoking embark-act? This might help ensure that the buffer’s directory is respected. Cheers!

    • goofansu@alien.topOPB
      link
      fedilink
      English
      arrow-up
      1
      ·
      10 months ago

      Hi, do you mean with-current-buffer in my/embark-aw-action? I don’t see how to pass the selected buffer to the function.

  • nullmove@alien.topB
    link
    fedilink
    English
    arrow-up
    1
    ·
    10 months ago

    I guess given that I see file metadata in marginalia correctly, project-find-file-in does call find-file with appropriate dynamic binding for default-directory, so I suspect the way embark works (or due to other stuffs, perhaps /u/oantolin can explain), it cannot continue from that scope, so by the time embark starts the old dynamic scope has already been unwound?

    Anyway, you can just wrap that function call with your own binding that covers embark:

    (defun find-file-in-project (&optional dir)
      (interactive)
      (when-let* ((project (project-current nil dir))
                  (default-directory (project-root project)))
        (project-find-file-in nil nil project)))
    
    • goofansu@alien.topOPB
      link
      fedilink
      English
      arrow-up
      1
      ·
      10 months ago

      Thank you! You’re right, the scope is not transformed, set default-directory in the middle function works.

    • goofansu@alien.topOPB
      link
      fedilink
      English
      arrow-up
      1
      ·
      10 months ago

      Thank you! You’re right, the scope is not transformed, set default-directory in the middle function works.