Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ val Versions = new {
val scalaVersions = Seq(Scala3)
val fansi = "0.5.0"
val jna = "5.14.0"
val catsEffect = "3.6.0"
val catsEffect = "3.7.0"
val osLib = "0.11.3"
val scalaJavaTime = "2.6.0"
}
Expand Down Expand Up @@ -126,7 +126,7 @@ lazy val example = projectMatrix
.nativePlatform(
Versions.scalaVersions,
settings = Seq(
Compile / mainClass := Some("cue4s_example.tictac"),
Compile / mainClass := Some("cue4s_example.sync"),
libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % Versions.scalaJavaTime,
),
)
Expand Down
17 changes: 15 additions & 2 deletions modules/core/src/main/scalanative/ChangeModeMac.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,23 @@ import cue4s.ChangeModeUnix.Termios
import scalanative.unsafe.*

object ChangeModeMac extends ChangeModeUnix:
// int read(int fd, byte[] buf, int count);
import scalanative.posix.termios.{TCSANOW, ECHO, ICANON}

type termios = scalanative.posix.termios.termios
type tcflag_t = CLong
type cc_t = CChar
type speed_t = CLong
import scalanative.unsafe.Nat.*
type NCCS = Digit2[_2, _0]
type c_cc = CArray[cc_t, NCCS]
type termios = CStruct7[
tcflag_t, /* c_iflag - input flags */
tcflag_t, /* c_oflag - output flags */
tcflag_t, /* c_cflag - control flags */
tcflag_t, /* c_lflag - local flags */
c_cc, /* cc_t c_cc[NCCS] - control chars */
speed_t, /* c_ispeed - input speed */
speed_t, /* c_ospeed - output speed */
]

private val VTIME = 17
private val VMIN = 16
Expand Down
153 changes: 94 additions & 59 deletions modules/example/src/main/scala-jvm-native/sync.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,69 +19,104 @@ package cue4s_example
import cue4s.*
import cue4s.Prompt.PasswordInput.Password

@main def sync =
@main def sync(which: String*) =
Prompts.sync.use: prompts =>
val likeCats = prompts
.confirm("Do you like cats?")
.toOption

val day = prompts
.singleChoice(
"How was your day?",
List(
"amazing",
"productive",
"relaxing",
"stressful",
"exhausting",
"challenging",
"wonderful",
"uneventful",
"interesting",
"exciting",
"boring",
"demanding",
"satisfying",
"frustrating",
"peaceful",
"overwhelming",
"busy",
"calm",
"enjoyable",
"memorable",
"ordinary",
"fantastic",
"rewarding",
"chaotic",
),
_.withWindowSize(7),
)
.toOption

val skyColor: Completion[Boolean] = prompts.run(
Prompt
.Input("What color is the sky?")
.mapValidated: s =>
Either.cond(s == "blue", true, PromptError("hint: it's blue")),
val examples = Map[String, (String, SyncPrompts => Unit)](
"confirm" -> ("Yes/No confirmation", likeCats),
"single-choice" -> ("Single choice", day),
"multi-choice" -> ("Multiple choice", letters),
"validated-int" -> ("Validated integer", seasons),
"password" -> ("Password", password),
)

val letters: Completion[List[String]] =
prompts.multiChoiceNoneSelected(
"What are your favourite letters?",
('A' to 'Z').map(_.toString).toList,
_.withWindowSize(7),
)
if which.isEmpty then
val maxLength = examples.keys.map(_.length).max

val selected = prompts
.multiChoiceNoneSelected(
"Which examples would you like to run?",
examples
.map { case (k, (desc, _)) =>
s"${k.padTo(maxLength, ' ')}: $desc"
}
.toList
.sorted,
)
.getOrThrow

val seasons: Completion[Int] =
prompts.int(
"How many seasons of Stargate SG-1 are there",
_.validate:
case x if x < 10 => Option(PromptError("More!"))
case x if x > 10 => Option(PromptError("Fewer!"))
case _ => None,
)
val toShow = selected.map(_.split(": ").head.trim)
toShow.foreach { k => examples(k)._2(prompts) }
else
val allowed = examples.keySet
val missing = which.toSet -- allowed

val password: Completion[Password] =
prompts.password("Choose a new password")
if missing.nonEmpty then
sys.error(s"Unknown example names: ${missing
.mkString(", ")}. Available examples: ${allowed.mkString(", ")}")
else which.foreach { k => examples(k)._2(prompts) }
end if

end sync

def likeCats(prompts: SyncPrompts) = prompts
.confirm("Do you like cats?")
.toOption

def day(prompts: SyncPrompts) = prompts
.singleChoice(
"How was your day?",
List(
"amazing",
"productive",
"relaxing",
"stressful",
"exhausting",
"challenging",
"wonderful",
"uneventful",
"interesting",
"exciting",
"boring",
"demanding",
"satisfying",
"frustrating",
"peaceful",
"overwhelming",
"busy",
"calm",
"enjoyable",
"memorable",
"ordinary",
"fantastic",
"rewarding",
"chaotic",
),
_.withWindowSize(7),
)
.toOption

def skyColor(prompts: SyncPrompts): Completion[Boolean] = prompts.run(
Prompt
.Input("What color is the sky?")
.mapValidated: s =>
Either.cond(s == "blue", true, PromptError("hint: it's blue")),
)

def letters(prompts: SyncPrompts): Completion[List[String]] =
prompts.multiChoiceNoneSelected(
"What are your favourite letters?",
('A' to 'Z').map(_.toString).toList,
_.withWindowSize(7),
)

def seasons(prompts: SyncPrompts): Completion[Int] =
prompts.int(
"How many seasons of Stargate SG-1 are there",
_.validate:
case x if x < 10 => Option(PromptError("More!"))
case x if x > 10 => Option(PromptError("Fewer!"))
case _ => None,
)

def password(prompts: SyncPrompts): Completion[Password] =
prompts.password("Choose a new password")
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.11.7
sbt.version=1.12.8
4 changes: 2 additions & 2 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.8.1")
// Scala.js and Scala Native
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.20.1")

addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.9")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.11")

addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16")

addSbtPlugin("com.indoorvivants.snapshots" % "sbt-snapshots" % "0.0.11")

addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.4")

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
Loading