Coder Social home page Coder Social logo

Comments (4)

noncog avatar noncog commented on July 18, 2024

I was able to make a minimal version of the feature to meet my needs. I redefined the let* bind in doom-modeline-buffer-file-name to use my own functions which provide the buffer file name variables.

This:

(defun doom-modeline-buffer-file-name ()
  "Propertize file name based on `doom-modeline-buffer-file-name-style'."
  (let* ((buffer-file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) "")))
         (buffer-file-truename (file-local-name
                                (or buffer-file-truename (file-truename buffer-file-name) "")))

Turned into this:

(defun doom-modeline-buffer-file-name ()
  "Propertize file name based on `doom-modeline-buffer-file-name-style'."
  (let* ((buffer-file-name (my/doom-modeline-buffer-file-name))
         (buffer-file-truename (my/doom-modeline-buffer-file-truename))

And these are responsible for checking if the file name should be formatted or returned like normal:

(defun my/org-roam-note-has-denote-title-p (file-name)
  "Return t if Org Roam note file name should be reformatted to display in Doom Modeline."
  (when (and (s-contains-p (expand-file-name org-roam-directory) (expand-file-name file-name))
             (string-match denote-title-regexp file-name)) t))

(defun my/org-roam-note-reformat-file-name (file-name)
  "Remove Denote ID and keywords from Org Roam file names."
  (replace-regexp-in-string (concat denote-id-regexp "--") "" (replace-regexp-in-string denote-keywords-regexp "" file-name)))

(defun my/doom-modeline-buffer-file-name ()
  "Return buffer-file-name filtered if necessary to display in Doom Modeline."
  (let ((file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) ""))))
    (if (my/org-roam-note-has-denote-title-p file-name)
        (my/org-roam-note-reformat-file-name file-name) file-name)))

(defun my/doom-modeline-buffer-file-truename ()
  "Return buffer-file-truename filtered if necessary to display in Doom Modeline."
  (let ((file-truename (file-local-name (or buffer-file-truename (file-truename buffer-file-name) ""))))
    (if (my/org-roam-note-has-denote-title-p file-truename)
        (my/org-roam-note-reformat-file-name file-truename) file-truename)))

So far, it works well and I get to benefit from the built-in styles too. Perhaps something like this can eventually become an official feature or extended further.

from doom-modeline.

seagle0128 avatar seagle0128 commented on July 18, 2024

Your proposal will make the package more extensible. Adding hooks should be able to implement it, but I prefer to add new options to handle the buffer names, as you did in the snippets.

For example,

(defcustom doom-modeline-file-name-function #'doom-modeline-format-file-name
  "The function to format the file name."
  :type 'function
  :group 'doom-modeline)

(defcustom doom-modeline-file-truename-function #'doom-modeline-format-file-truename
  "The function to format the file truename."
  :type 'function
  :group 'doom-modeline)

(defun doom-modeline-buffer-file-name ()
  "Propertize file name based on `doom-modeline-buffer-file-name-style'."
  (let* ((buffer-file-name (funcall #'doom-modeline-format-file-name))
         (buffer-file-truename (funcall #'doom-modeline-format-file-truename)))
    ;;...
  ))

Thoughts?

from doom-modeline.

noncog avatar noncog commented on July 18, 2024

My primary concern with implementing it in this way is the fact that there is some care needed when selecting the buffer names. For example, in the original function, you used the following logic:

(defun doom-modeline-buffer-file-name ()
  "Propertize file name based on `doom-modeline-buffer-file-name-style'."
  (let* ((buffer-file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) "")))
         (buffer-file-truename (file-local-name
                                (or buffer-file-truename (file-truename buffer-file-name) "")))

This appears to be able to handle remote filenames. It seems like you've put some care into ensuring the buffer file names are returned correctly in different scenarios.

If you were to remove this, then I feel that it would be possible for the user to lose this functionality or other future ones like it by simply calling to buffer-file-name and buffer-file-truename. I'm not sure about those additional context/requirements or "what is best" regarding this situation. I'm just concerned with the above structure putting that consideration onto the user whereas a simple filtering function doesn't. Perhaps I'm mistaken but it seems like they would have to handle all aspects of getting the buffer file name and filtering it based on its context.

Further thoughts:

In my opinion, I lean toward preferring a list of simple filter functions run on the buffer file name acquired by the package. I don't have any real opinions on hooks or other implementation, just about structure. So, I think that it should go:

Doom-Modeline gets buffer file names > Filter according to user function(s) > Continue to built-in styles.

Your previous example also appears to run a single function which the user would have to include all of their filtering logic into. Perhaps it could be used like a hook to run a list of filtering functions, which makes sense, run one filter function to return the formatted file name. I do think that I lean toward allowing the user to have filters separated into a list functions to easily add/remove logic. This would make individual filters more sharable and allow combinations of them to run in different contexts if desired. I doubt there is a need for many filters though so maybe that's not actually a concern.

The above could be restructured to include the acquisition of the initial buffer file names in the functions and somehow handle a list of functions from the user. To me, that sounds like the job of a hook, but could be implemented equivalently using customizations. At minimum, I think that the package should get the buffer file name for the user and then be filtered by a list of user function and then be styled.

What do you think? I'm not very experienced with hooks or package development. Is there some reason to prefer defcustoms over hooks? Also is there some form of like a no-op for the empty filter the package would ship with? I don't know how that would work. Either way, the only real concern is the acquisition of the buffer file name and then running a filter which can be structured equivalently in many ways, whether it's a single function, hook, list of functions, or whatever, that's all up to your preference.

from doom-modeline.

seagle0128 avatar seagle0128 commented on July 18, 2024

Doom-Modeline gets buffer file names > Filter according to user function(s) > Continue to built-in styles.

The steps are correct. The only issue is the return value of run-hook-with-args is unspecified. In my env (Windows & Linux, Emacs 29.1 & 28.1), the snippet below returns "Return value: nil". Can you please try?

(defvar my-hook nil
  "My custom hook")

(defun my-hook-function (arg1 arg2)
  "A function to be executed by the hook"
  (message "Argument 1: %s" arg1)
  (message "Argument 2: %s" arg2)
  (+ arg1 arg2))

(add-hook 'my-hook 'my-hook-function)

(let ((result (run-hook-with-args 'my-hook 2 3)))
  (message "Return value: %s" result))

So I implemented with functions but keep the original handles and styles. The default value is identity, and the users can implement a function to handle the names as what the users want. I think it meets the most of requirements, right?

Of course if I find a better solution, I shall update.

from doom-modeline.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.