joaotavora / breadcrumb

Emacs headerline indication of where you are in a large project
193 stars 10 forks source link

Customize node formatting function #6

Open mohkale opened 1 year ago

mohkale commented 1 year ago

Hi, Thanks for this package. I was looking for something like this and found some discussions from last year and this popping up this week :smiley:. Happy timing.

I'd like to be able to inject icons before each breadcrumb item based on its type. I'm not really sure how you're managing to detect the completion type but breadcrumb does seem to have it available :thinking:.

(breadcrumb-ipath (breadcrumb--ipath-alist) (point))
;; (#("foo" 0 3 (breadcrumb-region (1 . 102) breadcrumb-kind "Namespace")) #("bar" 0 3 (breadcrumb-region (21 . 100) breadcrumb-kind "Namespace")) #("baz" 0 3 (breadcrumb-region (45 . 94) breadcrumb-kind "Namespace")) #("foo" 0 3 (breadcrumb-region (73 . 83) breadcrumb-kind "Function")))

Is there any possibility of opening up the bc--format-node function as something customizeable so one can inject whatever they'd like into it.

S.N. Any way to use the standard company-kind values instead of this string (I presume that's passed from the imenu backend but if we could update eglot and any of the other builtins to supply this instead (perhaps as a separate field that breadcrumb then ingests) then that would be great).

S.S.N. Whatever we do to add icons to the statusline probably shouldn't influence breadcrumb-jump. If that needs annotations it should come from the standard minibuffer margin functionality like marginalia or consult provide.

joaotavora commented 1 year ago

Maybe you can just add this icon-injection to breadcrumb.el itself, perhaps by depending (optionally, i.e. not requiring) on a good (small) icon library, just like company-mode does. The breadcrumb-kind comes from the LSP standard, and I think I don't have a great reason to use any other standard. There will have to be some mapping.

joaotavora commented 1 year ago

@mohkale if you're still interested in this, propose some patch. Or just give me a suggestion: if an ideal interface (IYO) for this was already in place, what exactly would you be writing in your .emacs or your breadcrumb-using package?

mohkale commented 1 year ago

Hi @joaotavora

Yeah, I've been meaning to come back to this. I sort of blocked it off since my GNU copyright contributors agreement was kind of in a pending state until last week and I wasn't sure even if I do anything when it would be in a mergeable state. I'll take a look at this soon and propose something. Initially though I'll probably direct a patch to eglot to use make the breadcrumb-kind property consistent with company-kind. There's a lot of tools that have adopted symbols for this and it would line up with them.

Also, unrelated, have you had a chance to take a look at the discussion I opened on eglot about the imenu backend with DocumentSymbol? That's another thing that I can contribute now if you'd like. I'll continue that discussion their.

joaotavora commented 1 year ago

Initially though I'll probably direct a patch to eglot to use make the breadcrumb-kind

OK, but please assuming that that patch was already in place and Eglot or any other imenu-backend was placing the information you want in imenu node strings -- then how would you want to customize breadcrumb's formatting?

mohkale commented 1 year ago

I'd have to take a look at how breadcrumb is implemented but ideally this is a problem of two parts right. You have something that matches the each element (in the screenshot in your README this would be baz, foo, bar) and then something which concatenates all of these elements together to construct foo > bar > baz. So I'd say 2 functions:

I'd add icons using breadcrumb-annotation-function and I probably won't change breadcrumb-formatter-function. I'd expect some people may want the joining character to be an icon as well and rather than defining how they would want to join with a defcustom string it would be simpler to just let them override the entire formatting process by supplying their own function. Thoughts?

mohkale commented 1 year ago

Something to add, that I really like, is instead of having defcustoms for these functions some applications have a single defcustom for a backend type and then a cl-method variant for the implementation based on what that type is set to. For example my compile-multi package uses the base completing read interface by default but you can configure it to use a slightly nicer consult backend optionally.

kvaneesh commented 3 months ago

it would be nice to get this supported.

DevelopmentCool2449 commented 3 months ago

Hello, i'm sorry if i came late to this discussion, i could do icon-injection to breadcrumb, here is the code that i use in my config file:

(advice-add #'breadcrumb--format-project-node :around
            (lambda (og p more &rest r)
              "Icon For File"
              (let ((string (apply og p more r)))
                (if (not more)
                    (concat (nerd-icons-icon-for-file string)
                            " " string)
                  (concat (nerd-icons-faicon
                           "nf-fa-folder_open"
                           :face 'breadcrumb-project-crumbs-face)
                          " "
                          string)))))

(advice-add #'breadcrumb--project-crumbs-1 :filter-return
            (lambda (return)
              "Icon for Parent Node"
              (if (listp return)
                  (setf (car return)
                        (concat
                         " "
                         (nerd-icons-faicon
                          "nf-fa-rocket"
                          :face 'breadcrumb-project-base-face)
                         " "
                         (car return))))
              return))

(advice-add #'breadcrumb--format-ipath-node :around
            (lambda (og p more &rest r)
              "Icon for items"
              (let ((string (apply og p more r)))
                (if (not more)
                    (concat (nerd-icons-codicon
                             "nf-cod-symbol_field"
                             :face 'breadcrumb-imenu-leaf-face)
                            " " string)
                  (cond ((string= string "Packages")
                         (concat (nerd-icons-codicon "nf-cod-package" :face 'breadcrumb-imenu-crumbs-face) " " string))
                        ((string= string "Requires")
                         (concat (nerd-icons-codicon "nf-cod-file_submodule" :face 'breadcrumb-imenu-crumbs-face) " " string))
                        ((or (string= string "Variable") (string= string "Variables"))
                         (concat (nerd-icons-codicon "nf-cod-symbol_variable" :face 'breadcrumb-imenu-crumbs-face) " " string))
                        ((string= string "Function")
                         (concat (nerd-icons-mdicon "nf-md-function_variant" :face 'breadcrumb-imenu-crumbs-face) " " string))
                        (t string))))))

Here the final result Screenshot_20240620_211209

I don't know how this can be ported to this package, i would be willing to help if needed