Add a new setting to configure the default split layout for message list
tabs. The syntax is a bit different from the :split and :vsplit commands
since it needs to convey the direction in the value as well. I didn't
reuse split/vsplit since they are a bit confusing when used in
a configuration file.
The syntax is as follows:
message-list-split = [<direction>] <size>
The direction is optional and defaults to horizontal. The size is the
number of terminal cells that will be used to display the message list.
All these examples are equivalent:
message-list-split = horiz 12
message-list-split = h 12
message-list-split = 12
Same idea for vertical splits:
message-list-split = vertical 120
message-list-split = vert 120
message-list-split = v 120
Both :split and :vsplit commands remain usable as before. The
configuration options only affect the initial layout at startup.
Add config.SPLIT_* constants and sanitize AccountView.{Split,Vsplit}
methods.
Signed-off-by: Robin Jarry <robin@jarry.cc>
---
app/account.go | 38 +++++++++++++++++++++++---------------
commands/account/split.go | 4 ++--
config/aerc.conf | 13 +++++++++++++
config/ui.go | 38 ++++++++++++++++++++++++++++++++++++++
doc/aerc-config.5.scd | 12 ++++++++++++
5 files changed, 88 insertions(+), 17 deletions(-)
diff --git a/app/account.go b/app/account.go
index 2bdf970a8c18..08ab64989d55 100644
--- a/app/account.go
+++ b/app/account.go
@@ -40,7 +40,8 @@ type AccountView struct {
split *MessageViewer
splitSize int
splitDebounce *time.Timer
- splitDir string
+ splitDir config.SplitDirection
+ splitLoaded bool
// Check-mail ticker
ticker *time.Ticker
@@ -544,7 +545,7 @@ func (acct *AccountView) closeSplit() {
acct.split.Close()
}
acct.splitSize = 0
- acct.splitDir = ""
+ acct.splitDir = config.SPLIT_NONE
acct.split = nil
acct.grid = ui.NewGrid().Rows([]ui.GridSpec{
{Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)},
@@ -561,7 +562,16 @@ func (acct *AccountView) closeSplit() {
}
func (acct *AccountView) updateSplitView(msg *models.MessageInfo) {
- if acct.splitSize == 0 {
+ if !acct.splitLoaded {
+ switch acct.uiConf.MessageListSplit.Direction {
+ case config.SPLIT_HORIZONTAL:
+ acct.Split(acct.uiConf.MessageListSplit.Size)
+ case config.SPLIT_VERTICAL:
+ acct.Vsplit(acct.uiConf.MessageListSplit.Size)
+ }
+ acct.splitLoaded = true
+ }
+ if acct.splitSize == 0 || !acct.splitLoaded {
return
}
if acct.splitDebounce != nil {
@@ -580,9 +590,9 @@ func (acct *AccountView) updateSplitView(msg *models.MessageInfo) {
}
acct.split = NewMessageViewer(acct, view)
switch acct.splitDir {
- case "split", "hsplit":
+ case config.SPLIT_HORIZONTAL:
acct.grid.AddChild(acct.split).At(1, 1)
- case "vsplit":
+ case config.SPLIT_VERTICAL:
acct.grid.AddChild(acct.split).At(0, 2)
}
})
@@ -605,12 +615,12 @@ func (acct *AccountView) SetSplitSize(n int) {
// Split splits the message list view horizontally. The message list will be n
// rows high. If n is 0, any existing split is removed
-func (acct *AccountView) Split(n int) error {
+func (acct *AccountView) Split(n int) {
acct.SetSplitSize(n)
- if acct.splitDir == "split" || n == 0 {
- return nil
+ if acct.splitDir == config.SPLIT_HORIZONTAL || n == 0 {
+ return
}
- acct.splitDir = "split"
+ acct.splitDir = config.SPLIT_HORIZONTAL
acct.grid = ui.NewGrid().Rows([]ui.GridSpec{
// Add 1 so that the splitSize is the number of visible messages
{Strategy: ui.SIZE_EXACT, Size: func() int { return acct.SplitSize() + 1 }},
@@ -627,17 +637,16 @@ func (acct *AccountView) Split(n int) error {
acct.split = NewMessageViewer(acct, nil)
acct.grid.AddChild(acct.split).At(1, 1)
acct.updateSplitView(acct.msglist.Selected())
- return nil
}
// Vsplit splits the message list view vertically. The message list will be n
// rows wide. If n is 0, any existing split is removed
-func (acct *AccountView) Vsplit(n int) error {
+func (acct *AccountView) Vsplit(n int) {
acct.SetSplitSize(n)
- if acct.splitDir == "vsplit" || n == 0 {
- return nil
+ if acct.splitDir == config.SPLIT_VERTICAL || n == 0 {
+ return
}
- acct.splitDir = "vsplit"
+ acct.splitDir = config.SPLIT_VERTICAL
acct.grid = ui.NewGrid().Rows([]ui.GridSpec{
{Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)},
}).Columns([]ui.GridSpec{
@@ -653,7 +662,6 @@ func (acct *AccountView) Vsplit(n int) error {
acct.split = NewMessageViewer(acct, nil)
acct.grid.AddChild(acct.split).At(0, 2)
acct.updateSplitView(acct.msglist.Selected())
- return nil
}
// setTitle executes the title template and sets the tab title
diff --git a/commands/account/split.go b/commands/account/split.go
index 4b01da2d4bc6..5f09f21b88ce 100644
--- a/commands/account/split.go
+++ b/commands/account/split.go
@@ -70,9 +70,9 @@ func (s Split) Execute(args []string) error {
}
switch args[0] {
case "split", "hsplit":
- return acct.Split(s.Size)
+ acct.Split(s.Size)
case "vsplit":
- return acct.Vsplit(s.Size)
+ acct.Vsplit(s.Size)
}
return nil
}
diff --git a/config/aerc.conf b/config/aerc.conf
index 51c73a8f5850..17b9d216d2f3 100644
--- a/config/aerc.conf
+++ b/config/aerc.conf
@@ -162,6 +162,19 @@
# Default: 22
#sidebar-width=22
+#
+# Default split layout for message list tabs. The syntax is:
+#
+# [<direction>] <size>
+#
+# <direction> is optional and defaults to horizontal. It can take one
+# of the following values: h, horiz, horizontal, v, vert, vertical.
+#
+# <size> is a positive integer representing the size (in terminal cells)
+# of the message list window.
+#
+#message-list-split=
+
#
# Message to display when viewing an empty folder.
#
diff --git a/config/ui.go b/config/ui.go
index f5030ba0a2b1..46917fed7edf 100644
--- a/config/ui.go
+++ b/config/ui.go
@@ -5,6 +5,7 @@ import (
"math"
"path"
"regexp"
+ "strconv"
"text/template"
"time"
@@ -32,6 +33,7 @@ type UIConfig struct {
MessageViewThisYearTimeFormat string `ini:"message-view-this-year-time-format"`
PinnedTabMarker string "ini:\"pinned-tab-marker\" default:\"`\""
SidebarWidth int `ini:"sidebar-width" default:"22"`
+ MessageListSplit SplitParams `ini:"message-list-split" parse:"ParseSplit"`
EmptyMessage string `ini:"empty-message" default:"(no messages)"`
EmptyDirlist string `ini:"empty-dirlist" default:"(no folders)"`
EmptySubject string `ini:"empty-subject" default:"(no subject)"`
@@ -234,6 +236,42 @@ func (*UIConfig) ParseIndexColumns(section *ini.Section, key *ini.Key) ([]*Colum
return ParseColumnDefs(key, section)
}
+type SplitDirection int
+
+const (
+ SPLIT_NONE SplitDirection = iota
+ SPLIT_HORIZONTAL
+ SPLIT_VERTICAL
+)
+
+type SplitParams struct {
+ Direction SplitDirection
+ Size int
+}
+
+func (*UIConfig) ParseSplit(section *ini.Section, key *ini.Key) (p SplitParams, err error) {
+ re := regexp.MustCompile(`^\s*(v(?:ert(?:ical)?)?|h(?:oriz(?:ontal)?)?)?\s+(\d+)\s*$`)
+ match := re.FindStringSubmatch(key.String())
+ if len(match) != 3 {
+ err = fmt.Errorf("bad option value")
+ return
+ }
+ p.Direction = SPLIT_HORIZONTAL
+ switch match[1] {
+ case "v", "vert", "vertical":
+ p.Direction = SPLIT_VERTICAL
+ case "h", "horiz", "horizontal":
+ p.Direction = SPLIT_HORIZONTAL
+ }
+ size, e := strconv.ParseUint(match[2], 10, 32)
+ if e != nil {
+ err = e
+ return
+ }
+ p.Size = int(size)
+ return
+}
+
const MANUAL_COMPLETE = math.MaxInt
func (*UIConfig) ParseCompletionMinChars(section *ini.Section, key *ini.Key) (int, error) {
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index b13d6e8924aa..ea9316751c86 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -179,6 +179,18 @@ These options are configured in the *[ui]* section of _aerc.conf_.
Default: _22_
+*message-list-split* = _[<direction>] <size>_
+ The default split layout for message list tabs.
+
+ _<direction>_ is optional and defaults to _horizontal_. It can take one
+ of the following values: _h_, _horiz_, _horizontal_, _v_, _vert_,
+ _vertical_.
+
+ _<size>_ is a positive integer representing the size (in terminal cells)
+ of the message list window.
+
+ See *:split* in *aerc*(1) for more details.
+
*empty-message* = _<string>_
Message to display when viewing an empty folder.
--
2.43.0