157 Commits

Author SHA1 Message Date
Robin Jarry
3273f8071d commands: add settle
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-09 09:18:59 +02:00
Robin Jarry
767287718e workers: rework cancellable
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-09 09:18:18 +02:00
Robin Jarry
0211c9bf23 reload: fix crash when reloading via IPC
When reloading the configuration with :reload, global variables in the
config package are reset to their startup values and then, the config is
parsed from disk. While the parsing is done, these variables are
temporarily in an inconsistent and possibly invalid state.

When commands are executed interactively from aerc, they are handled by
the main goroutine which also deals with UI rendering. No UI render will
be done while :reload is in progress.

However, the IPC socket handler runs in an independent goroutine. This
has the unfortunate side effect to let the UI goroutine to run while
config parsing is in progress and causes crashes:

[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6bb142]

goroutine 1 [running]:
git.sr.ht/~rjarry/aerc/lib/log.PanicHandler()
	lib/log/panic-logger.go:51 +0x6cf
panic({0xc1d960?, 0x134a6e0?})
	/usr/lib/go/src/runtime/panic.go:783 +0x132
git.sr.ht/~rjarry/aerc/config.(*StyleConf).getStyle(0xc00038b908?, 0x4206b7?)
	config/style.go:386 +0x42
git.sr.ht/~rjarry/aerc/config.StyleSet.Get({0x0, 0x0, 0x0, {0x0, 0x0, 0x0}}, 0x421a65?, 0x0)
	config/style.go:408 +0x8b
git.sr.ht/~rjarry/aerc/config.(*UIConfig).GetStyle(...)
	config/ui.go:379
git.sr.ht/~rjarry/aerc/lib/ui.(*TabStrip).Draw(0xc000314700, 0xc000192230)
	lib/ui/tab.go:378 +0x15b
git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc000186fc0, 0xc0002c25f0)
	lib/ui/grid.go:126 +0x28e
git.sr.ht/~rjarry/aerc/app.(*Aerc).Draw(0x14b9f00, 0xc0002c25f0)
	app/aerc.go:192 +0x1fe
git.sr.ht/~rjarry/aerc/lib/ui.Render()
	lib/ui/ui.go:155 +0x16b
main.main()
	main.go:310 +0x997

Make the reload operation safe by changing how config objects are
exposed and updated. Change all objects to be atomic pointers. Expose
public functions to access their value atomically. Only update their
value after a complete and successful config parse. This way the UI
thread will always have access to a valid configuration.

NB: The account configuration is not included in this change since it
cannot be reloaded.

Fixes: https://todo.sr.ht/~rjarry/aerc/319
Reported-by: Anachron <gith@cron.world>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-09-08 12:19:51 +02:00
Robin Jarry
fcf59fecb0 app: improve hook debug logs
Add extra debug logs.

Co-authored-by: Simon Martin <simon@nasilyan.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-08-28 10:19:57 +02:00
Karel Balej
bf678f18d0 app: support color scheme change notifications
Some applications may request being notified of changes to the color
scheme of their host terminal so that they could redraw themselves
appropriately. Pass such notifications provided by Vaxis to virtual
terminal widgets that may be open inside aerc to facilitate these
notifications for the applications running in them.

Cc: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-28 09:58:16 +02:00
Moritz Poldrack
ef2516a992 account-wizard: show correct configuration path
The account-wizard only shows the default path for the configuration and
does not account for a modified XDG_CONFIG_HOME. Dynamically generate
the message to embed the correct path.

Changelog-fixed: The account wizard now always shows the correct path
 for the account configuration.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-28 09:56:02 +02:00
Moritz Poldrack
cba509b4da msgviewer: use three dots to indicate an ongoing process
During Review of another patch, this jumped at me and just looked wrong.
Change it to show three dots.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Reviewed-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-28 09:54:44 +02:00
Robin Jarry
abe5bb884b viewer: prevent crash when headers are nil
Prevent the following error from happening:

Error: runtime error: invalid memory address or nil pointer dereference

panic({0x11206c0?, 0x18dd700?})
	runtime/panic.go:792 +0x132
git.sr.ht/~rjarry/aerc/lib/auth.New.CreateParser.func1(0x0, {0x0, 0x0, 0x0})
	                                               ^^^
	git.sr.ht/~rjarry/aerc/lib/auth/auth.go:77 +0xdb
