aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
Commit message (Collapse)AuthorAgeFilesLines
* viewer: use correct contextual config for no-filter messageRobin Jarry2023-09-271-1/+1
| | | | | | | | When no filter is configured for a part, use the correct account contextual ui config. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
* ui: enable showing of thread-contextTim Culverhouse2023-09-272-4/+11
| | | | | | | | | | | | | | | Add a UI config value to enable showing of "thread-context", similar to `notmuch show --entire-thread=true`. Add an associated style called "msglist_thread_context" which can be used to style such messages. Currently this feature is only supported by notmuch. It would be possible for maildir to implement as well, IMAP with gmail custom extensions, and JMAP. This patch merely implements the notmuch version and puts the groundwork in for handling these sorts of displays. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* terminal: draw even if underlying command has diedRobin Jarry2023-09-271-24/+11
| | | | | | | | | | | | | | | | | After the command running in the terminal has exited, the tcell-term buffer still contains the last status of its virtual tty. If a virtual terminal is visible, draw it even after its command has exited. Calling tcellterm.VT.Draw() does not interact with the underlying process at all, it only accesses the screen buffer. This should fix incomplete drawing of message parts when using a pager that exits after printing contents (e.g. `less -F`). Also, it should fix redrawing of such message part contents after switching tabs back and forth. Reported-by: Julio B <julio.bacel@gmail.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Julio B <julio.bacel@gmail.com>
* msgviewer: add styles for part selectorRobin Jarry2023-09-192-101/+19
| | | | | | | | | Allow styling the part selector mime type and (if any) attachment filename. Remove custom alignment code since now both can be differentiated easily with colors and/or attributes. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* binds: improve display of key sequencesRobin Jarry2023-09-191-1/+0
| | | | | | | | | | Do not replace all spaces by <space>, it makes the bindings completely unreadable. Only replace trailing and leading spaces with <space> since these are the only one that actually matter. The others are implicit and it improves the readability level by over 9000. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* compose: respect header ordering from text editorRobin Jarry2023-09-191-4/+3
| | | | | | | | When [compose].edit-headers=true, make sure to respect the order of headers as set in the text editor. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* compose: avoid panic when deleting the last headerRobin Jarry2023-09-191-24/+49
| | | | | | | | When removing the last header, the focusable list may be empty, and the focused index becomes invalid. Avoid out of bounds access. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* split: remove previous split from gridTim Culverhouse2023-09-181-0/+1
| | | | | | | | | | | | Remove the previous split from the account grid view. When adding a new child at an existing location, the content is appended to a slice instead of replacing any old values. The old content must be explicitly removed. Reported-by: inwit <inwit@sindominio.net> Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
* compose: add option for LF-only editorsMoritz Poldrack2023-09-181-9/+31
| | | | | | | | | | | | Some editors only support LF line endings. For these, standard compliant eml files are not an option. Add an option compose.lf-editor to translate the eml file to lf lineendings. Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Matěj Cepl <mcepl@cepl.eu>
* msgviewer: show attachment file names first if possibleVitaly Ovchinnikov2023-09-052-6/+99
| | | | | | | | | | | | | | | | | | | | Change the parts switcher so it displays the file names first (if any) and then the mime types. The mime types are aligned to the right to help the file names to be more visible. If there is no file name - the mime type is displayed on the left, as usual. The idea is that the file name (if present) is more important than the mime type. Especially when both file names and mime types are long - this quickly becomes a mess. If there is no space for both file name and mime, the mime type is truncated with ellipsis. If there is no space for mime at all - it is dropped completely. If then there is no space for the file name, it is also truncated with ellipsis. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* compose: delete empty headersRobin Jarry2023-09-051-2/+4
| | | | | | | | | | | | | | When [compose].edit-headers=true and emptying a header in the text editor (not deleting it, only deleting its contents), the operation is ignored and the header is preserved as-is. Delete the header after exiting the text editor if the header is empty or not present. Make sure not to add empty headers. Fixes: 11e5390fa0ac ("compose: implement embedded headers in editor") Reported-by: Inwit <inwit@sindominio.net> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* dirlist: fix capturing of dirlist vars when selecting directoryTim Culverhouse2023-08-302-26/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The directory selecting logic allows for a delay in issuing the command to the backend. This delay is part of a goroutine which is supposed to capture variables intended to be used in a callback to set the selected directory. The callback does not capture the variable properly, specifically the context and the "dirlist.selecting" value. This results in contexts not being cancelled properly and incorrect selection logic. The flow of the issue only occurs when the delay is sufficiently low: 1. The user scrolls rapidly through the directory list. Each time passing over a directory, dirlist.selecting is set to that directory and a context is created for this selection. 2. If the delay is low enough that the context was not cancelled before the Action was posted, the worker could actually open this directory. The captured context is actually referencing to the _current_ context of the dirlist, and so even if this OpenDirectory Action makes it to the worker, which might properly check to see if the context is cancelled, it will be referring always to the current context and not be cancelled. 3. When posting back the Done result, the callback is processed. dirlist.selecting and the context are no longer referring to the values used when this Action was made. The backend thinks it has opened Directory A, but the callback sets the dirlist.selected to Directory B 4. The account widget grabs the selected msgstore (Directory B, even though the backend thinks its A). Sort messages are called, and all sorts of things are sent to the backend which now is out of sync. 5. Eventually this all comes back into sync once the correct directory has churned it's way through the worker and back to the account. Move the callback into the dirlist.Update method to ensure proper capture of all variables involved. Only reference the values set in the message instead of those referring to the dirlist. This ensures that the worker and UI are always in agreement for which directory is selected. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com>
* postpone: change recall/postpone logic for custom foldersVitaly Ovchinnikov2023-08-301-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change `:recall -f` behavior so it remembers the source folder the message is taken from and the further `:postpone` call can save it back to that folder. Change the `:recall` tab closing behavior, so it no longer asks if the recalled message needs to be deleted. This is now done automatically. Add an optional `-t <folder>` parameter to `:postpone`, so the message can be saved in a different folder. Change `:postpone` behavior, so it checks if the message was force-recalled from a different folder, and then it saves the message there. The "breaking" change is made to the closing handler of the recalled message tab. There was a confirmation dialog that asked if the recalled message needs to be deleted. This is now removed and replaced with a pretty simple logic: if the recalled message is either sent or re-postponed - it is safe to delete the original. Otherwise (if the recalled message editing is discarded, any other reasons?) the message is left intact, there is no need to ask for deleting it. If the user don't need that message - they can delete it manually. Another "breaking" change to the same handler is that it always works this way regardless of the curently selected folder. There was an `if` that checked that, but as the recalled messages are now only deleted if they are re-sent or re-postponed, it seems that there is no need to check the current folder anymore. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: use email domain name in Message-IdAdnan Maolood2023-08-281-1/+23
| | | | | | | | | | | | | RFC 5322 recommends using a domain name on the right-hand side of the "@" in Message-Ids. Since the local host domain name cannot be obtained reliably, use the sender email domain name by default. Add a new configuration option to maintain the old behavior. Link: https://www.rfc-editor.org/rfc/rfc5322.html#section-3.6.4 Signed-off-by: Adnan Maolood <adnan@maolood.com> Acked-by: Robin Jarry <robin@jarry.cc>
* xdg: get rid of deprecated dependenciesRobin Jarry2023-08-272-30/+11
| | | | | | | | | | | github.com/mitchellh/go-homedir has not received any update since 2019. The last release of github.com/kyoh86/xdg was in 2020 and it has been marked as deprecated by its author. Replace these with internal functions. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
* wizard: improve welcome screenRobin Jarry2023-08-261-3/+5
| | | | | | | | | | The wizard now supports all protocols. Adapt welcome text accordingly. Display key bindings in a more consistent manner. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add sendmail supportRobin Jarry2023-08-261-2/+30
| | | | | | | | Allow users to configure sendmail as outgoing protocol. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add notmuch supportRobin Jarry2023-08-261-3/+53
| | | | | | | | Allow users configuring notmuch as email source. Try to determine configuration based on notmuch config commands. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add support for maildirRobin Jarry2023-08-261-5/+41
| | | | | | | | Allow users configuring aerc for maildir. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add jmap supportRobin Jarry2023-08-261-9/+42
| | | | | | | | | | | | | | Use DNS SRV discovery for JMAP along with the /.well-known/jmap URL path. Add sane defaults to accounts.conf. Also support JMAP as outgoing protocol. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tim Culverhouse <tim@timculverhouse.com> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add oauth & xoauth optionsRobin Jarry2023-08-261-1/+11
| | | | | | | | These may be needed for some users. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add imap cache-headers default settingRobin Jarry2023-08-261-3/+20
| | | | | | | | | | This seems like a sane default. Set it to true in accounts.conf. Add a note in the final screen to encourage users to review accounts.conf at their convenience. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: do not require full nameRobin Jarry2023-08-261-8/+7
| | | | | | | | Allow users to omit their full name. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: factorize ui layoutRobin Jarry2023-08-261-219/+156
| | | | | | | | | | Avoid code duplication. Use a struct to store all fields along with their respective labels. Generate a ui.Grid at once with the correct padding between the fields. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tim Culverhouse <tim@timculverhouse.com> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: better url generationRobin Jarry2023-08-261-44/+40
| | | | | | | | | Prepare for other protocols. Do not expect that there will be an username/password. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: add protocol & transport fieldsRobin Jarry2023-08-262-89/+152
| | | | | | | | | | | | | In preparation for other protocols, add a new "Protocol" field both in the source and outgoing sections. For now, there is only one source protocol and one outgoing protocol. Rename the "mode" fields to "transport". They will be reused later to include different authentication mechanisms. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: autofill improvementsRobin Jarry2023-08-261-18/+30
| | | | | | | | | | | | | | * Do not determine the IMAP server based on the email domain. It will most of the time be incorrect. * Only mirror the email address in usernames if they are unset. * Only mirror the IMAP username & password into their SMTP counterparts if these are unset. * Try to guess the SMTP server based on the IMAP server only if the former is empty. * Only display the password warning if the user did type a password. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: rename incoming to sourceRobin Jarry2023-08-261-138/+136
| | | | | | | | | | | | | | | | | | | Rename stuff in preparation of support for other protocols. Match the terminology from accounts.conf. This patch is more or less the result of the following command (with some manual tweaks and cleanups): sed -i -r -e 's/_INCOMING/_SOURCE/g' \ -e 's/IMAP_//g' \ -e 's/SMTP_//g' \ -e 's/([\.[:space:]])imap/\1source/g' \ -e 's/([\.[:space:]])smtp/\1outgoing/g' \ widgets/account-wizard.go Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: allow setting special copy-to folderRobin Jarry2023-08-261-16/+7
| | | | | | | | | | | Instead of a boolean, allow specifying the exact folder where to copy sent messages. Depending on the IMAP provider, the folders may be different. Instead of putting a default value which may not be correct, leave it empty. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: fix typo in validationRobin Jarry2023-08-261-1/+1
| | | | | | | | Require that smtpServer is not empty. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* wizard: close open fileRobin Jarry2023-08-261-0/+1
| | | | | | | | Avoid leaking open file descriptors. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io> Tested-by: Tim Culverhouse <tim@timculverhouse.com>
* dirlist: apply unread style on top of recent styleKeenan Gugeler2023-08-251-4/+4
| | | | | | | | | In the documentation, we specify that the `dirlist_recent` style applies on top of the `dirlist_unread` style, but the switch statement we had only applied one of the two. Signed-off-by: Keenan Gugeler <me@kgugeler.ca> Acked-by: Robin Jarry <robin@jarry.cc>
* review: don't replace space escapesKeenan Gugeler2023-08-251-1/+0
| | | | | | | | | | Currently we replace `<space>` in the output column in the review pane. This causes the default actions `:attach<space>` and `:detach<space>` to not be correctly named, and causes a mismatch between `binds.conf` and the displayed bindings. Signed-off-by: Keenan Gugeler <me@kgugeler.ca> Acked-by: Robin Jarry <robin@jarry.cc>
* review: sort unknown review commandsKeenan Gugeler2023-08-251-0/+7
| | | | | | | | | | Currently, the unknown commands in the review window appear in an undefined order, since `go-ini` gives us a `map`. Instead, we should sort them by inputs, otherwise the ordering can get confusing between restarts of aerc. Signed-off-by: Keenan Gugeler <me@kgugeler.ca> Acked-by: Robin Jarry <robin@jarry.cc>
* colorize: only emit osc8 if [general].enable-osc8=trueRobin Jarry2023-08-241-0/+3
| | | | | | | | | | | | | | | | Some old versions of less do not handle OSC 8 escape sequences. Even if aerc's embedded terminal is configured to handle them, less corrupts them making the output unreadable. 8;id=colorize-1;https://foobar.com/stuff/https://foobar.com/stuff/ When [general].enable-osc8 is set to false (its default value) do not attempt to generate OSC 8 sequences with the built-in colorize filter. These sequences would be stripped out anyway. Reported-by: Omar Polo <op@omarpolo.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Kirill Chibisov <contact@kchibisov.com>
* terminal: avoid races between close and drawRobin Jarry2023-08-111-27/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix races where a goroutine calls Terminal.Draw and another one calls Terminal.Close or Terminal.Destroy. The closing thread will eventually set term.vterm to nil just before the drawing thread calls term.vterm.Draw(), causing this crash: Error: runtime error: invalid memory address or nil pointer dereference goroutine 1 [running]: panic({0xb09140, 0x10b5860}) runtime/panic.go:890 +0x263 git.sr.ht/~rockorager/tcell-term.(*VT).Draw(0x0) git.sr.ht/~rockorager/tcell-term@v0.8.0/vt.go:424 +0x50 git.sr.ht/~rjarry/aerc/widgets.(*Terminal).draw(0xc001c658b0) git.sr.ht/~rjarry/aerc/widgets/terminal.go:116 +0x29 git.sr.ht/~rjarry/aerc/widgets.(*Terminal).Draw(0xc001c658b0, 0xc002b08150) git.sr.ht/~rjarry/aerc/widgets/terminal.go:108 +0x1b4 git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc001d0c360, 0xc0008ddb30) git.sr.ht/~rjarry/aerc/lib/ui/grid.go:126 +0x225 git.sr.ht/~rjarry/aerc/widgets.(*Composer).Draw(0xc001c13180, 0xc0008ddb30) git.sr.ht/~rjarry/aerc/widgets/compose.go:747 +0x8f git.sr.ht/~rjarry/aerc/lib/ui.(*TabContent).Draw(0xc0003cc5b0, 0xc0008ddb30) git.sr.ht/~rjarry/aerc/lib/ui/tab.go:468 +0x1f4 git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc0001b2900, 0xc000037050) git.sr.ht/~rjarry/aerc/lib/ui/grid.go:126 +0x225 git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Draw(0xc000000180, 0xc000037050) git.sr.ht/~rjarry/aerc/widgets/aerc.go:193 +0x209 git.sr.ht/~rjarry/aerc/lib/ui.(*UI).Render(0xc000414040) git.sr.ht/~rjarry/aerc/lib/ui/ui.go:105 +0x62 main.main() git.sr.ht/~rjarry/aerc/main.go:279 +0xbac Use an atomic to determine if the terminal is closed or not. Never set vterm to nil (it is not necessary). Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Koni Marti <koni.marti@gmail.com> Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
* style: add msglist_gutter and msglist_pill to configKonstantin Shelekhin2023-08-111-2/+3
| | | | | | | | | | Allow a user to change the default style of the message list scrollbar. There is no easy way to set the default style for an object directly in code, so I've updated every built-in theme to preserve the existing style. Signed-off-by: Konstantin Shelekhin <k.shelekhin@ftml.net> Acked-by: Robin Jarry <robin@jarry.cc>
* account: fix contextual sortKoni Marti2023-08-041-4/+11
| | | | | | | | | | | | Fix contextual sort. Pass a folder-specific sort criteria to the message store when it is created. Before, the message store would receive the sort criteria from the UI config of the currently selected directory (if any was selected at all). Fixes: https://todo.sr.ht/~rjarry/aerc/121 Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* filters: put libexec/filters dirs before default PATHRobin Jarry2023-08-041-1/+4
| | | | | | | | | | | | | | | | | | Some distro packages install binaries in /usr/bin that clash with some of aerc's builtin filters (for example, colorize and wrap). The issue is that aerc filters dir (usually /usr/libexec/aerc/filters) is *after* /usr/bin, making the builtin filters not accessible when these distro packages are installed. Since this mostly concerns colorize and wrap, move $LIBEXEC/aerc/filters at the beginning of the exec PATH when running filter commands. If the intent is **really** to execute /usr/bin/colorize or /usr/bin/html, then their absolute paths should be used. Link: https://archlinux.org/packages/extra/x86_64/talkfilters/ Link: https://tracker.debian.org/pkg/colorize Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io>
* hooks: add account and folder to mail-received envRobin Jarry2023-08-041-0/+2
| | | | | | | | Add AERC_ACCOUNT and AERC_FOLDER to the environment of the mail-received hook command. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tristan Partin <tristan@partin.io>
* msglist: fetch headers even when not focusedRobin Jarry2023-08-041-0/+2
| | | | | | | | | | | | | | Do not rely on MessageList.Draw only to fetch missing headers. In Draw, report the current scroll offset and length to the message store and use them to determine if a new message UID should be candidate for fetching headers. This allows the mail-received hook to work even when the message list is not focused. Fixes: https://todo.sr.ht/~rjarry/aerc/147 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Tristan Partin <tristan@partin.io>
* templates: attach directly from templatesKoni Marti2023-08-031-1/+1
| | | | | | | | | | | | | | | | | | Attach a file from templates. Add a split template function. {{- .Attach "LICENSE" -}} or {{range (exec "find ./doc -type f -name *.scd" "" | split "\n") -}} {{with . }} {{- $.Attach . -}} {{- end}} {{- end}} Fixes: https://todo.sr.ht/~rjarry/aerc/109 Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* wizard: display warning when focus is lostKoni Marti2023-08-031-16/+13
| | | | | | | | | | | | | | | Display the warning that the password is stored in plaintext after the focus of the password input field is lost. The current behavior of showing the warning after the first character is entered is ackward and confusing. It also eliminates the need to debounce the warning when a password is pasted. Reported-by: Brad <super1337@posteo.net> Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* composer: reopen the email file when editor is closedRobin Jarry2023-08-021-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Some text editors save changes in a temp file before moving it over to the destination instead of rewriting the original file in place. This protects against all sorts of corruption, like writing partial files in disk-full scenarios for example. When this is the case, aerc's open file descriptor points to a different file, one that was never written to by the editor. For text editors that *do* overwrite the file (i.e. the same filesystem inode id), depending on timing, kernel version, operating system, filesystem options, caching, etc. Reading from aerc's file descriptor after the text editor has modified the same file on disk may not return the updated data. This behaviour can be easily observed with the following C program: #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(void) { int fd; ssize_t n; char buf[BUFSIZ]; unlink("test.txt"); fd = open("test.txt", O_CREAT|O_RDWR, 0644); write(fd, "Bonjour\n", strlen("Bonjour\n")); fsync(fd); lseek(fd, 0, SEEK_SET); n = read(fd, buf, sizeof(buf)); buf[n] = '\0'; printf("before: %s\n", buf); system("vim test.txt"); lseek(fd, 0, SEEK_SET); n = read(fd, buf, sizeof(buf)); buf[n] = '\0'; printf("after: %s\n", buf); return 0; } Most of the time, before and after texts will be identical even if you modified the test.txt file contents in the editor. The only reliable way to ensure to read the latest contents from the disk is to close and reopen the file after the text editor has exited. Do exactly that in termClosed before anything else. Fixes: 801caf812377 ("compose: factorize body read in a method") Fixes: https://todo.sr.ht/~rjarry/aerc/184 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Ronald Evers <ronald@ch10.nl>
* compose: fix panic when adding empty header with uppercase lettersRobin Jarry2023-07-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Running `:header Hello` causes a panic: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xa09328] goroutine 1 [running]: git.sr.ht/~rjarry/aerc/widgets.(*Composer).AddEditor git.sr.ht/~rjarry/aerc/widgets/compose.go:1302 git.sr.ht/~rjarry/aerc/commands/compose.Header.Execute git.sr.ht/~rjarry/aerc/commands/compose/header.go:83 git.sr.ht/~rjarry/aerc/commands.(*Commands).ExecuteCommand git.sr.ht/~rjarry/aerc/commands/commands.go:133 main.execCommand git.sr.ht/~rjarry/aerc/main.go:71 This is because addEditor() converts the header name to lowercase before updating the c.editors map. After this, c.editors[header] (with `header` containing uppercase letters) returns nil causes a nil pointer access. This is a side effect of splitting AddEditor into public and private functions. focusEditor also converts the argument to lowercase. Fix and simplify this. Only call focusEditor with whatever the user provided. Fixes: 11e5390fa0ac ("compose: implement embedded headers in editor") Reported-by: Koni Marti <koni.marti@gmail.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Koni Marti <koni.marti@gmail.com>
* compose: allow removing headersRobin Jarry2023-07-311-0/+13
| | | | | | | | Allow removing headers from the compose window when edit-headers=false (the default) with :header -d <name>. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Koni Marti <koni.marti@gmail.com>
* compose: only add signature if missingRobin Jarry2023-07-171-1/+21
| | | | | | | | | Allow putting signatures in the templates. Do not add a duplicate signature during :recall and :recover. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Tested-by: Koni Marti <koni.marti@gmail.com>
* compose: allow changing edit-headers on the flyRobin Jarry2023-07-172-13/+18
| | | | | | | | | Add -e|-E flags to all compose commands to allow switching between edit-headers = true/false without restarting aerc. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Tested-by: Koni Marti <koni.marti@gmail.com>
* compose: implement embedded headers in editorKoni Marti2023-07-171-51/+235
| | | | | | | | | Implement embedded header mode in the composer widget. To activate it, use set [compose].edit-headers=true in aerc.conf. Signed-off-by: Koni Marti <koni.marti@gmail.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* compose: always use cr-lf line endingsRobin Jarry2023-07-171-16/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | .eml files are universally formatted with DOS line-endings, per RFC5322. Make sure to replace line endings with CRLF before sending the message. Always present CRLF files to the text editor. If the editor forces LF line endings, convert them back to CRLF. Text editors (vim and nvim at least) detect the .eml extension and force dos line endings. Emacs seems not to care and will use whatever line endings are present in the file. Kakoune seems to force unix line endings and does not care about the contents of the file. Notes: * add explicit calls to Truncate() to ensure any trailing content is stripped from the file when overwriting with shorter content. * NewCRLFReader cannot be reused since we need buffered and unbuffered versions of it (for GetBody and {Set,append}Contents, respectively). Link: https://datatracker.ietf.org/doc/html/rfc5322 Link: https://github.com/vim/vim/blob/v8.2.3583/runtime/ftplugin/mail.vim#L29-L35 Link: https://github.com/neovim/neovim/blob/v0.6.0/runtime/ftplugin/mail.vim#L29-L35 Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Tested-by: Koni Marti <koni.marti@gmail.com>