Re: [PATCH v2] VIM: Use notmuch CLI for config
Ian Main writes: > This patch switches from reading .notmuch-config directly to using > the CLI the same way that emacs does it. It actually uses less code > and is probably less error prone. > > Ian The general approach seems sane; it seems quite brittle to read the config file directly. I notice there is not really any error handling; OTOH, as far as I can read Ruby, there is not any in the previous version either. Technically, this does add a dependency of the vim client on the CLI that did not exist before. Personally I don't find this onerous (even notmuch-vim users need "notmuch new", except in rather unusual circumstances.). I'd like feedback/testing from actual vim interface users before merging. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] VIM: Better reply handling with multiple emails
This patch fixes reply handling when using multiple emails. This adds a config check for other_email and uses that information when formulating reply headers. It will strip out your own email addresses from the reply and set the From: to be an email of yours found in the original message. Note that this is built on top of the config change patch. Ian --- vim/notmuch.vim | 57 - 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index b251af6..fbd0e21 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -467,6 +467,7 @@ ruby << EOF end $db_name = nil + $all_emails = [] $email = $email_name = $email_address = nil $searches = [] $threads = [] @@ -485,8 +486,14 @@ ruby << EOF $db_name = get_config_item('database.path') $email_name = get_config_item('user.name') $email_address = get_config_item('user.primary_email') + $secondary_email_addresses = get_config_item('user.primary_email') $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] + other_emails = get_config_item('user.other_email') + $all_emails = other_emails.split("\n") + # Add the primary to this too as we use it for checking + # addresses when doing a reply + $all_emails.unshift($email_address) end def vim_puts(s) @@ -562,14 +569,54 @@ ruby << EOF end end + def is_our_address(address) + $all_emails.each do |addy| + if address.to_s.index(addy) != nil + return addy + end + end + return nil + end + def open_reply(orig) reply = orig.reply do |m| - # fix headers - if not m[:reply_to] - m.to = [orig[:from].to_s, orig[:to].to_s] + m.cc = [] + email_addr = $email_address + # Append addresses to the new to: from the original from: + # so long as they are not ours. + if orig[:from] + orig[:from].each do |o| + if not is_our_address(o) + m.to << o + end + end + end + # This copies the cc list to the new email while + # stripping out our own addresses and sets the from: + # address to ours if it finds one. + if orig[:cc] + orig[:cc].each do |o| + if is_our_address(o) + email_addr = is_our_address(o) + else + m.cc << o + end + end + end + # This copies the to list to the new email while + # stripping out our own addresses and sets the from: + # address to ours if it finds one. + if orig[:to] + orig[:to].each do |o| + if is_our_address(o) + email_addr = is_our_address(o) + else + m.to << o + end + end end - m.cc = orig[:cc] - m.from = $email + m.to = m[:reply_to] if m[:reply_to] + m.from = "#{$email_name} <#{email_addr}>" m.charset = 'utf-8' end -- 1.9.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] VIM: Better reply handling with multiple emails
This patch fixes reply handling when using multiple emails. This adds a config check for other_email and uses that information when formulating reply headers. It will strip out your own email addresses from the reply and set the From: to be an email of yours found in the original message. Note that this is built on top of the config change patch. Ian --- vim/notmuch.vim | 57 - 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index b251af6..fbd0e21 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -467,6 +467,7 @@ ruby << EOF end $db_name = nil + $all_emails = [] $email = $email_name = $email_address = nil $searches = [] $threads = [] @@ -485,8 +486,14 @@ ruby << EOF $db_name = get_config_item('database.path') $email_name = get_config_item('user.name') $email_address = get_config_item('user.primary_email') + $secondary_email_addresses = get_config_item('user.primary_email') $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] + other_emails = get_config_item('user.other_email') + $all_emails = other_emails.split("\n") + # Add the primary to this too as we use it for checking + # addresses when doing a reply + $all_emails.unshift($email_address) end def vim_puts(s) @@ -562,14 +569,54 @@ ruby << EOF end end + def is_our_address(address) + $all_emails.each do |addy| + if address.to_s.index(addy) != nil + return addy + end + end + return nil + end + def open_reply(orig) reply = orig.reply do |m| - # fix headers - if not m[:reply_to] - m.to = [orig[:from].to_s, orig[:to].to_s] + m.cc = [] + email_addr = $email_address + # Append addresses to the new to: from the original from: + # so long as they are not ours. + if orig[:from] + orig[:from].each do |o| + if not is_our_address(o) + m.to << o + end + end + end + # This copies the cc list to the new email while + # stripping out our own addresses and sets the from: + # address to ours if it finds one. + if orig[:cc] + orig[:cc].each do |o| + if is_our_address(o) + email_addr = is_our_address(o) + else + m.cc << o + end + end + end + # This copies the to list to the new email while + # stripping out our own addresses and sets the from: + # address to ours if it finds one. + if orig[:to] + orig[:to].each do |o| + if is_our_address(o) + email_addr = is_our_address(o) + else + m.to << o + end + end end - m.cc = orig[:cc] - m.from = $email + m.to = m[:reply_to] if m[:reply_to] + m.from = "#{$email_name} <#{email_addr}>" m.charset = 'utf-8' end -- 1.9.3
[PATCH v2] VIM: Use notmuch CLI for config
This patch switches from reading .notmuch-config directly to using the CLI the same way that emacs does it. It actually uses less code and is probably less error prone. Ian --- This update changes result to be '' instead of nil by default so missing config items won't cause an error. vim/notmuch.vim | 31 --- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..b251af6 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -471,28 +471,21 @@ ruby << EOF $searches = [] $threads = [] $messages = [] - $config = {} $mail_installed = defined?(Mail) - def get_config - group = nil - config = ENV['NOTMUCH_CONFIG'] || '~/.notmuch-config' - File.open(File.expand_path(config)).each do |l| - l.chomp! - case l - when /^\[(.*)\]$/ - group = $1 - when '' - when /^(.*)=(.*)$/ - key = "%s.%s" % [group, $1] - value = $2 - $config[key] = value - end - end + def get_config_item(item) + result = '' + IO.popen(['notmuch', 'config', 'get', item]) { |out| + result = out.read + } + return result.rstrip + end - $db_name = $config['database.path'] - $email_name = $config['user.name'] - $email_address = $config['user.primary_email'] + def get_config + $db_name = get_config_item('database.path') + $email_name = get_config_item('user.name') + $email_address = get_config_item('user.primary_email') + $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] end -- 1.9.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2] VIM: Use notmuch CLI for config
This patch switches from reading .notmuch-config directly to using the CLI the same way that emacs does it. It actually uses less code and is probably less error prone. Ian --- This update changes result to be '' instead of nil by default so missing config items won't cause an error. vim/notmuch.vim | 31 --- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..b251af6 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -471,28 +471,21 @@ ruby << EOF $searches = [] $threads = [] $messages = [] - $config = {} $mail_installed = defined?(Mail) - def get_config - group = nil - config = ENV['NOTMUCH_CONFIG'] || '~/.notmuch-config' - File.open(File.expand_path(config)).each do |l| - l.chomp! - case l - when /^\[(.*)\]$/ - group = $1 - when '' - when /^(.*)=(.*)$/ - key = "%s.%s" % [group, $1] - value = $2 - $config[key] = value - end - end + def get_config_item(item) + result = '' + IO.popen(['notmuch', 'config', 'get', item]) { |out| + result = out.read + } + return result.rstrip + end - $db_name = $config['database.path'] - $email_name = $config['user.name'] - $email_address = $config['user.primary_email'] + def get_config + $db_name = get_config_item('database.path') + $email_name = get_config_item('user.name') + $email_address = get_config_item('user.primary_email') + $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] end -- 1.9.3
[PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, 02 Oct 2014, "W. Trevor King" wrote: > On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: >> This patch simplifies notmuch_database_close to explicitly abort any >> outstanding transaction and then just call Database::close. This >> works for both read-only and read/write databases, takes care of >> committing changes, unifies the exception handling path, and codifies >> aborting outstanding transactions. > > I don't expect atomic blocks are particularly useful for read-only > connections. If they aren't, I'd quibble with the ?This works for > both read-only?? wording above. If they are, I'd drop the read/write It's true that atomic sections aren't very useful on a read-only database, but we do allow them for symmetry. We also keep track of how deeply nested we are so notmuch_database_end_atomic can return a proper error message regardless of whether the database is read/write or read-only. But all I'm saying in the commit message is that Xapian::Database::close works for both read-only and read/write databases and will flush if necessary, so we don't have to worry about that. > check below: > >> +/* If there's an outstanding transaction, it's unclear if >> + * closing the Xapian database commits everything up to >> + * that transaction, or may discard committed (but >> + * unflushed) transactions. To be certain, explicitly >> + * cancel any outstanding transaction before closing. */ >> +if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && >> +notmuch->atomic_nesting) >> +(static_cast (notmuch->xapian_db)) >> +->cancel_transaction (); The notmuch->mode check here is necessary because atomic_nesting can be non-zero on a read-only database (for the reason I mentioned above), but we had better not cast xapian_db to a WritableDatabase if it isn't a WritableDatabase. > Thats a very minor quibble though, and I'd be glad to see this patch > land as is. > > Cheers, > Trevor > > -- > This email may be signed or encrypted with GnuPG (http://www.gnupg.org). > For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
[PATCH v4] lib: Simplify close and codify aborting atomic section
From: Austin Clements In Xapian, closing a database implicitly aborts any outstanding transaction and commits changes. For historical reasons, notmuch_database_close had grown to almost, but not quite duplicate this behavior. Before closing the database, it would explicitly (and unnecessarily) commit it. However, if there was an outstanding transaction (ie atomic section), commit would throw a Xapian exception, which notmuch_database_close would unnecessarily print to stderr, even though notmuch_database_close would ultimately abort the transaction anyway when it called close. This patch simplifies notmuch_database_close to explicitly abort any outstanding transaction and then just call Database::close. This works for both read-only and read/write databases, takes care of committing changes, unifies the exception handling path, and codifies aborting outstanding transactions. This is currently the only way to abort an atomic section (and may remain so, since it would be difficult to roll back things we may have cached from rolled-back modifications). --- lib/database.cc | 32 +--- lib/notmuch.h | 9 - 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index a3a7cd3..a47a71d 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -903,28 +903,30 @@ notmuch_database_close (notmuch_database_t *notmuch) { notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; -try { - if (notmuch->xapian_db != NULL && - notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) - (static_cast (notmuch->xapian_db))->flush (); -} catch (const Xapian::Error &error) { - status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; - if (! notmuch->exception_reported) { - fprintf (stderr, "Error: A Xapian exception occurred flushing database: %s\n", -error.get_msg().c_str()); - } -} - /* Many Xapian objects (and thus notmuch objects) hold references to * the database, so merely deleting the database may not suffice to * close it. Thus, we explicitly close it here. */ if (notmuch->xapian_db != NULL) { try { + /* If there's an outstanding transaction, it's unclear if +* closing the Xapian database commits everything up to +* that transaction, or may discard committed (but +* unflushed) transactions. To be certain, explicitly +* cancel any outstanding transaction before closing. */ + if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && + notmuch->atomic_nesting) + (static_cast (notmuch->xapian_db)) + ->cancel_transaction (); + + /* Close the database. This implicitly flushes +* outstanding changes. */ notmuch->xapian_db->close(); } catch (const Xapian::Error &error) { - /* don't clobber previous error status */ - if (status == NOTMUCH_STATUS_SUCCESS) - status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + if (! notmuch->exception_reported) { + fprintf (stderr, "Error: A Xapian exception occurred closing database: %s\n", +error.get_msg().c_str()); + } } } diff --git a/lib/notmuch.h b/lib/notmuch.h index fe2340b..dae0416 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -281,7 +281,7 @@ notmuch_database_open (const char *path, notmuch_database_t **database); /** - * Close the given notmuch database. + * Commit changes and close the given notmuch database. * * After notmuch_database_close has been called, calls to other * functions on objects derived from this database may either behave @@ -292,6 +292,13 @@ notmuch_database_open (const char *path, * notmuch_database_close can be called multiple times. Later calls * have no effect. * + * For writable databases, notmuch_database_close commits all changes + * to disk before closing the database. If the caller is currently in + * an atomic section (there was a notmuch_database_begin_atomic + * without a matching notmuch_database_end_atomic), this will discard + * changes made in that atomic section (but still commit changes made + * prior to entering the atomic section). + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Successfully closed the database. -- 2.1.0
[PATCH v3] lib: Simplify close and codify aborting atomic section
On Wed, 24 Sep 2014, "W. Trevor King" wrote: > On Wed, Sep 24, 2014 at 05:32:50PM -0400, Austin Clements wrote: >> + * If the caller is currently in an atomic section (there was a >> + * notmuch_database_begin_atomic without a matching >> + * notmuch_database_end_atomic), this will abort the atomic section, >> + * discarding any modifications made in the atomic section. All >> + * changes up to this will be committed. > > I still think Xapian's wording is more readable [1]: > > For a WritableDatabase, if a transaction is active it will be > aborted, while if no transaction is active commit() will be > implicitly called. > > How about: > > For a writable database, if a transaction is active (there was a > notmuch_database_begin_atomic without a matching > notmuch_database_end_atomic) it will be aborted, while if no > transaction is active any pending changes will be committed. What is a "pending change" from the perspective of the notmuch API? This is tricky because basically nothing in the library talks about durability (partly because the notmuch API provides almost no control over it). Likewise, the API doesn't expose the notion of a transaction (since that generally implies ACID), but only atomic sections. I actually find the Xapian wording rather confusing. Neither Xapian's documentation nor your suggested comment say what happens when there is *both* an outstanding transaction and pending changes. In fact, teasing this out made me realize that Xapian might in fact discard committed (but unflushed) changes if you close the database with an outstanding transaction. But we definitely do want to flush these transactions (especially since *all* of our atomic sections are "unflushed transactions"). In v4 I've added some code to make sure this happens, but because of the vagueness of the documentation I have no idea if it's necessary. > Cheers, > Trevor > > [1]: > http://xapian.org/docs/apidoc/html/classXapian_1_1Database.html#a59f5f8b137723dcaaabdbdccbc0cf1eb > > -- > This email may be signed or encrypted with GnuPG (http://www.gnupg.org). > For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
[PATCH] VIM: Use notmuch CLI for config
This patch switches from reading .notmuch-config directly to using the CLI the same way that emacs does it. It actually uses less code and is probably less error prone. Ian --- vim/notmuch.vim | 31 --- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..faee3d2 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -471,28 +471,21 @@ ruby << EOF $searches = [] $threads = [] $messages = [] - $config = {} $mail_installed = defined?(Mail) - def get_config - group = nil - config = ENV['NOTMUCH_CONFIG'] || '~/.notmuch-config' - File.open(File.expand_path(config)).each do |l| - l.chomp! - case l - when /^\[(.*)\]$/ - group = $1 - when '' - when /^(.*)=(.*)$/ - key = "%s.%s" % [group, $1] - value = $2 - $config[key] = value - end - end + def get_config_item(item) + result = nil + IO.popen(['notmuch', 'config', 'get', item]) { |out| + result = out.read + } + return result.rstrip + end - $db_name = $config['database.path'] - $email_name = $config['user.name'] - $email_address = $config['user.primary_email'] + def get_config + $db_name = get_config_item('database.path') + $email_name = get_config_item('user.name') + $email_address = get_config_item('user.primary_email') + $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] end -- 1.9.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] VIM: Use notmuch CLI for config
This patch switches from reading .notmuch-config directly to using the CLI the same way that emacs does it. It actually uses less code and is probably less error prone. Ian --- vim/notmuch.vim | 31 --- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..faee3d2 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -471,28 +471,21 @@ ruby << EOF $searches = [] $threads = [] $messages = [] - $config = {} $mail_installed = defined?(Mail) - def get_config - group = nil - config = ENV['NOTMUCH_CONFIG'] || '~/.notmuch-config' - File.open(File.expand_path(config)).each do |l| - l.chomp! - case l - when /^\[(.*)\]$/ - group = $1 - when '' - when /^(.*)=(.*)$/ - key = "%s.%s" % [group, $1] - value = $2 - $config[key] = value - end - end + def get_config_item(item) + result = nil + IO.popen(['notmuch', 'config', 'get', item]) { |out| + result = out.read + } + return result.rstrip + end - $db_name = $config['database.path'] - $email_name = $config['user.name'] - $email_address = $config['user.primary_email'] + def get_config + $db_name = get_config_item('database.path') + $email_name = get_config_item('user.name') + $email_address = get_config_item('user.primary_email') + $email_name = get_config_item('user.name') $email = "%s <%s>" % [$email_name, $email_address] end -- 1.9.3
Re: [PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, Oct 02, 2014 at 04:39:41PM -0400, Austin Clements wrote: > On Thu, 02 Oct 2014, W. Trevor King wrote: > > On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: > >> This patch simplifies notmuch_database_close to explicitly abort > >> any outstanding transaction and then just call Database::close. > >> This works for both read-only and read/write databases, takes > >> care of committing changes, unifies the exception handling path, > >> and codifies aborting outstanding transactions. > > > > I don't expect atomic blocks are particularly useful for read-only > > connections. If they aren't, I'd quibble with the “This works for > > both read-only…” wording above. If they are, I'd drop the > > read/write > > It's true that atomic sections aren't very useful on a read-only > database, but we do allow them for symmetry. Heh, and they're no-ops since the beginning in 957f1ba3 (lib: Add notmuch_database_{begin,end}_atomic, 2011-01-29). So both the commit message and read/write check make sense. Quibble retracted. Cheers, Trevor -- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy signature.asc Description: OpenPGP digital signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, Oct 02, 2014 at 04:39:41PM -0400, Austin Clements wrote: > On Thu, 02 Oct 2014, W. Trevor King wrote: > > On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: > >> This patch simplifies notmuch_database_close to explicitly abort > >> any outstanding transaction and then just call Database::close. > >> This works for both read-only and read/write databases, takes > >> care of committing changes, unifies the exception handling path, > >> and codifies aborting outstanding transactions. > > > > I don't expect atomic blocks are particularly useful for read-only > > connections. If they aren't, I'd quibble with the ?This works for > > both read-only?? wording above. If they are, I'd drop the > > read/write > > It's true that atomic sections aren't very useful on a read-only > database, but we do allow them for symmetry. Heh, and they're no-ops since the beginning in 957f1ba3 (lib: Add notmuch_database_{begin,end}_atomic, 2011-01-29). So both the commit message and read/write check make sense. Quibble retracted. Cheers, Trevor -- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20141002/e2fe9c19/attachment.pgp>
Re: [PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, 02 Oct 2014, "W. Trevor King" wrote: > On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: >> This patch simplifies notmuch_database_close to explicitly abort any >> outstanding transaction and then just call Database::close. This >> works for both read-only and read/write databases, takes care of >> committing changes, unifies the exception handling path, and codifies >> aborting outstanding transactions. > > I don't expect atomic blocks are particularly useful for read-only > connections. If they aren't, I'd quibble with the “This works for > both read-only…” wording above. If they are, I'd drop the read/write It's true that atomic sections aren't very useful on a read-only database, but we do allow them for symmetry. We also keep track of how deeply nested we are so notmuch_database_end_atomic can return a proper error message regardless of whether the database is read/write or read-only. But all I'm saying in the commit message is that Xapian::Database::close works for both read-only and read/write databases and will flush if necessary, so we don't have to worry about that. > check below: > >> +/* If there's an outstanding transaction, it's unclear if >> + * closing the Xapian database commits everything up to >> + * that transaction, or may discard committed (but >> + * unflushed) transactions. To be certain, explicitly >> + * cancel any outstanding transaction before closing. */ >> +if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && >> +notmuch->atomic_nesting) >> +(static_cast (notmuch->xapian_db)) >> +->cancel_transaction (); The notmuch->mode check here is necessary because atomic_nesting can be non-zero on a read-only database (for the reason I mentioned above), but we had better not cast xapian_db to a WritableDatabase if it isn't a WritableDatabase. > Thats a very minor quibble though, and I'd be glad to see this patch > land as is. > > Cheers, > Trevor > > -- > This email may be signed or encrypted with GnuPG (http://www.gnupg.org). > For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] VIM: Add URI handling
This patch adds URI handling to the vim client. You can now press 'u' by default and the client will parse the current line and find any URIs available. If there are more than one it opens the one under the cursor or else it opens the only one available. It also supports mailto: URI's and will compose a new message when activated. By default xdg-open is used for everything but mailto: which generally does the right thing afaict. Ian --- vim/notmuch.txt | 1 + vim/notmuch.vim | 59 ++--- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/vim/notmuch.txt b/vim/notmuch.txt index 4374102..d336406 100644 --- a/vim/notmuch.txt +++ b/vim/notmuch.txt @@ -72,6 +72,7 @@ q Quit view A Archive (-inbox -unread) I Mark as read (-unread) t Tag (prompted) +u Open URI s Search p Save patches r Reply diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..de82bb9 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -12,7 +12,7 @@ let g:notmuch_folders_maps = { \ '':'folders_show_search()', \ 's': 'folders_search_prompt()', \ '=': 'folders_refresh()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_search_maps = { @@ -25,7 +25,7 @@ let g:notmuch_search_maps = { \ 's': 'search_search_prompt()', \ '=': 'search_refresh()', \ '?': 'search_info()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_show_maps = { @@ -37,10 +37,11 @@ let g:notmuch_show_maps = { \ 'e': 'show_extract_msg()', \ 's': 'show_save_msg()', \ 'p': 'show_save_patches()', + \ 'u': 'show_open_uri()', \ 'r': 'show_reply()', \ '?': 'show_info()', \ '': 'show_next_msg()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_compose_maps = { @@ -59,6 +60,7 @@ let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S' let s:notmuch_reader_default = 'mutt -f %s' let s:notmuch_sendmail_default = 'sendmail' let s:notmuch_folders_count_threads_default = 0 +let s:notmuch_open_uri_default = 'xdg-open' function! s:new_file_buffer(type, fname) exec printf('edit %s', a:fname) @@ -135,8 +137,8 @@ function! s:show_reply() startinsert! endfunction -function! s:compose() - ruby open_compose +function! s:compose(to_email) + ruby open_compose(VIM::evaluate('a:to_email')) let b:compose_done = 0 call s:set_map(g:notmuch_compose_maps) autocmd BufDelete call s:on_compose_delete() @@ -159,6 +161,45 @@ ruby << EOF EOF endfunction +function! s:show_open_uri() + let line = getline(".") + let pos = getpos(".") + let col = pos[2] +ruby << EOF + m = get_message + line = VIM::evaluate('line') + col = VIM::evaluate('col') - 1 + uris = URI.extract(line) + wanted_uri = nil + if uris.length == 1 + wanted_uri = uris[0] + else + uris.each do |uri| + # Check to see the URI is at the present cursor location + idx = line.index(uri) + if col >= idx and col <= idx + uri.length + wanted_uri = uri + break + end + end + end + + if wanted_uri + uri = URI.parse(wanted_uri) + if uri.class == URI::MailTo + vim_puts("Composing new email to #{uri.to}.") + VIM::command("call s:compose('#{uri.to}')") + else + vim_puts("Opening #{uri.to_s}.") + cmd = VIM::evaluate('g:notmuch_open_uri') + system(cmd, uri.to_s) + end + else + vim_puts('URI not found.') + end +EOF +endfunction + function! s:show_open_msg() ruby << EOF m = get_message @@ -404,6 +445,10 @@ function! s:set_defaults() endif endif + if !exists('g:notmuch_open_uri') + let g:notmuch_open_uri = s:notmuch_open_uri_default + endif + if !exists('g:notmuch_reader') if exists('g:notmuch_rb_reader') let g:notmuch_reader = g:notmuch_rb_reader @@ -611,11 +656,11 @@ ruby << EOF open_compose_helper(lines, cur) end - def open_compose() + def open_compose(to_email) lines = [] lines << "From: #{$email}" - lines << "To: " + lines << "To: #{to_email}" cur = lines.count lines << "Cc: " -- 1.9.3
notmuch-vim doesn't respect notmuch config defaults
Sergei Shilovsky writes: > I would suggest to use `notmuch config list` to get configuration > values in vim if possible I guess this is a general question we haven't really resolved, namely sharing configuration information between various notmuch frontends. .notmuch-config is really the configuration file for the notmuch CLI; it isn't read by library, so clients using language bindings won't see it at all by default. On a somewhat related note I've been thinking how to best associate configuration information with a database (see e.g. the thread at id:1411805835-3563-1-git-send-email-david at tethera.net ). Note that this would not help this particular case. Offhand, I wouldn't be personally to some interface at the library level wrapping the reading and writing of ~/.notmuch-config, although as I mentioned before, the size and complexity of notmuch-config.c perturb me a little as far as being suitable for library code. d
[PATCH] VIM: Add URI handling
This patch adds URI handling to the vim client. You can now press 'u' by default and the client will parse the current line and find any URIs available. If there are more than one it opens the one under the cursor or else it opens the only one available. It also supports mailto: URI's and will compose a new message when activated. By default xdg-open is used for everything but mailto: which generally does the right thing afaict. Ian --- vim/notmuch.txt | 1 + vim/notmuch.vim | 59 ++--- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/vim/notmuch.txt b/vim/notmuch.txt index 4374102..d336406 100644 --- a/vim/notmuch.txt +++ b/vim/notmuch.txt @@ -72,6 +72,7 @@ q Quit view A Archive (-inbox -unread) I Mark as read (-unread) t Tag (prompted) +u Open URI s Search p Save patches r Reply diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..de82bb9 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -12,7 +12,7 @@ let g:notmuch_folders_maps = { \ '':'folders_show_search()', \ 's': 'folders_search_prompt()', \ '=': 'folders_refresh()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_search_maps = { @@ -25,7 +25,7 @@ let g:notmuch_search_maps = { \ 's': 'search_search_prompt()', \ '=': 'search_refresh()', \ '?': 'search_info()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_show_maps = { @@ -37,10 +37,11 @@ let g:notmuch_show_maps = { \ 'e': 'show_extract_msg()', \ 's': 'show_save_msg()', \ 'p': 'show_save_patches()', + \ 'u': 'show_open_uri()', \ 'r': 'show_reply()', \ '?': 'show_info()', \ '': 'show_next_msg()', - \ 'c': 'compose()', + \ 'c': 'compose("")', \ } let g:notmuch_compose_maps = { @@ -59,6 +60,7 @@ let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S' let s:notmuch_reader_default = 'mutt -f %s' let s:notmuch_sendmail_default = 'sendmail' let s:notmuch_folders_count_threads_default = 0 +let s:notmuch_open_uri_default = 'xdg-open' function! s:new_file_buffer(type, fname) exec printf('edit %s', a:fname) @@ -135,8 +137,8 @@ function! s:show_reply() startinsert! endfunction -function! s:compose() - ruby open_compose +function! s:compose(to_email) + ruby open_compose(VIM::evaluate('a:to_email')) let b:compose_done = 0 call s:set_map(g:notmuch_compose_maps) autocmd BufDelete call s:on_compose_delete() @@ -159,6 +161,45 @@ ruby << EOF EOF endfunction +function! s:show_open_uri() + let line = getline(".") + let pos = getpos(".") + let col = pos[2] +ruby << EOF + m = get_message + line = VIM::evaluate('line') + col = VIM::evaluate('col') - 1 + uris = URI.extract(line) + wanted_uri = nil + if uris.length == 1 + wanted_uri = uris[0] + else + uris.each do |uri| + # Check to see the URI is at the present cursor location + idx = line.index(uri) + if col >= idx and col <= idx + uri.length + wanted_uri = uri + break + end + end + end + + if wanted_uri + uri = URI.parse(wanted_uri) + if uri.class == URI::MailTo + vim_puts("Composing new email to #{uri.to}.") + VIM::command("call s:compose('#{uri.to}')") + else + vim_puts("Opening #{uri.to_s}.") + cmd = VIM::evaluate('g:notmuch_open_uri') + system(cmd, uri.to_s) + end + else + vim_puts('URI not found.') + end +EOF +endfunction + function! s:show_open_msg() ruby << EOF m = get_message @@ -404,6 +445,10 @@ function! s:set_defaults() endif endif + if !exists('g:notmuch_open_uri') + let g:notmuch_open_uri = s:notmuch_open_uri_default + endif + if !exists('g:notmuch_reader') if exists('g:notmuch_rb_reader') let g:notmuch_reader = g:notmuch_rb_reader @@ -611,11 +656,11 @@ ruby << EOF open_compose_helper(lines, cur) end - def open_compose() + def open_compose(to_email) lines = [] lines << "From: #{$email}" - lines << "To: " + lines << "To: #{to_email}" cur = lines.count lines << "Cc: " -- 1.9.3
notmuch-vim doesn't respect notmuch config defaults
I would suggest to use `notmuch config list` to get configuration values in vim if possible Reproduction example follows: /home/sh> cat .notmuch-config [new] tags=new;inbox;unread ignore= [search] exclude_tags=deleted;spam [maildir] synchronize_flags=false /home/sh> notmuch config list new.tags=new;inbox;unread new.ignore= search.exclude_tags=deleted;spam maildir.synchronize_flags=false database.path=/home/sh/mail user.name=Sergei Shilovsky user.primary_email=sshilovsky at gmail.com /home/sh> vim -c :NotMuch Error detected while processing function 13_NotMuch..13_folders.. 13_new_buffer: line6: TypeError: no implicit conversion of nil into String Error detected while processing function 13_NotMuch..13_folders: line2: NoMethodError: undefined method `query' for nil:NilClass Having explicit database.path=/home/sh/mail in the configuration file makes it work -- ? ?, ?? ? Sergei Shilovsky
Re: [PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: > This patch simplifies notmuch_database_close to explicitly abort any > outstanding transaction and then just call Database::close. This > works for both read-only and read/write databases, takes care of > committing changes, unifies the exception handling path, and codifies > aborting outstanding transactions. I don't expect atomic blocks are particularly useful for read-only connections. If they aren't, I'd quibble with the “This works for both read-only…” wording above. If they are, I'd drop the read/write check below: > + /* If there's an outstanding transaction, it's unclear if > + * closing the Xapian database commits everything up to > + * that transaction, or may discard committed (but > + * unflushed) transactions. To be certain, explicitly > + * cancel any outstanding transaction before closing. */ > + if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && > + notmuch->atomic_nesting) > + (static_cast (notmuch->xapian_db)) > + ->cancel_transaction (); Thats a very minor quibble though, and I'd be glad to see this patch land as is. Cheers, Trevor -- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy signature.asc Description: OpenPGP digital signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v4] lib: Simplify close and codify aborting atomic section
On Thu, Oct 02, 2014 at 03:19:08PM -0400, Austin Clements wrote: > This patch simplifies notmuch_database_close to explicitly abort any > outstanding transaction and then just call Database::close. This > works for both read-only and read/write databases, takes care of > committing changes, unifies the exception handling path, and codifies > aborting outstanding transactions. I don't expect atomic blocks are particularly useful for read-only connections. If they aren't, I'd quibble with the ?This works for both read-only?? wording above. If they are, I'd drop the read/write check below: > + /* If there's an outstanding transaction, it's unclear if > + * closing the Xapian database commits everything up to > + * that transaction, or may discard committed (but > + * unflushed) transactions. To be certain, explicitly > + * cancel any outstanding transaction before closing. */ > + if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && > + notmuch->atomic_nesting) > + (static_cast (notmuch->xapian_db)) > + ->cancel_transaction (); Thats a very minor quibble though, and I'd be glad to see this patch land as is. Cheers, Trevor -- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20141002/6a1b6789/attachment.pgp>
Re: notmuch-vim doesn't respect notmuch config defaults
David Bremner wrote: > Sergei Shilovsky writes: > > > I would suggest to use `notmuch config list` to get configuration > > values in vim if possible > > I guess this is a general question we haven't really resolved, namely > sharing configuration information between various notmuch frontends. > .notmuch-config is really the configuration file for the notmuch CLI; it > isn't read by library, so clients using language bindings won't see it > at all by default. > > On a somewhat related note I've been thinking how to best associate > configuration information with a database (see e.g. the thread at > id:1411805835-3563-1-git-send-email-da...@tethera.net ). Note that this > would not help this particular case. > > Offhand, I wouldn't be personally to some interface at the library level > wrapping the reading and writing of ~/.notmuch-config, although as I > mentioned before, the size and complexity of notmuch-config.c perturb me > a little as far as being suitable for library code. I could change the vim client to use notmuch config list easily enough. Any consensus here? How does the emacs client do it? I can make up a patch if this seems like the right way to go. Also, someone on IRC mentioned making it so config list could dump JSON which would make that more reasonable. Ian ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
notmuch-vim doesn't respect notmuch config defaults
David Bremner wrote: > Sergei Shilovsky writes: > > > I would suggest to use `notmuch config list` to get configuration > > values in vim if possible > > I guess this is a general question we haven't really resolved, namely > sharing configuration information between various notmuch frontends. > .notmuch-config is really the configuration file for the notmuch CLI; it > isn't read by library, so clients using language bindings won't see it > at all by default. > > On a somewhat related note I've been thinking how to best associate > configuration information with a database (see e.g. the thread at > id:1411805835-3563-1-git-send-email-david at tethera.net ). Note that this > would not help this particular case. > > Offhand, I wouldn't be personally to some interface at the library level > wrapping the reading and writing of ~/.notmuch-config, although as I > mentioned before, the size and complexity of notmuch-config.c perturb me > a little as far as being suitable for library code. I could change the vim client to use notmuch config list easily enough. Any consensus here? How does the emacs client do it? I can make up a patch if this seems like the right way to go. Also, someone on IRC mentioned making it so config list could dump JSON which would make that more reasonable. Ian
notmuch-vim doesn't respect notmuch config defaults
Sergei Shilovsky wrote: > I would suggest to use `notmuch config list` to get configuration > values in vim if possible > > Reproduction example follows: > > /home/sh> cat .notmuch-config > [new] > tags=new;inbox;unread > ignore= > > [search] > exclude_tags=deleted;spam > > [maildir] > synchronize_flags=false > > /home/sh> notmuch config list > new.tags=new;inbox;unread > new.ignore= > search.exclude_tags=deleted;spam > maildir.synchronize_flags=false > database.path=/home/sh/mail > user.name=Sergei Shilovsky > user.primary_email=sshilovsky at gmail.com > > /home/sh> vim -c :NotMuch > Error detected while processing function > 13_NotMuch..13_folders.. > 13_new_buffer: > line6: > TypeError: no implicit conversion of nil into String > Error detected while processing function 13_NotMuch..13_folders: > line2: > NoMethodError: undefined method `query' for nil:NilClass > > Having explicit database.path=/home/sh/mail in the configuration file > makes it work Right, so you didn't have database.path in your config file before right? Doesn't the default notmuch setup set that for you? It wouldn't be too hard to change vim to use 'notmuch config list' to get its configuration information, but as mentioned a library would be much nicer. Anyone have any thoughts on this? How does the emacs client do it? If the config list method is superior I'll write up a patch for it. Ian
Re: [PATCH v3] lib: Simplify close and codify aborting atomic section
On Wed, 24 Sep 2014, "W. Trevor King" wrote: > On Wed, Sep 24, 2014 at 05:32:50PM -0400, Austin Clements wrote: >> + * If the caller is currently in an atomic section (there was a >> + * notmuch_database_begin_atomic without a matching >> + * notmuch_database_end_atomic), this will abort the atomic section, >> + * discarding any modifications made in the atomic section. All >> + * changes up to this will be committed. > > I still think Xapian's wording is more readable [1]: > > For a WritableDatabase, if a transaction is active it will be > aborted, while if no transaction is active commit() will be > implicitly called. > > How about: > > For a writable database, if a transaction is active (there was a > notmuch_database_begin_atomic without a matching > notmuch_database_end_atomic) it will be aborted, while if no > transaction is active any pending changes will be committed. What is a "pending change" from the perspective of the notmuch API? This is tricky because basically nothing in the library talks about durability (partly because the notmuch API provides almost no control over it). Likewise, the API doesn't expose the notion of a transaction (since that generally implies ACID), but only atomic sections. I actually find the Xapian wording rather confusing. Neither Xapian's documentation nor your suggested comment say what happens when there is *both* an outstanding transaction and pending changes. In fact, teasing this out made me realize that Xapian might in fact discard committed (but unflushed) changes if you close the database with an outstanding transaction. But we definitely do want to flush these transactions (especially since *all* of our atomic sections are "unflushed transactions"). In v4 I've added some code to make sure this happens, but because of the vagueness of the documentation I have no idea if it's necessary. > Cheers, > Trevor > > [1]: > http://xapian.org/docs/apidoc/html/classXapian_1_1Database.html#a59f5f8b137723dcaaabdbdccbc0cf1eb > > -- > This email may be signed or encrypted with GnuPG (http://www.gnupg.org). > For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v4] lib: Simplify close and codify aborting atomic section
From: Austin Clements In Xapian, closing a database implicitly aborts any outstanding transaction and commits changes. For historical reasons, notmuch_database_close had grown to almost, but not quite duplicate this behavior. Before closing the database, it would explicitly (and unnecessarily) commit it. However, if there was an outstanding transaction (ie atomic section), commit would throw a Xapian exception, which notmuch_database_close would unnecessarily print to stderr, even though notmuch_database_close would ultimately abort the transaction anyway when it called close. This patch simplifies notmuch_database_close to explicitly abort any outstanding transaction and then just call Database::close. This works for both read-only and read/write databases, takes care of committing changes, unifies the exception handling path, and codifies aborting outstanding transactions. This is currently the only way to abort an atomic section (and may remain so, since it would be difficult to roll back things we may have cached from rolled-back modifications). --- lib/database.cc | 32 +--- lib/notmuch.h | 9 - 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index a3a7cd3..a47a71d 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -903,28 +903,30 @@ notmuch_database_close (notmuch_database_t *notmuch) { notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; -try { - if (notmuch->xapian_db != NULL && - notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) - (static_cast (notmuch->xapian_db))->flush (); -} catch (const Xapian::Error &error) { - status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; - if (! notmuch->exception_reported) { - fprintf (stderr, "Error: A Xapian exception occurred flushing database: %s\n", -error.get_msg().c_str()); - } -} - /* Many Xapian objects (and thus notmuch objects) hold references to * the database, so merely deleting the database may not suffice to * close it. Thus, we explicitly close it here. */ if (notmuch->xapian_db != NULL) { try { + /* If there's an outstanding transaction, it's unclear if +* closing the Xapian database commits everything up to +* that transaction, or may discard committed (but +* unflushed) transactions. To be certain, explicitly +* cancel any outstanding transaction before closing. */ + if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE && + notmuch->atomic_nesting) + (static_cast (notmuch->xapian_db)) + ->cancel_transaction (); + + /* Close the database. This implicitly flushes +* outstanding changes. */ notmuch->xapian_db->close(); } catch (const Xapian::Error &error) { - /* don't clobber previous error status */ - if (status == NOTMUCH_STATUS_SUCCESS) - status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + if (! notmuch->exception_reported) { + fprintf (stderr, "Error: A Xapian exception occurred closing database: %s\n", +error.get_msg().c_str()); + } } } diff --git a/lib/notmuch.h b/lib/notmuch.h index fe2340b..dae0416 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -281,7 +281,7 @@ notmuch_database_open (const char *path, notmuch_database_t **database); /** - * Close the given notmuch database. + * Commit changes and close the given notmuch database. * * After notmuch_database_close has been called, calls to other * functions on objects derived from this database may either behave @@ -292,6 +292,13 @@ notmuch_database_open (const char *path, * notmuch_database_close can be called multiple times. Later calls * have no effect. * + * For writable databases, notmuch_database_close commits all changes + * to disk before closing the database. If the caller is currently in + * an atomic section (there was a notmuch_database_begin_atomic + * without a matching notmuch_database_end_atomic), this will discard + * changes made in that atomic section (but still commit changes made + * prior to entering the atomic section). + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Successfully closed the database. -- 2.1.0 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: notmuch-vim doesn't respect notmuch config defaults
Sergei Shilovsky writes: > I would suggest to use `notmuch config list` to get configuration > values in vim if possible I guess this is a general question we haven't really resolved, namely sharing configuration information between various notmuch frontends. .notmuch-config is really the configuration file for the notmuch CLI; it isn't read by library, so clients using language bindings won't see it at all by default. On a somewhat related note I've been thinking how to best associate configuration information with a database (see e.g. the thread at id:1411805835-3563-1-git-send-email-da...@tethera.net ). Note that this would not help this particular case. Offhand, I wouldn't be personally to some interface at the library level wrapping the reading and writing of ~/.notmuch-config, although as I mentioned before, the size and complexity of notmuch-config.c perturb me a little as far as being suitable for library code. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
notmuch-vim doesn't respect notmuch config defaults
I would suggest to use `notmuch config list` to get configuration values in vim if possible Reproduction example follows: /home/sh> cat .notmuch-config [new] tags=new;inbox;unread ignore= [search] exclude_tags=deleted;spam [maildir] synchronize_flags=false /home/sh> notmuch config list new.tags=new;inbox;unread new.ignore= search.exclude_tags=deleted;spam maildir.synchronize_flags=false database.path=/home/sh/mail user.name=Sergei Shilovsky user.primary_email=sshilov...@gmail.com /home/sh> vim -c :NotMuch Error detected while processing function 13_NotMuch..13_folders.. 13_new_buffer: line6: TypeError: no implicit conversion of nil into String Error detected while processing function 13_NotMuch..13_folders: line2: NoMethodError: undefined method `query' for nil:NilClass Having explicit database.path=/home/sh/mail in the configuration file makes it work -- С уважением, Сергей Шиловский Sergei Shilovsky ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] VIM: Add better attachment support
This patch changes how the notmuch vim client supports attachments: - For each attachment an 'Attachment : ' is added to the header - You can then use 'e' to extract the attachment under the cursor or use it elsewhere to extract all attachments (the prior behavior) - You can use 'v' to 'view' the attachment using xdg-open by default. Ian --- vim/notmuch.txt | 8 +++- vim/notmuch.vim | 60 +++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/vim/notmuch.txt b/vim/notmuch.txt index 4374102..838a904 100644 --- a/vim/notmuch.txt +++ b/vim/notmuch.txt @@ -72,6 +72,9 @@ q Quit view A Archive (-inbox -unread) I Mark as read (-unread) t Tag (prompted) +e Extract attachment on the current 'Attachment' line or all + attachments if the cursor is elsewhere. +v View attachment on the current 'Attachment' line. s Search p Save patches r Reply @@ -148,6 +151,9 @@ You can also configure your externail mail reader and sendemail program: > let g:notmuch_reader = 'mutt -f %s' let g:notmuch_sendmail = 'sendmail' -< + +You can also configure what probram is used to view attachments: + + let g:notmuch_view_attachment = 'xdg-open' vim:tw=78:ts=8:noet:ft=help: diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..a5830b5 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -35,6 +35,7 @@ let g:notmuch_show_maps = { \ 't': 'show_tag("")', \ 'o': 'show_open_msg()', \ 'e': 'show_extract_msg()', + \ 'v': 'show_view_attachment()', \ 's': 'show_save_msg()', \ 'p': 'show_save_patches()', \ 'r': 'show_reply()', @@ -58,6 +59,8 @@ let s:notmuch_date_format_default = '%d.%m.%y' let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S' let s:notmuch_reader_default = 'mutt -f %s' let s:notmuch_sendmail_default = 'sendmail' +let s:notmuch_view_attachment_default = 'xdg-open' +let s:notmuch_attachment_tmpdir_default = '~/.notmuch/tmp' let s:notmuch_folders_count_threads_default = 0 function! s:new_file_buffer(type, fname) @@ -147,13 +150,53 @@ function! s:show_info() ruby vim_puts get_message.inspect endfunction +function! s:show_view_attachment() + let line = getline(".") +ruby << EOF + m = get_message + line = VIM::evaluate('line') + + match = line.match(/^Attachment (\d*):/) + if match and match.length == 2 + a = m.mail.attachments[match[1].to_i - 1] + tmpdir = VIM::evaluate('g:notmuch_attachment_tmpdir') + tmpdir = File.expand_path(tmpdir) + Dir.mkdir(tmpdir) unless Dir.exists?(tmpdir) + filename = File.expand_path("#{tmpdir}/#{a.filename}") + vim_puts "Viewing attachment #{filename}" + File.open(filename, 'w') do |f| + f.write a.body.decoded + cmd = VIM::evaluate('g:notmuch_view_attachment') + system(cmd, filename) + end + else + vim_puts "No attachment on this line." + end +EOF +endfunction + function! s:show_extract_msg() + let line = getline(".") ruby << EOF m = get_message - m.mail.attachments.each do |a| + line = VIM::evaluate('line') + + # If the user is on a line that has an 'Attachment' + # line, we just extract the one attachment. + match = line.match(/^Attachment (\d*):/) + if match and match.length == 2 + a = m.mail.attachments[match[1].to_i - 1] File.open(a.filename, 'w') do |f| f.write a.body.decoded - print "Extracted '#{a.filename}'" + vim_puts "Extracted #{a.filename}" + end + else + # Extract them all.. + m.mail.attachments.each do |a| + File.open(a.filename, 'w') do |f| + f.write a.body.decoded + vim_puts "Extracted #{a.filename}" + end end end EOF @@ -326,6 +369,11 @@ ruby << EOF b << "To: %s" % msg['to'] b << "Cc: %s" % msg['cc'] b << "Date: %s" % msg['date'] + cnt = 0 + nm_m.mail.attachments.each do |a| + cnt += 1 + b << "Attachment %d: %s" % [cnt, a.filename] + end nm_m.body_start = b.count b << "--- %s ---" % part.mime_type part.convert.each_line do |l| @@ -420,6 +468,14 @@ function! s:set_defaults() endif endif + if !exists('g:notmuch_attachment_tmpdir') +
[PATCH] VIM: Add better attachment support
This patch changes how the notmuch vim client supports attachments: - For each attachment an 'Attachment : ' is added to the header - You can then use 'e' to extract the attachment under the cursor or use it elsewhere to extract all attachments (the prior behavior) - You can use 'v' to 'view' the attachment using xdg-open by default. Ian --- vim/notmuch.txt | 8 +++- vim/notmuch.vim | 60 +++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/vim/notmuch.txt b/vim/notmuch.txt index 4374102..838a904 100644 --- a/vim/notmuch.txt +++ b/vim/notmuch.txt @@ -72,6 +72,9 @@ q Quit view A Archive (-inbox -unread) I Mark as read (-unread) t Tag (prompted) +e Extract attachment on the current 'Attachment' line or all + attachments if the cursor is elsewhere. +v View attachment on the current 'Attachment' line. s Search p Save patches r Reply @@ -148,6 +151,9 @@ You can also configure your externail mail reader and sendemail program: > let g:notmuch_reader = 'mutt -f %s' let g:notmuch_sendmail = 'sendmail' -< + +You can also configure what probram is used to view attachments: + + let g:notmuch_view_attachment = 'xdg-open' vim:tw=78:ts=8:noet:ft=help: diff --git a/vim/notmuch.vim b/vim/notmuch.vim index 331e930..a5830b5 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -35,6 +35,7 @@ let g:notmuch_show_maps = { \ 't': 'show_tag("")', \ 'o': 'show_open_msg()', \ 'e': 'show_extract_msg()', + \ 'v': 'show_view_attachment()', \ 's': 'show_save_msg()', \ 'p': 'show_save_patches()', \ 'r': 'show_reply()', @@ -58,6 +59,8 @@ let s:notmuch_date_format_default = '%d.%m.%y' let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S' let s:notmuch_reader_default = 'mutt -f %s' let s:notmuch_sendmail_default = 'sendmail' +let s:notmuch_view_attachment_default = 'xdg-open' +let s:notmuch_attachment_tmpdir_default = '~/.notmuch/tmp' let s:notmuch_folders_count_threads_default = 0 function! s:new_file_buffer(type, fname) @@ -147,13 +150,53 @@ function! s:show_info() ruby vim_puts get_message.inspect endfunction +function! s:show_view_attachment() + let line = getline(".") +ruby << EOF + m = get_message + line = VIM::evaluate('line') + + match = line.match(/^Attachment (\d*):/) + if match and match.length == 2 + a = m.mail.attachments[match[1].to_i - 1] + tmpdir = VIM::evaluate('g:notmuch_attachment_tmpdir') + tmpdir = File.expand_path(tmpdir) + Dir.mkdir(tmpdir) unless Dir.exists?(tmpdir) + filename = File.expand_path("#{tmpdir}/#{a.filename}") + vim_puts "Viewing attachment #{filename}" + File.open(filename, 'w') do |f| + f.write a.body.decoded + cmd = VIM::evaluate('g:notmuch_view_attachment') + system(cmd, filename) + end + else + vim_puts "No attachment on this line." + end +EOF +endfunction + function! s:show_extract_msg() + let line = getline(".") ruby << EOF m = get_message - m.mail.attachments.each do |a| + line = VIM::evaluate('line') + + # If the user is on a line that has an 'Attachment' + # line, we just extract the one attachment. + match = line.match(/^Attachment (\d*):/) + if match and match.length == 2 + a = m.mail.attachments[match[1].to_i - 1] File.open(a.filename, 'w') do |f| f.write a.body.decoded - print "Extracted '#{a.filename}'" + vim_puts "Extracted #{a.filename}" + end + else + # Extract them all.. + m.mail.attachments.each do |a| + File.open(a.filename, 'w') do |f| + f.write a.body.decoded + vim_puts "Extracted #{a.filename}" + end end end EOF @@ -326,6 +369,11 @@ ruby << EOF b << "To: %s" % msg['to'] b << "Cc: %s" % msg['cc'] b << "Date: %s" % msg['date'] + cnt = 0 + nm_m.mail.attachments.each do |a| + cnt += 1 + b << "Attachment %d: %s" % [cnt, a.filename] + end nm_m.body_start = b.count b << "--- %s ---" % part.mime_type part.convert.each_line do |l| @@ -420,6 +468,14 @@ function! s:set_defaults() endif endif + if !exists('g:notmuch_attachment_tmpdir') +
[PATCH] Add default configuration values to the man page
--- doc/man1/notmuch-config.rst | 18 ++ 1 file changed, 18 insertions(+) diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst index 3c9a568..9de5534 100644 --- a/doc/man1/notmuch-config.rst +++ b/doc/man1/notmuch-config.rst @@ -49,19 +49,31 @@ The available configuration items are described below. within a sub-directory of the path configured here named ``.notmuch``. +Default: ``$MAILDIR``, otherwise ``$HOME/mail``. + **user.name** Your full name. +Default: ``$NAME`` variable if set, otherwise read from +``/etc/passwd``. + **user.primary\_email** Your primary email address. +Default: ``$EMAIL`` variable if set, otherwise constructed from the +username and hostname of the current machine. + **user.other\_email** A list of other email addresses at which you receive email. +Default: not set. + **new.tags** A list of tags that will be added to all messages incorporated by **notmuch new**. +Default: ``unread;inbox``. + **new.ignore** A list of file and directory names, without path, that will not be searched for messages by **notmuch new**. All the files and @@ -69,11 +81,15 @@ The available configuration items are described below. ignored, regardless of the location in the mail store directory hierarchy. +Default: no tags. + **search.exclude\_tags** A list of tags that will be excluded from search results by default. Using an excluded tag in a query will override that exclusion. +Default: ``deleted;spam``. + **maildir.synchronize\_flags** If true, then the following maildir flags (in message filenames) will be synchronized with the corresponding notmuch tags: @@ -104,6 +120,8 @@ The available configuration items are described below. are properly synchronized to the maildir flags, as the commands expect the database and maildir to be in sync. +Default: ``true``. + ENVIRONMENT === -- 2.1.0