git.sr.ht/~rjarry/aerc/app.NewMessageViewer.func2(...)
	git.sr.ht/~rjarry/aerc/app/msgviewer.go:93 +0x517
git.sr.ht/~rjarry/aerc/app.HeaderLayout.grid(...)
	git.sr.ht/~rjarry/aerc/app/headerlayout.go:39 +0x19e
git.sr.ht/~rjarry/aerc/app.NewMessageViewer(...)
	git.sr.ht/~rjarry/aerc/app/msgviewer.go:72 +0x185
git.sr.ht/~rjarry/aerc/commands/account.ViewMessage.Execute.func1(...)
	git.sr.ht/~rjarry/aerc/commands/account/view.go:68 +0x95
git.sr.ht/~rjarry/aerc/lib.NewMessageStoreView.func1(...)
	git.sr.ht/~rjarry/aerc/lib/messageview.go:80
git.sr.ht/~rjarry/aerc/lib.NewMessageStoreView(...)
	git.sr.ht/~rjarry/aerc/lib/messageview.go:127 +0x3e5
git.sr.ht/~rjarry/aerc/commands/account.ViewMessage.Execute(...)
	git.sr.ht/~rjarry/aerc/commands/account/view.go:57 +0x3c5
git.sr.ht/~rjarry/aerc/commands.ExecuteCommand(...)
	git.sr.ht/~rjarry/aerc/commands/commands.go:218 +0x73d
main.execCommand(...)
	git.sr.ht/~rjarry/aerc/main.go:45 +0x69
git.sr.ht/~rjarry/aerc/app.(*Aerc).BeginExCommand.func1(...)
	git.sr.ht/~rjarry/aerc/app/aerc.go:645 +0x5e
git.sr.ht/~rjarry/aerc/app.(*ExLine).Event(...)
	git.sr.ht/~rjarry/aerc/app/exline.go:92 +0xb82
git.sr.ht/~rjarry/aerc/app.(*Aerc).Event(...)
	git.sr.ht/~rjarry/aerc/app/aerc.go:344 +0x87e
git.sr.ht/~rjarry/aerc/app.(*Aerc).simulate(...)
	git.sr.ht/~rjarry/aerc/app/aerc.go:315 +0x2ae
git.sr.ht/~rjarry/aerc/app.(*Aerc).Event(...)
	git.sr.ht/~rjarry/aerc/app/aerc.go:377 +0xc45
git.sr.ht/~rjarry/aerc/lib/ui.HandleEvent(...)
	git.sr.ht/~rjarry/aerc/lib/ui/ui.go:188 +0x5e9
main.main()
	git.sr.ht/~rjarry/aerc/main.go:298 +0x11b4

Do not try to build an auth header set if the message headers are nil.

Reported-by: Moritz Poldrack <moritz@poldrack.dev>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Simon Martin <simon@nasilyan.com>
2025-08-05 11:52:47 +02:00
Moritz Poldrack
fc5b6896ff chore: switch to using stdlib helper functions
Go has evolved significantly over the years and has introduced some
handy helper functions that make the code easier to read.

Use helper functions like slices.Contains, map.Copy, and
strings.CutPrefix, when appropriate.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-04 12:47:05 +02:00
Karel Balej
7ec71db2d6 app: handle Vaxis FocusIn and FocusOut events
Pass the focus changes to the content of the currently active tab if it
wants to be notified of them.

Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-08-04 12:03:46 +02:00
Terrance
c9e3c1e919 app: expose toggle-headers command for open split
This adds support for the :toggle-headers command from the message list,
which will flip the config value and refresh the split if open.

Signed-off-by: Terrance <git@terrance.allofti.me>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-20 09:01:57 +02:00
Simon Martin
2b6aeb5446 ui: allow message split viewer to automatically mark messages as read
Users can specify that messages should be marked as read when they're
viewed, but not when they're previewed in a message list split.

This patch makes it possible via two configuration knobs: one stating
whether the split message viewer should mark messages as read (off by
default), and one specifying the delay after which to do it.

Fixes: https://todo.sr.ht/~rjarry/aerc/126
Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-11 10:12:16 +02:00
Simon Martin
4cfc71b1be imap: improve seen count management
While investigating a reported slowness when marking messages (un)read,
I noticed an issue with commit 7cb8e0e7ce: it systematically updates
the Seen count using the unsolicited message's status. This is wrong
because we might receive that message long after we updated things on
our end, or at the next action on the message (e.g. opening it).

We need to compare the status reported by the server with ours, and only
if they differ update the counter with what the server states.

Doing so also allows to fix the reported slowdown by reflecting Seen
flag updates right after an explicit :[un]read command, instead of
deferring to the confirmation by the IMAP server, and paying the
(unnecessary) latency of a round-trip. It is safe because we will only
do it after a successful UidStore call, hence confirmation from the IMAP
server of the flag change.

Fixes: 7cb8e0e7ce ("imap: properly handle out-of-band Unseen flag updates")
Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3CDACPBQ04UHUF.30CJJ4QKJDYLY@zoho.com%3E
Reported-by: skejg <grolleman@zoho.com>
Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-11 10:11:16 +02:00
Simon Martin
0cd1e6c2e2 app: fix crash updating split view
This fixes a crash that I have encountered recently, and whose report
(https://paste.sr.ht/~simartin/69a18952e28116cb07e734eeb27248d45e61cbea)
pretty clearly shows that we somehow end up with a nil BodyStructure().

I have unfortunately not been able to reproduce, but we surely should
protect ourselves against this and not crash.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-06-02 11:58:47 +02:00
Simon Martin
68606ec946 dirlist: avoid unnecessary work upon next/prev-folder 0
I noticed that navigating to the 0-th next/previous folder is far from a
no-op while it should be: it triggers an open of the current folder,
which in turn does a mail listing, etc.

This patch makes NextPrevDelta return early if delta is 0.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-21 18:30:52 +02:00
Simon Martin
6c33d979e7 menu: small usability improvements
Following up on the great discussion on IRC and in patch #59448, improve
the usability of the ":menu" command, namely:

- Add the possibility to override the dialog title, that defaults to the
  actual command, for instance "-cf -a ...".

- Select the first matching row, so that the user can simply type enter
  if it actually matches what they're looking for. In passing, also fix
  a bug whereby if the user had selected a matching row and then updates
  the filter so that that row does *not* match anymore (e.g. the filter
  was box, matching INBOX, and is updated to boxnono), the box would
  still remember that row's value (and give it if the user typed Enter,
  even though nothing was matching the filter).

Make "<C-g> = :menu -d -t "Open folder" :cf<Enter>" behave exactly like
Sublime or VS Code, and improve aerc usability a lot for mailboxes with
many folders.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-21 18:29:00 +02:00
Simon Martin
3381ab129d app: robustify unread counter updates upon message deletion
I recently added a call to updateDirCounts for deletions, and that
function does not check the account store against nil before
dereferencing it. It could be nil for example in case of a disconnection
with the IMAP server during a large deletion, and aerc crashes.

This makes updateDirCounts properly handle cases where the store is nil.

Fixes: b099981a ("update folder counters upon message deletion")
Reported-by: Andreas Radke <andreas.radke@mailbox.org>
Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-21 18:28:46 +02:00
Nicole Patricia Mazzuca
4711d86179 account: allow globs in folders-sort
In a reasonably folder-heavy workflow, folders-sort quickly becomes
quite unwieldy. This change allows users to sort using a pattern syntax,
where folders that all match the pattern are sorted alphabetically.

Given the folders:
- `a`
- `b`
- `c/a`
- `c/b`

and the configuration:

```ini
folders-sort = b,c/*,a
```

one will get the following output in aerc:

- `b`
- `c/a`
- `c/b`
- `a`

This is an RFC because it needs docs changes and the like; I just wanted
to see if people liked it before going ahead with that.

Changelog-changed: The `<account>.folders-sort` now supports patterns
 for folder names.
Signed-off-by: Nicole Patricia Mazzuca <nicole@streganil.no>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-07 17:13:23 +02:00
Antonin Godard
caf717fc30 commands: add -u option to {next,prev}-folder
Add the "-u" option to the :next-folder and :prev-folder commands, used
to jump to the next or the previous folder that contains at least one
unseen email.

For directory trees, we have to factor in that the number of currently
visible folders may be lower than the total number of folders, so count
that in visibleDirsCount().

I find the following bindings useful:

  <A-j> = :next-folder -u<Enter>
  <A-k> = :prev-folder -u<Enter>

