Skip to content

Instantly share code, notes, and snippets.

@ryochack
Last active June 28, 2019 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryochack/3ff1d3287910c9c32a19065808e21a48 to your computer and use it in GitHub Desktop.
Save ryochack/3ff1d3287910c9c32a19065808e21a48 to your computer and use it in GitHub Desktop.
Get current tabstop
use std::io;
mod term {
use termios;
/// echo off. Return old termios state.
pub fn echo_off() -> termios::Termios {
let oldstat = termios::Termios::from_fd(0).unwrap();
let mut termstat = oldstat;
termstat.c_lflag &= !(termios::ICANON | termios::ECHO);
termios::tcsetattr(0, termios::TCSANOW, &termstat).unwrap();
oldstat
}
/// echo on. Pass old termios state.
pub fn echo_on(termstat: &termios::Termios) {
termios::tcsetattr(0, termios::TCSANOW, &termstat).unwrap();
}
}
mod csi {
use std::io::{self, Read, Write};
// avoid zero
fn _nz(n: u32) -> u32 {
if n == 0 {
1
} else {
n
}
}
/// CHA: cursor horizontal absolute
pub fn cha(w: &mut Write, n: u32) {
write!(w, "{}", format!("\x1b[{}G", _nz(n))).unwrap();
}
/// DSR: device status report
/// return (row, col)
pub fn dsr(w: &mut Write) -> Option<(u32, u32)> {
let oldstat: Box<termios::Termios> = Box::new(super::term::echo_off());
write!(w, "\x1b[6n").unwrap();;
w.flush().unwrap();
let (mut row, mut col, mut tmp) = (0u32, 0u32, 0u32);
let s = io::stdin();
// => "[${row};${col}R"
for b in s.lock().bytes().filter_map(|v| v.ok()) {
match b {
// '0' ... '9'
0x30...0x39 => {
tmp = tmp * 10 + u32::from(b - 0x30);
}
// ';'
0x3b => {
row = tmp;
tmp = 0;
}
// 'R'
0x52 => {
col = tmp;
break;
}
_ => {}
}
}
super::term::echo_on(&*oldstat);
Some((row, col))
}
}
// print current tabstop
fn main() {
let mut w = io::stdout();
csi::cha(&mut w, 1);
let base = csi::dsr(&mut w).unwrap().1;
print!("\t");
let tab = csi::dsr(&mut w).unwrap().1;
csi::cha(&mut w, 1);
println!("tabstop={}", tab - base);
}
@ryochack
Copy link
Author

ryochack commented Jun 26, 2019

$ tabs 2
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/tabstop`
tabstop=2
$ tabs 4
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/tabstop`
tabstop=4
$ tabs 8
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/tabstop`
tabstop=8
$ tabs 16
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/tabstop`
tabstop=16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment