diff successive buffers with embedded ansi codes in rust, outputting a minimal change

Overview

ansi-diff

diff successive buffers with embedded ansi codes in rust, outputting a minimal change

You can use this crate to build command-line interfaces in an "immediate mode" way where you can produce pages of output which will be diffed to avoid the flicker you would otherwise get if you cleared the whole screen between updates, but preserving the convenience of that approach.

You can include ansi codes for formatting your output but codes that adjust the cursor position are not (yet) supported. You can manage cursor positions to place panes of content using the output of this crate, but you will need to write that glue yourself.

This package is a rust port of the node.js ansi-diff package also including code adapted from ansi-split and ansi-regex.

example: time

This is a simple example that prints 4 lines of text and updates a counter for the seconds elapsed:

(u32,u32) { term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap() }">
use std::io::Write;

fn main() {
  let mut diff = ansi_diff::Diff::new(get_size());
  let start = std::time::Instant::now();
  loop {
    print!["{}", diff.update(&format![
      "-------------\nseconds elapsed: {:.0} ...\n-------------\n",
      start.elapsed().as_secs_f32()
    ])];
    std::io::stdout().flush().unwrap();
    std::thread::sleep(std::time::Duration::from_secs(1));
  }
}

fn get_size() -> (u32,u32) {
  term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap()
}

example: resize

This is a version of the previous time example that sets up terminal resize hooks for the SIGWINCH event:

(u32,u32) { term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap() } fn resizer(diff: Arc >) { let mut signals = SignalsInfo:: ::new(&vec![SIGWINCH]).unwrap(); for info in &mut signals { if info.signal == SIGWINCH { diff.lock().unwrap().resize(get_size()) } } }">
// to use this example, enable iterator and extended-siginfo features in Cargo.toml dependencies:
// signal-hook = { version = "0.3.13", features = [ "iterator", "extended-siginfo" ] }

use std::io::Write;
use signal_hook::{iterator::{SignalsInfo,exfiltrator::WithOrigin},consts::signal::SIGWINCH};
use std::sync::{Arc,Mutex};
use ansi_diff::Diff;

fn main() {
  let diff = Arc::new(Mutex::new(Diff::new(get_size())));
  let diff_c = diff.clone();
  std::thread::spawn(move || { resizer(diff_c) });

  let start = std::time::Instant::now();
  loop {
    print!["{}", diff.lock().unwrap().update(&format![
      "-------------\nseconds elapsed: {:.0} ...\n-------------\n",
      start.elapsed().as_secs_f32()
    ])];
    std::io::stdout().flush().unwrap();
    std::thread::sleep(std::time::Duration::from_secs(1));
  }
}

fn get_size() -> (u32,u32) {
  term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap()
}

fn resizer(diff: Arc
      
       >) {
  
       let 
       mut signals 
       = SignalsInfo
       ::
       <WithOrigin
       >
       ::
       new(
       &
       vec![SIGWINCH]).
       unwrap();
  
       for info 
       in 
       &
       mut signals {
    
       if info.signal 
       == SIGWINCH { diff.
       lock().
       unwrap().
       resize(
       get_size()) }
  }
}
      
     

example: colors

This is a more involved version of the first example that includes ansi formatting in the output stream:

(u32,u32) { term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap() }">
use std::io::Write;

