Skip to content

Commit

Permalink
Merge pull request #20 from bash/windows
Browse files Browse the repository at this point in the history
  • Loading branch information
bash authored Sep 3, 2024
2 parents 3a8b2f9 + 5f41e47 commit 9880503
Show file tree
Hide file tree
Showing 23 changed files with 139 additions and 136 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
run: rustup override set '${{matrix.rust-version}}'
- name: Build
run: cargo build --workspace --all-features
- name: Check fallback implementation
run: cargo check --workspace
env:
RUSTFLAGS: --cfg terminal_colorsaurus_test_unsupported -Dwarnings
docs:
name: Docs
runs-on: ubuntu-latest
Expand All @@ -58,6 +62,8 @@ jobs:
- name: Run clippy
run: cargo clippy --workspace --all-targets --all-features -- --deny warnings
- uses: EmbarkStudios/cargo-deny-action@v1
- name: Check spelling
uses: crate-ci/typos@v1.24.4
test:
name: Test
strategy:
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@ cfg-if = "1.0.0"
[target.'cfg(unix)'.dependencies]
memchr = "2.7.1"
mio = { version = "1", features = ["os-ext"], default-features = false }
terminal-trx = "0.2.0"
terminal-trx = "0.2.3"

[target.'cfg(target_os = "macos")'.dependencies]
libc = "0.2.151"

[target.'cfg(windows)'.dependencies]
memchr = "2.7.1"
terminal-trx = "0.2.3"
windows-sys = { version = "0.59.0", features = ["Win32_System_Threading"] } # Keep this in sync with terminal-trx's version to avoid duplicate deps.

[lints.rust]
missing_debug_implementations = "warn"
missing_docs = "warn"
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(terminal_colorsaurus_test_unsupported)"] }

[lints.clippy]
dbg_macro = "warn"
Expand Down
2 changes: 1 addition & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* Add new convenience function `color_scheme` which returns a nice `Dark / Light` enum.
* Add support for urxvt's `rgba:` color format.
* Further refined the documentation (more organized terminal list, new terminals tested).
* Improved handling of ambigous color palettes (e.g. when background color is the same as foreground).
* Improved handling of ambiguous color palettes (e.g. when background color is the same as foreground).
* Queries are now terminated with `ST` (the standard string terminator) instead of `BEL` (which is an xterm extension).

## 0.3.3
Expand Down
2 changes: 1 addition & 1 deletion doc/feature-detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Colorsaurus sends two escape sequences: `OSC 10` (or `OSC 11`) followed by `DA1`
`DA1` is supported by almost every terminal.

Terminals process incoming escape sequences in order.
Therefore if the reponse to `DA1` is seen first, then the terminal does not support `OSC 10` (or `OSC 11`).
Therefore if the response to `DA1` is seen first, then the terminal does not support `OSC 10` (or `OSC 11`).

Colorsaurus thus doesn't need to rely on a timeout to detect if a terminal supports `OSC 10` (or `OSC 11`).

Expand Down
7 changes: 4 additions & 3 deletions doc/terminal-survey.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ A list of terminals that were tested for support of `OSC 10` / `OSC 11` and `DA1
| [Termux] | yes | yes | 0.118.0 |
| VSCode ([xterm.js]) | yes | yes | 1.85.1 (macOS) |
| [WezTerm] | yes | yes | 20240203-110809-5046fc22 (flatpak) |
| Windows Terminal (conhost) | yes | yes | [`b3f4162`][conhost-commit] |
| [xterm] | yes | yes | 385 |
| [zed] | yes | yes | [`9245015`][zed-version]|
| [zed] | yes | yes | [`9245015`][zed-commit]|
| anyterm | no | *no* | 1.2.3 |
| ConEmu / Cmder | no | yes | 230724 stable |
| cool-retro-term | no | yes | 1.2.0 |
Expand All @@ -35,7 +36,6 @@ A list of terminals that were tested for support of `OSC 10` / `OSC 11` and `DA1
| shellinabox | no | *no* | 2.20 |
| QMLKonsole | no | yes | 23.08.5 |
| [QTerminal] | no | yes | 1.3.0 |
| Windows Terminal (conhost) | no | yes | 1.18.3181.0 |

