Add support for :rmdir
The `:rmdir` command removes the current directory (`-f` is required if the directory is not empty). This is not supported on the notmuch backend. An issue with the maildir backend is that some sync programs (e.g. offlineimap) may recover the directory after it is deleted. They need to specifically be configured to accept deletions, or special commands need to be executed (e.g. `offlineimap --delete-folder`) to properly delete folders. A danger of using this on the IMAP backend is that it is possible for a new message to be added to the directory and for aerc to not show it immediately (due to a slow connection) - using `:rmdir` at this moment (with `-f` if the directory already contains messages) would delete the directory and the new message that just arrived (and all other contents). This is documented in aerc(1) so that users are aware of possible risks.
This commit is contained in:
parent
f4dc7e1f74
commit
fe1cabb077
8 changed files with 161 additions and 0 deletions
commands/account
96
commands/account/rmdir.go
Normal file
96
commands/account/rmdir.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~sircmpwn/getopt"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc/widgets"
|
||||
"git.sr.ht/~sircmpwn/aerc/worker/types"
|
||||
)
|
||||
|
||||
type RemoveDir struct{}
|
||||
|
||||
func init() {
|
||||
register(RemoveDir{})
|
||||
}
|
||||
|
||||
func (RemoveDir) Aliases() []string {
|
||||
return []string{"rmdir"}
|
||||
}
|
||||
|
||||
func (RemoveDir) Complete(aerc *widgets.Aerc, args []string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (RemoveDir) Execute(aerc *widgets.Aerc, args []string) error {
|
||||
acct := aerc.SelectedAccount()
|
||||
if acct == nil {
|
||||
return errors.New("No account selected")
|
||||
}
|
||||
|
||||
force := false
|
||||
|
||||
opts, optind, err := getopt.Getopts(args, "f")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, opt := range opts {
|
||||
switch opt.Option {
|
||||
case 'f':
|
||||
force = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) != optind {
|
||||
return errors.New("Usage: rmdir [-f]")
|
||||
}
|
||||
|
||||
// Check for any messages in the directory.
|
||||
if !acct.Messages().Empty() && !force {
|
||||
return errors.New("Refusing to remove non-empty directory; use -f")
|
||||
}
|
||||
|
||||
curDir := acct.SelectedDirectory()
|
||||
var newDir string
|
||||
dirFound := false
|
||||
|
||||
if oldDir, ok := history[acct.Name()]; ok {
|
||||
if oldDir != curDir {
|
||||
newDir = oldDir
|
||||
dirFound = true
|
||||
}
|
||||
}
|
||||
|
||||
if !dirFound {
|
||||
for _, dir := range acct.Directories().List() {
|
||||
if dir != curDir {
|
||||
newDir = dir
|
||||
dirFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !dirFound {
|
||||
return errors.New("No directory to move to afterwards!")
|
||||
}
|
||||
|
||||
acct.Directories().Select(newDir)
|
||||
|
||||
acct.Worker().PostAction(&types.RemoveDirectory{
|
||||
Directory: curDir,
|
||||
}, func(msg types.WorkerMessage) {
|
||||
switch msg := msg.(type) {
|
||||
case *types.Done:
|
||||
aerc.PushStatus("Directory removed.", 10*time.Second)
|
||||
case *types.Error:
|
||||
aerc.PushError(" " + msg.Error.Error())
|
||||
case *types.Unsupported:
|
||||
aerc.PushError(":rmdir is not supported by the backend.")
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue