yuya373 / emacs-slack

slack client for emacs
1.11k stars 117 forks source link

Support for org-agenda #528

Open erichlf opened 3 years ago

erichlf commented 3 years ago

I was thinking it would be nice to have some way to display unread messages in org-agenda. I am guessing this is already possible, but at the moment I haven't a clue how. Anyway, I figured I would open a "feature request" to discuss the possibility of this and maybe how to do it.

ag91 commented 3 years ago

hi @erichlf what a coincidence! I just published a blog about this and I was going to open an issue as well: here the blog https://ag91.github.io/blog/2020/08/14/slack-messages-in-your-org-agenda/ and here the code you need https://github.com/ag91/emacs-slack-org-mode-example/blob/master/emacs-slack-org-mode.el. I plan to also work on https://github.com/yuya373/emacs-slack/issues/475 as soon as I got some time available to make it even more cool. Let me know if this helps and feedback about it: I am happy to improve this.

erichlf commented 3 years ago

Seems to work pretty well, thanks. Now to figure out how to remove things from the agenda when they are complete... I don't really want to see all the done messages.

ag91 commented 3 years ago

Probably the easiest is to make those headlines SCHEDULED instead of having a simple timestamp and then you can use: (setq org-agenda-skip-scheduled-if-done t) as suggested here. Or otherwise you can always filter the agenda (even manually): https://orgmode.org/manual/Filtering_002flimiting-agenda-items.html

erichlf commented 3 years ago

I went with the SCHEDULED solution. Only issue that seems to come up is that org-agenda doesn't see that the item is scheduled if the message is more than one line. The other solution that I thought of would be to mark as done using t and then archive with $ inside org-agenda. I suppose I could create key-binding to make this one stroke instead of two.

ag91 commented 3 years ago

hey @erichlf, I think you can also solve that long message problem with this bit of code: (s-truncate 127 (plist-get info :message)). In that way you will have a partial message in the headline and it should not break. I have updated the repository to also copy the message in the body of the heading in case you want to look at it from the agenda: https://github.com/ag91/emacs-slack-org-mode-example/blob/master/emacs-slack-org-mode.el

erichlf commented 3 years ago

One issue I am having with the schedule or archive method is that I am constantly being asked if I want to save changes to slack.org and slack.org_archive. But sometimes things have changed on disk, so things gets messed up.

ag91 commented 3 years ago

Yeah, good point: can you try (progn (find-file "<your path>/Slack.org") (auto-save-mode)) ? That way it is auto saved any time there is a change.

erichlf commented 3 years ago

That didn't seem to work. The problem is that when marking an entry as complete in org-agenda it doesn't save. So I am guessing there probably needs to be a hook or something.

ag91 commented 3 years ago

@erichlf yep, you are right! Thanks for pointing out this problem I needed to solve it too. So I am going to update that repo again, but here the solution: add (when (get-buffer "Slack.org") (with-current-buffer "Slack.org" (save-buffer))) just before the (write-region ... line, where Slack.org should be the name of your org file with slack messages. This way if the buffer is around and we are up to overwrite it, we will first save it and then write on it. I tested and it seems to work this time.

erichlf commented 3 years ago

I switched to the original method and added a keybinding to set as done and archive

(defun my/org-agenda-todo-archive () (interactive) (org-agenda-todo 'done) (org-agenda-archive))
(add-hook 'org-agenda-mode-hook (lambda () (local-set-key (kbd "T") 'my/org-agenda-todo-archive)))

The auto-save doesn't seem to be working for me.

erichlf commented 3 years ago

One other issue I ran into is saving the org file when someone has typed a unsupported character.

erichlf commented 3 years ago

I finally came up with something that works. It still needs a bit of touch-up, since whenever an org-agenda item is archived, using "T", the slack buffers will be saved, but here you go:

(defun my/save-slack ()
  "Save slack buffers"
  (interactive)
  (save-excursion
    (dolist (buf '("slack.org_archive" "slack.org"))
      (set-buffer buf)
      (if (and (buffer-file-name) (buffer-modified-p))
        (basic-save-buffer)
        )
      )
    )
  )

(defun my/org-agenda-todo-archive ()
  "Mark an agenda item as done, archive it, and save the slack buffers"
  (interactive)
  (org-agenda-todo 'done)
  (org-agenda-archive)
  (my/save-slack)
  )

;; add a hook so that we can mark a slack item as read and archive it
(add-hook 'org-agenda-mode-hook (lambda () (local-set-key (kbd "T") 'my/org-agenda-todo-archive)))
emin63 commented 3 years ago

Thanks for this. I've been fiddling with it some as well and have a question:

Don't we need something like (with-current-buffer <buffer-name> (revert-buffer nil 't)) near https://github.com/ag91/emacs-slack-org-mode-example/blob/master/emacs-slack-org-mode.el#L46 in order to reload the buffer after a new alert gets written? Without that I sometimes have a situation where the buffer is open in emacs but doesn't have the latest alerts in it so my agenda won't build correctly.

Thanks.

ag91 commented 3 years ago

That is weird. I make sure anytime you are mentioned on slack, the Slack.org file is saved in this line. If you revert that buffer you may lose data, I think. How about you try to copy that saving line also after L46? That way you save the file before and after, making sure that things cannot go wrong. (In my use case the current version does not create problems though.)