Introduce the ability to configure stylesets, allowing customization of
aerc's look (color scheme, font weight, etc). Default styleset is
installed to /path/to/aerc/stylesets/default.
Aerc usually used the path []int{1} if it didn't know what the proper path is.
However this only works for multipart messages and breaks if it isn't one.
This patch removes all the hard coding and extracts the necessary helpers to lib.
More mail flags can now be set, unset, and toggled, not just the
read/seen flag.
This functionality is implemented with a new `:flag` and `:unflag`
command, which are extensions to the matching `:read` and `:unread`
commands, adding support for different flags. In fact, the
`read`/`unread` commands are now recognized aliases to `flag`/`unflag`.
The new commands are also well documented in aerc(1).
The change mostly extends the previous read/unread setting functionality
by adding a selection for the flag to change.
This stops the ui being blocked while the resource is opened. The wait
ensures that resources are reclaimed when the process finishes while
aerc is still running.
The data was passed around as a string for some reason, which led to time
precision loss and wrong dates being displayed.
Simply pass the time as is to fix that.
This changes the scrolling to be done on the draw, when the height is
updated, ensuring that the selected item is kept on screen during
resizing.
Also, this ensures that messages will fill the screen when resizing the
window, for instance, shrinking and then growing drags down more
messages if possible.
This is a transplant of the dirlist scrolling logic.
The grid used static sizes which meant that changing settings didn't
have an effect on elements of the ui, notably the sidebar width. This
patch makes the `Size` parameter of a cell a function which returns the
`int`, allowing for dynamic sizes.
A `Const` function is also included for ease of use for static sizes.
The following functionalities are added to configure aerc ui styles.
- Read stylesets from file with very basic fnmatch wildcard matching
- Add default styleset
- Support different stylesets as part of UiConfig allowing contextual
styles.
- Move widgets/ui elements to use the stylesets.
- Add configuration manual for the styleset
Especially if one tries to interact with all marked messages there could be
the case that not all headers are fetched yet, hence the messageInfo is still nil.
This segfaults a lot of commands which in principle only need the uid to complete.
If we switch to uids, this issue can be alleviated for those commands.
This command uses the Postpone folder from the account config to save
messages to. Messages are saved as though they were sent so have a valid
'to' recipient address and should be able to be read back in for later
editing.
Due to headers being essentially free text, we constantly run into issues
with parts of the body being interpreted as headers.
Remove the ability to overwrite headers to avoid that, while keeping the ability
to specify headers in the template files.
Fixes#383
This adds the commands pin-tab and unpin-tab. Once pinned a tab lives on
the left of the tabstrip and has a configurable marker, defaulting to `
before its name.
- Add maildir flags to complement a messages imap flags
- Set the "seen" flag on sent messages when using the maildir backend
- Cleanup AppendMessage interface to use models.Flag for both IMAP and
maildir
The functionality was broken since the decoding changes.
This commit also simplifies the code (in my view) to make the application logic
easier to follow.
The docs are updated accordingly (the feature was poorly documented).
As far as I am aware there should be no breaking changes (and is certainly
still in the spec of the prior documentation)
Previously the workers returned a mixture of decoded / encoded parts.
This lead to a whole bunch of issues.
This commit changes the msgviewer and the commands to assume parts to already
be decoded
Hi!
This patch will fix missing filename if it is RFC2231 encoded with charset
different then ASCII or UTF8. Example how it looks like in mail:
Content-Type: application/pdf;
name="=?UTF-8?Q?Opis_przedmiotu_zam=c3=b3wienia_-_za=c5=82=c4=85cznik_nr_1?=
=?UTF-8?Q?=2epdf?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename*0*=iso-8859-2''%4F%70%69%73%20%70%72%7A%65%64%6D%69%6F%74%75%20;
filename*1*=%7A%61%6D%F3%77%69%65%6E%69%61%20%2D%20%7A%61%B3%B1%63%7A%6E;
filename*2*=%69%6B%20%6E%72%20%31%2E%70%64%66
Yes, this should be forbidden :-). Anyway, best solotion in such cases
is to failback to Content-Type name. I am not sure if it is guaranted to
be there, but probably it will.
Leszek
Hello guys,
on the hunt for bugs related to wrong encoding. This patch is fixing
reply to non-utf8 messages.
We were using global message headers instead of part specific. In
practice header were often something like:
multipart; boundry=...
where there should be:
text/plain; charset=...
Fixed also missing SubType.
Have great weekend!
Leszek
Pressing `Enter` on a view that has not yet loaded messages (e.g. at
startup) would return `nil` from `Selected()`. Accessing `msg.Uid` on a
`nil` reference crashes aerc.
This patch moves the `msg == nil` check before accessing `msg.Uid` thus
avoiding the crash.
To test this patch repeatedly press `Enter` on startup.
Allowing the user to view deleted messages creates all sorts of race
conditions. The most devious race condition is pv.source can be set to a
nil while another PartViewer is still running a goroutine in
attemptCopy.
Here is a trace when this happens.
goroutine 76 [running]: io.copyBuffer(0x7f8ad02641d0, 0xc00040f590, 0x0,
0x0, 0xc0007cc000, 0x8000, 0x8000, 0x0, 0x0, 0x8b3d60)
/usr/lib/go/src/io/io.go:402 +0x101 io.Copy(...)
/usr/lib/go/src/io/io.go:364
git.sr.ht/~sircmpwn/aerc/widgets.(*PartViewer).attemptCopy.func4(0xc00017efd0,
0xc0004da7c0) /home/keur/repos/aerc/widgets/msgviewer.go:576 +0x611
created by git.sr.ht/~sircmpwn/aerc/widgets.(*PartViewer).attemptCopy
/home/keur/repos/aerc/widgets/msgviewer.go:544 +0x144
We could add a guard in store.FetchBodyPart to only call the callback
when msg.Part.Reader != nil, but we still get a hanging pager. Therefore
it seems more reasonable to disable this completely.
Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
+ Changes NewComposer to return error.
+ Add lib to handle templates using "text/template".
+ Add -T option to following commands
- compose.
- reply
- forward
+ Quoted replies using templates.
+ Forwards as body using templates
+ Default templates are installed similar to filters.
+ Templates Config in aerc.conf.
- Required templates are parsed while loading config.
+ Add aerc-templates.7 manual for using template data.
A pager is spawned every time an email is viewed but not killed off when
quitting the msgviewer, thus leading to process leakage. This patch
fixes this by adding a Close method to the msgview widget, which is
called in the close command.
Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
This patch ensures the following commands join their arguments with
spaces to make it easier to interact with:
- cf
- mkdir
- cd
- attach
- detach
- ct
- copy
- move
- save
There is a command and config option. The criteria are a list of the
sort criterion and each can be individually reversed.
This only includes support for sorting in the maildir backend currently.
The other backends are not supported in this patch.
This adds the ability for per-account signatures in the accounts.conf
config file. The signature is added to emails in the editor at the
bottom of the email. This includes when forwarding, replying to, and
composing emails.
There are two config options: signature-file and signature-cmd. The
former allows a signature to be read from a file and the latter allows
an arbitrary command to be executed to return the signature.
The config options have been documented in aerc-config
Usage:
:prompt <prompt> <command...>
Displays the prompt on the status bar, waits for user input, then
appends that input as the last argument to the command and executes it.
The input is passed as one argument to the command, unless it is empty,
in which case no extra argument is added.
Fixes ~sircmpwn/aerc2#205. Many functions do a nil check on the store,
so this changes Store() so it returns nil when msglist is nil.
It also places the Scroll() behind the nil check in the next-message command.
https://todo.sr.ht/~sircmpwn/aerc2/205
This fixes ~sircmpwn/aerc2#195. While `read -t` works fine.
The `unread` command is not wired. This patch fixes it.
https://todo.sr.ht/~sircmpwn/aerc2/195
Before, lower_only was not being correctly set and was only considering
whether the string ended with a lowercase sequence. Refactored this with
some more explicit functions as the logic is a little confusing.
This allows selection of a tab using its index. It attempts to parse the
given argument as a number, if it fails then it uses it as a name.
Also supports relative indexes using prefixed + or -.
Add a command for removing attachments from a composed message. Syntax
is :detach [path], with path being an optional argument specifying the
path of one existing attachment. If no path is specified, the first
attachment is removed.
This adds tab completion to textinput components. They can be configured
with a completion function. This function is called when the user
presses <tab>. The first completion is initially shown to the user
inserted into the text. Repeated presses of <tab> or <backtab> cycle
through the completions list. The completions list is invalidated when
any other non-tab-like key is pressed.
Also changed is some logic for current completion generation so that
all available commands are returned when <tab> is pressed with no
current text and similarly for arguments of commands.
Aerc will keep track of the previous 1000 commands, which the user can
cycle through using the arrow keys while in the ex-line. Pressing up
will move backwards in history while pressing down will move forward.
This patch sets up the trigger config section of aerc.conf.
Each trigger has its own function which is called from the place where
it is triggered. Currently only the new-email trigger is implemented.
The triggers make use of format strings. For instance, in the new-email
trigger this allows the user to select the trigger command and also the
information extracted from the command and placed into their command.
To actually execute the trigger commands the keypresses are simulated.
Further triggers can be implemented in the future.
Formatting of the command is moved to a new package.
Executing :close on a terminal would panic due to it already having been
removed.
This is also related to the fact that removing a tab doesn't check for
whether it actually found a tab to remove or not.
This command allows the user to change tab by giving the tab name. This
can be tab completed too. The previous tab is stored in the tabs module
so that when a new tab is created it is still possible to go to the
previous one.
Normal invocation is :ct folder
Previous tab is :ct -
Allow users to add attachments to emails in the Compose view. Syntax is
:attach <path>, where path is a valid file. Attachments will show up in
the pre-send review screen.
There is a LoadConf and a LoadConfFromFile.
LoadConfFromFile reads the iniFile into memory and and calls
LoadConf, which executes the old parsing commands from
LoadConf (old func).
The remaining of the LoadConfFromFile is the same as the old OldConf.
Before, we were using several IMAP-specific concepts to represent
information being displayed in the UI. Factor these structures out of
the IMAP package to make it easier for other backends to provide the
required information.
The unsubscribe command, available when in a message viewer context,
enables users to easily unsubscribe from mailing lists.
When the command is executed, aerc looks for a List-Unsubscribe header
as defined in RFC 2369. If found, aerc will attempt to present the user
with a suitable interface for completing the request. Currently, mailto
and http(s) URLs are supported. In the case of a HTTP(S) URL, aerc will
open the link in a browser. For mailto links, a new composer tab will be
opened with a message filled out according to the URL. The message is
not sent automatically in order to provide the user a chance to review
it first.
Closes#101
commands/msgview/save and commands/msgview/pipe now use case
insensitive comparisons to determine if the part is encoded as base64
or quoted-printable.
This adds new functionality to :save in the message view for specifying
directories in the path. A new flag, -p, is also added to :save for
automatically creating any directories in the path that do not exist.
If the path ends in a / (e.g. "Downloads/mail/") or if the path is an
existing directory, the part's file name is the filename from the mail
header for the part. Otherwise, it uses the last element in the path as
the filename (e.g. 'blah.jpg' is the filename if the path is
'Downloads/mail/blah.jpg')
Inside the generic msg command we cannot use aerc.SelectedAccount()
because the method naively assumes the current tab is an AccountView.
Use the ProvidesMessage interface instead.
Signed-off-by: Kevin Kuehler <kkuehler@brave.com>
Adds an archive command that moves the current message into the folder
specified in the account config entry.
Supports three layouts at this point:
- flat: puts all messages next to each other
- year: creates a folder per year
- month: same as above, plus folders per month
This also adds a "-p" argument to "cp" and "mv" that works like
"--parents" on mkdir(1). We use this to auto-create the directories
for the archive layout.
Consists of 3 functions
* Store: Access to MessageStore type
* SelectedAccount: Access to Account widget that the target widget
belongs to
* SelectedMessage: Current message (selected in msglist or the one we
are viewing)
Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>
* :save takes a path and saves the current message part to that location
* :pipe is the same as pipe on the account page, but uses the current
message part rather than the whole email (ie :pipe gzip -d)
* Refactored account:pipe and extracted common pipe code to
commands.util.QuickTerm
* Added helper command aerc.PushError