kaorahi / howm

note-taking tool on Emacs
GNU General Public License v2.0
147 stars 11 forks source link

Diary/Calendar integration ? #45

Closed xmailla closed 2 months ago

xmailla commented 2 months ago

It seems there is something here: https://www.emacswiki.org/emacs/HowmAndCalendar

But as far as I can tell it does too much as changing the diary file. Etc.

What's the recommended way to incorporate safely diary in howm ?

kaorahi commented 2 months ago

I don't have a direct answer, but just FYI, calfw-howm looks well-designed as a calendar tool. I haven't tried it myself.

https://github.com/kiwanami/emacs-calfw/

Alternatively, I once started writing an export script for the iCal format in ext/hcal.rb, but it's incomplete. It's a low priority for me, as I don't plan to use it myself.

xmailla commented 2 months ago

I like the diary syntax to enter repetitive schedules like birthdays, regular event (payday), regular reminders (give pocket money to lulu on 1st of each month), etc.

I do not know how to do it directly with howm :/

Example: `%%(diary-float t 0 1) Argent de poche de Lubin ;; pocket money reminder

%%(let ((dayname (calendar-day-of-week date)) (day (cadr date))) (or (and (= day 20) (memq dayname '(1 2 3 4 5))) (and (memq day '(18 19)) (= dayname 5))) ) Jours de paye. ; pay day ` How would you do that ?

mmarshall540 commented 2 months ago

I adapted some of the code from that EmacsWiki page about diary integration. It was no longer working. Adding this to init.el/.emacs and %hdiary to the howm-menu-file causes diary entries to appear in the Howm-menu.

At least the updated parts shouldn't make any changes to the Emacs diary file. It only opens the file to look for appointments. Parts that I haven't gotten around to updating are commented out.

