Do not throw an error when the charset is unknown; the message entity
can still be read, but log the error instead.
Reported-by: falsifian
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This setting has been around for ages but not in the default aerc.conf
file. Add it to make it more visible to new users.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Having a default value is confusing because to disable the dynamic time
format, the users need to explicitly configure these settings to the
empty string.
Do not set default values for these settings when they are unset in the
configuration. Comment the default config file values to serve as
examples.
Fixes: aae29324fd ("config: fix default time format values")
Reported-by: Nicolai Dagestad <nicolai@dagestad.fr>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
When cached headers are fetched, an action is posted back to the Worker
to immediately fetch the flags for the message from the server (we can't
know the flags state, therefore it's not cached). When scrolling, a lag
occurs when loading cached headers because the n+1 message has to wait
for the flag request to return before the cached headers are retrieved.
Collect the message UIDs in the UI that need flags, and fetch them based
off a debounce timer in a single request. Post the action from the UI to
eliminate an (ugly) go routine in the worker.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Many panics occur from calling Draw on a nil widget, stemming from the
grid ui element. Protect the calls to Draw from within grid to prevent
this method of panic.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The grid method Children returns the children of a grid, and is never
used. The function is reimplemented in both aerc.go and account.go, also
never called.
Remove these unused methods.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The dirlist is invalidated explicitly after the spinner is stopped.
For simplicitly, don't invalidate on spinner.Invalidate.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Update status line when switching accounts in the composer.
Fixes: 371c1a ("commands: add switch-account command for composer")
Reported-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Allow switching to next or previous account with switch-account -n and
switch-account -p, respectively. By default, these are bound to Alt-n
and Alt-p.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Koni Marti <koni.marti@gmail.com>
This reverts commit 7473571159.
The commit has introduced a regression that lead to the pager not being
filled with content, thereby making reading mails impossible.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
When errors occur during a fetch header request, the requested headers
are deleted from pending and no information is given to the UI. Spinners
keep spinning, and ultimately as the view is refreshed, the headers are
fetched again. This can lead to infinite loops, and extremely long logs.
Update the store with a MessageInfo message when an error is received.
Have the UI display that the header couldn't be fetched in the message
list.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Send to worker.Messages in goroutine to prevent deadlocks: the UI can
fill the worker.Actions channel. The worker can generate more than one
Message per action, and if it generates enough to fill the
worker.Messages channel from a single message while the worker.Actions
channel is full, a deadlock occurs.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The IMAP worker has a few methods that post a new Action to itself. This
can create a deadlock when the worker.Actions channel is full: The
worker can't accept a new Action because it's trying to post an action.
This is most noticeable when cached headers are enabled and the message
list is scrolled fast.
Use a goroutine to post actions to the worker when posting from within
the worker.
Fixes: https://todo.sr.ht/~rjarry/aerc/45
Fixes: 7aa71d334b ("imap: add option to cache headers")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Since commit 5c8a749cfa ("binds: display active keybinds in a dialog
box") the ? key is bound to `:help keys` in the global section which
applies to all binding contexts. Pressing ? while editing any email
headers in the compose window (when the editor is not selected) displays
the active bindings menu.
Add $noinherit=true in the [compose] context to allow typing any
character. Copy the bindings for next-tab and prev-tab so that users can
still change tabs while editing headers.
Cc: Akspecs <akspecs@gmail.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Switch accounts when in the composer mode. When switching accounts, the
From header, the crypto status and the address completer will be
updated.
Accounts can be switched with :switch-account <account-name>. The
completions for the switch-account command will list the available
accounts. If switch-account is run without arguments, the current
account name with the correct usage is displayed.
Fixes: https://todo.sr.ht/~rjarry/aerc/72
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Extract some functionality of the composer constructor into a
account-specific setup function that can be used to implement account
switching.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
There is a race between PartViewer.Cleanup and PartViewer.Draw. pv.term
may be not nil in Draw and Cleanup() may set it to nil before
pv.term.Draw() is called, causing an invalid memory access:
[signal SIGSEGV: segmentation violation code=0x1 addr=0x29 pc=0x9413b8]
git.sr.ht/~rjarry/aerc/widgets.(*Terminal).Draw(0x0?, 0x0?)
git.sr.ht/~rjarry/aerc/widgets/terminal.go:97 +0x18
git.sr.ht/~rjarry/aerc/widgets.(*PartViewer).Draw(0xc00012a540, 0xc0026ea690)
git.sr.ht/~rjarry/aerc/widgets/msgviewer.go:862 +0x2fd
There is no need to reset term to nil.
Fixes: 77f69501d6 ("msgviewer: properly close embedded terminal")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
The terminal widget uses it's own internal event handler to redraw
itself for improved performance. The event handler draws, updates the
screen, and invalidates. The last invalidate is redundant: Invalidating
has the result of telling aerc to redraw the screen. A race condition
can occur where an event is emitted from the terminal and the terminal
is closed before the event is handled. This results in handling the
event after the terminal is closed, and a panic:
panic: Attempted to invalidate unknown cell
goroutine 54685 [running]:
git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).cellInvalidated(0xc00b0a34a0, {0xbb8f10?, 0xc00360cd80})
git.sr.ht/~rjarry/aerc/lib/ui/grid.go:287 +0x175
git.sr.ht/~rjarry/aerc/lib/ui.(*Invalidatable).DoInvalidate(0xc0002e7900?, {0xbb8f10?, 0xc00360cd80?})
git.sr.ht/~rjarry/aerc/lib/ui/invalidatable.go:22 +0x82
git.sr.ht/~rjarry/aerc/widgets.(*Terminal).invalidate(...)
git.sr.ht/~rjarry/aerc/widgets/terminal.go:93
git.sr.ht/~rjarry/aerc/widgets.(*Terminal).HandleEvent(0xc00360cd80, {0xbb4ba0?, 0xc006022690?})
git.sr.ht/~rjarry/aerc/widgets/terminal.go:192 +0xd2
github.com/gdamore/tcell/v2/views.(*WidgetWatchers).PostEvent(...)
github.com/gdamore/tcell/v2@v2.5.3/views/widget.go:113
github.com/gdamore/tcell/v2/views.(*WidgetWatchers).PostEventWidgetContent(0xc0001b9360, {0xbbc950?, 0xc0001b9320})
github.com/gdamore/tcell/v2@v2.5.3/views/widget.go:123 +0x12b
git.sr.ht/~rockorager/tcell-term.(*Terminal).run.func1()
git.sr.ht/~rockorager/tcell-term@v0.1.0/terminal.go:117 +0x9d
created by git.sr.ht/~rockorager/tcell-term.(*Terminal).run
git.sr.ht/~rockorager/tcell-term@v0.1.0/terminal.go:104 +0x110
Don't invalidate on EventWidgetContent. The terminal already handles
drawing and updating the tcell Screen internally.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Allow showing the current working directory in the statusline via
[statusline] render-format=%p, which is useful if the user changes
directories often.
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
A race condition can occur when a PartViewer is closing and also working
on a draw. The closing process sets the terminal to nil, which will
create a panic. This can be tested in development by setting the timer
in the main aerc tick loop to something very low (1 ms for example).
One other unprotected call to terminal exists in the composer widget.
Check that the terminal is not nil before calling methods on it.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Add idle-debounce and idle-timeout to aerc-imap manpage.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Improve terminal mouse support by forwarding mouse events to the
terminal widget. Clicking and dragging are supported.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
The terminal widget already handles most boring stuff: unwatch terminal
events, kill the underlying process, wait for it to exit, etc. Call the
Close() method and be done with it.
This avoids issues where the embedded terminal widget is destroyed but
the pager process does not know about it and dies in agony, writing over
aerc's UI:
Vim: Caught deadly signal HUP
Also, it may avoid leaving child processes as zombies without giving
them a proper burial.
Reported-by: skejg
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
The terminal widget internally uses several context methods. Check that
context is not nil before calling any method to prevent panics.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Allow forwarding paste events to embedded applications. When a bracketed
paste is in progress, do not process any command bindings.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Replace go-libvterm package with tcell-term. go-libvterm provides the
embedded terminal for aerc. It uses a statically linked C library,
requiring CGO.
tcell-term is written in pure go and is written to be portable with
tcell applications by implementing the tcell Widget interface. This
allows the terminal to take a view (which aerc already supplies) and
draw directly to it, as well as issue tcell Events to a Watcher.
Enable setting cursor shapes in embedded terminals.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Export context.viewport for use in implementing tcell-term.
Bump tcell version to enable SetCursorStyle feature. Add this function
to the ui for future use with tcell-term.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Now that tcell events are handled in a goroutine, no need for a channel
to buffer them.
Rename ui.Tick() to ui.Render() and ui.Run() to ui.ProcessEvents() to
better reflect what these functions do.
Move screen.PollEvent() into ui.ProcessEvents(). Register the panic
handler in ui.ProcessEvents().
Remove aerc.ui.Tick() from DecryptKeys(). What the hell was that?
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Losing your progress in case of a crash, or when accidentally closing
aerc is annoying and costs time. This can be drastically reduced by
keeping a persistent history.
Write commands to XDG_CACHE_DIR/aerc/histfile when they are run and load
them when needed. If another instance of aerc is already writing the
file, fall back to the current model, where the history is kept in
memory.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Some people are worried that they might leak their timezone and wish to
send their mails with the Date header in UTC. For this a new key is
added to the account sections to enforce sending in UTC instead of the
system's timezone.
Suggested-by: "Ricardo Correia" <aerc-lists.sr.ht@wizy.org>
Thanks: to Ricardo for checking and correcting my incorrect assertions
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
When using ephemeral aerc sessions – for example while writing patches
for it – the mailto: functionality breaks if the socket is removed.
Try to send a ping (an empty message) to the socket and remove it, if
the send fails or no noop reply is received.
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
The UI runs off a 16 ms ticker. If no render is required, and no event
is seen, aerc waits 16 ms before checking for new events or render
requests. This severely limits handling of events from tcell, and is
particularly noticeable on pasting of large quantities of text.
Process tcell events in a separate go routine from the render loop.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
URLs are extremely loosely defined and can take many shapes which may
not be parsed at all if unusual characters like the exclamation mark are
present. To ensure lists and odd use of spaces are not parsed as links
some sanity-checks are in place:
- the URL's schema must be at least two characters long
- the URL's authority, path, and fragment must have a combined
length of 8 characters or longer
- the URL must not contain a whitespace character, >, ), or "
- the URL may only contain a ] when followed by a different allowed
character or at the end of the line (necessary for IPv6
authorities)
The tests for this function now include links with an exclamation point
and IPv6 addresses. The tests are given names to be easier identifiable.
Link: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
Reported-by: "Bence Ferdinandy" <bence@ferdinandy.com>
Cc: "Koni Marti" <koni.marti@gmail.com>
Fixes: e1d8bc4d17 ("msgviewer: open http links from messages")
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
zoxide is a command line utility, supported by many CLI programs. Enable
zoxide support via the :z command which is a drop-in replacement for :cd
(and calls ChangeDirectory in the background), but also manages adding
paths to and querying from the zoxide database. The command is not
registered if zoxide is not on $PATH.
Link: https://github.com/ajeetdsouza/zoxide
Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
Acked-by: Robin Jarry <robin@jarry.cc>
outgoing-cred-cmd is used to retrieve the password from a password
manager such as UNIX pass or bitwarden CLI. These tools often prompt for
a passphrase to secure the passwords and it is annoying having to enter
it every time sending an email with aerc.
Add a new option outgoing-cred-cmd-cache (default to true) to control
whether aerc will keep a cache of the password or run outgoing-cred-cmd
every time an email needs to be sent.
NB: If the cached password is incorrect, the only way to change it is to
restart aerc.
Fixes: ca90343850 ("outgoing-cred-cmd: delay execution until an email needs to be sent")
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Adjust default values in config.go to follow what is set in the default
aerc.conf file.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Fix reggression introduced by 70bfcfef42 ("lint: work nicely with
wrapped errors (errorlint)").
Discovered this because it broke my arec-notmuch config where I have
`exclude-tags=deleted`. Queries with `tag:deleted` would now fail with
error message saying "Argument was ignored".
Fixes: 70bfcfef42 ("lint: work nicely with wrapped errors (errorlint)")
Signed-off-by: Jose Lombera <jose@lombera.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
When quoting an encrypted message for reply, the quoted text is shown as
"Version: 1.0". This is due to this being the first non-multipart text
portion of the message, which is what the quoted reply logic looks for.
Properly quote replies to encrypted messages by decrypting the message,
and quoting the content. The message must be open in a message view in
order to quote it (it must be decrypted, which is handled by the message
viewer).
Suggested-by: Moritz Poldrack <moritz@poldrack.dev>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Jens Grassel <jens@wegtam.com>
Commit 380cf13cff ("msgstore: run threadBuilder with no debounce on
DirectoryContents msg") fixed an issue related to running the
threadbuilder with a debounce. This fix causes the thread builder to run
for any DirectoryContents message, even if the view is not threaded.
Don't call runThreadBuilderNow unless in a threaded view.
Fixes: 380cf13cff ("msgstore: run threadBuilder with no debounce on DirectoryContents msg")
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Enable path globbing using Go's standard library globbing capabilities,
which allows for attaching multiple files at once.
Suggested-by: Anderson John Njahi <johnjahi55@gmail.com>
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>