<br>

Expand All @@ -54,6 +54,7 @@ printf '\e]11;?\e\\' && cat -v # Tests for background color support. Example out

[Alacritty]: https://alacritty.org/
[anyterm]: https://anyterm.org/
[conhost-commit]: https://github.com/microsoft/terminal/commit/b3f41626b4d212da8ca7c08077b12c289f918c86
[Console]: https://apps.gnome.org/en-GB/Console/
[Contour]: https://contour-terminal.org/
[cool-retro-term]: https://github.com/Swordfish90/cool-retro-term
Expand All @@ -78,5 +79,5 @@ printf '\e]11;?\e\\' && cat -v # Tests for background color support. Example out
[WezTerm]: https://wezfurlong.org/wezterm/
[xterm.js]: https://xtermjs.org/
[xterm]: https://invisible-island.net/xterm/
[zed-commit]: https://github.com/zed-industries/zed/commit/9245015d1a005611801d7393e4d7e3cdf5fbca0c
[zed]: https://zed.dev/
[zed-version]: https://github.com/zed-industries/zed/commit/9245015d1a005611801d7393e4d7e3cdf5fbca0c
24 changes: 0 additions & 24 deletions doc/windows-read-with-timeout.md

This file was deleted.

21 changes: 0 additions & 21 deletions doc/windows.md

This file was deleted.

8 changes: 8 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mod time_out;
use time_out::*;
mod poll;
pub(crate) use poll::*;
mod read_until;
pub(crate) use read_until::*;
mod term_reader;
pub(crate) use term_reader::*;
10 changes: 5 additions & 5 deletions src/os/macos/poll.rs → src/io/poll/macos.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use crate::os::unix_common::timed_out;
use super::super::read_timed_out;
use libc::{c_int, pselect, time_t, timespec, FD_ISSET, FD_SET};
use std::io;
use std::mem::zeroed;
use std::os::fd::{AsRawFd as _, BorrowedFd};
use std::ptr::{null, null_mut};
use std::time::Duration;
use terminal_trx::Transceive;

