Commit graph

97 commits

Author SHA1 Message Date
Koni Marti
cfbb548fb8 threads: match regular view scrolling behavior
Try to keep the position in the message list when scrolling through
threaded messages to match the scrolling behavior of the regular view.
This only needs to be implemented for the client-side threading since we
have to rebuild the threads when new messages arrive.

Reported-by: akspecs <akspecs@gmail.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 22:22:56 +02:00
Koni Marti
866867c616 threads: fix race warnings for client-side debouncing
Client-side thread debouncing happens in a different goroutine. Any
function or variable that is called or accessed by this goroutine should
be protected from a concurrent access.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 22:22:53 +02:00
Koni Marti
54a0a377e0 threads: debounce client-side thread building
Debounce client-side thread building in the message store. Debouncing is
useful when multiple messages are loaded, i.e. when scrolling with
PgUp/PgDown.

Without the debouncing, all client-side threads will be built everytime
the message store is updated which creates a noticable lag in the
message list ui when client-side threading is activated.

The default debouncing delay can be changed by changing
'client-threads-delay' in the UI config section.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 22:22:48 +02:00
Koni Marti
8f7695fde5 msgstore: implement a uid-based architecture
Change the message store architecture from an index-based to a uid-based
one. Key advantage of this design approach is that no reselect mechanism
is required anymore since it comes with the design for free.

Fixes: https://todo.sr.ht/~rjarry/aerc/43
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 11:34:19 +02:00
akspecs
0f86666f52 msgstore: check if message index < 0, select 0 if so
Calling :prev without this check can cause the index to go below 0 if
the current index is smaller than the value being scrolled / incremented
by. This results in the email selector wrapping around from the top to
the bottom most email in the mailbox folder due to changes in ec150f0
'store: fix Select behaviour'.

Signed-off-by: akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-24 23:05:07 +02:00
Tim Culverhouse
4036f696ad msgstore: refactor NextPrev
Refactor NextPrev to use already existing selection methods and bounds
checking

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-24 23:05:00 +02:00
Tim Culverhouse
f8e6478d46 store: fix Select behavior
Fix the behavior of the Select(index int) method to select the last
message if an index > len(list) or select from bottom of list for
negative indexes.

Thanks: akspecs <akspecs@gmail.com>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-24 23:04:52 +02:00
Robin Jarry
cd19995557 logging: use level-based logger functions
Do not pass logger objects around anymore. Shuffle some messages to make
them consistent with the new logging API. Avoid using %v when a more
specific verb exists for the argument types.