fn main() {
  let mut diff = ansi_diff::Diff::new(get_size());
  // todo: on sigwinch, diff.resize()
  let start = std::time::Instant::now();
  loop {
    print!["{}", diff.update(&format![
      "{}\n{}\n{}\n",
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ`0123456789-=",
      format![
        "\x1b[31m{:.0}\x1b[39m seconds have elapsed \x1b[32m!!!\x1b[39m",
        start.elapsed().as_secs_f32(),
      ],
      "abcdefghijklmnopqrstuvwxyz~!@#$%^&*()_+",
    ])];
    std::io::stdout().flush().unwrap();
    std::thread::sleep(std::time::Duration::from_secs(1));
  }
}

fn get_size() -> (u32,u32) {
  term_size::dimensions().map(|(w,h)| (w as u32, h as u32)).unwrap()
}

license

bsd-2-clause

You might also like...
A compatibility layer to smooth the transition between different versions of embedded-hal

Embedded HAL Compatibility Layer A compatibility layer to smooth the transition between different versions of embedded-hal (specifically 0.2.x and 1.0

⚙️ Crate to discover embedded programming with uno r3 project

⚙️ Crate to discover embedded programming with uno r3 project

Ector is an open source async, no-alloc actor framework for embedded devices

Ector is an open source async, no-alloc actor framework for embedded devices. Ector is an open source async, no-alloc actor framework for embedded dev

An embedded-hal driver for the TT21100 multi-touch touchscreen controller

tt21100 An embedded-hal driver for the TT21100 multi-touch touchscreen controller. If there is a feature which has not yet been implemented and which

Embedded-hal simulator.

hal-sim - embedded-hal Simulator (WIP - UNFINISHED) This crate simulates a small portion of the embedded-hal traits. Namely: GPIO ADC Additionally, it

Drop-in embedded database
Drop-in embedded database

Struct DB 🔧 🔩 Provides a drop-in, fast, and embedded database solution, focusing on maintaining coherence between Rust types and stored data with mi

A reactive runtime for embedded systems.

Actuate Examples A reactive diagram for robotics and control systems. Actuate leverages Rust's type system to create an efficient diagram that connect

A lean, minimal, and stable set of types for color interoperation between crates in Rust.

This library provides a lean, minimal, and stable set of types for color interoperation between crates in Rust. Its goal is to serve the same function that mint provides for (linear algebra) math types.

Minimal, flexible framework for implementing solutions to Advent of Code in Rust

This is advent_of_code_traits, a minimal, flexible framework for implementing solutions to Advent of Code in Rust.

Owner
James Halliday
James Halliday
Freebsd-embedded-hal - Like linux-embedded-hal but FreeBSD

freebsd-embedded-hal Implementation of embedded-hal traits for FreeBSD devices: gpio: using libgpio, with stateful and toggleable support, with suppor

null 2 Oct 1, 2022
Simple ansi colors

Simple ansi colors

null 1 Dec 24, 2021
Check Have I Been Pwned and see if it's time for you to change passwords.

checkpwn Check Have I Been Pwned and see if it's time for you to change passwords. Getting started Install: cargo install checkpwn Update: cargo inst

Johannes 93 Dec 13, 2022
A small utility for tracking the change in opening and closing of issues in a GitHub repo

A small utility for tracking the change in opening and closing of issues in a GitHub repo. This tool can be used to build visualizations for issue triage over time with the hope of motivating closing more issues than are opened.

Ryan Levick 12 Sep 29, 2021
tri-angle trader without trade, just watch pair's price change, print arbtrage chance.

tri-angle trader without trade, just watch pair's price change, print arbtrage chance.

铁哥 5 Nov 19, 2022
TI LDC1312/LDC1314/LDC1612/LDC1614 inductance-to-digital converter driver for Rust embedded-hal

ldc1x1x Rust embedded-hal 1.x driver for Texas Instruments (TI) I²C inductance-to-digital converters (LDC): LDC1312/LDC1314, LDC1612/LDC1614. Includes

null 2 Oct 2, 2022
Port of the fantastic Iconoir Icon Pack to Rust embedded devices, with a focus on speed, usability, and completeness.

embedded-iconoir - Icons for every device, ever. What is embedded-iconor? embedded-iconoir is a library that allows you to use Iconoir on embedded dev

null 9 Mar 25, 2023
Crate of GitHub’s collection of gitignores, embedded, automatically updated

Gitignores GitHub’s collection of gitignores, embedded, automatically updated. API documentation. Public Domain via CC0-1.0 (same as source data). MSR

null 3 May 3, 2022
C API to SpringQL (for embedded mode)

SpringQL C Client This repository is a C client for SpringQL and provides it provides: springql.h: C header file. libspringql_client.{so,dylib}: Share

SpringQL 4 Jun 8, 2022
An asynchronous Hardware Abstraction Layer (HAL) for embedded systems

embedded-hal-async An asynchronous Hardware Abstraction Layer (HAL) for embedded systems. This crate contains asynchronous versions of the embedded-ha

Diego Barrios Romero 3 Jan 22, 2022