diff --git a/lib/mu-contacts-cache.cc b/lib/mu-contacts-cache.cc index 8d68af13..fc3a22ed 100644 --- a/lib/mu-contacts-cache.cc +++ b/lib/mu-contacts-cache.cc @@ -304,7 +304,7 @@ using ContactSet = std::set, ContactLessThan>; void -ContactsCache::for_each(const EachContactFunc& each_contact) const +ContactsCache::for_each(const EachContactFunc& each_contact, size_t max_num) const { std::lock_guard l_{priv_->mtx_}; @@ -316,8 +316,13 @@ ContactsCache::for_each(const EachContactFunc& each_contact) const for (const auto& item : priv_->contacts_) sorted.emplace(item.second); - for (const auto& ci : sorted) + // sadly, there's no set::resize + size_t n{}; + for (const auto& ci : sorted) { + if (max_num > 0 && n++ >= max_num) + break; each_contact(ci); + } } bool diff --git a/lib/mu-contacts-cache.hh b/lib/mu-contacts-cache.hh index a80260c8..5b2e2b49 100644 --- a/lib/mu-contacts-cache.hh +++ b/lib/mu-contacts-cache.hh @@ -142,9 +142,10 @@ public: /** * Invoke some callable for each contact, in order of rank. * - * @param each_contact + * @param each_contact function invoked for each contact + * @param max_num stop after at most so many contacts, or 0 for no limit */ - void for_each(const EachContactFunc& each_contact) const; + void for_each(const EachContactFunc& each_contact, size_t max_num=0) const; private: struct Private; diff --git a/lib/mu-server.cc b/lib/mu-server.cc index f5d196a0..9c3db9f6 100644 --- a/lib/mu-server.cc +++ b/lib/mu-server.cc @@ -228,7 +228,8 @@ Server::Private::make_command_map() ArgMap{{":personal", ArgInfo{Type::Symbol, false, "only personal contacts"}}, {":after", ArgInfo{Type::String, false, "only contacts seen after time_t string"}}, - {":tstamp", ArgInfo{Type::String, false, "return changes since tstamp"}}}, + {":tstamp", ArgInfo{Type::String, false, "return changes since tstamp"}}, + {":maxnum", ArgInfo{Type::Number, false, "max number of contacts to return"}}}, "get contact information", [&](const auto& params) { contacts_handler(params); }}); cmap.emplace( diff --git a/mu4e/mu4e-contacts.el b/mu4e/mu4e-contacts.el index beac895b..a7698033 100644 --- a/mu4e/mu4e-contacts.el +++ b/mu4e/mu4e-contacts.el @@ -56,6 +56,17 @@ time-based restriction." :type 'string :group 'mu4e-compose) +(defcustom mu4e-compose-complete-max 2000 + "Consider only the top-n contacts. +After considering the other +constraints (`mu4e-compose-complete-addresses' and +`mu4e-compose-complete-only-after'), pick only the highest-ranked n. + +This reduce start-up time and memory usage. Set to nil for no +limits." + :type 'string + :group 'mu4e-compose) + ;; names and mail-addresses can be mapped onto their canonical ;; counterpart. use the customizeable function ;; mu4e-canonical-contact-function to do that. below the identity @@ -293,6 +304,7 @@ nothing." (mu4e--server-contacts mu4e-compose-complete-only-personal mu4e-compose-complete-only-after + mu4e-compose-complete-max mu4e--contacts-tstamp))) (provide 'mu4e-contacts) diff --git a/mu4e/mu4e-server.el b/mu4e/mu4e-server.el index bf6942f6..9f0f6d11 100644 --- a/mu4e/mu4e-server.el +++ b/mu4e/mu4e-server.el @@ -441,17 +441,21 @@ The result is delivered to the function registered as :decrypt ,(and decrypt t) :docid ,docid))) -(defun mu4e--server-contacts (personal after tstamp) - "Ask for contacts with PERSONAL AFTER TSTAMP. -S-expression (:contacts () :tstamp \"\") is expected in -response. If PERSONAL is non-nil, only get personal contacts, if -AFTER is non-nil, get only contacts seen AFTER (the time_t -value)." +(defun mu4e--server-contacts (personal after maxnum tstamp) + "Ask for contacts with PERSONAL AFTER MAXNUM TSTAMP. + +S-expression (:contacts () :tstamp \"\") +is expected in response. + +If PERSONAL is non-nil, only get personal contacts, if AFTER is +non-nil, get only contacts seen AFTER (the time_t value). If MAX is non-nil, +get at most MAX contacts." (mu4e--server-call-mu `(contacts :personal ,(and personal t) :after ,(or after nil) - :tstamp ,(or tstamp nil)))) + :tstamp ,(or tstamp nil) + :maxnum ,(or maxnum nil)))) (defun mu4e--server-find (query threads sortfield sortdir maxnum skip-dups include-related)