It allows jumping between folders efficiently while keeping the ability
to jump to the next or previous folder normally.

References: https://todo.sr.ht/~rjarry/aerc/168
Changelog-added: Add the -u option to :next-folder and :prev-folder
 commands to cycle between folders that contain unseen messages.
Signed-off-by: Antonin Godard <antonin@godard.cc>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-05 14:26:52 +02:00
Karel Balej
5919e9dfda term: allow setting custom title for the terminal tab
Add a template for the terminal tab title and define two
terminal-specific properties: Title which expands to whatever the
underlying application requests via OSC and defaults to the command name
and Bell which is a boolean indicating whether the application has
emitted bell, the flag is cleared when the corresponding tab gains focus
and is not set at all if it currently has it.

This can among other things be used to highlight the terminal tab when
the underlying process prints the bell, such as by setting the template
as such:

	tab-title-terminal={{if .Bell}}[BELL] {{end}}{{.Title}}

Implements: https://todo.sr.ht/~rjarry/aerc/138
Changelog-added: A tab-title-terminal setting for customizing the
 title of tabs in which the terminal widget is run.
Requested-by: Drew DeVault <drew@ddevault.org>
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-05-05 13:49:04 +02:00
Simon Martin
7cb8e0e7ce imap: properly handle out-of-band Unseen flag updates
I noticed that the fix I made via b576ab28 (and the general idea to get
rid of materialized RUE counters) does not work, because we're extremely
unlikely to have all the messages' flags in memory. So the patch worked
"by chance" when updating messages that are in the active message list
(e.g. their headers are already fetched) but not for "out of view"
messages.

This alternative patch "just" captures unsolicited MessageUpdate
messages from the server, and updates the Unseen counter according to
the status reported by the server for that message. This allows to
synchronize our view with the server's.

Fixes: b576ab28 ("properly update UI upon message (un)read in [...]")
Fixes: https://todo.sr.ht/~rjarry/aerc/307
Signed-off-by: Simon Martin <simon@nasilyan.com>
Tested-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-07 10:51:38 +02:00
Karel Balej
f0ec95d7dd account: allow indicating new messages in the tab title
Add a flag to indicate whether the account has received new messages
since it last had focus and allow its use in the templates.

Changelog-added: A `.HasNew` flag indicating whether the account has
 received new messages to be used in the templates.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-07 10:51:14 +02:00
Robin Jarry
0ca8087ec9 treewide: replace interface{} with any
Since go 1.18, interface{} can be replaced with any.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Karel Balej <balejk@matfyz.cz>
2025-04-07 10:51:05 +02:00
Simon Martin
87a3b42daa imap: partially revert two recent patches
Karel reported weird behaviour with RUE counters that are linked to two
of my recent patches:

- 96ccb183fb is simply wrong
- c9a57f76bf is a bit too eager at
  trusting the message store to recompute counters

This patch addresses those issues, and seems to address all the reported
issues at least on my mailboxes.

Fixes: 96ccb183fb ("imap: remove spurious checkmail when changing directories")
Fixes: c9a57f76bf ("msgstore: properly rebuild message store upon reconnection")
Signed-off-by: Simon Martin <simon@nasilyan.com>
Tested-by: Karel Balej <balejk@matfyz.cz>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-04-02 17:33:48 +02:00
Simon Martin
c9a57f76bf msgstore: properly rebuild message store upon reconnection
I noticed another status synchronization issue between aerc and the IMAP
server when multiple clients are involved *and* the computer running
aerc hibernates. I acknowledge it's probably not very frequent but
that's my day to day ;-)

The scenario is as follows:
- aerc sees new unread emails, and renders them properly
- The computer running aerc goes to sleep
- Those emails get read via another client
- The computer running aerc wakes up, and aerc reconnects to the IMAP
  server and creates a new session.
- aerc does NOT redraw the message list (because no other mail was
  received while it was asleep) and from there on
   - The unread messages remain bold
   - Explicitly marking them read does not do anything because this
     involves a call to the server that already knows the message is
     read, and does not send back a MessageUpdate (that aerc usually
     reacts to to "unbold" the message)

This patch fixes this issue by making sure that we clear the directory
list's message store upon disconnection from the backend, and
recomputing the RUE counts from memory when processing a
types.DirectoryContents, via new AccountView.refreshDirCounts function.
It also leverages this function in the fix I made earlier via
https://lists.sr.ht/~rjarry/aerc-devel/patches/58306, and protects from
showing negative counters in the UI, just in case.

This function is pretty cheap since it's working on memory (we're well
below the millisecond on my largish mailbox - see
https://paste.sr.ht/~simartin/124a5fa4568a4ed8cb6e639c62bb01b2d6803588),
and given the number of synchronization issues I'm meeting with those
counters, my aim is to leverage it more in the future, and ideally get
rid of the RUE counts in models.Directory, and the dance we're doing to
try to keep them up-to-date.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Tested-by: Julio B <julio.bacel@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-31 18:55:30 +02:00
inwit
a6220d025a tag: allow to toggle tags
So far, the :tag command in the notmuch and jmap workers allows adding a
tag (by prefixing it with '+') and removing it (by prefixing it with
'-'). Add a new functionality to this command, allowing it to toggle a
tag by prefixing it with '!'.

Fixes: https://todo.sr.ht/~rjarry/aerc/292
Changelog-added: It is now possible to toggle notmuch and JMAP tags.
Signed-off-by: inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 22:10:58 +02:00
Simon Martin
b576ab281d imap: properly update UI upon message (un)read in another client
I access my personal mailbox from at least 3 different clients, and have
noticed that aerc only half handles the read/unread actions made from
another client on messages in the currently selected directory. While
the message list is properly updated, the unread count is not, and I end
up again looking for unread messages that don't exist :-)

The problem is that in such scenarii, aerc receives a MessageUpdate
message from the IMAP server, and if it already has a message with the
same UID in its message store, happily replaces it... without looking at
the Seen status, that is materialized outside of the message table.

This patch detects when the Seen status changes, and updates the UI
accordingly.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 21:32:16 +02:00
Simon Martin
3eb0046dde foldermap: map directory in Messages{Moved,Copied} and RemoveDirectory
When moving an unread message from current directory C to directory D,
the unseen count for C is properly decremented. However the one for D is
not consistently handled:

- If D is not folder-mapped, it's incremented, as expected.
- If D is folder-mapped, it's unchanged, a clear bug.

The problem is that the folderMapper.PostMessage is not intercepting and
de-mapping three commands that manipulate directory names.

This patch handles all them (I grepped for all PostMessage calls and I
think I got all the missing ones). It also adds an error log to
AccountView.updateDirCounts in case it processes a message that
references an unknown directory, a likely folder mapping bug.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-30 21:31:28 +02:00
Simon Martin
b099981adb app: update folder counters upon message deletion
I noticed that when deleting an unread email from the current folder (or
moving it to another folder), the "visual unread count" is not
decremented (and later on I'm desperately looking for the mysterious
unread mail that does not exist anymore :-)).

This patch adds a parameter to AccountView.updateDirCounts stating
whether the caller reacts to a deletion, and makes sure to call it when
processing a MessagesDeleted message.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-20 10:13:36 +01:00
Simon Martin
3d6d5e5c09 app: add missing account name in trace log
While investigating IMAP interactions, I noticed that the "Listing
mailboxes..." trace does not mention the account we're working on, while
we have the information in our hands. This patch simply adds it.

Signed-off-by: Simon Martin <simon@nasilyan.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-03-19 00:28:47 +01:00
Robin Jarry
03777bec28 viewer: disable passthrough mode on pager exit
To avoid accidentally closing the pager while the passthrough mode is
enabled (and therefore all key presses go to /dev/null), make sure to
exit the passthrough mode when the pager exits.

Also, to make the user experience more pleasant, exit the passthrough
mode upon pressing the <enter> key in the pager virtual terminal. This
should match the workflow where the users press "/" to start searching
in the pager, and press enter to validate their search.

Move the toggling of passthrough mode in a global function. Since that
setting is global to all accounts, make sure to update all the status
lines. Reuse that function for the :toggle-key-passthrough command and
when exiting the message viewer or pressing enter.

Reported-by: Jonathan Dowland <jon@dow.land>
Signed-off-by: Robin Jarry <robin@jarry.cc>
2025-03-06 09:59:32 +01:00
Moritz Poldrack
1f87e219dc wizard: add a spinner
Add a little spinner to inform the user that processes running in the
background and have not experienced a lockup.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:28 +01:00
Moritz Poldrack
9dc8e98b1b wizard: add new autodiscovery system
Add the new, more extensive configuration detection system to the
wizard. This replaces the older system doing only SRV discovery.

Changelog-added: More extensive automatic configuration when using
 `:new-accoount`.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-02-14 13:50:27 +01:00
Karel Balej
02324e9d9c lib: disallow < in URLs when parsing HTML
Make sure that links placed verbatim inside HTML elements' bodies are
not parsed along with adjacent HTML tags as illustrated in the new test
case.

Also change the existing code to use the idiomatic Go way to get a
set-like functionality.

Changelog-fixed: Parsed links in HTML message parts now do not include
 trailing HTML tags.
Signed-off-by: Karel Balej <balejk@matfyz.cz>
Tested-by: Jakub Růžička <jakub.ruzicka@matfyz.cz>
2025-02-04 15:18:01 +01:00
Robin Jarry
d2ff2c3c10 compose: group aliased bindings on review screen
Aliased bindings were grouped before and there was no good reason not to
do so.

Only group aliased bindings if they don't have any annotation.

Fixes: 928e5ae026 ("compose: only show default annotations if absent from config")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Skejg <grolleman@zoho.com>
2025-01-24 09:28:03 +01:00
Robin Jarry
1203f92440 compose: only hide bindings explicitly identified
My boolean fu was too weak. Even if default bindings annotations are
removed, they will be forcibly restored.

I was made aware that this behaviour was preferable compared to simply
make them disappear without warning.

Add a special "-" annotation to explicitly exclude bindings from the
review screen.

If a binding has no annotation at all, still display it without
annotation, just with its command.

Fixes: 928e5ae026 ("compose: only show default annotations if absent from config")
Changelog-changed: It is now possible to explicitly hide key bindings
 from the compose review screen by using a special ` # -` annotation.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Skejg <grolleman@zoho.com>
2025-01-24 09:27:53 +01:00
Robin Jarry
928e5ae026 compose: only show default annotations if absent from config
Currently, it is impossible to "hide" bindings presented on the review
screen even if removing the annotations from binds.conf.

If the configuration contains any annotated bindings, completely ignore
all of the default annotations.

Only display bindings from the config that are both present and
annotated.

Fixes: 64502d9e8b ("compose: show annotations on the review screen")
Changelog-changed: Key bindings available on the compose review screen
 are now only displayed if they are annotated with a comment. If
 no binding is annotated in `[compose::review]`, then the default
 annotations will be used as a fallback to avoid displaying a blank
 screen.
Reported-by: Skejg <grolleman@zoho.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2025-01-23 22:32:42 +01:00
Robin Jarry
297795cce6 binds: preserve order from the config file
Parse binds.conf and fill in the bindings list preserving the order as
it is in the file.

Disable sorting of the review commands as they should now be displayed
in their original order.

Changelog-changed: Key bindings in the compose review screen
 are now displayed in the order in which they are defined in the
 `[compose::review]` section of `binds.conf`.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2025-01-23 22:32:42 +01:00
Robin Jarry
4e545d45fa treewide: fix English spelling
Use codespell to fix typos in code, comments and man pages.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: inwit <inwit@sindominio.net>
2025-01-21 13:39:01 +01:00
Robin Jarry
5a90e2f355 compose: merge repeated address headers
When composing a message with edit-headers=true and some To, Cc, Bcc
headers are repeated, only the last occurrence will be considered. All
other addresses will be dropped and lost without any error/warning.

When parsing the embedded headers, merge any repeated To, Cc, Bcc
headers and warn the user about it.

Reported-by: Inwit <inwit@sindominio.net>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2025-01-18 11:33:34 +01:00
Jelte Fennema-Nio
ae38305d2f reply: support multiple copy-to destinations
In some setups it is useful to copy an email to multiple destinations,
e.g. to automatically put sent emails in a folder with "interesting"
emails. This allows doing so.

Changelog-added: `copy-to` now supports multiple destination folders.
Signed-off-by: Jelte Fennema-Nio <aerc@jeltef.nl>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-01-16 21:00:06 +01:00
Robin Jarry
7766b4b333 compose: fix deadlock when editor exits with an error
When exiting vim with :cq, it exits with an error status which is caught
in the termClosed() callback. This causes the composer tab to be closed
and it is a known and expected behaviour.

A recent fix of the tab strip removal revealed that the composer lock is
still held when calling RemoveTab(). Internally, RemoveTab() hides and
unfocuses the removed tab both operations require the composer lock as
well, causing a complete deadlock of the application.

Unfortunately, we cannot rely on the go defer statement to have
RemoveTab(), called *AFTER* c.Unlock(). Deferred statements are called
in the reverse order they were evaluated.

Use an explicit function array to ensure that the composer is unlocked
before RemoveTab() is called.

Fixes: 6b97085ae5 ("tab: fix broken history on removal")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Julio B <julio.bacel@gmail.com>
2025-01-14 15:00:58 +01:00
Robin Jarry
ee36166bf9 compose: add note that edit is also for headers
It has been reported that it was not obvious that :edit allowed to
change the email headers. Make it explicit.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
2025-01-14 15:00:54 +01:00
Robin Jarry
e50dbedc6a compose: disable {prev,next}-field on review screen
It is currently possible to focus the various header editors while on
the compose::review screen but it is impossible to actually change their
value.

Prevent the focus from even occurring and return an explicit error
message to make it explicit that :next-field and :prev-field only work
when the text editor is visible and [compose].edit-headers = false.

Also, to avoid any ambiguity, prevent any text input from being focused
unless the text editor is visible. This effectively prevents the cursor
from being displayed.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Bence Ferdinandy <bence@ferdinandy.com>
2025-01-14 15:00:50 +01:00
Bence Ferdinandy
bc487a52be viewer: decode Sender header
The Sender header is displayed verbatim, unlike the other address
headers like From. Decode the Sender header as well.

Fixes: https://todo.sr.ht/~rjarry/aerc/294
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2025-01-07 19:20:48 +01:00
Robin Jarry
56002158df expand,collapse: allow specifying folder name
In addition of expanding collapsing the currently selected folder with
no argument, allow specifying a folder name.

Changelog-added: `:expand-folder` and `:collapse-folder` can now act
 on a non selected folder.
Suggested-by: Drew Devault <sir@cmpwn.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2024-12-21 17:02:31 +01:00
Jonathan Dowland
4f7f5d40b6 compose: prevent trailing spaces on empty headers
When using format-flowed=true, you need to configure your editor to
format the text accordingly. With (neo)vim, this is achieved by setting
formatoptions+=w (trailing whitespace indicates paragraph continuation).
This may also be combined with +=a (automatically reflow paragraphs as
you edit).

When also using edit-headers=true, empty header lines are considered
part of the same paragraph (by vim) if they have a trailing space. This
can make editing the headers difficult (the editor may mistakenly join
them together).

To prevent this, vary the separator between header field name and body
depending on whether the body is empty. If so, only use the ":".  This
is valid syntax for the populated case too, but including a space is
aesthetically pleasing, so for that case use ": " as the separator.

Signed-off-by: Jonathan Dowland <jon+aerc-devel@dow.land>
Acked-by: Robin Jarry <robin@jarry.cc>
2024-12-16 15:47:55 +01:00
Robin Jarry
5a119d7c64 viewer: allow filters to provide their own paging
Allow filter commands to declare that they will provide their own paging
functionality. To do so, a filter command must start with an exclamation
mark "!". For example:

	text/html = ! w3m -I UTF-8 -T text/html

This will effectively run w3m as the main process running in the
embedded terminal of the part viewer. It will provide interactive access
to w3m and will effectively allow navigating using w3m paging and
coloring.

Implements: https://todo.sr.ht/~rjarry/aerc/250
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2024-12-05 10:57:11 +01:00
Robin Jarry
88b9065ff8 viewer: set term size environment vars before filter command starts
When the part viewer embedded terminal starts we take the opportunity to
initialize the COLUMNS and LINES environment variables of the filter
command before starting the terminal.

Unfortunately, the part viewer Draw() method will start the terminal
after fetching the body part which will (when complete) start the filter
command in attemptCopy(). There is a race which can lead to the env
variables being updated after the filter command has been started.

Set the environment variables before triggering the part fetch. This
will guarantee that they are present when the filter command starts.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2024-12-05 10:57:11 +01:00
Robin Jarry
43ff140611 viewer: avoid potential race condition
Make sure to do a test and set atomically on the copying boolean.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Inwit <inwit@sindominio.net>
2024-12-05 10:57:11 +01:00