Commit graph

385 commits

Author SHA1 Message Date
Koni Marti
d3b62dd3b0 view: add peek flag and propagate
Add a peek flag -p to the view commands to open the message viewer
without setting the "seen" flag. If the flag is set, it would ignore the
"auto-mark-read" config.

The SetSeen flag will be propagated in case the message viewer moves on
to other messages, i.e. with the delete or archive commands.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-10-04 09:44:04 +02:00
Koni Marti
e4d418eed1 viewer: option to not mark message as seen
Add option to open a message in the message viewer without setting the
seen flag. Enables the message viewer to be used as a preview pane
without changing the message flags unintentionally. Before, the message
viewer would set the seen flag by default. The IMAP backend will now
always fetch the message body with the peek option enabled (same as we
fetch the headers).

An "auto-mark-read" option is added to the ui config which is set to
true by default. If set the false, the seen flag is not set by the
message viewer.

Co-authored-by: "James Cook" <falsifian@falsifian.org>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-10-04 09:43:58 +02:00
Koni Marti
dc299cc8ad logging: substitute %w for %v
Subsitute the format specifier %w for %v in the logging facility. The
logging functions use a fmt.Sprintf call behind the scene which does not
recognize %w. %w should be used in fmt.Errorf when you want to wrap
errors. Hence, the log entries that use %w are improperly formatted like
this:

ERROR 2022/10/02 09:13:57.724529 worker.go:439: could not get message
info %!w(*fmt.wrapError=&{could not get structure: [snip] })
      ^

Links: https://go.dev/blog/go1.13-errors
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
2022-10-02 18:56:26 +02:00
Julian Pidancet
9217dbeea4 imap,smtp: add XOAUTH2 support
Add XOAUTH2 authentication support for IMAP and SMTP. Although XOAUTH2
is now deprecated in favor of OAuthBearer, it is the only way to connect
to Office365 since Basic Auth is now completely removed.

Since XOAUTH2 is very similar to OAuthBearer and uses the same
configuration parameters, this is basically a copy-paste of the existing
OAuthBearer code.

However, XOAUTH2 support was removed from go-sasl library, so this
change reimports the code that was removed from go-sasl and offers it
a new home in lib/xoauth2.go. Hopefully it shouldn't be too hard to
maintain, being less than 50 SLOC.

Link: https://github.com/emersion/go-sasl/commit/7bfe0ed36a21
Implements: https://todo.sr.ht/~rjarry/aerc/78
Signed-off-by: Julian Pidancet <julian.pidancet@oracle.com>
Tested-by: Inwit <inwit@sindominio.net>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2022-10-01 15:47:33 +02:00
Robin Jarry
45bff88515 open: allow overriding default program
Instead of xdg-open (or open on MacOS), allow forcing a program to open
a message part. The program is determined in that order of priority:

1) If :open has arguments, they will be used as command to open the
   attachment. If the arguments contain the {} placeholder, the
   temporary file will be substituted, otherwise the file path is added
   at the end of the arguments.

2) If a command is specified in the [openers] section of aerc.conf for
   the part MIME type, then it is used with the same rules of {}
   substitution.

3) Finally, fallback to xdg-open/open with the file path as argument.

Update the docs and default config accordingly with examples.

Fixes: https://todo.sr.ht/~rjarry/aerc/64
Co-authored-by: Jason Stewart <support@eggplantsd.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
2022-10-01 15:47:25 +02:00
Robin Jarry
92ba132d70 open: simplify code
There is no need for convoluted channels and other async fanciness.
Expose a single XDGOpen static function that runs a command and returns
an error if any.

Caller is responsible of running this in an async goroutine if needed.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
2022-10-01 15:46:49 +02:00
Tim Culverhouse
4e84df4a28 command/read: run in main thread
The read command calls store.Flag in a separate goroutine unnecessarily.
Calling this method on store should be very fast, as it only sends a
message to the backend worker and does not wait on IO.

Call the store.Flag method from the main thread. Remove wrapper function
and call store.Flag directly for cleaner code.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-09-29 21:21:00 +02:00
Koni Marti
7701f22bf0 mark: fix (un)mark -a when no message is selected
Call SelectedMessage() in the mark command only when the uid of the
currently selected message is actually needed. If no message is
selected, i.e. after some filter operations where the previously
selected message is not in the results, 'mark -a' would fail since no
message is selected and an error is returned from SelectedMessage() even
though this is not necessary to mark or unmark all messages.