The loggers are completely disabled (i.e. Sprintf is not even called)
by default. They are only enabled when redirecting stdout to a file.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
2022-07-23 22:52:15 +02:00
Tim Culverhouse
04097e8743 msgstore: do not build threads when threaded view is off
Commit 3a614e45fc ("threading: enable toggle-threads for server-side
threads") changed the behavior of the msgstore.buildThreads variable to
reflect whether the client needs to build threads or the server will.
However, a call to runThreadbuilder was not updated with an extra
conditional. As a result, threads were built regardless of the state of
the threadedView resulting in a large performance penalty for
non-threaded views with client side threading.

Only run thread builder if threaded view is enabled.

Fixes: 3a614e45fc ("threading: enable toggle-threads for server-side threads")
Reported-by: akspecs <akspecs@gmail.com>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-17 18:35:21 +02:00
Tim Culverhouse
a953e4dbe9 threading: refactor reselect logic
This patch refactors reselection of a message during certain operations
(searching, filtering, clearing, deleting, moving, new message arrival).
The addition of server-side filtering for threaded views broke the
existing reselection logic.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-10 21:15:12 +02:00
Tim Culverhouse
c2f4404fca threading: enable filtering of server-side threads
This patch enables the filtering of a threaded view which uses
server-built threads. Filtering is done server-side, in order to
preserve the use of server-built threads.

In adding this feature, the filtering of notmuch folders was brought up
to feature parity with the other workers. The filters function the same
(ie: they can be stacked). The notmuch filters, however, still use
notmuch syntax for the filtering.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-10 21:15:12 +02:00
Tim Culverhouse
ccd042889f threading: add force-client-threads option
This patch adds a config option to force the use of client side threads.
This option will override a servers Thread capability, and only build
threads on the client. It can be enabled contextually. For example:

	[ui]
	threading-enabled = true

	[ui:folder~^Archive]
	force-client-threads = true

This config would enable threads for all views, and use client threads
for folders that start with Archive. This can be advantageous if, for
example, the folder is very large and the server has a slow response due
to building threads for the entire mailbox

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-10 21:15:12 +02:00
Tim Culverhouse
3a614e45fc threading: enable toggle-threads for server-side threads
Enable the :toggle-threads command to work for workers which have Thread
capability. The implementation of that feature has the side effect that
the threading-enabled config option now sets the default view (threaded
or not threaded) for any worker, not just IMAP or notmuch.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-10 21:15:12 +02:00
Tim Culverhouse
a8879d79c6 msgstore: remove duplicate calls to store.update
Move and Delete commands perform a store.update() when their worker is
completed and also when the method is called. This patch removes the
call performed in the store.Move and store.Delete methods.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-10 21:15:12 +02:00
Tim Culverhouse
4753cfd3e3 visual-mode: deselect messages after performing command
In order to better align to vim functionality: deselect visual mode
selections after performing a command on the selection. This patch also
introduces a new command to allow for re-selecting (remarking) the
previous selection set so that commands can be chained together. The
deselection only applies to msg commands that *do not* move the message
from the store (those types of commands already deselect):
- read/unread
- flag/unflag
- modify-labels
- copy
- pipe

Previous usage to mark several messages as read and deselect all:
Vjjj:read<Enter>:unmark -a<Enter>

New usage, similar to vim:
Vjjj:read<Enter>

To chain a command together:
Vjjj:read<Enter>:remark<Enter>{next command}<Enter>

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-06-14 22:12:42 +02:00
Tim Culverhouse
2551dd1bfa feat: add background mail polling option for all workers
Check for new mail (recent, unseen, exists counts) with an external
command, or for imap with the STATUS command, at start or on
reconnection and every X time duration

IMAP:
The selected folder is skipped, per specification. Additional config
options are included for including/excluding folders explicitly.

Maildir/Notmuch:
An external command will be run in the background to check for new mail.
An optional timeout can be used with maildir/notmuch. Default is 10s

New account options:
check-mail
check-mail-cmd (maildir/notmuch only)
check-mail-timeout (maildir/notmuch only), default 10s
check-mail-include (IMAP only)
check-mail-exclude (IMAP only)

If unset, or set less than or equal to 0, check-mail will be ignored

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-05-31 14:32:51 +02:00
Koni Marti
30d5788974 store: clean marked messages
Clean marked messages after new uids are fetched.

Commit 5c5158b3 ("store: remove callbacks on error") removed side
effects in the message store after a longer suspend period but neglected
to remove marked zombie messages.

References: https://todo.sr.ht/~rjarry/aerc/28
Co-authored-by: inwit <inwit@sindominio.net>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-05-31 14:32:45 +02:00
Koni Marti
5c5158b3c1 store: remove callbacks on error
Unmark deleted messages and remove pending headers in the callback
function when an error in the backend occurs (e.g. due to connection
issues).

The message store marks messages that should be deleted. If the delete
operation in the backend fails, messages are never unmarked and will
remain rendered as empty lines in the message list. This also affects
the move and archive commands that rely on a copy and delete operation.

A similar issue occurs with the pending headers when the operation to
fetch them fails. In this case, messages will appear as loading
indefinitely in the message list and are never re-fetched because the
corresponding pending headers from the failed operations are still
present.

Fixes: https://todo.sr.ht/~rjarry/aerc/28
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-05-06 11:02:33 +02:00
Koni Marti
cb887a2d9d store: keep current message selected
Keep current message selected when clearing or changing filters and when
toggling threads.

Add -s flag to the clear command to also clear the selected message and
set cursor to the top of the message list.

Implements: https://todo.sr.ht/~rjarry/aerc/36
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-04-17 12:18:33 +02:00
Koni Marti
f6e34e4cf1 imap: fix no-envelope-for-message error
Fix the "no envelope available for this message" error that can occur
when using the same imap mailbox in another mailclient (e.g.
through a webmail interface) at the same time.

Complements the fixes in commit 7fe7fe4 ("ui: fix panic in header
formatter") and commit 074b0a1 ("view,list: fix crash when viewing
incomplete imap messages").

The error is caused when a message attribute update is received by the
message store before the message list had a chance to fetch the proper
header first. In this case, an (incomplete) message info is stored in
the message store and the message list will never fetch the correct
header. To prevent this, add only messages to the store with a non-nil
envelope but make sure that message attribute updates are properly
merged.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-04-11 12:06:53 +02:00
Koni Marti
20218de913 store: sort messages even when a filter is applied
Sort the message list even when a filter is applied according to the
sort criteria given by the sort command.

Currently, the sort command has no effect when a filter is in use.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-25 13:07:22 +01:00
Koni Marti
e50ab59284 sort: keep sort criteria applied to folder
Keep the sort criteria applied to the selected folder until the default
sort order should be restored. Call the sort command without arguments
to restore the default sort order.

The current behavior is that the default sort order is restored as soon
as the folder reloads. This happens often and then the results of the
sort command are lost. This makes the sort command not very
user-friendly. Instead, we should keep the sort criteria applied until
the user explicitly wants to restore the default sort order again.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-25 13:07:20 +01:00
Koni Marti
9f4da4de0c msglist: update message counter upon filter change
Update message counter in msglist when the filter is changed (either set or
cleared in the msgstore).

When we apply a filter, we change the number of uids in the message
store. This can unintentionally trigger the storeUpdate() function of
the msglist which checks the number of uids for new messages and
advances the pointer by the difference in the number of messages. This
can be avoided when we update the message counter upon changing the
filter.

Fixes: https://todo.sr.ht/~rjarry/aerc/23
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-20 10:00:50 +01:00
Koni Marti
7d2b0f579d store: fix deleting messages in filter mode
fix deleting messages when in filter mode.

Link: https://lists.sr.ht/~rjarry/aerc-devel/%3CCIO3IVSM2JUB.3L46NM6LJZ2KB%40Archetype%3E

Reported-by: Moritz Poldrack <git@moritz.sh>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-20 10:00:23 +01:00
Koni Marti
2a19c30879 store: allow consecutive filter and search queries
Enable consecutive filter and search queries. Filter narrows down
message list consecutively and clears search results. Search applies to
the current message list.

Fixes: https://todo.sr.ht/~rjarry/aerc/24
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Inwit <inwit@sindominio.net>
Tested-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-14 23:59:58 +01:00
Moritz Poldrack
4bc43d2741 all: fix minor issues found by staticcheck
Signed-off-by: Moritz Poldrack <git@moritz.sh>
2022-03-12 21:00:23 +01:00
Koni Marti
65ae87a524 threading: honor user-defined sort criteria
Apply the user-defined sort criteria to the message with the highest
uid in a threaded discussion. Restore the default sort order when
leaving threading mode.

Commit 7811620eb8 ("threading: implement on-the-fly message
threading") introduced message threading with the threaded messages
being only sorted by their message uids irrespective of the defined sorting
criteria. It did not restore the default sort order either.

Reported-by: Sebastien Binet <s@sbinet.org>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-03-09 00:08:26 +01:00
Koni Marti
7811620eb8 threading: implement on-the-fly message threading
implement message threading on the message store level using the
jwz algorithm. Build threads on-the-fly when new message headers arrive.

Use the references header to create the threads and the in-reply-to
header as a fall-back option in case no references header is present.

Does not run when the worker provides its own threading (e.g. imap
server threads).

Include only those message headers that have been fetched and are
stored in the message store.

References: https://www.jwz.org/doc/threading.html
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Inwit <inwit@sindominio.net>
Tested-by: akspecs <akspecs@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-02-24 13:00:12 +01:00
Koni Marti
e5ad877af5 msgstore: fetch missing headers in visual mode
fetches missing headers when in visual selection mode. This prevents
large archive operations from panicking due to a nil pointer
dereference.

The archive command will return an error to the ui when a nil message is
encountered to signal that the message store is not ready yet.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
2022-01-22 17:07:50 +01:00
y0ast
dc2a2c2dfd messages: allow displaying email threads
Display threads in the message list. For now, only supported by the
notmuch backend and on IMAP when the server supports the THREAD
extension.

Setting threading-enable=true is global and will cause the message list
to be empty with maildir:// accounts.

Co-authored-by: Kevin Kuehler <keur@xcf.berkeley.edu>
Co-authored-by: Reto Brunner <reto@labrat.space>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2021-11-13 15:05:59 +01:00
Robin Jarry
0d645bcebd go.mod: change base git url
I'm not sure what are the implications but it seems required.

Link: https://github.com/golang/go/issues/20883
Signed-off-by: Robin Jarry <robin@jarry.cc>
2021-11-05 10:21:45 +01:00
Reto Brunner
8b4f2d148c Fix linter warnings
* Remove redundant return (code was never reached)
* Remove redundant type information
* Rename unused function parameters to "_"
2021-02-26 22:14:58 +01:00
Reto Brunner
8446d48664 run go fmt 2020-07-17 17:50:24 +02:00
Andrew Jeffery
6401b105cb Remove deleted messages from search/filter results
This ensures that when moving/deleting messages with a filter active the
view gets updated properly.
2020-07-10 09:15:11 +02:00
ARaspiK
0535f6333f Add additional flagging functionality
More mail flags can now be set, unset, and toggled, not just the
read/seen flag.

This functionality is implemented with a new `:flag` and `:unflag`
command, which are extensions to the matching `:read` and `:unread`
commands, adding support for different flags.  In fact, the
`read`/`unread` commands are now recognized aliases to `flag`/`unflag`.
The new commands are also well documented in aerc(1).

The change mostly extends the previous read/unread setting functionality
by adding a selection for the flag to change.
2020-07-08 09:13:03 +02:00
Srivathsan Murali
b1eb7ad18d Set AnsweredFlag on successful reply 2020-05-25 11:29:53 -04:00
Reto Brunner
13a6a3fa71 FetchBodyPart doesn't need the parent body structure 2020-05-17 11:44:38 +02:00
Reto Brunner
bae678e8f2 imap: Remove FetchMessageBodyPart.{Encoding,Charset}
Fixes https://todo.sr.ht/~sircmpwn/aerc2/352 exactly as suggested by emersion.
2020-05-16 20:03:42 +02:00
Ben Fiedler
05fa79eb8e store.FetchFull: Change callback type to expose entire message
This is a prerequisite for allowing the FetchFull message to return both
the message content and the message headers.
2020-05-01 11:10:08 -04:00
Reto Brunner
f3dbecaaea remove the dirInfoUpdateRequest functionality
The notmuch worker followed suit in handling the dirInfo submission manually.
That removes the last user so we might as well remove the functionality.
2020-02-29 13:16:33 -05:00
Jeffas
b55813f2c0 Don't show empty message while sorting
This changes the ui to show the spinner while we are sorting. It only
shows one line of the spinner since there are an unknown number of
messages at this time.
2020-02-28 22:06:01 -05:00
Reto Brunner
5dd0f454c1 lib/msgstore: debounce directoryUpdateRequests
Apparently sending an event for every incoming messageInfo slows down
the application significantly.

Therefore this slows down the emmision rate, on the cost of being out of date
in some cases.
2020-02-25 11:05:26 -05:00
Reto Brunner
d44bdc9fb9 Revert "Only fetch the directory contents when we are switching directories"
This reverts commit bd4df53009.

I did not properly untangle the opening / dirlist update of each other.
This interferes with the imap worker, hence the revert
2020-02-19 08:37:20 +01:00
Reto Brunner
89b742dc6c Request DirInfo whenever the unread count may have changed
Actions such as read / unread or the addition of new messages do change
the read/unread/recent count. Hence we request an update from the workers.
Workers going over the network should probably cache the information and invalidate
it only if necessary
2020-02-16 10:41:17 -05:00
Reto Brunner
bd4df53009 Only fetch the directory contents when we are switching directories
Previously, sending a DirectoryInfo assumed that a directory change
happened. However we don't want that if we only want to update the
unread message count.
2020-02-16 10:41:15 -05:00
Reto Brunner
9096049f75 FetchBodyParts: decode source in the workers
Previously the workers returned a mixture of decoded / encoded parts.
This lead to a whole bunch of issues.
This commit changes the msgviewer and the commands to assume parts to already
be decoded
2020-01-05 16:02:45 -05:00
Reto Brunner
63391b7dca Add labels to index format (%g)
Exposes the notmuch tags accordingly, stubs it for the maildir worker.
2019-12-27 10:20:29 -07:00
Reto Brunner
cf43066d5b msgstore: add marking functionality 2019-12-21 09:27:49 -05:00
Kiril Vladimiroff
d9a0522780 Break early when delete happens in outdated state
A panic could happen when multiple delete messages are sent one after
another without waiting until there are no messages left to be deleted:

	panic: runtime error: makeslice: len out of range

	goroutine 1 [running]:
	git.sr.ht/~sircmpwn/aerc/lib.(*MessageStore).Update(0xc000592e00, 0xa8fe60, 0xc0003340f0)
		/go/src/git.sr.ht/~sircmpwn/aerc/lib/msgstore.go:222 +0x5b8
	git.sr.ht/~sircmpwn/aerc/widgets.(*AccountView).onMessage(0xc0000a0460, 0xa8fe60, 0xc0003340f0)
		/go/src/git.sr.ht/~sircmpwn/aerc/widgets/account.go:251 +0x307
	git.sr.ht/~sircmpwn/aerc/widgets.(*AccountView).Tick(0xc0000a0460, 0xc0001496b0)
		/go/src/git.sr.ht/~sircmpwn/aerc/widgets/account.go:90 +0xa1
	git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Tick(0xc0000a9f40, 0xc000020501)
		/go/src/git.sr.ht/~sircmpwn/aerc/widgets/aerc.go:123 +0x91
	main.main()
		/go/src/git.sr.ht/~sircmpwn/aerc/aerc.go:182 +0x5bf

The make that blows up is:

	uids := make([]uint32, len(store.uids)-len(msg.Uids))

This change simply checks whether the make is going to be valid before
starting to work on the actual delete. If there are more messages queued
to be deleted than what's left in the store, then we're obviously in an
inconsistent state, ask for an update and break.
2019-12-12 12:29:39 -05:00
Rafael Castillo
74c13e84b7 Initialize an empty message map in the message store on initialization
This addresses occasional crashes when a `MessageInfo` event reached the message
store before `DirectoryContents`, particularly on slower (imap) accounts.
2019-12-07 14:29:36 -05:00