Refactor keymap to allow showing help
This commit is contained in:
parent
0acbca2e62
commit
18c0f6ea7a
|
@ -10,19 +10,37 @@ enum SlideAction:
|
||||||
case Next
|
case Next
|
||||||
case QuickNext
|
case QuickNext
|
||||||
case Quit
|
case Quit
|
||||||
|
case Help
|
||||||
case Interactive(cmd: Vector[String], wd: Path)
|
case Interactive(cmd: Vector[String], wd: Path)
|
||||||
case Other(code: List[Int])
|
case Other(code: List[Int])
|
||||||
|
|
||||||
|
def show: String = this match
|
||||||
|
case Start => "go to first slide"
|
||||||
|
case Goto(slideIndex: Int) => s"jump directly to slide $slideIndex"
|
||||||
|
case GotoSelect => "jump to slide"
|
||||||
|
case Prev => "previous slide (skip animations)"
|
||||||
|
case Next => "next slide"
|
||||||
|
case QuickNext => "next slide (skip animations)"
|
||||||
|
case Quit => "quit"
|
||||||
|
case Help => "show help"
|
||||||
|
case Interactive(cmd: Vector[String], wd: Path) => s"execute command \"${cmd.mkString(" ")}\""
|
||||||
|
case Other(code: List[Int]) => s"Unknown key sequence: $code"
|
||||||
|
|
||||||
|
|
||||||
object SlideAction:
|
object SlideAction:
|
||||||
def runForeground(cmd: String*)(implicit wd: Path) = Interactive(cmd.toVector, wd)
|
def runForeground(cmd: String*)(implicit wd: Path) = Interactive(cmd.toVector, wd)
|
||||||
|
|
||||||
import SlideAction.*
|
import SlideAction.*
|
||||||
|
|
||||||
case class Keymap(bindings: Map[List[Int], SlideAction]):
|
case class Keymap(bindings: Map[Key, SlideAction]):
|
||||||
def apply(keycode: List[Int]): SlideAction = bindings.getOrElse(keycode, Other(keycode))
|
private val lookup = bindings.map((k,v) => k.codes -> v)
|
||||||
|
def apply(keycode: List[Int]): SlideAction = lookup.getOrElse(keycode, Other(keycode))
|
||||||
|
|
||||||
|
def extend(newBindings: Map[Key, SlideAction]) = Keymap(bindings ++ newBindings)
|
||||||
|
def ++(newBindings: Map[Key, SlideAction]) = extend(newBindings)
|
||||||
|
def help: String =
|
||||||
|
bindings.toSeq.sortBy(_._2.toString).map((k,v) => k.show.padTo(8, ' ') + " " + v.show).mkString("\n")
|
||||||
|
|
||||||
def extend(newBindings: Map[List[Int], SlideAction]) = Keymap(bindings ++ newBindings)
|
|
||||||
def ++(newBindings: Map[List[Int], SlideAction]) = Keymap(bindings ++ newBindings)
|
|
||||||
object Keymap:
|
object Keymap:
|
||||||
val empty = Keymap(Map())
|
val empty = Keymap(Map())
|
||||||
val default = Keymap(Map(
|
val default = Keymap(Map(
|
||||||
|
@ -30,53 +48,71 @@ object Keymap:
|
||||||
Key.Left -> Prev,
|
Key.Left -> Prev,
|
||||||
Key.PageUp -> Prev,
|
Key.PageUp -> Prev,
|
||||||
Key('k') -> Prev,
|
Key('k') -> Prev,
|
||||||
Key(' ') -> Next,
|
Key.Space -> Next,
|
||||||
Key('j') -> Next,
|
Key('j') -> Next,
|
||||||
Key.Down -> QuickNext,
|
Key.Down -> QuickNext,
|
||||||
Key.Right -> QuickNext,
|
Key.Right -> QuickNext,
|
||||||
Key.PageDown -> QuickNext,
|
Key.PageDown -> QuickNext,
|
||||||
Key('q') -> Quit,
|
Key('q') -> Quit,
|
||||||
Key('g') -> Start,
|
Key('g') -> Start,
|
||||||
|
Key.Enter -> Start,
|
||||||
Key('s') -> GotoSelect,
|
Key('s') -> GotoSelect,
|
||||||
|
Key('?') -> Help,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
enum Key:
|
||||||
|
case Code(name: String, codepoints: List[Int])
|
||||||
|
case Printable(char: Char)
|
||||||
|
|
||||||
|
def codes: List[Int] =
|
||||||
|
this match
|
||||||
|
case Code(_, cp) => cp
|
||||||
|
case Printable(char) => List(char.toInt)
|
||||||
|
|
||||||
|
def show: String =
|
||||||
|
this match
|
||||||
|
case Code(name, _) => name
|
||||||
|
case Printable(c) => c.toString
|
||||||
|
|
||||||
object Key:
|
object Key:
|
||||||
|
def apply(char: Char): Key = Printable(char)
|
||||||
|
def apply(name: String, codepoints: Int*): Key = Code(name, codepoints.toList)
|
||||||
object codes:
|
object codes:
|
||||||
val Esc = 27
|
val esc = 27
|
||||||
val Backspace = 127
|
val backspace = 127
|
||||||
val Esc = List[Int](codes.Esc)
|
|
||||||
val Backspace = List[Int](codes.Backspace)
|
|
||||||
val Delete = List[Int](codes.Esc, '[', '3', '~')
|
|
||||||
|
|
||||||
val PageUp = List[Int](codes.Esc, '[', '5', '~')
|
val Esc = Key("Escape", codes.esc)
|
||||||
val PageDown = List[Int](codes.Esc, '[', '6', '~')
|
val Backspace = Key("Backspace", codes.backspace)
|
||||||
|
val Delete = Key("Delete", codes.esc, '[', '3', '~')
|
||||||
|
|
||||||
val Home = List[Int](codes.Esc, '[', 'H')
|
val PageUp = Key("PageUp", codes.esc, '[', '5', '~')
|
||||||
val End = List[Int](codes.Esc, '[', 'F')
|
val PageDown = Key("PageDown", codes.esc, '[', '6', '~')
|
||||||
|
|
||||||
val F1 = List[Int](codes.Esc, 'P')
|
val Home = Key("Home", codes.esc, '[', 'H')
|
||||||
val F2 = List[Int](codes.Esc, 'Q')
|
val End = Key("End", codes.esc, '[', 'F')
|
||||||
val F3 = List[Int](codes.Esc, 'R')
|
|
||||||
val F4 = List[Int](codes.Esc, 'S')
|
|
||||||
|
|
||||||
val F5 = List[Int](codes.Esc, '1', '5', '~')
|
val F1 = Key("F1", codes.esc, 'P')
|
||||||
val F6 = List[Int](codes.Esc, '1', '7', '~')
|
val F2 = Key("F2", codes.esc, 'Q')
|
||||||
val F7 = List[Int](codes.Esc, '1', '8', '~')
|
val F3 = Key("F3", codes.esc, 'R')
|
||||||
val F8 = List[Int](codes.Esc, '1', '9', '~')
|
val F4 = Key("F4", codes.esc, 'S')
|
||||||
|
|
||||||
val F9 = List[Int](codes.Esc, '2', '0', '~')
|
val F5 = Key("F5", codes.esc, '1', '5', '~')
|
||||||
val F10 = List[Int](codes.Esc, '2', '1', '~')
|
val F6 = Key("F6", codes.esc, '1', '7', '~')
|
||||||
val F11 = List[Int](codes.Esc, '2', '3', '~')
|
val F7 = Key("F7", codes.esc, '1', '8', '~')
|
||||||
val F12 = List[Int](codes.Esc, '2', '4', '~')
|
val F8 = Key("F8", codes.esc, '1', '9', '~')
|
||||||
|
|
||||||
val Tab = List[Int]('\t')
|
val F9 = Key("F9", codes.esc, '2', '0', '~')
|
||||||
|
val F10 = Key("F10", codes.esc, '2', '1', '~')
|
||||||
|
val F11 = Key("F11", codes.esc, '2', '3', '~')
|
||||||
|
val F12 = Key("F12", codes.esc, '2', '4', '~')
|
||||||
|
|
||||||
val Up = List[Int](codes.Esc, '[', 'A')
|
val Space = Key("<space>", ' ')
|
||||||
val Down = List[Int](codes.Esc, '[', 'B')
|
val Tab = Key("<tab>", '\t')
|
||||||
val Right = List[Int](codes.Esc, '[', 'C')
|
val Enter = Key("<enter>", '\n')
|
||||||
val Left = List[Int](codes.Esc, '[', 'D')
|
|
||||||
|
|
||||||
def apply(char: Char): List[Int] = List(char.toInt)
|
val Up = Key("Up", codes.esc, '[', 'A')
|
||||||
|
val Down = Key("Down", codes.esc, '[', 'B')
|
||||||
|
val Right = Key("Right", codes.esc, '[', 'C')
|
||||||
|
val Left = Key("Left", codes.esc, '[', 'D')
|
||||||
|
|
||||||
/* vim:set tw=120: */
|
/* vim:set tw=120: */
|
||||||
|
|
|
@ -10,14 +10,14 @@ case class Presentation(slides: Vector[Slide], meta: Map[String, String] = Map.e
|
||||||
run()
|
run()
|
||||||
|
|
||||||
import Presentation._
|
import Presentation._
|
||||||
def run()(using Keymap) =
|
def run()(using keymap: Keymap) =
|
||||||
import SlideAction.*
|
import SlideAction.*
|
||||||
@annotation.tailrec def rec(p: Presentation, pos: Int, action: SlideAction): Unit =
|
@annotation.tailrec def rec(p: Presentation, pos: Int, action: SlideAction): Unit =
|
||||||
action match
|
action match
|
||||||
case Start =>
|
case Start =>
|
||||||
executeSlide(p, pos)()
|
executeSlide(p, pos)()
|
||||||
rec(p, 0, waitkey)
|
rec(p, 0, waitkey)
|
||||||
case Next | Other(_) =>
|
case Next =>
|
||||||
if pos + 1 < p.slides.size then
|
if pos + 1 < p.slides.size then
|
||||||
executeSlide(p, pos + 1)()
|
executeSlide(p, pos + 1)()
|
||||||
rec(p, pos + 1, waitkey)
|
rec(p, pos + 1, waitkey)
|
||||||
|
@ -55,6 +55,15 @@ case class Presentation(slides: Vector[Slide], meta: Map[String, String] = Map.e
|
||||||
target match
|
target match
|
||||||
case Some(i) => rec(p, pos, Goto(i))
|
case Some(i) => rec(p, pos, Goto(i))
|
||||||
case None => rec(p, pos - 1, QuickNext)
|
case None => rec(p, pos - 1, QuickNext)
|
||||||
|
case Help =>
|
||||||
|
Terminal.clear()
|
||||||
|
println(keymap.help)
|
||||||
|
waitkey
|
||||||
|
rec(p, pos - 1, QuickNext)
|
||||||
|
case Other(codes) =>
|
||||||
|
Terminal.cursorTo(Terminal.height, 1)
|
||||||
|
println(action.show)
|
||||||
|
rec(p, pos, waitkey)
|
||||||
case Quit =>
|
case Quit =>
|
||||||
()
|
()
|
||||||
rec(this, 0, Start)
|
rec(this, 0, Start)
|
||||||
|
|
Loading…
Reference in a new issue