Reported-by:  Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
2022-09-29 17:18:20 +02:00
Koni Marti
044519e1dc switch: update status line
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>
2022-09-20 21:05:15 +02:00
Robin Jarry
bb9ac43e13 switch: add -n and -p flags for relative switch
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>
2022-09-20 20:55:29 +02:00
Koni Marti
d371c1ac8d commands: add switch-account command for composer
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>
2022-09-19 21:26:34 +02:00
Bence Ferdinandy
74fd5d1119 statusline-format: add %p placeholder for current path
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>
2022-09-19 21:25:10 +02:00
Moritz Poldrack
ef99ec17d6 history: store command history in a file
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>
2022-09-14 20:51:51 +02:00
Moritz Poldrack
9c11ab21c7 history: don't store duplicate entries
Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-09-14 20:51:41 +02:00
Bence Ferdinandy
ba9d79fd2d commands: add zoxide support via :z
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>
2022-09-13 23:22:50 +02:00
Tim Culverhouse
dcd397f776 pgp: enable quoted replies of encrypted messages
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>
2022-08-31 10:10:03 +02:00
Moritz Poldrack
af9390d38b attach: enable path globbing
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>
2022-08-30 22:23:24 +02:00
Ben Cohen
cd72812781 archive: respect the next-message-on-delete flag
Reuse the next-message-on-delete configuration flag to mirror the
behavior of delete when archiving.

Signed-off-by: Ben Cohen <ben@bencohen.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 20:33:28 +02:00
Koni Marti
45e506e6ae delete: fix find-next function
Fixes the find-next-loop when deleting the last message. The reverse
loop with store.Prev() will break too early because the value of
'previous' was not reset correctly.

