Labels for emails (without gmail)

372 views
Skip to first unread message

Stephen Eglen

unread,
Nov 28, 2014, 8:56:25 AM11/28/14
to mu-di...@googlegroups.com
Hi,

Has anyone yet got a good workflow for adding labels ("todo", "fixme" etc)
to mail messages?  This is working with a regular Imap server, not gmail.

Stephen

Paul Rankin

unread,
Nov 28, 2014, 9:01:28 AM11/28/14
to mu-di...@googlegroups.com

Stephen Eglen <stephe...@gmail.com> writes:

> Has anyone yet got a good workflow for adding labels ("todo", "fixme" etc)
> to mail messages? This is working with a regular Imap server, not gmail.

As far as I'm aware, labels are a Google invention, and not part of the
IMAP spec, but I'd be interested to learn otherwise.

Eduardo Mercovich

unread,
Nov 28, 2014, 12:53:57 PM11/28/14
to mu-di...@googlegroups.com
Hi.

> As far as I'm aware, labels are a Google invention, and not part of the
> IMAP spec, but I'd be interested to learn otherwise.

According to
* the explanation in http://deflexion.com/2006/05/server-side-message-labels and
* the specs in http://www.faqs.org/rfcs/rfc3501.html, it seems keywords or flags are (or should be) a standard IMAP service.

If we can couple this with mu super seach capabilities, then the whole folder idea became simplified (in extremis, inbox+archive only) and bookmarks become the greatest things since chocolate biscuits (which already are). ;)

This may imply some UI to manage the user defined keywords/flags, and if it is the case, I volunteer my UX years to help with that.

--
e

Stephen Eglen

unread,
Nov 28, 2014, 3:08:15 PM11/28/14
to mu-di...@googlegroups.com
Thanks.  I was thinking of something simpler along the lines of the "X-label:" header, e.g.:


Stephen

Paul Rankin

unread,
Nov 29, 2014, 12:09:42 AM11/29/14
to mu-di...@googlegroups.com

Eduardo Mercovich <eduardo....@gmail.com> writes:

> According to
> * the explanation in
> http://deflexion.com/2006/05/server-side-message-labels and
> * the specs in http://www.faqs.org/rfcs/rfc3501.html, it seems keywords or
> flags are (or should be) a standard IMAP service.
>
> If we can couple this with mu super seach capabilities, then the whole
> folder idea became simplified (in extremis, inbox+archive only) and
> bookmarks become the greatest things since chocolate biscuits (which
> already are). ;)

Wow I had no idea. This IS the greatest thing since chocolate
biscuits..!

--
Paul W. Rankin
http://www.paulwrankin.com

Before printing this email please take a moment to think about the
environment. Just stop and think about it. Think about the last time you
were walking alone in a forest, how you felt at peace, how a wave of
clarity seemed to overcome you and you had to stop and reevaluate your
life, what you're doing with the limited time you have here. "Damn," you
thought, "life is so precious. I should really be doing ______." Are you
doing that now? Why not? Go on, pick up your computer and throw it out
the window! It'll be great, like that scene from Network where everyone
starts yelling "I'M MAD AS HELL AND I'M NOT GOING TO TAKE THIS ANY
MORE." That'll be you, but it will be real. Now's your moment.

Benjamin Slade

unread,
Nov 29, 2014, 3:26:10 PM11/29/14
to mu-di...@googlegroups.com
If you use recent versions of offlineimap, you can sync labels, e.g. including something like this in your .offlineimaprc

[Account EXAMPLEGMAIL]
localrepository = LocalEXAMPLEGMAIL
remoterepository = RemoteEXAMPLEGMAIL

synclabels = yes                         
labelsheader = X-Keywords                
filterheaders = X-Keywords               
ignorelabels = \Important, \Draft, \Sent, \Starred, ARCHIVED

[Repository LocalEXAMPLEGMAIL]
type = GmailMaildir
localfolders = ~/Maildir/EXAMPLEGMAIL

[Repository RemoteEXAMPLEGMAIL]
type = Gmail
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
folderfilter = lambda folder: folder in ['ARCHIVED',  '[Gmail]/Sent Mail', '[Gmail]/Bin', '[Gmail]/Spam', '[Gmail]/Drafts',  'INBOX']
remotehost = imap.gmail.com
remoteuser = examp...@gmail.com
remotepass = something
ssl = yes
maxconnections = 1
realdelete = no


and then add something like this to your .emacs:

;; add tags
(setq mu4e-action-tags-header "X-Keywords")
(add-to-list 'mu4e-headers-actions '("tRetag message" . mu4e-action-retag-message) t)
(add-to-list 'mu4e-view-actions '("tRetag message" . mu4e-action-retag-message) t)

What I still need is something which lets me do autocompletion for existing labels when I'm searching or wanting to add a label.  I see someone has written up some elisp for this: https://gist.github.com/lgatto/7091552   --  but the grepping bit doesn't work for me (fails because it complains argument list to grep is too long).  Ultimately I wouldn't even mind a hand-inputted list in .emacsrc --- since I don't use *that* many labels.

Stephen Eglen

unread,
Nov 30, 2014, 4:53:11 AM11/30/14
to mu-di...@googlegroups.com
Thanks!  I just checked with Laurent Gatto (who wrote the autocompletion code you refer to).  I will try this approach -- do you happen to know which version of offlineimap you need to get this to work?  I'm concerned how if I add a label on the mu side whether offlineimap propagates it back to a non-gmail.  I guess I should try it, but will try and test in a simple sandbox rather than break my email!


To solve your grep problem (I also got the "too many messages error"; you might need to run it through xargs/parallel?), what you could do is just
manually create the file Maildir/xkeys.txt and put in your tags there, one tags per line (no commas).

"All" the grep does is find all the labels currently stored in your maildir; so editing the list yourself should be fine.

Laurent: perhaps you (or I can) can volunteer a patch to get your gist into mu4e?  I was thinking the Emacs way to do it might be
simply to have an extra list called mu4e-xlabels, e.g.

