Commit graph

472 commits

Author SHA1 Message Date
Drew DeVault
403b6af379 compose: add space between headers and editor
Until the PGP changes, this was merged into the header widget.
2020-03-03 16:57:21 -05:00
Drew DeVault
f3158b36f1 Initial support for PGP decryption & signatures 2020-03-03 16:49:52 -05:00
Jeffas
68f179021d Add move-tab command 2020-03-03 20:08:29 +01:00
Jeffas
e661ead57b Only show spinner while sorting if no uids
This fixes the problem where we already have messages and then have to
sort again.
2020-02-28 23:03:34 -05:00
Jeffas
b55813f2c0 Don't show empty message while sorting
This changes the ui to show the spinner while we are sorting. It only
shows one line of the spinner since there are an unknown number of
messages at this time.
2020-02-28 22:06:01 -05:00
Jeffas
2a0430ab90 Set the store on the message list if it is nil 2020-02-28 20:54:15 -05:00
Jeffas
583b129c94 Don't set the store on an update to it
Updates to a store can be asynchronous so we shouldn't select it just
because it had an update. Selection of the stores should be driven by
explicit user commands.
2020-02-28 19:00:23 -05:00
Reto Brunner
53d0c0a903 widgets/dirlist: Fix total message count
This fixes an issue with the updated count logic, where only fetched messages
where counted to the exists string of the rue count.

Note that the count is still broken (we only count read / unread messages we
fetched, but that is the same behaviour as prior to the commit
66b68f35b3)
2020-02-25 11:05:25 -05:00
Amir Yalon
8ad517ea92 Fix crash on mouse scrolling between message parts 2020-02-25 11:05:18 -05:00
Wiktor Kwapisiewicz
1455ad97a9 Fix crash on mouse scrolling before messages load
Using mouse scroll before messages load will trigger a panic as
`ml.store` has not been assigned yet and is `nil`.
2020-02-22 11:06:15 -05:00
Reto Brunner
cb04629f3c fix missing import 2020-02-19 17:09:26 +01:00
Reto Brunner
d44bdc9fb9 Revert "Only fetch the directory contents when we are switching directories"
This reverts commit bd4df53009.

I did not properly untangle the opening / dirlist update of each other.
This interferes with the imap worker, hence the revert
2020-02-19 08:37:20 +01:00
Reto Brunner
66b68f35b3 dirlist: actually honor the DirInfo
Currently the dirlist ignores the counts provided by the dirInfo.
However some of the workers can actually provide accurate counts much quicker
than if we count the flags.

Eventually we will also want to enable displaying counts for background folders,
where the brute force counting won't work as none of the headers are fetched yet.

This commit models it in an opt-in manner, if the flag isn't set then we still
count the messages manually.
2020-02-16 10:41:16 -05:00
Reto Brunner
bd4df53009 Only fetch the directory contents when we are switching directories
Previously, sending a DirectoryInfo assumed that a directory change
happened. However we don't want that if we only want to update the
unread message count.
2020-02-16 10:41:15 -05:00
Andreas Rammhold
aed847f9eb Ensure we aren't selecting negative directories
When the list of directories is empty trying to navigate in the
directory list did previously lead to a crash. With this change we
instead return early before trying to change the directory.

Example backtrace:

> panic: runtime error: index out of range [-1]
>
> goroutine 1 [running]:
> git.sr.ht/~sircmpwn/aerc/widgets.(*DirectoryList).NextPrev(0xc000160680, 0xffffffffffffffff)
> 	source/aerc/widgets/dirlist.go:285 +0xd4
> git.sr.ht/~sircmpwn/aerc/commands/account.NextPrevFolder.Execute(0xc000191040, 0xc00025c210, 0x1, 0x1, 0x0, 0xc00016f420)
> 	source/aerc/commands/account/next-folder.go:44 +0xe0
> git.sr.ht/~sircmpwn/aerc/commands.(*Commands).ExecuteCommand(0xc0000101a8, 0xc000191040, 0xc00025c210, 0x1, 0x1, 0xc000020070, 0xb46d01)
> 	source/aerc/commands/commands.go:66 +0xa7
> main.execCommand(0xc000191040, 0xc0001ca190, 0xc00025c210, 0x1, 0x1, 0xc00025c210, 0xc0003fb080)
> 	source/aerc/aerc.go:60 +0xc7
> main.main.func3(0xc00025c210, 0x1, 0x1, 0x1, 0x1)
> 	source/aerc/aerc.go:162 +0x57
> git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).BeginExCommand.func1(0xc000201db0, 0xb)
> 	source/aerc/widgets/aerc.go:382 +0x83
> git.sr.ht/~sircmpwn/aerc/widgets.(*ExLine).Event(0xc0003be100, 0xb475a0, 0xc00023cba0, 0xc00023cba0)
> 	source/aerc/widgets/exline.go:79 +0x131
> git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Event(0xc000191040, 0xb475a0, 0xc00023cba0, 0x99ee01)
> 	source/aerc/widgets/aerc.go:202 +0x4c1
> git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).simulate(0xc000191040, 0xc000036f00, 0xd, 0x10)
> 	source/aerc/widgets/aerc.go:195 +0x8d
> git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Event(0xc000191040, 0xb475a0, 0xc00023c9c0, 0x9c5a60)
> 	source/aerc/widgets/aerc.go:218 +0x3e8
> git.sr.ht/~sircmpwn/aerc/lib/ui.(*UI).Tick(0xc0001ca190, 0xa99d00)
> 	source/aerc/lib/ui/ui.go:92 +0x190
> main.main()
> 	source/aerc/aerc.go:192 +0x5f2
2020-02-07 10:40:37 -05:00
Reto Brunner
ea0df7bee4 dirlist: adapt to dynamic UIconfig 2020-01-28 10:36:01 -05:00
Reto Brunner
2a3d120d6f dirlist: remove not needed sort function
The docs of strings.Compare state:

> Compare is included only for symmetry with package bytes. It is usually
> clearer and always faster to use the built-in string comparison operators
> ==, <, >, and so on.

So let's do that.
2020-01-28 10:36:00 -05:00
Reto Brunner
e78b7b85e4 config: Strongly type context type
The go compiler can't help much with untyped int constants.
Even though the only valid constants are 0-3 it will happily accept 4 as input.

Let's let the go compiler worry about correctness here. This also allows people
not very familiar with the code to use it properly via auto completion.
2020-01-24 12:25:59 -05:00
Srivathsan Murali
b2fa5a16f5 Contextual UI Configuration
+ Adds parsing of contextual ui sections to aerc config.
+ Add GetUiConfig method for AercConfig that is used to get the
  specialized UI config.
+ Add UiConfig method to AccountView to get specialized UI Config.
+ Modifies Aerc codebase to use specialized UIConfig instead.
+ Adds documentation for Contextual UI Configuration
2020-01-24 10:50:21 -05:00
Luke Drummond
ef029aa263 Display the mimetype when offering to pipe or save 2020-01-20 09:08:38 -05:00
Ben Fiedler
686ca24405 Switch back to upstream pty library
The relevant change was merged upstream, and thus allows us to clean up
unneeded forks.
2020-01-16 13:45:27 -05:00
Reto Brunner
f9391fe798 Correct spelling 2020-01-16 07:21:01 +01:00
Leszek Cimała
5255585b3b remove Original* check 2020-01-09 14:31:19 -05:00
Leszek Cimała
bf28e23933 create OriginalMail struct 2020-01-09 14:31:19 -05:00
Reto Brunner
9096049f75 FetchBodyParts: decode source in the workers
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
2020-01-05 16:02:45 -05:00
Reto Brunner
126119c0b1 msgviewer: decode headers prior to displaying them 2020-01-05 16:02:42 -05:00
Reto Brunner
cb168682b3 msgviewer: bypass filter for headers 2020-01-05 16:02:41 -05:00
Reto Brunner
7a1770f129 msgviewer: do not anchor ansi escape to start of line 2020-01-05 16:02:39 -05:00
Reto Brunner
b360cca977 msgviewer: Add Labels as a virtual header
In order to accommodate for that, the headerlayout needed to be rewritten
to pass the filter criteria back to the msgviewer, instead of just using
the normal headers.
2019-12-27 10:20:30 -07:00
Reto Brunner
2705d8460d add LabelList event 2019-12-21 11:20:11 -05:00
Reto Brunner
b9d2938f9f msglist: highlight marked messages
Note that, until we get color configuration, this means that the user *must*
have the %Z verb in the index format else it'll be horribly confusing
as no visual indication is provided
2019-12-21 09:27:53 -05:00
Reto Brunner
3e535f49b3 msgviewer: implement ProvidesMessages interface 2019-12-21 09:27:49 -05:00
Reto Brunner
98418764b6 AccountView: implement ProvidesMessages 2019-12-21 09:27:48 -05:00
Reto Brunner
684978e77d widgets: add msgInfoFromUids helper 2019-12-21 09:27:47 -05:00
Reto Brunner
b57a47a74f add ProvidesMessages interface 2019-12-21 09:27:47 -05:00
Ben Burwell
fad375c673 Add address book completion in composer
Complete email address fields in the message composer with an external
address book command, compatible with mutt's query_cmd.
2019-12-21 09:23:22 -05:00
Ben Burwell
7160f98a90 Show textinput completions in popovers
Rather than showing completions inline in the text input, show them in a
popover which can be scrolled by repeatedly pressing the tab key. The
selected completion can be executed by pressing enter.
2019-12-21 09:23:21 -05:00
Ben Burwell
ef4c2f61d8 Use timestamp-format in msgviewer
This allows the time to be displayed in a user-configurable way. Also
localize the time in the message viewer as it is in the message list.
2019-12-19 08:45:26 +01:00
Drew DeVault
0ef4b6f9e2 Composer: fix EOF errors
PrepareHeaders generated a fresh message ID and Date header every time.
This instead generates those headers in advance.
2019-12-12 10:22:28 -05:00
Michele Finotto
dfe58842b9 Add custom sorting for folders
A new config options for accounts.conf (folders-sort) was added to
allow a user to choose which folders should be shown on top.
My use case was to avoid stepping into heavy, but rarely viewed folders
when cycling through other often accessed ones.

To test add this to your account.conf:

folders-sort  = INBOX,Sent,Archive

INBOX, Sent and Archive should then show at the top of your dirlist,
and all other folders should come next in alphabetical order.
2019-12-09 12:42:40 -05:00
Leszek Cimała
2559ebfac5 remove garbage headers in reply message
Very important fix. Remove garbage from reply message headers. Till
now all Original fields were send in reply, which we do not want and could
lead to uncorrect email message.
2019-12-08 14:40:36 -05:00
Leszek Cimała
4f2892695e failback to Content-Type filename when encoded Content-Disposition is used
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
2019-12-07 14:30:35 -05:00
ernierasta
0a1a75aed1 fix non-utf8 encoding in msgviewer
This patch should fix encoding problem with non-utf8 text/plain mime.
It is now correctly convert to utf8 before sending to pager. It will
also solve quoting such mails.

Leszek
2019-12-07 14:30:03 -05:00
Robert Günzler
e88cc08d79 Parse headers from template
This patch parses the processed template for headers and populates
matching header editors.
Those are then stripped from the template body before prepending the template
and remaining header fields to the composer content.

The main motivation for this is keeping receiver, sender and subject
lines in the template file and generating the message subject from the
date.
2019-12-07 14:29:48 -05:00
Drew DeVault
eef662c606 Revert "Parse headers from template"
This reverts commit 31e3e9f56e.
2019-12-04 09:49:53 -05:00
Robert Günzler
31e3e9f56e Parse headers from template
Parse the processed template for headers and populates matching header
editors accordingly.
Those are then stripped from the template body before prepending it
and remaining header fields to the composer content.

The motivation for this is keeping receiver, sender and subject
lines in the template file and generating the message subject with the
date functions.
2019-12-04 09:37:52 -05:00
Kevin Kuehler
06f81e8cd9 widgets/terminal: Reap more zombies
The editor and pager were not properly being reaped, causing resource
leakage whenever a user replies to a message.

Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
2019-11-21 14:34:50 -05:00
Greg Anders
3338dce8a1 Allow fields in compose widget to be clicked
When the mouse is enabled, clicking on a header field switches focus to
that field (likewise for the terminal).
2019-11-17 13:19:47 -05:00
Srivathsan Murali
c655afa32b Complete the F rune.
%F now shows the auth name or recepient name/address if the
message is from you.
2019-11-17 13:19:20 -05:00
Greg Anders
4bdef7d860 Add UI options to save/pipe messages with unsupported mimetypes
Adds a message indicating the user's ability to :save or :pipe a message
with an unsupported mimetype and also adds a selector widget (similar to
the tutorial).

The selector widget was previously defined in the account wizard module,
so this commit breaks it out into its own module to allow for re-use.

Further, modify the BeginExLine() function to take an argument that
pre-populates the command line, allowing functions to initiate an ex
command without executing it.

Closes #95.
2019-11-17 13:19:13 -05:00
Greg Anders
809083f843 Check for terminal before forwarding mouse event
When viewing a message part with no available filter, clicking the UI
would cause a nil pointer dereference because the MouseEvent was passed
to the PartViewer's `term` field, which does not exist in the case of an
absent filter.
2019-11-17 13:19:11 -05:00
Drew DeVault
cb7d7a0438 Add some defaults for template options 2019-11-10 11:00:21 -05:00
Srivathsan Murali
3ba69edab5 Add Templates with Parsing
+ 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.
2019-11-10 10:15:49 -05:00
Kevin Kuehler
ad68a9e4e4 widgets/msgviewer: Don't crash if pager is nil
Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
2019-11-10 10:11:34 -05:00
Kevin Kuehler
310bec2702 widgets/msgview: Reap the filter command
The filter command shells out and returns almost immediately. Call
Wait() so the filter process gets reaped. Prior to this patch, aerc
creates a zombie process for every email that is viewed.

Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
2019-10-16 11:13:54 -04:00
Kevin Kuehler
be4ea0d96b Cleanup pager processes after closing a msgviewer
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>
2019-10-16 11:13:53 -04:00
Drew DeVault
f1b365dfc3 Revert "Show spinner when fetching contents"
This reverts commit 1339faf788.
2019-10-09 19:57:53 -04:00
Jeffas
1339faf788 Show spinner when fetching contents
The spinner should be shown when fetching the contents as we don't know
at that point whether there are some messages or not.
2019-10-09 19:46:43 -04:00
Jeffas
00b9ca5032 Fix selected account to return for messageviewer
This ensures that the selectedaccount is returned if currently selected
tab is a messageviewer. This also makes it more extensible for adding
other ways of getting the selected account.
2019-10-02 15:40:23 -04:00
Jeffas
90d26da58a Add sorting functionality
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.
2019-09-20 14:56:02 -04:00
Drew DeVault
956f1366a5 Revert "Fix out-of-order messages by sorting as we display"
This reverts commit ac99d9ed62.
2019-09-18 10:21:45 -04:00
Wagner Riffel
ecc26b53c9 widgets: remove duplicate import
Signed-off-by: Wagner Riffel <wgrriffel@gmail.com>
2019-09-12 23:42:08 -04:00
Jeffas
e2d5c456dc Add signatures
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
2019-09-12 16:18:34 -04:00
Reto Brunner
a93b4de6f3 Add modify-labels command
This adds the event type as well as the command implementation, but no backend
supports it yet.
2019-09-12 16:17:24 -04:00
Jeffas
618a500341 Add display of unread messages in dirlist
Add an onUpdateDirs handler. This is used to invalidate the dirlist and
redraw with the correct number of recent/unread/total messages is shown.

A config option and formatting options are provided.
2019-09-11 12:37:43 -04:00
Devon Johnson
572d9ff728 Fix segfault on delete 2019-09-11 12:24:37 -04:00
Jeffas
f6216bb621 Add Mouseable
This adds the Mouseable interface. When this is implemented for a
component that item can accept and process mouseevents.

At the top level when a mouse event is received it is passed to the
grid's handler and then it trickles down until it reaches a component
that can actually handle it, such as the tablist, dirlist or msglist.

A mouse event is passed so that components can handle other things such
as scrolling with the mousewheel. The components themselves then perform
the necessary actions.

Clicking emails in the messagelist opens them in a new tab.

Textinputs can be clicked to position the cursor inside them.

Mouseevents are not forwarded to the terminal at the moment.

Elements which do not handle mouse events are not required to implement
the Mouseable interface.
2019-09-11 11:41:34 -04:00
Wagner Riffel
e28f45b5aa widgets: gofmt
Signed-off-by: Wagner Riffel <wgrriffel@gmail.com>
2019-09-04 16:30:57 -10:00
Wagner Riffel
1d04c2a292 widgets: rewrite references to os.SET_SEEK to io.SeekStart
Os.SET_SEEK is deprecated, it's recommended to use contants from io
package

Signed-off-by: Wagner Riffel <wgrriffel@gmail.com>
2019-09-04 16:30:57 -10:00
Wagner Riffel
6838c23478 all: purge redundant underscores
Signed-off-by: Wagner Riffel <wgrriffel@gmail.com>
2019-09-04 16:30:57 -10:00
a3v
2257b29a82 Use sort.Stable for sorting displayed messages
With sort.Sort, sometimes two messages with the same timestamp will switch
places every time the message list is redrawn
2019-09-02 10:27:54 +09:00
Paul Spooren
e4104a8674 Allow custom spinner via config file
Allows to set `ui.spinner=` to a string which is then split by
`ui.spinner-delimiter=` (Default: comma) instead of having a hard coded
animation.

This implementation doesn't use INIs capabilities to split strings as
it trims whitespaces breaking the default animation.

Signed-off-by: Paul Spooren <mail@aparcar.org>
2019-08-30 10:32:28 +09:00
Stephen Brennan
ac99d9ed62 Fix out-of-order messages by sorting as we display
Sometimes I observe out-of-order messages when using a maildir inbox. It
appears that the UIDs for these messages are returned out of order by
the MessageStore. In order for a maildir MessageStore to return messages
in most recently received order, it must have already opened all
messages and parsed the date to use as a sort key. Rather than implement
that, simply sort messages by time as we display. This fix shows my
emails in order.
2019-08-29 08:44:08 +09:00
Christopher Vittal
ecd803aae4 Add :prompt command
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.
2019-08-26 09:48:39 +09:00
Daniel Xu
6fcc047c31 Only compile regex portion of folder filter
The code was trying to compile the `~` as well. In this case, it was
trying to match a literal `~` to the front of the supplied regex.

Fixes: 334ca89bea ("folder filter: only assume regex if filter is
~fmt")

Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
2019-08-20 16:03:37 +09:00
Drew DeVault
334ca89bea folder filter: only assume regex if filter is ~fmt 2019-08-20 13:04:58 +09:00
Jelle Besseling
1f5293931a Add forwarding as attachment feature
This allows a single message to be forward as attachment with the
:forward -a command
2019-08-20 10:05:51 +09:00
Jelle Besseling
36c6030e81 Add addresses argument to forward command 2019-08-20 10:04:29 +09:00
Christopher Vittal
cc639a1e65 Add support for <C-j> as '<Enter>' in ExLine 2019-08-19 15:23:07 +09:00
Daniel Xu
9fd6054ca1 Support regex filters for folders
It's nice to be able to filter the folders displayed in the side
bar. Basic string matching can get verbose with enough folders
whitelisted.

Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
2019-08-19 15:22:59 +09:00
Drew DeVault
4fc6fee734 Revert "add close command at global level"
This reverts commit f0a0c5aa73.
2019-08-13 10:55:50 +09:00
Aditya Srivastava
f0a0c5aa73 add close command at global level 2019-08-13 10:49:34 +09:00
Drew DeVault
5493af8c8f Prevent drawing terminal with nil cmd 2019-08-12 09:51:45 +09:00
Jelle Besseling
4478c6a4b7 Ignore scroll command when msgstore is nil
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
2019-08-12 08:58:57 +09:00
Reto Brunner
072b5f453c Close backends prior to shutdown
We need some way to signal the backends that we are about to shutdown,
allowing them to clean up (for example in notmuch committing the db changes).
This commit implements a hook which gets called upon shutdown, providing
backends implement the io.Closer interface.
2019-08-08 10:24:03 +09:00
Jelle Besseling
3650b72ca6 Implement next-folder using NextPrev with amount
This fixes ~sircmpwn/aerc2#182

https://todo.sr.ht/~sircmpwn/aerc2/182
2019-08-07 15:02:11 +09:00
Daniel Bridges
0a52124102 Allow cc/bcc command to receive no arguments 2019-08-07 14:07:48 +09:00
Kevin Kuehler
0ceea02720 cc/bcc: Append to existing headers if called twice
Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>
2019-08-07 14:07:22 +09:00
Ben Cohen
302bc1cda6 Fixing #231 (alternative preferred mimetypes) 2019-08-03 10:47:58 -04:00
Daniel Bridges
f4b7741463 Add cc and bcc commands 2019-08-03 10:43:55 -04:00
Ben Burwell
c9a909fee3 Fix sending attachments with less than 512 bytes 2019-08-02 09:34:10 -04:00
Ben Burwell
bb620e0900 Include body MIME terminator in multipart messages
Before, the text/plain part of the multipart MIME message was not being
correctly terminated with its boundary. The multipart writer writes the
terminator when its Close is called, but since the call to Close() was
deferred, it was not being called until after the attachments were being
written resulting in the boundary not being included at all.
2019-08-02 09:34:08 -04:00
Reto Brunner
9570f4b4d0 msglist: add initialization state
Make the msglist aware of whether we are still initializing or not.
We never stopped spinning the msglist if we didn't get any Directories back
from types.ListDirectories.
With this change, we can set the init state from the account and display
the spinner only if we don't know whether we have directories or not and else
the "no messages" string from the config.
2019-08-02 09:26:10 -04:00
Ben Burwell
152f8c9519 Ring bell when new messages arrive
Add a "new-message-bell" option to the UI section of aerc.conf. A new
hook into the message store allows the msglist widget to detect new
messages being added to the displayed list. When new messages are
delivered, and the new-message-bell option is enabled (as it is by
default), the terminal will beep.
2019-07-29 15:01:49 -04:00
Jeffas
989730d470 Add index option to change-tab
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 -.
2019-07-27 12:40:28 -04:00
Galen Abell
0ee7d30187 Add :detach command
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.
2019-07-27 12:37:55 -04:00
Galen Abell
a669233614 Fix review message not filling entire space
Adding an attachment, switching to a different tab, and switching back
to the review message caused the "filled space" in the review message to
disappear, since there was one too many rows in the layout.
2019-07-27 12:37:54 -04:00
Jeffas
cded067bc3 Add tab completion to textinputs
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.
2019-07-26 14:39:42 -04:00
Galen Abell
8635c70fda Add command history and cycling
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.
2019-07-26 14:29:34 -04:00
Daniel Bridges
67fb0938a6 Support configurable header layout in compose widget 2019-07-26 14:22:04 -04:00
Jeffas
1b673b5ea7 Move msgstore map to dirstore
This map represents a mapping from directory names to their associated
messagestores anyway so they should be under dirstore. This simply moves
them there and adds some methods required to interact with them.
2019-07-26 14:15:27 -04:00
Jeffas
dc4c36adbf Add new-email trigger
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.
2019-07-26 14:00:24 -04:00
Jeffas
0950e39f53 Show the directory being selected in gray 2019-07-25 18:15:49 -04:00
Jeffas
e42b95a617 Add change tab command
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 -
2019-07-23 10:27:59 -04:00
Drew DeVault
97bee661b7 Fix alternatives config 2019-07-19 17:26:43 -04:00
Drew DeVault
d8518909cc Add [a]ttach to the review message prompts 2019-07-19 16:12:26 -04:00
Drew DeVault
7a489cb001 Add Unix socket for communicating with aerc 2019-07-19 14:15:48 -04:00
Kevin Kuehler
f81e4bd41c Implement :filter, :clear
Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>
2019-07-19 11:30:32 -04:00
Galen Abell
7899d15d60 Add :attach command for compose
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.
2019-07-19 10:30:47 -04:00
Jeffas
fb124139f3 Add option to always show mimetype in viewer
A user may want to be able to see what mimetype they are viewing, so
that they can determine what program it may be opened in or for some
other reason.

The config option is under the [viewer] section and is called
'always-show-mime'. It defaults to false to preserve the current
behaviour.
2019-07-17 17:34:43 -04:00
Jeffas
4a5aa7dc27 Remove passing of showHeaders explicitly
Where it is needed the configs are already available so just extract the
value from these.
2019-07-17 17:33:31 -04:00
Jeffas
1d1fe7c7ef Ensure new partswitcher doesn't start on multipart 2019-07-17 17:31:49 -04:00
Daniel Bridges
dfc048fe28 Display user specified headers in viewer if present 2019-07-17 17:26:43 -04:00
Jeffas
d7975132b6 Show currently pressed keys in statusline
This patch adds the currently pressed keys to the statusline. This is
useful when keybindings are multiple keys long and you might forget
which keys are already pressed.
2019-07-17 17:12:52 -04:00
Drew DeVault
dbd583c969 Revert "Ensure new partswitcher doesn't start on multipart"
This reverts commit 41390bc3e1.
2019-07-17 16:09:40 -04:00
Jeffas
8534720e72 When reviewing an email don't pass characters on
This stops characters being passed to the focused box when reviewing an
email. To edit headers the user should go back to the edit page.
2019-07-17 16:00:02 -04:00
Jeffas
41390bc3e1 Ensure new partswitcher doesn't start on multipart 2019-07-17 15:59:09 -04:00
Drew DeVault
5b2336d0d7 Don't initialize an invalid pty size 2019-07-13 11:13:48 -04:00
Jeffas
3b09c07e7a Add clickable tabs
This introduces a new interface `Clickable`. I'd imagine this would be
implemented for most widgets eventually and would allow for programs run
in the terminal to also have their mouse events forwarded to them.

For the tabs it was relatively simple to check that the position of the
click is within the boxes for the tabs. For other components I'd imagine
that some state representing their currently drawn bounding box would be
useful.
2019-07-11 19:45:53 -04:00
Jeffas
0b3aca4167 Add backtab to tutorial navigation
This allows users to use backtab (Shift+tab) to go back through the
fields in the tutorial, like C-K. This then mimics the other methods in
having a forward and backward variant.

Also documented this in the wizard help paragraph.
2019-07-11 19:38:12 -04:00
Daniel Bridges
217e85a55d Fix crashes when operating on empty folder (#216) 2019-07-10 13:21:38 -04:00
Ben Burwell
c610c3cd9d Factor IMAP-specific structs out of UI models
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.
2019-07-08 16:06:28 -04:00
Ben Burwell
cce7cb4808 Factor UI models out of the worker message package
Before, the information needed to display different parts of the UI was
tightly coupled to the specific messages being sent back and forth to
the backend worker. Separating out a models package allows us to be more
specific about exactly what a backend is able to and required to
provide for the UI.
2019-07-08 16:06:23 -04:00
Drew DeVault
363aab5cc1 Make :pipe command more generic 2019-07-05 12:21:12 -04:00
Drew DeVault
f7387f8c60 Sort out dirstore once and for all 2019-07-04 12:31:27 -04:00
Reto Brunner
b12eba55c3 dirlist: simplify nextPrev() considerably
Assuming we always have a sorted dirlist
(other code depends on that already), we don't need to loop over the
dirStore.
Any filtering done should be performed elsewhere
2019-07-04 12:24:16 -04:00
Reto Brunner
0abca31c15 dirlist: remove the additional filtering in Draw() 2019-07-04 12:24:16 -04:00
Reto Brunner
d7fecf7740 dirlist: sync dirstore in filterDirsByFoldersConfig
Also sets the public List() method to return the unfiltered
list of directories directly from the store.
2019-07-04 12:24:16 -04:00
Gregory Mullen
f9d26eef58 Add IMAP folder tab completion
Credit for this fix goes to Reto; I guess if we're not gonna be mutt
we should probabaly do things correctly.
2019-07-04 11:28:04 -04:00
Ben Burwell
8d9d94f0ee Use go-message implementation of GenerateMessageID
Now that this is available in the upstream, we no longer need to
maintain a parallel implementation.
2019-07-04 11:24:19 -04:00
Drew DeVault
491e360178 Revert "Remove dirs field and references to it"
This reverts commit 0e55637aac.
2019-07-02 19:43:41 -04:00
Robert Günzler
0e55637aac Remove dirs field and references to it
This fixes prev/next-folder that broke after
546dfcd76d
2019-06-30 10:33:50 -04:00
Gregory Mullen
546dfcd76d Add new lib/dirstore to source completions from 2019-06-29 14:24:19 -04:00
Gregory Mullen
2a0961701c Implement basic tab completion support
Tab completion currently only works on commands. Contextual completion
will be added in the future.
2019-06-29 14:24:19 -04:00
Stefan Rakel
59df06fe28 Reopening mailcontent file to fix #166
Because editors like vim use backupfiles and rename them to the original
name, the file handle used can point to the wrong file. Reopening the
file should fix this.
2019-06-27 09:25:27 -04:00
Drew DeVault
bf02ad30ca Fix jumping around in search 2019-06-26 20:52:34 -04:00
Drew DeVault
91a75cd98b Implement :search, :next-result, :prev-result 2019-06-26 20:50:54 -04:00
Daniel Lublin
61c94e54cd account-wizard: look up imap and smtp server by SRV records (#100) 2019-06-25 10:31:28 -04:00
Drew DeVault
ceeb30abeb Fix Cc & Bcc handling in replies 2019-06-21 14:33:09 -04:00
Noah Loomans
d1654def19 account-wizard: automatically replace imap.* with smtp.*
Many email providers use the imap sub-domain for imap and the smtp
sub-domain for smtp. FastMail is an example of this[1]. This is a small
quality-of-life improvement which automatically replaces imap.* with
smtp.* when going from the imap screen to the smtp screen in the wizard

[1]: https://www.fastmail.com/help/technical/servernamesandports.html
2019-06-18 19:40:02 -04:00
Reto Brunner
99c363b724 Set empty message in dirlist if no folder exist. 2019-06-14 10:42:26 -04:00
Reto Brunner
626f91c483 imap: respect the folder config option 2019-06-14 10:42:24 -04:00
Drew DeVault
408a9e7b10 Fix automatic scrolling when messages arrive/leave 2019-06-11 10:08:44 -04:00
Kevin Kuehler
a54f4adb8f lib/ui/tab: Add Replace method
Also expose a light wrapper method in aerc.go for tab replacement

Signed-off-by: Kevin Kuehler <kkuehler@brave.com>
2019-06-11 09:34:45 -04:00
Kevin Kuehler
32f970e053 Move select functionality from msglist to msgstore
Remove msglist Next and Prev commands

Signed-off-by: Kevin Kuehler <kkuehler@brave.com>
2019-06-11 09:34:36 -04:00
Clayton Craft
dd178262bb Select user's preferred mimetype in MessageViewer
This implements selecting the most preferred mimetype under the
'View->Alternatives' configuration setting when viewing a message.
Mimetypes in the alternatives array are weighted by their position,
where the lower the index in the array the higher the priority, so this
is taken into account during selection.

If no message part matches a mimetype in the alternatives array, then it
selects the first mimetype in the message.
2019-06-09 11:49:11 -04:00
Robert Günzler
acfe7d7625 Add archive command
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.
2019-06-09 11:33:50 -04:00
Yash Srivastav
5f651b32e5 msglist: use distinct style for unread emails 2019-06-08 10:59:51 -04:00
Drew DeVault
da62f63aad Truncate long subject lines 2019-06-07 16:22:04 -04:00
Yash Srivastav
fca7321639 Message list: implement index-format option 2019-06-07 16:22:01 -04:00
Drew DeVault
0647ea6483 Move ANSI stripping from filters to Go 2019-06-07 11:14:50 -04:00
Drew DeVault
668f7f9e5d Remove unnecessary branch 2019-06-07 10:19:29 -04:00
Drew DeVault
a974027efe Execute the editor with the shell
Fixes #164
2019-06-07 10:15:35 -04:00
Drew DeVault
150a271b36 Add binding to toggle headers 2019-06-07 10:08:09 -04:00
Yash Srivastav
b83e7c9fa6 implements ability to view headers in message view 2019-06-07 09:20:24 -04:00
Lucas F. Souza
2279ac3ab3 Skip rendering dirlist if sidebar width is 0 2019-06-07 09:20:06 -04:00
Drew DeVault
92dc31bad0 Use SetAddressList for From header 2019-06-05 13:58:07 -04:00
JanUlrich
0771eaf24c Introduce :new-account -t
Adding the [-t] temporary flag to the new-account command
- when using -t a newly created account will not be stored into the
accounts.conf

Issue #134
2019-06-05 09:32:43 -04:00
Drew DeVault
7d1770754f Add date to message viewer 2019-06-02 10:23:53 -04:00
Kevin Kuehler
753adb9069 widget: Add ProvidesMessage interface
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>
2019-06-02 10:16:29 -04:00
Kevin Kuehler
5090a4c802 Only add message to store if store exists
Prevents the program from panicing when changing folders too quickly.
onMessage can race store creation for an AccountView.

Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>
2019-06-02 09:43:55 -04:00
Drew DeVault
6e745cb9f3 Enumerate Cc and Bcc lists in composer 2019-06-02 09:40:47 -04:00
Drew DeVault
7f434850b5 Simplify layout of message viewer grid
This sub-grid was an artifact of an older design
2019-06-02 09:33:41 -04:00
Drew DeVault
56b84d3da5 Use forked version of tcell 2019-06-01 11:28:29 -04:00
Kevin Kuehler
3445b80d7a widgets/terminal: Don't segfault on resize
vterm.Write and vterm.SetSize race when the window resizes, which
causing the underlying library to segfault.

Signed-off-by: Kevin Kuehler <keur@ocf.berkeley.edu>
2019-06-01 11:09:14 -04:00
Galen Abell
28fc9fa53d Add :save and :pipe commands to viewer
* :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
2019-05-27 09:37:07 -04:00
Drew DeVault
62cd0b08aa Update terminal color handling per vterm changes 2019-05-26 15:48:29 -04:00
Drew DeVault
855362d813 Update to the latest go-libvterm 2019-05-26 15:13:37 -04:00
Drew DeVault
887ff6550d Implement :edit in compose screen 2019-05-26 11:58:14 -04:00
Drew DeVault
3cf6c82633 msgviewer: copy stderr into pager
This prevents a broken filter config from being a silent error
2019-05-26 11:18:51 -04:00
Drew DeVault
cef784bf52 Fix special characters in address.PersonalName 2019-05-25 11:56:56 -04:00
Drew DeVault
9b19e3ad05 Show account wizard if no accounts configured 2019-05-22 11:35:55 -04:00
Drew DeVault
58bc15b472 Implement opening tutorial after account wizard 2019-05-22 11:13:55 -04:00
Drew DeVault
937b33c850 Write new accounts to config and open tab 2019-05-22 10:40:08 -04:00
Drew DeVault
a7341aff21 Fix always showing last account tab 2019-05-22 10:39:52 -04:00
Drew DeVault
4d6e665204 Remove excess padding from incoming config page 2019-05-21 17:00:35 -04:00
Drew DeVault
6811143925 New account wizard, part one 2019-05-21 16:53:50 -04:00
Drew DeVault
2dc436555d Load IMAP worker for imap+insecure 2019-05-20 19:28:04 -04:00
Drew DeVault
33f2d4f9ee Show unsupported mimetype message in red 2019-05-20 17:05:37 -04:00
Drew DeVault
d224487b68 Show attachment names in multipart view 2019-05-20 17:03:37 -04:00
Drew DeVault
0897413a3e Implement :next-part, :prev-part 2019-05-20 16:49:39 -04:00
Drew DeVault
511fea3944 Flesh out multipart switcher 2019-05-20 16:43:08 -04:00
Drew DeVault
3376f926ed Refactor message part into dedicated widget 2019-05-20 15:03:47 -04:00
Drew DeVault
5de1bb8cc3 Verify TLS certificates
I was partway done implementing a UI for users to approve untrusted
certs with, but let's just make them configure their servers right
instead.
2019-05-20 14:03:00 -04:00
Drew DeVault
fa5d8d7a00 Advance cursor after :delete and :move
So that you can repeat the action on the next message if appropriate
2019-05-19 18:21:02 -04:00
Drew DeVault
f9251c2344 Reset message list cursor when switching stores 2019-05-19 18:18:48 -04:00
Drew DeVault
13032734cd Advance message list cursor when messages arrive 2019-05-19 18:18:48 -04:00
Simon Ser
a15ea01cfb Update internal state and draw from the same goroutine
This commit introduces a new Aerc.Tick function that should be called to
refresh the internal state. This in turn makes each AccountView process worker
events.

The UI goroutine repeatedly refreshes the internal state before drawing a new
frame. The reason for this is that many worker messages may need to be
processed for a single frame, and drawing the UI is far slower than refreshing
the internal state. This has been confirmed in my testing (calling Aerc.Tick
only once per frame results in a slower display).

Many synchronization code has been removed. We can now write widgets without
having to care so much about races. The remaining sync users are:

- widgets/spinner: the spinner value is updated from inside an internal
  goroutine
- lib/ui/invalidatable: Invalidate may be called from any goroutine
- lib/ui/grid: same
- lib/ui/ui: an internal goroutine needs read access to UI.exit
- worker/types/worker: Worker.callbacks is used for both worker and UI
  callbacks

The exact goroutine requirements for Drawable have been documented.
2019-05-19 11:51:16 -04:00
Simon Ser
1da3239345 widgets/terminal: fix damage race condition
Terminal.damage is accessed when drawing and when invalidating the widget. For
this reason we need to protect it with a mutex.

This seems to fix various damage issues I've been experiencing (where some
regions of the terminal weren't correctly repainted).

Race detector trace:

    Read at 0x00c0000c6670 by main goroutine:
      git.sr.ht/~sircmpwn/aerc/widgets.(*Terminal).Draw()
          /home/simon/src/aerc/widgets/terminal.go:292 +0x191
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*Grid).Draw()
          /home/simon/src/aerc/lib/ui/grid.go:117 +0x575
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*Grid).Draw()
          /home/simon/src/aerc/lib/ui/grid.go:117 +0x575
      git.sr.ht/~sircmpwn/aerc/widgets.(*MessageViewer).Draw()
          /home/simon/src/aerc/widgets/msgviewer.go:231 +0x253
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*TabContent).Draw()
          /home/simon/src/aerc/lib/ui/tab.go:124 +0x12e
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*Grid).Draw()
          /home/simon/src/aerc/lib/ui/grid.go:117 +0x575
      git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Draw()
          /home/simon/src/aerc/widgets/aerc.go:95 +0x5a
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*UI).Tick()
          /home/simon/src/aerc/lib/ui/ui.go:93 +0x1dd
      main.main()
          /home/simon/src/aerc/aerc.go:105 +0x539

    Previous write at 0x00c0000c6670 by goroutine 37:
      git.sr.ht/~sircmpwn/aerc/widgets.(*Terminal).onDamage-fm()
          /home/simon/src/aerc/widgets/terminal.go:429 +0x131
      git.sr.ht/~sircmpwn/go-libvterm._go_handle_damage()
          /home/simon/go/pkg/mod/git.sr.ht/~sircmpwn/go-libvterm@v0.0.0-20190421201021-3184f6f13687/vterm.go:481 +0xf9
      git.sr.ht/~sircmpwn/go-libvterm._cgoexpwrap_5e22200b58b7__go_handle_damage()
          _cgo_gotypes.go:731 +0x58
      runtime.call32()
          /usr/lib/go/src/runtime/asm_amd64.s:519 +0x3a
      git.sr.ht/~sircmpwn/go-libvterm.(*VTerm).Write.func1()
          /home/simon/go/pkg/mod/git.sr.ht/~sircmpwn/go-libvterm@v0.0.0-20190421201021-3184f6f13687/vterm.go:329 +0x9d
      git.sr.ht/~sircmpwn/go-libvterm.(*VTerm).Write()
          /home/simon/go/pkg/mod/git.sr.ht/~sircmpwn/go-libvterm@v0.0.0-20190421201021-3184f6f13687/vterm.go:329 +0x7f
      git.sr.ht/~sircmpwn/aerc/widgets.NewTerminal.func1()
          /home/simon/src/aerc/widgets/terminal.go:131 +0x18c

    Goroutine 37 (running) created at:
      git.sr.ht/~sircmpwn/aerc/widgets.NewTerminal()
          /home/simon/src/aerc/widgets/terminal.go:121 +0x23f
      git.sr.ht/~sircmpwn/aerc/widgets.NewMessageViewer()
          /home/simon/src/aerc/widgets/msgviewer.go:147 +0xfbe
      git.sr.ht/~sircmpwn/aerc/commands/account.ViewMessage()
          /home/simon/src/aerc/commands/account/view-message.go:26 +0x4a4
      git.sr.ht/~sircmpwn/aerc/commands.(*Commands).ExecuteCommand()
          /home/simon/src/aerc/commands/commands.go:47 +0x1f0
      main.main.func1()
          /home/simon/src/aerc/aerc.go:76 +0x205
      git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).BeginExCommand.func1()
          /home/simon/src/aerc/widgets/aerc.go:262 +0x89
      git.sr.ht/~sircmpwn/aerc/widgets.(*ExLine).Event()
          /home/simon/src/aerc/widgets/exline.go:47 +0x222
      git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Event()
          /home/simon/src/aerc/widgets/aerc.go:133 +0x83c
      git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).simulate()
          /home/simon/src/aerc/widgets/aerc.go:126 +0x12a
      git.sr.ht/~sircmpwn/aerc/widgets.(*Aerc).Event()
          /home/simon/src/aerc/widgets/aerc.go:148 +0x766
      git.sr.ht/~sircmpwn/aerc/lib/ui.(*UI).Tick()
          /home/simon/src/aerc/lib/ui/ui.go:86 +0x11b
      main.main()
          /home/simon/src/aerc/aerc.go:105 +0x539
2019-05-19 11:37:38 -04:00
Drew DeVault
98da4c9509 s/aerc2/aerc/g 2019-05-17 20:57:10 -04:00
Drew DeVault
fcdcd32de7 Remove unimplemented color configuration
Will probably end up doing this differently anyway
2019-05-17 11:52:38 -04:00
Drew DeVault
89ffd8653d Implement ui.empty-message config option
Also removes some options that aren't going to be supported any time
soon.
2019-05-17 11:42:34 -04:00
Drew DeVault
23650ac0c7 Fix date header on outgoing emails 2019-05-17 11:05:21 -04:00
Drew DeVault
5701b6e949 Decode email when reading it for quoting 2019-05-16 14:09:57 -04:00
Drew DeVault
8be59cae6c Implement :reply -q and :reply -a 2019-05-16 12:39:22 -04:00
Drew DeVault
475b697bdf Implement (basic form) of :reply 2019-05-16 12:15:34 -04:00
Drew DeVault
2b3e123cb8 Let caller pass in custom headers to compose 2019-05-16 10:49:50 -04:00
Drew DeVault
b0bf09b98f Copy sent emails to the Sent folder
Or rather, to a user-specified folder
2019-05-15 19:41:21 -04:00
Drew DeVault
07138146a0 Force INBOX to be included in dirlist 2019-05-14 16:53:47 -04:00
Drew DeVault
db213fd0ae Implement :copy (aka :cp) 2019-05-14 16:44:59 -04:00