aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* jmap: avoid displaying archive folder when use-labels=trueRobin Jarry2023-06-253-6/+22
| | | | | | | | | | When archiving a message, the counts of archive folder are changed. When use-labels=true, the archive folder is hidden and should remain so. Do not send updates to the UI. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* doc: folder-map in aerc-accountsKoni Marti2023-06-222-0/+34
| | | | | | | | Document folder-map option in aerc-accounts. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* maildir: add folder-mapKoni Marti2023-06-224-20/+56
| | | | | | | | | | | | | Add the folder-map functionality to the maildir backend. If the folder-map config option is specified, the folder-map worker middleware is used. Unroll the worker.PostMessageInfoError function for a streamlined WorkerInteractor interface. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* imap: add folder-mapKoni Marti2023-06-224-5/+27
| | | | | | | | | Add the folder-map functionality to the imap backend. If the folder-map config option is specified, the folder-map worker middleware is used. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* lib: parse query-map and folder-map filesKoni Marti2023-06-223-17/+90
| | | | | | | | Combine the query-map and folder-map parsing functionality. Add tests. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* worker: implement folder-map middlewareKoni Marti2023-06-221-0/+152
| | | | | | | | | | Implement a folder-map middleware that will translate the folder names between the ui and the backend according to a provided key-value map. Fixes: https://todo.sr.ht/~rjarry/aerc/175 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* worker: add WorkerInteractor interfaceKoni Marti2023-06-229-41/+35
| | | | | | | | | | | | Add a WorkerInteractor interface. Avoid exposing any public fields in the types.Worker. This will set the stage to implement a middleware pattern for the workers, i.e. to map folder names between the ui and the backend. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
* textinput: fix stemming with multi-byte charsKoni Marti2023-06-221-1/+1
| | | | | | | | | Fix a panic in the textinput when using multi-byte chars in the completions. Fixes: https://todo.sr.ht/~rjarry/aerc/180 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* worker: add jmap supportRobin Jarry2023-06-2133-10/+2507
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add support for JMAP backends. This is on par with IMAP features with some additions specific to JMAP: * tagging * sending emails This makes use of git.sr.ht/~rockorager/go-jmap for the low level interaction with the JMAP server. The transport is JSON over HTTPS. For now, only oauthbearer with token is supported. If this proves useful, we may need to file for an official three-legged oauth support at JMAP providers. I have tested most features and this seems to be reliable. There are some quirks with the use-labels option. Especially when moving and deleting messages from the "All mail" virtual folder (see aerc-jmap(5)). Overall, the user experience is nice and there are a lot less background updates issues than with IMAP (damn IDLE mode hanging after restoring from sleep). I know that not everyone has access to a JMAP provider. For those interested, there are at least these two commercial offerings: https://www.fastmail.com/ https://www.topicbox.com/ And, if you host your own mail, you can use a JMAP capable server: https://stalw.art/jmap/ https://www.cyrusimap.org/imap/download/installation/http/jmap.html Link: https://www.rfc-editor.org/rfc/rfc8620.html Link: https://www.rfc-editor.org/rfc/rfc8621.html Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* imap: implement cancellation of searching and fetchingTim Culverhouse2023-06-202-0/+26
| | | | | | | | | Check for cancelled contexts before and after performing headers or flag fetches and any directory searching. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* imap: implement cancellation of opening dir and listing contentsTim Culverhouse2023-06-201-39/+72
| | | | | | | | | | | Check for a cancelled context when opening a directory, and before+after fetching directory contents/threads. Clean up the nesting of fetchDirectoryContents by using what we already know about server capabilities and using a switch statement. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* notmuch: implement cancellation of requestsTim Culverhouse2023-06-202-17/+38
| | | | | | | | | Implement cancellation of cancellable requests. These include listing of directory contents, searching, and sorting. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* maildir: implement cancellation of requestsTim Culverhouse2023-06-202-55/+78
| | | | | | | | | Implement cancellation of cancellable requests. These include listing of directory contents, searching, and sorting. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: delete pending headers when done or cancelledTim Culverhouse2023-06-201-1/+2
| | | | | | | | | | | | | | The msgstore keeps a map of UIDs it has requested headers for. The map is only cleared of pending headers when either an error or a valid header is received. This can lead to pending headers not being removed from the list (and therefore never re-requested) if a user has navigated away from the directory before the response is received. Delete the pending headers list if the request is finished or cancelled. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* worker: add context to cancellable requestsTim Culverhouse2023-06-204-16/+39
| | | | | | | | | | | | | Add a Context field to requests which we may want to cancel when changing directories. Add a Cancelled meta-message to inform the UI that a request was cancelled (as opposed to Done or Error). Delete callbacks when a request is Cancelled. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: pass context from dirlist to msgstoreTim Culverhouse2023-06-202-19/+30
| | | | | | | | | | | | | Most, if not all, requests to the worker that may need cancellation are sent by the msgstore. These requests are typically only relevant when the msgstore is the selected one. Pass a context from the dirlister to the msgstore when it is selected. This context will be passed in future commits to worker requests. The context is cancelled when a new directory is selected. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msgstore: allocate properly sized mapsTim Culverhouse2023-06-201-3/+2
| | | | | | | | Allocate properly sized maps when receiving a DirectoryContents or DirectoryThreaded message Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
* commands: fix panic in template executionKoni Marti2023-06-201-0/+3
| | | | | | | | | | | | Fix a panic in the template execution when the template evalutes to nil. Check for length of returned arguments after the template code is expanded. To reproduce, run :{{exec "cat > /dev/null" .MessageId}} Fixes: 42cd4157 ("commands: execute commands with templates") Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* mk: do not create $(DESTDIR)$(SHAREDIR)/filtersRobin Jarry2023-06-191-1/+4
| | | | | | | | | | | This folder is not used anymore and remains empty. Some distros complain about empty folders. Add note about why we need to create these folders. Link: https://ss64.com/osx/install.html Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* doc: fix typosRobin Jarry2023-06-192-2/+2
| | | | | | | Reported by lintian. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* save: fix saving of multiple files with the same nameMoritz Poldrack2023-06-173-2/+45
| | | | | | | | | When an email has multiple attachments with the same name, aerc currently only saves one of them. This patch adds a counter to them. the file has an extension, the counter is added before the extension. Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Koni Marti <koni.marti@gmail.com>
* account: create new store when creating foldersKoni Marti2023-06-173-26/+40
| | | | | | | | | | | | | | | | | Add a correct message store entry to the DirStore for newly created directories. This is currently not done, so the directory name does either not show up in the directory list or contains a nil message store. Either way, such a directory cannot be used in the current session and aerc needs to be restarted/reconnected. This affects the :mkdir and :archive commands (archive when a new directory is created). To reproduce on imap: create a new directory (:mkdir testdir), try to move a message into it (:move testdir). It will not show up because there is not message store. Fixes: 8ced001d ("listDirectories: refactor listdirectories handling") Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* doc: move toggle-headers to view categoryErik Schilling2023-06-171-3/+3
| | | | | | | This is a command for the viewer not the composer. Signed-off-by: Erik Schilling <erik.schilling@linaro.org> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* notmuch: translate filter/search options to queryKoni Marti2023-06-172-4/+106
| | | | | | | | | | | | | | | | Translate the regular filter and search options to a notmuch query to achieve a basic equivalence across backends for these commands. The following examples have the same filtering effect: :filter -uf koni :filter -u from:koni :filter tag:unread from:koni And ':filter -x Flagged' would translate to ':filter tag:flagged'. Fixes: https://todo.sr.ht/~rjarry/aerc/177 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Inwit <inwit@sindominio.net>
* logging: remove ultra verbose trace logsRobin Jarry2023-06-125-45/+3
| | | | | | | | | | | | | | | | | Every message exchanged between the UI and the worker(s) is logged at least twice with some obscure IDs and struct pointer names. When enabling trace logging, this floods the files for very little or no benefit and makes the meaningful logging message hard to catch. Also, other messages tend to flood the output for no specific reason. These are most of the time leftovers from the development process and are not useful for tracking potential issues. Remove these. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* mbox: use named loggerRobin Jarry2023-06-121-10/+10
| | | | | | | | Use the worker's logging functions to have all mbox related messages prefixed by the account name. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* notmuch: use named loggerRobin Jarry2023-06-122-36/+35
| | | | | | | | Use the worker's logging functions to have all notmuch related messages prefixed by the account name. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* maildir: use named loggerRobin Jarry2023-06-122-40/+40
| | | | | | | | Use the worker's logging functions to have all maildir related messages prefixed by the account name. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* imap: use named loggerRobin Jarry2023-06-129-48/+47
| | | | | | | | Use the worker's logging functions to have all imap related messages prefixed by the account name. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* worker: use named loggerRobin Jarry2023-06-121-8/+30
| | | | | | | Add a named logger for each worker based on the account name. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* logger: add support for named loggersRobin Jarry2023-06-121-25/+64
| | | | | | | | Allow creating loggers with name prefixes. This will be used in next commits to have per worker/account loggers. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* templates: add map functionsRobin Jarry2023-06-106-0/+75
| | | | | | | | | Similar to switch and .StyleSwitch, add map and .StyleMap to work on lists. An extra "exclude" item is available to filter elements out of the list. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* bindings: add backspace keyVitaly Ovchinnikov2023-06-103-0/+4
| | | | | | | | Add `<backspace>` option to bindings, so it can be used to leave the message view similar to some file managers. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Acked-by: Robin Jarry <robin@jarry.cc>
* help: do not run a command when displaying keysRobin Jarry2023-06-101-0/+1
| | | | | | | | | | | | Running :help keys displays the current active key bindings in a dialog. When the dialog appears, a terminal tab also briefly appears and disappears immediately since aerc-keys is not an actual man page. Do not run any command when running :help keys. Fixes: 5c8a749cfa97 ("binds: display active keybinds in a dialog box") Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* mk: trim \r from the base64 outputOmar Polo2023-06-101-1/+1
| | | | | | | | | base64 terminates the lines with CRLF and we're currently stripping only line feeds. The shell then does word-splitting on the carriage return apparently and it breaks the build. Spotted on OpenBSD. Signed-off-by: Omar Polo <op@omarpolo.com> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* readme: mention openSUSE aerc packageMatěj Cepl2023-06-101-0/+1
| | | | | | | Add reference to the openSUSE package. Signed-off-by: Matěj Cepl <mcepl@cepl.eu> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* save: new option for saving attachmentsVitaly Ovchinnikov2023-06-104-10/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add a new `-A` option to `:save` that works in the same manner as `-a`, but saves all the named parts of an email, not just attachments. The reason is that I have an email with this structure: multipart/related multipart/alternative text/plain text/html image/png (image001.png) image/png (image002.png) image/png (image003.png) text/plain (env.txt) Where the `env.txt` is a "real" attachment, while the images are just a part of the HTML version of the email. However, in this particular email it was important to see them which can't be done with text UI and opening the HTML part with the browser also didn't work. Saving them to a temorary folder did the job and this can be useful in other scenarios. So before the patch we could do `:save -ap /some/path` and get just the `env.txt` saved there. After the patch we could also do `:save -Ap /some/path` and get all the images and the text file saved into the folder. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Tested-by: Moritz Poldrack <moritz@poldrack.dev>
* config: fix multiple dynamic stylesTim Culverhouse2023-06-011-3/+4
| | | | | | | | | | | | | | | When a user sets multiple dynamic styles, only the first one is applied. The parsing function is modifying the matching pattern prior to saving it to the style. When a second occurrence of the same dynamic style is seen, the patterns don't match because we compare against the raw user input instead of the modified pattern value. Store the raw user input as the pattern instead of our modified regex. Fixes: 2f46f64b0b0b ("styleset: allow dynamic msglist styling") Reported-by: Drew Devault <sir@cmpwn.com> Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Drew Devault <sir@cmpwn.com> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: quit composing when editor returns errorMoritz Poldrack2023-06-013-0/+14
| | | | | | | | | | When the editor crashes, or the user forces it to exit with an error code, it is safe to assume that they can't (if the command failed) or don't want to (if :cq'd) continue composing a meaningful message. Suggested-by: tristan957 Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Robin Jarry <robin@jarry.cc>
* contrib: add carddav-query scriptRobin Jarry2023-06-015-3/+382
| | | | | | | | | | | Add a standalone python script to allow querying contacts from a CardDAV compatible server. The script works with python 3.6+ and has no external dependencies. Link: https://sabre.io/dav/building-a-carddav-client/ Link: https://www.rfc-editor.org/rfc/rfc6352 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* contributing: cleanupRobin Jarry2023-05-301-4/+7
| | | | | | Remove outdated information. Add wiki specific instructions. Signed-off-by: Robin Jarry <robin@jarry.cc>
* doc: fix invalid markupRobin Jarry2023-05-301-1/+1
| | | | | | | Extraneous underscore slipped in. Fixes: 3d99fae3d224 ("term: add config options for TERM and osc8") Signed-off-by: Robin Jarry <robin@jarry.cc>
* doc: mention regex for the bindings definitioninwit2023-05-281-1/+10
| | | | | | | | Document the possibility of using regex when defining bindings for specific accounts or folders. Signed-off-by: inwit <inwit@sindominio.net> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* lib: don't set seen flag upon errorKoni Marti2023-05-281-4/+9
| | | | | | | | | Don't set the Seen flag when an error occurs during opening the message. Fixes: https://todo.sr.ht/~rjarry/aerc/125 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Acked-by: Robin Jarry <robin@jarry.cc>
* dirstore: list the folders in arrival orderKoni Marti2023-05-283-1/+45
| | | | | | | | | | | | | List the folders in arrival order when dirstore.List() is called instead of returning it in an arbitrary order. If enable-folders-sort=false and dirlist-tree=false, the directory list will arbitrarly reshuffle when changing directories because the dirlist.dirs are generated from keys in a map in the dirstore. Fixes: https://todo.sr.ht/~rjarry/aerc/178 Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* statusline: fix typo in deprecation warningVlad-Stefan Harbuz2023-05-211-2/+2
| | | | | | | | This was a bad copy paste from config/ui.go. Fixes: d2e74cdb91e1 ("statusline: add column based render format") Signed-off-by: Vlad-Stefan Harbuz <vlad@vladh.net> Acked-by: Robin Jarry <robin@jarry.cc>
* maildirpp: fix path separatorKoni Marti2023-05-201-3/+0
| | | | | | | | | | Fix path separator for the maildir++ backend. Maildir++ already substitutes '.' for os.PathSeparator. Returning '.' will thus break the directory tree and the other logic for this backend. Fixes: 2040fc18 ("imap: use delimiter from server") Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* ui: fix deadlocks in message channelRobin Jarry2023-05-2010-70/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are several ways the ui message channel can fill up leading to deadlocks. 1) Invalidate() changes the value of uiState to DIRTY. The following call sequence: QueueRedraw() Invalidate() QueueRedraw() Leads to multiple nil messages being queued in the message channel whereas one could assume that the second QueueRedraw() would do nothing. This is caused by the tri-state nature of uiState. 2) We use the same channel to convey state change, keyboard events and redraw requests. Since a keyboard event almost always triggers a redraw, we end up trying to append a redraw message in the same goroutine that reads from the channel. This triggers a deadlock when there are more than 50 pending messages. Solve the issue by using multiple channels, one per type of message that needs to be sent to the main ui thread. Remove QueueRedraw() and merge its functionality in Invalidate(). Only use a DIRTY/CLEAN state to determine if something needs to be queued in the redraw channel. Use a channel for quitting instead of an atomic. Restructure some code functions to have a cleaner API. Use a for loop in the main thread and select from all channels. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Koni Marti <koni.marti@gmail.com> Tested-by: Maarten van Gompel <proycon@anaproy.nl>
* templates: add boolean flagsRobin Jarry2023-05-205-0/+69
| | | | | | | | | | | | | | | | | | Allow accessing email flags via boolean properties instead of having to rely on obscure regular expressions on (.Flags | join ""). With this patch, it is now possible to do this: [ui] index-columns = star:1,name<15%,reply:1,subject,size>=,date>= column-star = {{if .IsFlagged}}★{{end}} column-name = {{if eq .Role "sent"}}{{.To | names | join ", "}}{{else}}{{.From | names | join ", "}}{{end}} column-reply = {{if .IsReplied}}{{end}} column-subject = {{.ThreadPrefix}}{{.Subject}} column-size = {{if .HasAttachment}}📎 {{end}}{{humanReadable .Size}} column-date = {{.DateAutoFormat .Date.Local}} Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Koni Marti <koni.marti@gmail.com>
* templates: use template interface consistentlyKoni Marti2023-05-1610-73/+147
| | | | | | | | | | | | | | | Use the template interface consistently. Before, we have exported the state.TemplateData struct and used it in most places instead of the models.TemplateData interface. This lead to some inconsistencies, i.e. Role() has been defined on the exported struct but not on the interface. Unexport the state.TemplateData struct, add a DataSetter interface to set the data needed for the template data and call the Data() method which returns a models.TemplateData interface when the template data is needed. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Tim Culverhouse <tim@timculverhouse.com>