Fixes: d941960f "delete: improve find next function"
References: https://todo.sr.ht/~rjarry/aerc/59
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
2022-08-22 10:04:12 +02:00
Koni Marti
117f99e187 mark: (un)mark message threads
Mark or unmark the shown message threads. Threads must be available in the
message store. Use the -T option for the mark or unmark commands. Can be
used in combination with the toggle flag (-t).

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:37 +02:00
Koni Marti
b12dd9f926 mark: allow multiple visual selections
When entering visual selection mode, the current selection is deleted.
This patch extends the visual mode behavior to select multiple blocks of
messages.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:37 +02:00
Koni Marti
16dbb94221 util: fetch message headers for nil messages
Fix large archive operations that covers messages in the store with
unfetched headers. Commit e5ad877af5 ("msgstore: fetch missing headers
in visual mode") fixed this for the visual selection mode but omitted
the case when 'mark -a' is used to mark all messages.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:37 +02:00
Koni Marti
cfc19a7ec2 store: extract marking behavior and add tests
Separate the marking functions from the message store and extract the
marking behavior into its own class with tests.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:37 +02:00
Koni Marti
5c8a749cfa binds: display active keybinds in a dialog box
Show contextual keybinds in a textbox when using the ':help keys'
command. This command is bound to '?' by default.

Fixes: https://todo.sr.ht/~rjarry/aerc/42
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:37 +02:00
Moritz Poldrack
9cffc45f03 go: removed io/ioutil
Since the minimum required version of Go has been bumped to 1.16, the
deprecation of io/ioutil can now be acted upon. This Commit removes the
remaining dependencies on ioutil and replaces them with their io or os
counterparts.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-22 09:30:19 +02:00
Tim Culverhouse
6057d156e6 delete: revert deleted messages if Delete is unsupported
Delete operations are not supported by the notmuch backend. Revert
deleted messages when the operation is not supported, and reselect the
original selection.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-05 21:57:12 +02:00
Moritz Poldrack
70bfcfef42 lint: work nicely with wrapped errors (errorlint)
Error wrapping as introduced in Go 1.13 adds some additional logic to
use for comparing errors and adding information to it.

Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:58:04 +02:00
Moritz Poldrack
978d35d356 lint: homogenize operations and minor fixes (gocritic)
Apply GoDoc comment policy (comments for humans should have a space
after the //; machine-readable comments shouldn't)

Use strings.ReplaceAll instead of strings.Replace when appropriate

Remove if/else chains by replacing them with switches

Use short assignment/increment notation

Replace single case switches with if statements

Combine else and if when appropriate

Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:58:01 +02:00
Moritz Poldrack
5ca6022d00 lint: ensure errors are at least logged (errcheck)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:57 +02:00
Moritz Poldrack
ef599aa8fc lint: simplify code (gosimple)
Replaces infinite for loops containing a select on a channel with a
single case with a range over the channel.

Removes redundant assignments to blank identifiers.

Remove unnecessary guard clause around delete().

Remove `if condition { return true } return false` with return condition

Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:52 +02:00
Moritz Poldrack
77a00de741 lint: remove redundant returns (S1023)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:45 +02:00
Moritz Poldrack
ea2ac83a4d lint: fix function parameters being overwritten before they are used (SA4009)
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:57:43 +02:00
Moritz Poldrack
b92e9dab19 lint: formatted code
Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-04 21:56:33 +02:00
Moritz Poldrack
aaf0a0c656 lint: apply new formatting rules
Run `make fmt`.

Signed-off-by: Moritz Poldrack <git@moritz.sh>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-01 10:44:52 +02:00
Tim Culverhouse
0c85b5a6cf msglist: remove invalidate from commands which remove messages
Archive, delete, and move all remove messages from the message store.
The commands themselves invalidated the message list. The message list
was also invalidated for every MessagesDeleted message received. Remove
the call in the command logic to reduce redraws of the message list

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-01 10:37:44 +02:00
Tim Culverhouse
894668aec2 archive,move: fix reselect next message
Move and Archive used store.Next to select the next message. When moving
or archiving multiple messages with an upward movement, this would
result in a to-be-removed message being selected. Use findNextNonDeleted
function to select the correct next message for these commands.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-01 10:37:42 +02:00
Tim Culverhouse
56dabb5c9c msgstore: leave visual-mark mode after certain commands
Commit "4753cfd visual-mode: deselect messages after performing command"
introduced the behavior of leaving visual mark mode after performing
certain commands. Add this behavior to additional commands:

- Delete
- Archive
- Move

Remark the selected mail files if an error occurred during the
operation.

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-01 10:37:35 +02:00
Tim Culverhouse
db195bebf0 commands: add check-mail command
Add :check-mail command for ad-hoc checking of mail. Reset timer for
automatic checking if it is enabled.

Suggested-by: staceee
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-08-01 10:37:28 +02:00
Robin Jarry
c816103a24 pipe: fix ordering by message id for long patch series
Git send-email Message-Id headers have the following format:

   DATETIME.PID-NUM-COMMITTER

Unfortunately, when there are more than 9 patches, the patch number
(NUM) is not zero-padded which makes ascii sorting invalid, e.g.:

   1 10 11 12 2 3 4 5 6 7 8 9

Instead of:

   1 2 3 4 5 6 7 8 9 10 11 12

We need the patches to be ordered correctly to pipe them to git am.

Make sure to pad the patch number with zero characters to allow series
of up to 999 patches.

Only re-order messages before piping them if all the Message-Id headers
look like git-send-email headers.

Link: https://github.com/git/git/blob/v2.36.0/git-send-email.perl#L1197
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Koni Marti <koni.marti@gmail.com>
2022-08-01 09:38:15 +02:00
Stas Rudakou
ca90343850 outgoing-cred-cmd: delay execution until an email needs to be sent
This can be useful in cases when:

1. outgoing-cred-cmd requires a user action or confirmation (e.g. when
   using pass with a Yubikey or similar smart card that requires a user
   to enter a pin or touch the device when decrypting the password)

2. A user starts aerc frequently, but not all the sessions end up with
   sending emails

3. So the user only wants to execute outgoing-cred-cmd when the password
   is really used, so the user doesn't have to enter pin or touch their
   Yubikey each time aerc starts

Signed-off-by: Stas Rudakou <stas@garage22.net>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-31 19:53:13 +02:00
Tim Culverhouse
6db766260b sort: clear sort criteria when called without arguments
Fix a regression introduced by commit c2f4404fca ("threading: enable
filtering of server-side threads"). Prior to this commit, a :sort
command (no args) would clear out the current sort criteria (or rather,
apply the value from the config). Restore this functionality.

Fixes: c2f4404fca ("threading: enable filtering of server-side threads")
Reported-by: akspecs <akspecs@gmail.com>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 22:24:01 +02:00
Koni Marti
26b9c3d966 sort: show warning when sort is not supported
Use the capabilities returned by the backend to check whether sort is
implemented when the user tries to use the sort command. Print a warning
to the log when a sort request is silently dropped by the backend.

Suggested-by: |cos|
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 22:22:58 +02:00
Koni Marti
d941960fe1 delete: improve find next function
Improve the function to find the next valid message after the delete
operation. This ensures that messages at the end or when marked in the
visual mode are properly dealt with.

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

Fixes: https://todo.sr.ht/~rjarry/aerc/43
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-26 11:34:19 +02:00
Tim Culverhouse
9bfcec5660 delete: select new last message if last message was deleted
If the last message is deleted, the new selection should be the last
message instead of the first message.

Fixes: https://todo.sr.ht/~rjarry/aerc/59
Reported-by: Sebastien Binet <s@sbinet.org>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-24 23:05:53 +02:00
Tim Culverhouse
80f8bab6cf delete: move tab replace logic into Done callback
Move tab replacement logic for next-message-on-delete into the
callback. This also moves the Invalidate() call into the callback, and
should make imap deletion UI work more reliably - there is a race
condition between the worker and the UI in displaying deleted messages.
This should resolve the race condition, and also only remove the MsgView
tab if the message is actually deleted.

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

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

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
2022-07-23 22:52:15 +02:00
Robin Jarry
171fefd209 tabs: make fields private
The Tabs object exposes an array of Tab objects and the current selected
index in that array. The these two fields are sometimes modified in
goroutines, which can lead to data races causing fatal out of bounds
accesses on the tab array.

Hide these fields as private API. Expose only what needs to be seen from
the outside. This will prepare for protecting concurrent access with
a lock in the next commit.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
2022-07-23 22:00:25 +02:00
Robin Jarry
c841f36513 tabs: rename SelectedTab to SelectedTabContent
This function returns an ui.Drawable. Use a more explicit name. This
prepares for adding a new SelectedTab function which will return
an ui.Tab.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Koni Marti <koni.marti@gmail.com>
2022-07-23 22:00:21 +02:00
Koni Marti
76b39311dc send: enter no-quit mode until message is sent
Protect the sending of a message by entering the no-quit mode. This
prevents aerc from exiting with the :quit command until the operation is
done or the exit is forced.

Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
2022-07-14 23:15:13 +02:00