aboutsummaryrefslogtreecommitdiffstats
path: root/app
Commit message (Collapse)AuthorAgeFilesLines
* ui: allow thread arrow customizationinwit2024-01-292-20/+75
| | | | | | | | | | | | | | | | | | The thread prefix appearance is inspired by mutt and has been regarded by some as too wide and not very aesthetically pleasing. Nevertheless, it has some technical limitations, like not being able to show if a thread is folded. Allow for full customisation of the thread prefix by introducing 14 new config options. Dirlist is not affected. Changelog-added: Thread arrow prefixes are now fully configurable. Co-authored-by: Robin Jarry <robin@jarry.cc> Signed-off-by: inwit <inwit@sindominio.net> Tested-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* bindings: do not systematically trigger completionRobin Jarry2024-01-271-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When simulating keystrokes of a binding, the command completion is disabled momentarily for performance reasons and re-enabled once the sequence is finished. See commit 055c6dc6604f ("exline: don't draw completions for keybinds") for more details. Since commit 0b0095eeadaf ("complete: allow disabling automatic completion"), it is possible to only rely on explicit keystrokes to display the completion menu. With the default settings, if a key sequence contains more than [ui].completion-min-chars, it should trigger completion after [ui].completion-delay. But since the completion was disabled when the keystrokes are input, it does not trigger the completion. To work around this, an artificial <Tab> keystroke was added at the end of the sequence to force trigger the completion menu. For more details, see commit 04869bd2a39a ("aerc: fix popover menu regression"). The workaround that was added, along with commit b3dc63d69c14 ("complete: only display popover for more than one choice"), forces the completion when there is a single choice. Completely ignoring [ui].completion-min-chars = manual. Only explicitly trigger the completion if the completion key was seen in the keystroke sequence or if completion-min-chars is not set to manual. Use the correct completion key and not hard code Tab. Fixes: 0b0095eeadaf ("complete: allow disabling automatic completion") Fixes: https://todo.sr.ht/~rjarry/aerc/210 References: https://todo.sr.ht/~rjarry/aerc/104 Cc: Skejg <grolleman@zoho.com> Reported-by: Karel Balej <balejk@matfyz.cz> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Karel Balej <balejk@matfyz.cz> Tested-by: Koni Marti <koni.marti@gmail.com>
* tabs: optimize switching by offsetsdelitako2024-01-262-0/+5
| | | | | | | | | | | | | | | | | I imagine no sane user requires aerc to correctly handle commands like `:next-tab 1000000000`, but I tried anyway and it froze aerc while also eating up many GBs of system memory. This behavior is not ideal, so I improved it. This commit adds functions for selecting a tab at an offset from the currently-selected tab and changes the next-tab, prev-tab, and change-tab commands to use these functions instead of looping. Signed-off-by: delitako <delitako@delitako.xyz> Tested-by: Thomas Böhler <witcher@wiredspace.de> Reviewed-by: Thomas Böhler <witcher@wiredspace.de> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: don't attach key when removing signatureThomas Böhler2024-01-261-2/+0
| | | | | | | | | | | | | | If pgp-attach-key is set in accounts.conf, the key is detached with :detach and the signature removed with :sign, the key will be attached again. When :sign is called again two keys will be attached instead of one. Fix this by not attaching a key if it cannot be detached. Fixes: 9d90b70b4edf ("compose: refactor attachment handling") Signed-off-by: Thomas Böhler <witcher@wiredspace.de> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: allow automatic attachment of signing keyRobin Jarry2024-01-251-0/+10
| | | | | | | | | | | | | | | | | | Add a new pgp-attach-key boolean setting in accounts.conf. When set to true, enabling message signing (either automatically via pgp-auto-sign or manually with :sign) will imply attaching the (public) key that will be used to sign the message before sending. The automatically attached key can be unattached like any other attachment with :detach. Implements: https://todo.sr.ht/~rjarry/aerc/207 Changelog-added: Automatically attach signing key with `pgp-attach-key` in `accounts.conf`. Requested-by: Drew Devault <sir@cmpwn.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Thomas Böhler <witcher@wiredspace.de> Reviewed-by: Thomas Böhler <witcher@wiredspace.de>
* compose: ensure rfc2045 compliant mime messageKoni Marti2024-01-191-0/+8
| | | | | | | | | | | | Ensure that the encrypted and/or signed messages contain a correct MIME-Version header field at the top level of the message in compliance with RFC2045 Section 4. Link: https://datatracker.ietf.org/doc/html/rfc2045#section-4 Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3C1704071512-sup-2798%40honeycomb%3E Reported-by: Dan Callaghan <djc@djc.id.au> Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* templates: move signature from compose to templatesBence Ferdinandy2024-01-081-91/+0
| | | | | | | | | | | | | | | | Currently, when composing a new message, everything is read from the template files, except the signature, which is added directly in the compose code. Add a new template variable {{.Signature}}, by moving the logic of reading signature from command or file from compose to templates. Update the various default template files to preserve the original placement of signatures. Users using the default templates should not notice the change. Users with custom compose templates will need to update their templates with {{.Signature}}. Changelog-changed: Signature placement is now controlled via the `{{.Signature}}` template variable and not hardcoded. Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* msglist: refactor tree buildingMoritz Poldrack2023-12-301-35/+26
| | | | | | | | | | | | Our way of building trees seems absurd: generate a list of prefixes, reverse it, and trim the first element. Change it so the string is built back to front and define the arrows beforehand so they are easier to configure. Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* patch/list: add list sub-cmdKoni Marti2023-12-303-17/+8
| | | | | | | | | Implement the :patch list command. List the the current project and add a flag to list all saved projects. Use the pager to display the data and extract the pager commands and move them into the config package. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* cf: allow changing folder of another accountRobin Jarry2023-12-051-0/+8
| | | | | | | | | | | | | | Add a new -a flag to :cf. When specified, an account name is required before the folder name and the focus will be changed to the corresponding account tab before changing folders. If the target folder does not exist, an explicit error will be reported. Changelog-added: Change to a folder of another account with `:cf -a <account> <folder>`. Signed-off-by: Robin Jarry <robin@jarry.cc> Co-authored-by: Johannes Thyssen Tishman <johannes@thyssentishman.com> Tested-by: Johannes Thyssen Tishman <johannes@thyssentishman.com>
* dirtree: prevent folder selection when archivingKoni Marti2023-12-011-13/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Prevent an unwanted folder selection in the directory tree when archiving. A previous fix (commit 0be135a3) introduced a regression which caused the directory tree to select the folder for which a CreateDirectory message returned successfully. Since the :archive command will issue a CreateDirectory message in every operation, the directory tree will thus erroneously select the target archive directory. However, the functionality to select a newly created folder by the :mkdir command is actually correct and should be kept since this corresponds to the regular directory list behavior. Another quirk that is addressed is caused by the rebuilding of the directory tree when the underyling directories change. In that case, the ui.DirListCollapse setting would overwrite the user changes. Therefore, only apply the ui.DirListCollapse setting at the first time of building the directory tree. Fixes: 0be135a38186 ("dirtree: fix jumping folders") Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com>
* dirtree: fix jumping foldersKoni Marti2023-11-241-3/+5
| | | | | | | | | | | Fix jumping folders in the directory structure. Fixes: a35d9bab ("rmdir: ensure proper sequence of operations") Reported-by: inwit <inwit@sindominio.net> Reported-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Acked-by: Robin Jarry <robin@jarry.cc>
* term: ensure cursor is hidden before closingRobin Jarry2023-11-241-0/+3
| | | | | | | | | | | When running a terminal in a dialog that is closed before the terminal has had a chance of being redrawn, the cursor may be left visible. Make sure to hide the cursor in the close routine. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Tested-by: Jason Cox <me@jasoncarloscox.com>
* dirtree: add custom virtual directory roleKoni Marti2023-11-231-0/+24
| | | | | | | | | Add a new directory role to indicate virtual nodes in the directory tree. This allows to style the virtual nodes differently and apply different behaviors in some commands (i.e. rmdir). Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* dirlist/dirtree: context handlingKoni Marti2023-11-232-11/+16
| | | | | | | | | | | Add a NewContext() function that extracts and handles the canceling and re-creation of a new context for the directory list. This enables a better control of the context cancellation especially for a directory tree when a virtual node is selected. Before, the previous folder would have been opened if a virtual node was selected. Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: define useful vars in the editor's envJason Cox2023-11-231-0/+5
| | | | | | | | | | | | Add AERC_ACCOUNT and AERC_ADDRESS_BOOK_CMD to the editor's environment when composing a message. These variables allow for per-account configuration of the editor and facilitate address completion when edit-headers = true. Changelog-added: `AERC_ACCOUNT` and `AERC_ADDRESS_BOOK_CMD` are now defined in the editor's environment when composing a message. Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
* rmdir: ensure proper sequence of operationsKoni Marti2023-11-122-4/+27
| | | | | | | | | | | | | | | | | | | | Ensure the proper sequence of opening and removing a directory. Fix a potential race between the OpenDirectory (issued by dirlist.Select()) and the RemoveDirectory messages when removing a directory. Due to the delay in the current dirlist.Select() function, the RemoveDirectory message can arrive at the backend before the directory was changed to a different one. This can cause an error on some imap servers and problems with the watcher on the maildir backends. Introduce dirlist.Open() that accepts a callback function so that the operations can be performed in proper sequence. Dirlist.Select() is now a wrapper call to dirlist.Open(). Reported-by: inwit <inwit@sindominio.net> Signed-off-by: Koni Marti <koni.marti@gmail.com> Acked-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* threads: add .ThreadUnread to template datainwit2023-11-121-2/+17
| | | | | | | | | | | | | | | | | When a thread is folded, it can be useful to know how many unseen messages lie below the root. For example, one might want to show that count in the message list: column-folded = {{if .ThreadFolded \ }}{{if ne .ThreadUnread 0 \ }}{{.ThreadUnread | printf "%s/"}}{{ \ end}}{{ .ThreadCount | printf "%s"}}{{end}} Add `.ThreadUnread` to the template functions. Changelog-added: `.ThreadUnread` is now available in templates. Signed-off-by: inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* complete: allow setting the completion key bindingRobin Jarry2023-11-022-0/+6
| | | | | | | | | | | | | | | | | | | | | Until now, if less than complete-min-chars were entered or if completion-delay had not expired yet, the only way to force trigger completion was to press <tab>. In some cases, <tab> is already bound to another action (for example :next-field in the compose::editor context). This makes forcing the completion impossible. Allow defining a key to trigger manual completion via the new $complete special entry in binds.conf. Leave the default binding to <tab>. Set it to <C-o> in the [compose::editor] to avoid conflicting with the existing <tab> binding. Changelog-added: Customize key to trigger completion with `$complete` in `binds.conf`. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Tim Culverhouse <tim@timculverhouse.com>
* hooks: add mail-added hookJason Cox2023-11-021-0/+9
| | | | | | | | | | | | | | The mail-added hook runs whenever a message is added to a folder. Note that the hook does not run when a new message is received (the mail-received hook already covers that) but instead runs whenever aerc itself adds a message to a folder, e.g. when moving or copying a message. Changelog-added: `mail-added` hook that triggers when a message is added to a folder. References: https://todo.sr.ht/~rjarry/aerc/136 Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
* hooks: add mail-deleted hookJason Cox2023-11-021-0/+9
| | | | | | | | | | | | The mail-deleted hook runs whenever a message is deleted from a folder. Note that this means moving a message from one folder to another triggers the mail-deleted hook. Changelog-added: `mail-deleted` hook that triggers when a message is removed/moved from a folder. References: https://todo.sr.ht/~rjarry/aerc/136 Signed-off-by: Jason Cox <me@jasoncarloscox.com> Acked-by: Robin Jarry <robin@jarry.cc>
* binds: folder-specific bindings for composerVitaly Ovchinnikov2023-11-022-3/+12
| | | | | | | | | Add folder-specific bindings for composer, so custom binginds might be specified for a composer opened in a given folder. Changlelog-Added: `[compose::editor:folder=$name]` binding context. Signed-off-by: Vitaly Ovchinnikov <v@ovch.ru> Acked-by: Robin Jarry <robin@jarry.cc>
* fold: allow for multiple folding levelsinwit2023-11-022-12/+20
| | | | | | | Extend the :fold/:unfold behaviour to allow for multiple folding levels. Signed-Off-By: inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* treewide: replace shlex.Split with opt.SplitArgsRobin Jarry2023-10-281-6/+2
| | | | | | | | | | Replace the remaining shlex.Split calls with opt.SplitArgs. Remove dependency to shlex. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Tested-by: Inwit <inwit@sindominio.net>
* commands: pass raw command line down to template evaluationRobin Jarry2023-10-282-17/+13
| | | | | | | | | | | | | | | | | | | | | | | | Some commands need to invoke others and/or run shell commands. For this, we need the raw command line as entered by the user. Pass it down the call chain just before it is split to invoke the command Execute method. Remove unit tests for the template expand() test which does have any added value now that it is performed on a single string without any quote juggling. Update all code to handle a single string instead of a list of arguments. Introduce a new dependency on git.sr.ht/~rjarry/go-opt to deal with shell splitting. This is in preparation for using opt.ArgsToStruct to parse arguments for all aerc commands. There should be no functional change after this patch. Signed-off-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Koni Marti <koni.marti@gmail.com> Tested-by: Moritz Poldrack <moritz@poldrack.dev> Tested-by: Inwit <inwit@sindominio.net>
* compose: fix crash when getting hostnameMoritz Poldrack2023-10-261-0/+5
| | | | | | | | | | | | | Currently we assume that a From: address is present when retrieving the hostname for the message ID. This results in an index-out-of-range error when no From address is present. Generate a random hostname for the message ID, if no From: address is present. Fixes: 608bc4fa7fa7 ("compose: use email domain name in Message-Id") Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Robin Jarry <robin@jarry.cc>
* compose: fix header navigation after :compose -eRobin Jarry2023-10-251-9/+4
| | | | | | | | | | | | | | | | | | When the terminal is closed with [compose].edit-headers=true, all headers are deleted and recreated based on the email content. Since the terminal is not active, adding the first header was working fine, but the next ones were replacing the single entry on each call of addEditor(). Fix the broken append() logic. Reported-by: Inwit <inwit@sindominio.net> Fixes: c2a4fc7fdfae ("compose: avoid panic when deleting the last header") Changelog-fixed: Selection of headers in composer after `:compose -e` followed by `:edit -E`. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Inwit <inwit@sindominio.net>
* terminal: add `:send-keys` commandVitaly Ovchinnikov2023-10-224-0/+38
| | | | | | | | | | | | Add a new command for sending keystrokes to the active terminal, if there is one visible. Covers split preview, message viewer, composer and the terminal mode. This can be used to navigate the embedded applications to scroll or safely quit them when needed. Signed-off-by: Vitaly Ovchinnikov <v@postbox.nz> Acked-by: Robin Jarry <robin@jarry.cc>
* split: add an alias for horizontal splitinwit2023-10-131-1/+1
| | | | | | | | | | To date, there are two orthogonal commands named :vsplit and :split, which create a vertical and a horizontal split, respectively. Add a :hsplit alias for the latter. Signed-Off-By: inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc> Reviewed-by: Moritz Poldrack <moritz@poldrack.dev>
* switcher: add scrollbarKoni Marti2023-10-132-73/+101
| | | | | | | | | | | | Add scrollbar to part switcher. Add config value "max-mime-height" to the [Viewer] section to set the maximum height before a scrollbar is drawn. The part switcher height is restricted to half of the context height. Update docs. Fixes: https://todo.sr.ht/~rjarry/aerc/194 Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* msgviewer: separate part switcher from viewerKoni Marti2023-10-132-162/+186
| | | | | | | | | | Separate part switcher from message viewer. The part switcher implementation was woven into the message viewer code. Decouple them to make the code more readable. Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
* ui: export global functionsRobin Jarry2023-10-111-5/+0
| | | | | | | | | | | | | There is no need for an UI object. The Aerc.ui field is unused. And there is a single instance of it anyway. Move the object's public fields as global variables and change methods to public functions. This makes the code cleaner and removes boilerplate. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* app: fix nil pointer dereference on startupRobin Jarry2023-10-116-42/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix the following crash on startup: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x80 pc=0x9e2314] goroutine 1 [running]: git.sr.ht/~rjarry/aerc/log.PanicHandler() git.sr.ht/~rjarry/aerc/log/panic-logger.go:51 +0x70f panic({0xae95a0, 0x119f9b0}) runtime/panic.go:890 +0x263 git.sr.ht/~rjarry/aerc/app.(*Aerc).SelectedAccount(0x8503cdd28?) git.sr.ht/~rjarry/aerc/app/aerc.go:384 +0x14 git.sr.ht/~rjarry/aerc/app.SelectedAccount(...) git.sr.ht/~rjarry/aerc/app/app.go:44 git.sr.ht/~rjarry/aerc/app.(*AccountView).isSelected(...) git.sr.ht/~rjarry/aerc/app/account.go:225 git.sr.ht/~rjarry/aerc/app.(*AccountView).UpdateStatus(0x850364380) git.sr.ht/~rjarry/aerc/app/account.go:127 +0x28 git.sr.ht/~rjarry/aerc/app.(*AccountView).SetStatus(0x850364380, {0x850243a50, 0x1, 0x0?}) git.sr.ht/~rjarry/aerc/app/account.go:123 +0x94 git.sr.ht/~rjarry/aerc/app.NewAccountView(0x8503d38c0, 0x85041bf80) git.sr.ht/~rjarry/aerc/app/account.go:111 +0x573 git.sr.ht/~rjarry/aerc/app.NewAerc({0xcab0c0?, 0x11fa3c8}, 0x850433860, 0xbf3040, {0xca75e8?, 0x11ca800}, 0x0?) git.sr.ht/~rjarry/aerc/app/aerc.go:91 +0x6ce git.sr.ht/~rjarry/aerc/app.Init(...) git.sr.ht/~rjarry/aerc/app/app.go:24 main.main() git.sr.ht/~rjarry/aerc/main.go:242 +0x52e There was two things very wrong: - Access of the global aerc pointer before it was initialized. - The host field of AccountView was left there and still accessed but never initialized. Replace the global aerc pointer with a real struct value. Update code accordingly. Remove the AccountView.host field which is now useless. Reported-by: Jens Grassel <jens@wegtam.com> Reported-by: Matěj Cepl <mcepl@cepl.eu> Fixes: bc176bd61ba7 ("app: export global functions") Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Moritz Poldrack <moritz@poldrack.dev>
* app: export global functionsRobin Jarry2023-10-108-86/+149
| | | | | | | | | | | | | | | The single Aerc object is passed around in almost all command functions. This hinders readability. Store the single Aerc instance as a global variable. Export public functions from the app package to access methods of that object. Remove all explicit references to *app.Aerc and replace them with calls to these functions. For references to private/unexported fields and functions from within the app package, directly access the global aerc object. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>
* widgets: rename package to appRobin Jarry2023-10-1022-0/+8420
This is the central point of all aerc. Having it named widgets is confusing. Rename it to app. It will make a cleaner transition when making the app.Aerc object available globally in the next commit. Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Moritz Poldrack <moritz@poldrack.dev>