(setq mu4e-xlabels '("work" "home" "todo"))

which is used as the list for completion; in Laurent's workflow the variable would be set thus:

(setq mu4e-xlabels (read-lines mu4e-xkeys))


and then the tags are completed using:

(completing-read "Tags: " mu4e-xlabels)

Stephen

Benjamin Slade

unread,
Dec 2, 2014, 7:07:01 PM12/2/14
to mu-di...@googlegroups.com

Thanks, Stephen.

It worked perfectly.  The main thing I'm missing is some sort of batch tagging.



For others, just to make implementing like this easier, here is the elisp code:

(setq mu4e-xlabels '("home" "work" "todo" "whatever-labels-you-want"))

(defun mu4e-action-retag-message (msg &optional retag-arg)
  "Change tags of a message. Example: +tag \"+long tag\" -oldtag
   adds 'tag' and 'long tag', and removes oldtag."
  (let* ((retag (or retag-arg (completing-read "Tags: " mu4e-xlabels)))
          (path (mu4e-message-field msg :path))
          (maildir (mu4e-message-field msg :maildir))
          (oldtags (mu4e-message-field msg :tags))
          (header  mu4e-action-tags-header)
          (sep     (cond ((string= header "Keywords") " ")
                     ((string= header "X-Label") " ")
                     ((string= header "X-Keywords") ", ")
                     (t ", ")))
          (taglist (if oldtags (copy-sequence oldtags) '()))
          tagstr)
    (dolist (tag (split-string-and-unquote retag) taglist)
      (cond
        ((string-match "^\\+\\(.+\\)" tag)
          (setq taglist (push (match-string 1 tag) taglist)))
        ((string-match "^\\-\\(.+\\)" tag)
          (setq taglist (delete (match-string 1 tag) taglist)))
        (t
          (setq taglist (push tag taglist)))))
 
    (setq taglist (sort (delete-dups taglist) 'string<))
    (setq tagstr (mapconcat 'identity taglist sep))
 
    (setq tagstr (replace-regexp-in-string "[\\&]" "\\\\\\&" tagstr))
    (setq tagstr (replace-regexp-in-string "[/]"   "\\&" tagstr))
 
    (if (not (mu4e~contains-line-matching (concat header ":.*") path))
      ;; Add tags header just before the content
      (mu4e~replace-first-line-matching
        "^$" (concat header ": " tagstr "\n") path)
 
      ;; replaces keywords, restricted to the header
      (mu4e~replace-first-line-matching
        (concat header ":.*")
        (concat header ": " tagstr)
       path))
 
    (mu4e-message (concat "tagging: " (mapconcat 'identity taglist ", ")))
    (mu4e-refresh-message path maildir)))

Benjamin Slade

unread,
Dec 2, 2014, 10:02:41 PM12/2/14
to mu-di...@googlegroups.com
Forgot to address this bit:


On Sunday, 30 November 2014 02:53:11 UTC-7, Stephen Eglen wrote:
Thanks!  I just checked with Laurent Gatto (who wrote the autocompletion code you refer to).  I will try this approach -- do you happen to know which version of offlineimap you need to get this to work?  I'm concerned how if I add a label on the mu side whether offlineimap propagates it back to a non-gmail.  I guess I should try it, but will try and test in a simple sandbox rather than break my email!

It works from offlineimap 6.5.6 .

I don't think it'll propagate to a non-gmail remote account.  Note in the .offlineimaprc file you have to specify for the remote account  "type = IMAP" or "type = Gmail".  The label propagation will only work with Gmail accounts as far as I know.

Abdó Roig-Maranges

unread,
Dec 4, 2014, 6:17:33 AM12/4/14
to mu-di...@googlegroups.com, Stephen Eglen

Hi Stephen,


> Apologies for the direct mail, rather than going through the email lists.

I answer back to your post on the mu mailing list, in case anyone else is
interested.



> I have a quick query about your offlineimap fork on github.

Note that my offlineimap fork is obsolete, the gmail-labels functionality is
already merged upstream since version 6.5.6.



> Does that (or offlineimap 6.5.6) support syncing of labels back to a normal
> (i.e. not gmail) imap server?

No. offlineimap uses gmail's IMAP extensions for querying and modifying labels
on the gmail side. Then embeds them into a special header of your chosing
(X-Labels, X-Keywords, etc) in the local copy of the messages. The
label-querying on the server will not work for non-gmail servers.

The point of this was, to NOT modify the message content on the gmail side (only
the local copy). Gmail's IMAP extensions allows you to change and query the
labels of a message without touching the content. The end result is that I can
use the labels from both, web interface and mu4e, and keep them in sync.



> I use mu4e, and I'd like to add tags locally and then have them in X-Label:
> header locally, and then for those headers to be resync'ed back to the imap
> server.

I assume that what you want is to propagate message content changes (the X-Label
header) back to the IMAP server. I don't think the IMAP protocol is designed to
allow messages to be changed. Also, this is not a good idea anyway: On a message
with a 5 Mb attachment, you would have to upload all 5 Mb on every label
change...

Keep in mind that embedding the labels inside the local messages was a hack in
the first place, because I couldn't find a better way to store labels close to
the local messages. The fact that gmail extensions to the IMAP protocol allows
you to keep the hack local, and not propagate any message content changes to
gmail (only the labels metadata) is what mitigates the issue.



Let me suggest an alternative solution. I assume you want this because you want
to use the IMAP server as a synchronization mechanism between two or more
machines you use. Is this correct?

What I do for this purpose is to sync my local maildir across machines, together
with offlineimap metadata, using an external tool. All my mail lives in
different subdirectories of '~/mail', and in '~/mail/metadata' there is the
offlineimap metadata. Then I use this piece of config for offlineimap:

[General]
# where to store offlineimap's metadata
metadata = ~/mail/metadata

[...]

[Account blah]
# prevent the X-Keywords header from propagating back to the IMAP server
filterheaders = X-Keywords

[...]


When I synchronize '~/mail' across machines, all the offlineimap state, and
message labels go along with the messages! And I can use offlineimap to fetch
new messages from any machine.

Depending on your mail client, or whether you use the gmail label syncing, you
need to make sure the file modification time gets synced across machines too.

The tool I use for the synchronisation across machines is git. This is a bit
involved since it needs hooks to recover modification times + a little patch for
offlineimap to write sorted metadata files. This way git produces nice short
diffs of the offlineimap metadata.

Of course it is much easier to use other tools to do the syncing, like unison,
rsync, etc. Maybe you already use one them to synchronize other files.

I hope this helps!

Abdó.

Reply all
Reply to author
Forward
0 new messages