Skip to content

Link a daily note to the previous one #1706

Closed

Description

@riccardoferretti

Is your feature request related to a problem? Please describe.

Users have requested a way to connect the current daily note to the previous one, e.g. with the following morning workflow:

  1. Open the daily note
  2. Use /yesterday or (/-friday)to get to the previous one
  3. Carry over the tasks that are still open

This requires the user to remember which was the last daily note, and can break after any gap.

It'd be nice if the daily note template could link to the last note that was actually written, without reaching for a JS template.

Related: #930, #931

Describe the solution you'd like

Describe alternatives you've considered

Screenshots or Videos

No response

Activity

  1. sschaefer-allegromicro commented on Sep 24, 2026

    @sschaefer-allegromicro

    Hi @riccardoferretti, thanks for adding that feature. I had a need for that just a few days ago when I wanted to copy over all unchecked tasks from the most recent journal entry and found a workaround using a daily-note.js template. As documentation on those is a bit more limited than the .md templates I was wondering if it would be helpful to add this either in the foam-template or documentation? The former would be convenient, but with foam giving .js templates priority over the more common .md templates this is probably not the best way forward.
    Feel free to use (or not) the below template in either the foam-template or documentation if you find it helpful.

    const JOURNAL_DATE_RE = /^(\d{4}-\d{2}-\d{2})\.md$/;
    
    function getUnfinishedActionItems(noteText) {
      const lines = noteText.split(/\r?\n/);
      const startIndex = lines.findIndex((line) => /^##\s+Action Items$/i.test(line.trim()));
      if (startIndex === -1) {
        return [];
      }
    
      const items = [];
      for (let i = startIndex + 1; i < lines.length; i++) {
        const line = lines[i];
        if (/^##\s+/.test(line.trim())) {
          break;
        }
        if (/^-\s+\[ \]\s*\S/.test(line.trim())) {
          items.push(line.trim());
        }
      }
      return items;
    }
    
    function findMostRecentPriorNote(workspace, formattedDay) {
      const priorNotes = workspace
        .list()
        .map((resource) => {
          const match = JOURNAL_DATE_RE.exec(resource.uri.getBasename());
          return match ? { uri: resource.uri, date: match[1] } : null;
        })
        .filter((entry) => entry && entry.uri.path.includes('/journal/') && entry.date < formattedDay)
        .sort((a, b) => (a.date < b.date ? 1 : -1));
    
      return priorNotes.length > 0 ? priorNotes[0].uri : null;
    }
    
    async function createNote({ trigger, foam, resolver, foamDate }) {
      const today = dayjs();
      // or you could use foamDate for day specific notes, see FOAM_DATE_* variables
      // const day = dayjs(foamDate)
      const formattedDay = today.format('YYYY-MM-DD');
    
      // if you need a variable you can use the resolver
      // const title = await resolver.resolveFromName('FOAM_TITLE');
    
      console.log('Creating note for today: ' + formattedDay, JSON.stringify(trigger));
    
      let carriedItems = [];
      const priorNoteUri = findMostRecentPriorNote(foam.workspace, formattedDay);
      if (priorNoteUri) {
        try {
          const priorNoteText = await foam.workspace.readAsMarkdown(priorNoteUri);
          if (priorNoteText) {
            carriedItems = getUnfinishedActionItems(priorNoteText);
            if (carriedItems.length > 0) {
              console.log(`Carried over ${carriedItems.length} unfinished action item(s) from ${priorNoteUri.getBasename()}`);
            }
          }
        } catch (e) {
          console.log(`Could not read prior note ${priorNoteUri.path}: ${e.message}`);
        }
      }
    
      const actionItemsSection = carriedItems.length > 0
        ? carriedItems.join('\n')
        : '<!-- - [ ] open task -->';
    
      let template = `# ${formattedDay}
    
    ## Agenda
    -
    
    ## Notes
    -
    
    ## Action items
    ${actionItemsSection}
    
    `
    
    
      return {
        content: template,
        filepath: `/journal/${formattedDay}.md`,
      };
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions