Skip to content

Commit

Permalink
Fix readOrNull throwing on timeout (#258)
Browse files Browse the repository at this point in the history
Fixes #256
  • Loading branch information
ajalt authored Feb 15, 2025
1 parent a8f3462 commit 82d3c90
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 8 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Changelog

## Unreleased
## Changed
- `Terminal.rawPrint` now takes a `CharSequence` instead of a `String`
### Changed
- `Terminal.rawPrint` now takes a `CharSequence` instead of a `String` [(#255)](https://github.com/ajalt/mordant/issues/255)

### Fixed
- Fixed `Terminal.read*OrNull` throwing an exception on timeout on Windows. [(#256)](https://github.com/ajalt/mordant/issues/256)

## 3.0.1
### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.ajalt.mordant.terminal.terminalinterface.ffm

import com.github.ajalt.mordant.rendering.Size
import com.github.ajalt.mordant.terminal.TimeoutException
import com.github.ajalt.mordant.terminal.terminalinterface.TerminalInterfaceWindows
import java.lang.foreign.*

Expand Down Expand Up @@ -279,7 +280,7 @@ internal class TerminalInterfaceFfmWindows : TerminalInterfaceWindows() {
val stdin = stdinHandle
val waitResult = kernel.WaitForSingleObject(stdin, dwMilliseconds)
if (waitResult != 0) {
throw RuntimeException("Timeout reading from console input")
throw TimeoutException()
}
val inputEvents = arena.allocate(WinKernel32Library.INPUT_RECORD.Layout.layout, 1)
val eventsReadSeg = arena.allocateInt()
Expand Down
4 changes: 4 additions & 0 deletions mordant/api/mordant.api
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,10 @@ public final class com/github/ajalt/mordant/terminal/TerminalRecorder : com/gith
public final fun stdout ()Ljava/lang/String;
}

public final class com/github/ajalt/mordant/terminal/TimeoutException : java/lang/RuntimeException {
public fun <init> ()V
}

public final class com/github/ajalt/mordant/terminal/YesNoPrompt : com/github/ajalt/mordant/terminal/Prompt {
public fun <init> (Ljava/lang/String;Lcom/github/ajalt/mordant/terminal/Terminal;Ljava/lang/Boolean;ZZLjava/util/List;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Lcom/github/ajalt/mordant/terminal/Terminal;Ljava/lang/Boolean;ZZLjava/util/List;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.ajalt.mordant.input

import com.github.ajalt.mordant.terminal.Terminal
import com.github.ajalt.mordant.terminal.TimeoutException
import kotlin.time.Duration
import kotlin.time.TimeSource

Expand Down Expand Up @@ -102,11 +103,13 @@ class RawModeScope internal constructor(
timeout: Duration, skip: (InputEvent) -> Boolean,
): InputEvent? {
val t = TimeSource.Monotonic.markNow() + timeout
do {
val event = terminal.terminalInterface.readInputEvent(t, mouseTracking) ?: continue
if (event is MouseEvent && mouseTracking == MouseTracking.Off || skip(event)) continue
return event
} while (t.hasNotPassedNow())
try {
do {
val event = terminal.terminalInterface.readInputEvent(t, mouseTracking) ?: continue
if (event is MouseEvent && mouseTracking == MouseTracking.Off || skip(event)) continue
return event
} while (t.hasNotPassedNow())
} catch (_: TimeoutException) {}
return null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,5 @@ data class PrintRequest(
*/
val stderr: Boolean,
)

class TimeoutException : RuntimeException("Timeout waiting for input")

0 comments on commit 82d3c90

Please sign in to comment.