Move SSD relative group lookup to typed Kotlin

ober

3220cc8ad5f17dfc9cb281ba3b04f8cd316e282c

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index f302f30..a4707c7 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -554,6 +554,7 @@
                 ssdSessionFindGroupById ssdSessionSelectedGroup
                 ssdCurrentSelectedGroup
                 ssdSessionSelectedGroupId ssdSessionRelativeGroupId
+                ssdCurrentRelativeGroupId
                 ssdSessionCellIdsForGroupId
                 ssdSessionGroupPresent ssdSessionGroupMissing
                 ssdGroupMissing ssdGroupOrEmpty
@@ -854,6 +855,12 @@
                       (list-ref
                         (SsdSession-groups session)
                         (mod (+ (+ current delta) size) size)))))))))
+        (def (ssdCurrentRelativeGroupId (session : (Nullable SsdSession))
+                                        (id : (Nullable String))
+                                        (delta : Int32)) : (Nullable String)
+          (if (nullable-null? session)
+            (nullable-none String)
+            (ssdSessionRelativeGroupId (nullable-get session) id delta)))
         (def (ssdSessionCellIdsForGroupId (session : SsdSession)
                                           (id : (Nullable String))) : (MutableList String)
           (let ((group (ssdSessionFindGroupById session id)))
@@ -6969,9 +6976,7 @@
        "    }"
        ""
        "    private fun selectRelativeGroup(delta: Int) {"
-       "        if (sessionMissing(currentSession)) return"
-       "        val session = ssdSessionOrEmpty(currentSession)"
-       "        val next = ssdSessionRelativeGroupId(session, selectedGroupId, delta)"
+       "        val next = ssdCurrentRelativeGroupId(currentSession, selectedGroupId, delta)"
        "        if (!nullableTextPresent(next)) return"
        "        selectGroup(nullableTextOrEmpty(next))"
        "    }"