Coder Social home page Coder Social logo

Comments (6)

protesilaos avatar protesilaos commented on September 2, 2024

from denote.

mentalisttraceur avatar mentalisttraceur commented on September 2, 2024

Glad to hear you're open to it too @protesilaos!

In the meantime, I've decided to go ahead and write up what I currently do to make this work in my config.

Big picture: I have four separate commands - one to add keywords one, to remove keywords, one to change the title, and one to change the datetime, Each one prompts for the thing they're changing, then retrieves all the other information that it's not changing, and finally calls denote-rename-wrapper through my wrapper.

Details:

First, I have these two helper functions to add a fake ID to a path, and to strip the ID off:

(defun denoted--remove-id (path)
     (concat
         (file-name-directory path)
         (string-remove-prefix "--"
             (substring (file-name-nondirectory path) 15))))

(defun denoted--add-nil-id (path)
    (let ((name (file-name-nondirectory path)))
        (concat
            (file-name-directory path)
            "00000000T000000"
            (if (or (string-prefix-p "==" name)
                    (string-prefix-p "__" name))
                ""
                "--")
            name)))

For retrieving the title, I use this:

(defun denoted-title-get (path)
    (let ((denote-directory default-directory)
          (note-type (denote-file-note-type path)))
        (if note-type
            (denote-retrieve-title-value path note-type)
            (if (denote-file-has-identifier-p path)
                (denote-retrieve-filename-title path)
                (denote-retrieve-filename-title
                    (denoted--add-nil-id path))))))
  • denote-file-note-type (see #284) already works whether or not the file name has a Denote ID in it.

  • If denote-file-note-type did not recognize the file as a note, get the title from the file name. (I am using the not-yet-release definition of denote-retrieve-filename-path, per #272.)

    • If the file name does not have an ID, I just slap a fake one on it so that I can reuse Denote's own logic.

denote-extract-id-from-string, denote-extract-keywords-from-path, and denote-retrieve-filename-signature Just Work with the naming scheme described above.

Then I wrap denote-rename-file calls to apply some advice during the call, kinda like this:

(defun my-denote-rename-file-wrapper (... id)
    (with-advice ('denote-get-file-extension
                      :filter-args 'hack-denote-get-file-extension)
        (if (equal id "")
            (with-advice ('denote-format-file-name
                              :filter-return 'denoted--remove-id)
                (denote-rename-file ...))
            (with-advice ('denote-retrieve-filename-identifier
                              :override (lambda (&rest _) id))
                (denote-rename-file ...)))))

where hack-denote-get-file-extension is defined as

(defun hack-denote-get-file-extension (arguments)
    (let ((path (car arguments)))
        (unless (denote-file-has-identifier-p path)
            (setcar arguments (denoted--add-nil-id path))))
    arguments)

and if I the ID is blank, I abuse a lucky aspect of the denote-rename-file implementation by advising denote-format-file-name to remove the ID from its return value - otherwise, I do the trick described in #278 .

from denote.

mentalisttraceur avatar mentalisttraceur commented on September 2, 2024

We have a basic version of this in the manual: https://protesilaos.com/emacs/denote#h:e666ced6-da75-4bdb-9be3-82c2f4455ee9

Okay, I took the time to understand this. Thank you for the pointer @protesilaos !

I think I could achieve what I currently do without monkey-patching (or even calling) denote-rename-file by combining

  • denote-format-file-name,
  • denote-rename-file-prompt,
  • denote-rename-file-and-buffer (with #279),
  • denote-update-dired-buffers,
  • denote-rewrite-front-matter,
  • denote--edit-front-matter-p, and
  • denote-file-note-type (from #284).

(I disable denote--add-front-matter with :override 'ignore during my wrapped Denote rename calls, so I don't need that.)

I'm gonna try that out. I'd certainly much rather move away from monkey-patching with advice dependent on internal implementation details.

from denote.

mentalisttraceur avatar mentalisttraceur commented on September 2, 2024

Okay, assuming

  1. denote-file-note-type from #284 ,
  2. denote-rename-buffer-and-file is patched to ignore missing-file from rename-file (the simplest subset of #279 ), and
  3. denote-format-rename-file is patched to accept an empty string ID to produce names with with no ID as described in this issue,

then I think I can achieve everything I am currently doing+wanting with denote-rename-file without resorting to any monkey-patching. Here's a sketch, untested:

    (defun denoted-rename-file (path datetime prefix title tags)
        (setq-if-nil datetime "")
        (setq-if-nil prefix "")
        (setq-if-nil title "")
        (let* ((directory (file-name-directory (expand-file-name path)))
               (extension (...))
               (new-path  (denote-format-file-name
                              directory
                              datetime
                              tags
                              (denote-sluggify title 'title)
                              (concat "." extension)
                              (denote-sluggify-signature prefix))))
            (when (denote-rename-file-prompt path new-path)
                (denote-rename-file-and-buffer path new-path)
                (let ((denote-directory directory))
                    (denote-update-dired-buffers))
                (when-let (type (denote-file-note-type new-path))
                    (denote-rewrite-front-matter new-path title tags type t)))))

That ends up being much clearer than all the advising monkey patching I was doing, and significantly less code in total.

from denote.

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.