// macOS does not support polling /dev/tty using kqueue, so we have to
// resort to pselect/select. See https://nathancraddock.com/blog/macos-dev-tty-polling/.
pub(crate) fn poll_read(terminal: BorrowedFd, timeout: Duration) -> io::Result<()> {
pub(crate) fn poll_read(terminal: &dyn Transceive, timeout: Duration) -> io::Result<()> {
if timeout.is_zero() {
return Err(timed_out());
return Err(read_timed_out());
}

let fd = terminal.as_raw_fd();
Expand All @@ -32,7 +32,7 @@ pub(crate) fn poll_read(terminal: BorrowedFd, timeout: Duration) -> io::Result<(
if FD_ISSET(fd, &readfds) {
Ok(())
} else {
Err(timed_out())
Err(read_timed_out())
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/io/poll/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use cfg_if::cfg_if;

cfg_if! {
if #[cfg(target_os = "macos")] {
mod macos;
pub(crate) use macos::*;
} else if #[cfg(unix)] {
mod unix;
pub(crate) use unix::*;
} else if #[cfg(windows)] {
mod windows;
pub(crate) use windows::*;
}
}
10 changes: 5 additions & 5 deletions src/os/unix/poll.rs → src/io/poll/unix.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::os::unix_common::timed_out;
use super::super::read_timed_out;
use mio::unix::SourceFd;
use mio::{Events, Interest, Poll, Token};
use std::io;
use std::os::fd::{AsRawFd as _, BorrowedFd};
use std::time::Duration;
use terminal_trx::Transceive;

pub(crate) fn poll_read(terminal: BorrowedFd, timeout: Duration) -> io::Result<()> {
pub(crate) fn poll_read(terminal: &dyn Transceive, timeout: Duration) -> io::Result<()> {
if timeout.is_zero() {
return Err(timed_out());
return Err(read_timed_out());
}

let mut poll = Poll::new()?;
Expand All @@ -24,5 +24,5 @@ pub(crate) fn poll_read(terminal: BorrowedFd, timeout: Duration) -> io::Result<(
return Ok(());
}
}
Err(timed_out())
Err(read_timed_out())
}
17 changes: 17 additions & 0 deletions src/io/poll/windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use super::super::read_timed_out;
use std::io;
use std::os::windows::io::AsRawHandle as _;
use std::time::Duration;
use terminal_trx::Transceive;
use windows_sys::Win32::Foundation::{WAIT_ABANDONED, WAIT_OBJECT_0, WAIT_TIMEOUT};
use windows_sys::Win32::System::Threading::WaitForSingleObject;

pub(crate) fn poll_read(terminal: &dyn Transceive, timeout: Duration) -> io::Result<()> {
let handle = terminal.input_buffer_handle();
match unsafe { WaitForSingleObject(handle.as_raw_handle(), timeout.as_millis() as u32) } {
// The state of the specified object is signaled.
WAIT_OBJECT_0 => Ok(()),
WAIT_ABANDONED | WAIT_TIMEOUT => Err(read_timed_out()),
_ => Err(io::Error::last_os_error()),
}
}
38 changes: 1 addition & 37 deletions src/xterm/io_utils.rs → src/io/read_until.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use crate::os::poll_read;
use std::io::{self, BufRead};
use std::os::fd::AsFd;
use std::time::{Duration, Instant};

// Copied from the standard library with modification
// to support searching for two bytes.
// https://github.com/rust-lang/rust/blob/e35a56d96f7d9d4422f2b7b00bf0bf282b2ec782/library/std/src/io/mod.rs#L2067
pub(super) fn read_until2<R: BufRead + ?Sized>(
pub(crate) fn read_until2<R: BufRead + ?Sized>(
r: &mut R,
delim1: u8,
delim2: u8,
Expand Down Expand Up @@ -35,36 +32,3 @@ pub(super) fn read_until2<R: BufRead + ?Sized>(
}
}
}

#[derive(Debug)]
pub(super) struct TermReader<R> {
inner: R,
timeout: Duration,
first_read: Option<Instant>,
}

impl<R> io::Read for TermReader<R>
where
R: io::Read + AsFd,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let timeout = self.remaining_timeout();
poll_read(self.inner.as_fd(), timeout)?;
self.inner.read(buf)
}
}

impl<R> TermReader<R> {
pub(super) fn new(inner: R, timeout: Duration) -> Self {
Self {
inner,
timeout,
first_read: None,
}
}

fn remaining_timeout(&mut self) -> Duration {
let first_read = self.first_read.get_or_insert_with(Instant::now);
self.timeout.saturating_sub(first_read.elapsed())
}
}
37 changes: 37 additions & 0 deletions src/io/term_reader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use super::poll_read;
use std::io;
use std::time::{Duration, Instant};
use terminal_trx::Transceive;

#[derive(Debug)]
pub(crate) struct TermReader<R> {
inner: R,
timeout: Duration,
first_read: Option<Instant>,
}

impl<R> io::Read for TermReader<R>
where
R: Transceive,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let timeout = self.remaining_timeout();
poll_read(&self.inner, timeout)?;
self.inner.read(buf)
}
}

impl<R> TermReader<R> {
pub(crate) fn new(inner: R, timeout: Duration) -> Self {
Self {
inner,
timeout,
first_read: None,
}
}

fn remaining_timeout(&mut self) -> Duration {
let first_read = self.first_read.get_or_insert_with(Instant::now);
self.timeout.saturating_sub(first_read.elapsed())
}
}
2 changes: 1 addition & 1 deletion src/os/unix_common.rs → src/io/time_out.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error;
use std::{fmt, io};

pub(crate) fn timed_out() -> io::Error {
pub(crate) fn read_timed_out() -> io::Error {
io::Error::new(io::ErrorKind::TimedOut, PollReadTimedOutError)
}

Expand Down
Loading

0 comments on commit 9880503

Please sign in to comment.