;; Adapted from
;; https://www.emacswiki.org/emacs/HowmAndCalendar
(autoload 'howm-reminder-today "howm-reminder")
(autoload 'howm-reminder-search "howm-reminder")
(autoload 'calendar-mark-date-pattern "diary-lib")
(autoload 'diary-list-entries "diary-lib")
(autoload 'howm-mode "howm-mode")
(autoload 'action-lock-general "action-lock")
(autoload 'action-lock-set-rules "action-lock")
(with-eval-after-load 'howm
  (require 'calendar)
  (defvar calendar-date-display-form)
  (defvar howm-directory)
  (defvar howm-schedule-menu-types)

  ;; Format calendar dates for display in the Howm-menu
  (setopt calendar-date-display-form
          '("[" year "-" (format "%02d" (string-to-number month))
            "-" (format "%02d" (string-to-number day)) "]"))

  ;; Necessary?
  ;; (setopt diary-file (expand-file-name "diary" howm-directory))

  ;; (defun howm-mark-calendar-date ()
  ;;   (interactive)
  ;;   (require 'howm-reminder)
  ;;   (let* ((today (howm-reminder-today 0))
  ;;          (limit (howm-reminder-today 1))
  ;;          (howm-schedule-types
  ;;           howm-schedule-menu-types)
  ;;          (raw (howm-reminder-search
  ;;                howm-schedule-types))
  ;;          (str nil) (yy nil) (mm nil) (dd nil))
  ;;     (while raw
  ;;       (setq str (nth 1 (car raw)))
  ;;       (when
  ;;           (string-match
  ;;            "\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)"
  ;;            str)
  ;;         (setq yy (match-string 1 str))
  ;;         (setq mm (match-string 2 str))
  ;;         (setq dd (match-string 3 str)))
  ;;       (when (and yy mm dd)
  ;;         (calendar-mark-date-pattern
  ;;          (string-to-number mm)
  ;;          (string-to-number dd)
  ;;          (string-to-number yy)))
  ;;       (setq mm nil)
  ;;       (setq dd nil)
  ;;       (setq yy nil)
  ;;       (setq raw (cdr raw)))))

  ;; Add advice to `diary-mark-entries' to call the above function
  ;; `:after'.
  ;; (advice-add 'diary-mark-entries :after 'howm-mark-calendar-date)

  ;; Add an entry for `howm-menu-diary' to `howm-menu-display-rules'
  (defvar howm-menu-display-rules)
  (setopt howm-menu-display-rules
          (cons
           (cons "%hdiary[\n]?" 'howm-menu-diary)
           howm-menu-display-rules))

  ;; Function to insert diary entries to the Howm-menu in place of
  ;; the "%hdiary" tag.
  (defvar diary-display-function)
  (defvar howm-menu-schedule-days)
  (defun howm-menu-diary ()
    (require 'diary-lib)
    (message "scanning diary...")
    (delete-region
     (match-beginning 0) (match-end 0))
    (let* ((now (decode-time (current-time)))
           (diary-date
            (list (nth 4 now) (nth 3 now) (nth 5 now)))
           (diary-display-function 'ignore)
           ;; (cbuf (current-buffer))
           (howm-diary-entry nil)
           (howm-diary-entry-day nil)
           str mm dd yy)
      (unwind-protect
          (setq howm-diary-entry
                (diary-list-entries
                 diary-date howm-menu-schedule-days))
        (with-current-buffer (find-buffer-visiting diary-file)
          (subst-char-in-region
           (point-min) (point-max) ?\^M ?\n t)
          (setq selective-display nil)))
      (while howm-diary-entry
        (setq howm-diary-entry-day (car howm-diary-entry))
        (setq mm (nth 0 (car howm-diary-entry-day)))
        (setq dd (nth 1 (car howm-diary-entry-day)))
        (setq yy (nth 2 (car howm-diary-entry-day)))
        (setq str (nth 1 howm-diary-entry-day))
        (setq howm-diary-entry (cdr howm-diary-entry))
        (insert
         (format
          ">>d [%04d-%02d-%02d] %s\n" yy mm dd str))))
    (message "scanning diary...done"))

  ;; Add '("\\[" year "-" month "-" day "\\]" "[^0-9]")' to the list
  ;; of `diary-date-forms'
  (defvar diary-date-forms)
  (setq diary-date-forms
        '((month "/" day "[^/0-9]")
          (month "/" day "/" year "[^0-9]")
          ("\\[" year "-" month "-" day "\\]" "[^0-9]")
          (monthname " *" day "[^,0-9]")
          (monthname " *" day ", *" year "[^0-9]")
          (dayname "\\W")))

  (defun howm-open-diary (&optional _dummy)
    (interactive)
    (let ((date-str nil) (str nil))
      (save-excursion
        (beginning-of-line)
        (when (re-search-forward
               ">>d \\(\\[[-0-9]+\\]\\) " nil t)
          (setq str
                (concat
                 "^.+"
                 (buffer-substring-no-properties
                  (point) (line-end-position))))
          (setq date-str
                (concat
                 "^.+"
                 (buffer-substring-no-properties
                  (match-beginning 1)
                  (match-end 1))
                 " " str))
          (find-file
           (substitute-in-file-name diary-file))
          (howm-mode t)
          (goto-char (point-min))
          (if (re-search-forward date-str nil t)
              ()
            (re-search-forward str nil t))))))

  (defvar action-lock-default-rules)
  (defun add-diary-action-lock-rule ()
    (let ((rule
           (action-lock-general
            'howm-open-diary
            "^\\(>>d\\) "
            1 1)))
      (if (not (member rule action-lock-default-rules))
          (progn
            (setq action-lock-default-rules
                  (cons rule action-lock-default-rules))
            (action-lock-set-rules
             action-lock-default-rules)))))

  (add-hook 'action-lock-mode-on-hook
            'add-diary-action-lock-rule)

  ;; (defadvice make-diary-entry
  ;;     (after howm-mode activate)
  ;;   (text-mode)
  ;;   (howm-mode t))
  )

;;;;;;;;;;

;; M-x calendar, move cursor to a certain date, and
;; M-x howm-from-calendar to search that date in howm notes.
;; (defun howm-from-calendar ()
;;   (interactive)
;;   (require 'howm-mode)
;;   (let* ((mdy (calendar-cursor-to-date t))
;;          (m (car mdy))
;;          (d (second mdy))
;;          (y (third mdy))
;;          (key (format-time-string
;;                howm-date-format
;;                (encode-time 0 0 0 d m y))))
;;     (howm-keyword-search key)))

;; Bind howm-from-calendar to "d" key.
;; (add-hook 'initial-calendar-window-hook
;;           '(lambda ()
;;              (local-set-key
;;               "d" 'howm-from-calendar)))

;; Type "C" in howm menu to open calendar.
;; (add-hook 'howm-menu-hook
;;           '(lambda ()
;;              (local-set-key "C" 'calendar)))
kaorahi commented 2 months ago

Not everyone may agree, but I prefer a naive approach for repetitive schedules (#9).

xmailla commented 2 months ago

I adapted some of the code from that EmacsWiki page about diary integration. It was no longer working. Adding this to init.el/.emacs and %hdiary to the howm-menu-file causes diary entries to appear in the Howm-menu.

At least the updated parts shouldn't make any changes to the Emacs diary file. It only opens the file to look for appointments. > Parts that I haven't gotten around to updating are commented out.

Thank you. I will have a look at it and report back.

xmailla commented 2 months ago

Not everyone may agree, but I prefer a naive approach for repetitive schedules (#9).

After thinking about it, maybe I find the "naive" approach, rather interesting and without needing to think more than that.

By the way, why is there no more discussion list?

kaorahi commented 2 months ago

Are you asking about the mailing list (Howm-eng)? We stopped using it after the service was acquired by another company, as we experienced issues like connection failures.

https://osdn.net/projects/howm/lists/archive/eng/

I'd prefer to use GitHub Issues for discussions now.

kaorahi commented 2 months ago

See also: #49

old tips (in JP) https://web.archive.org/web/20221128143450/https://howm.osdn.jp/cgi-bin/hiki/hiki.cgi?CalendarMode