-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 31bf144
Showing
23 changed files
with
10,886 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
target/ | ||
**/*.rs.bk | ||
Cargo.lock | ||
target/ | ||
**/*.rs.bk | ||
target/ | ||
**/*.rs.bk | ||
.gdb_history | ||
*.log | ||
|
||
|
||
#Added by cargo | ||
# | ||
#already existing elements are commented out | ||
|
||
/target | ||
#**/*.rs.bk | ||
|
||
|
||
#Added by cargo | ||
# | ||
#already existing elements are commented out | ||
|
||
#/target | ||
#**/*.rs.bk |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "bb" | ||
version = "0.1.0" | ||
authors = ["Manos Pitsidianakis <[email protected]>"] | ||
edition = "2018" | ||
build = "build.rs" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[[bin]] | ||
name = "bb" | ||
path = "src/main.rs" | ||
|
||
[dependencies] | ||
crossbeam = "0.7" | ||
signal-hook = "0.1.10" | ||
termion = "1.5.3" | ||
libc = "0.2.62" | ||
unicode-segmentation = "1.2.1" | ||
nix = "0.15.0" | ||
|
||
[profile.release] | ||
opt-level = 'z' # Optimize for size. | ||
lto = true | ||
codegen-units = 1 | ||
panic = 'abort' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
const LINE_BREAK_TABLE_URL: &str = "http://www.unicode.org/Public/UCD/latest/ucd/LineBreak.txt"; | ||
use std::fs::File; | ||
use std::io::prelude::*; | ||
use std::io::BufReader; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
|
||
include!("src/ui/text_processing/types.rs"); | ||
|
||
fn main() -> Result<(), std::io::Error> { | ||
let mod_path = PathBuf::from("src/ui/text_processing/tables.rs"); | ||
if mod_path.exists() { | ||
eprintln!( | ||
"{} already exists, delete it if you want to replace it.", | ||
mod_path.display() | ||
); | ||
std::process::exit(0); | ||
} | ||
let mut tmpdir_path = PathBuf::from( | ||
std::str::from_utf8(&Command::new("mktemp").arg("-d").output()?.stdout) | ||
.unwrap() | ||
.trim(), | ||
); | ||
tmpdir_path.push("LineBreak.txt"); | ||
Command::new("curl") | ||
.args(&["-o", tmpdir_path.to_str().unwrap(), LINE_BREAK_TABLE_URL]) | ||
.output()?; | ||
|
||
let file = File::open(&tmpdir_path)?; | ||
let buf_reader = BufReader::new(file); | ||
|
||
let mut line_break_table: Vec<(u32, u32, LineBreakClass)> = Vec::with_capacity(3800); | ||
for line in buf_reader.lines() { | ||
let line = line.unwrap(); | ||
if line.starts_with('#') || line.starts_with(' ') || line.is_empty() { | ||
continue; | ||
} | ||
let tokens: &str = line.split_whitespace().next().unwrap(); | ||
|
||
let semicolon_idx: usize = tokens.chars().position(|c| c == ';').unwrap(); | ||
/* LineBreak.txt list is ascii encoded so we can assume each char takes one byte: */ | ||
let chars_str: &str = &tokens[..semicolon_idx]; | ||
|
||
let mut codepoint_iter = chars_str.split(".."); | ||
|
||
let first_codepoint: u32 = | ||
u32::from_str_radix(std::dbg!(codepoint_iter.next().unwrap()), 16).unwrap(); | ||
|
||
let sec_codepoint: u32 = codepoint_iter | ||
.next() | ||
.map(|v| u32::from_str_radix(std::dbg!(v), 16).unwrap()) | ||
.unwrap_or(first_codepoint); | ||
let class = &tokens[semicolon_idx + 1..semicolon_idx + 1 + 2]; | ||
line_break_table.push((first_codepoint, sec_codepoint, LineBreakClass::from(class))); | ||
} | ||
|
||
let mut file = File::create(&mod_path)?; | ||
file.write_all(b"use crate::types::LineBreakClass::*;\n") | ||
.unwrap(); | ||
file.write_all(b"use crate::types::LineBreakClass;\n\n") | ||
.unwrap(); | ||
file.write_all(b"const line_break_rules: &'static [(u32, u32, LineBreakClass)] = &[\n") | ||
.unwrap(); | ||
for l in &line_break_table { | ||
file.write_all(format!(" (0x{:X}, 0x{:X}, {:?}),\n", l.0, l.1, l.2).as_bytes()) | ||
.unwrap(); | ||
} | ||
file.write_all(b"];").unwrap(); | ||
std::fs::remove_file(&tmpdir_path).unwrap(); | ||
tmpdir_path.pop(); | ||
std::fs::remove_dir(&tmpdir_path).unwrap(); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* bb - bin.rs | ||
* | ||
* Copyright 2019 Manos Pitsidianakis | ||
* | ||
* bb is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* bb is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with bb. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
//! | ||
//! This crate contains the frontend stuff of the application. The application entry way on | ||
//! `src/bin.rs` creates an event loop and passes input to the `ui` module. | ||
//! | ||
//! The mail handling stuff is done in the `bb` crate which includes all backend needs. The | ||
//! split is done to theoretically be able to create different frontends with the same innards. | ||
//! | ||
extern crate crossbeam; | ||
extern crate nix; | ||
extern crate signal_hook; | ||
extern crate termion; | ||
|
||
use crossbeam::channel::{bounded, tick}; | ||
use crossbeam::select; | ||
use libc::c_int; | ||
use std::io::Error; | ||
use std::time::{Duration, Instant}; | ||
|
||
mod ui; | ||
use ui::*; | ||
|
||
fn notify(signals: &[c_int]) -> Result<crossbeam::channel::Receiver<c_int>, Error> { | ||
let (s, r) = bounded(100); | ||
let signals = signal_hook::iterator::Signals::new(signals)?; | ||
std::thread::spawn(move || { | ||
for signal in signals.forever() { | ||
s.send(signal).unwrap(); | ||
} | ||
}); | ||
Ok(r) | ||
} | ||
|
||
fn main() -> Result<(), Error> { | ||
let signals = &[ | ||
signal_hook::SIGALRM, | ||
signal_hook::SIGTERM, | ||
signal_hook::SIGINT, | ||
signal_hook::SIGQUIT, | ||
/* Catch SIGWINCH to handle terminal resizing */ | ||
signal_hook::SIGWINCH, | ||
]; | ||
|
||
let ticker = tick(Duration::from_millis(800)); | ||
|
||
let signal_recvr = notify(signals)?; | ||
|
||
/* Create the application State */ | ||
let mut state = State::new(); | ||
|
||
let receiver = state.receiver(); | ||
|
||
let window = Box::new(HSplit::new( | ||
Box::new(ui::components::KernelMetrics::new()), | ||
Box::new(ui::components::ProcessList::new()), | ||
83, | ||
false, | ||
)); | ||
|
||
state.register_component(window); | ||
|
||
/* Keep track of the input mode. See ui::UIMode for details */ | ||
'main: loop { | ||
'inner: loop { | ||
/* Poll on all channels. Currently we have the input channel for stdin, watching events and the signal watcher. */ | ||
select! { | ||
recv(ticker) -> _ => { | ||
state.redraw(true); | ||
}, | ||
recv(signal_recvr) -> sig => { | ||
eprintln!("got signal {:?}", sig); | ||
match sig.unwrap() { | ||
signal_hook::SIGWINCH => { | ||
state.update_size(); | ||
state.render(); | ||
state.redraw(true); | ||
}, | ||
_ => {} | ||
} | ||
}, | ||
recv(receiver) -> msg => { | ||
match msg.unwrap() { | ||
ThreadEvent::Input(Key::Ctrl('z')) => { | ||
state.switch_to_main_screen(); | ||
//_thread_handler.join().expect("Couldn't join on the associated thread"); | ||
let self_pid = nix::unistd::Pid::this(); | ||
nix::sys::signal::kill(self_pid, nix::sys::signal::Signal::SIGSTOP).unwrap(); | ||
state.switch_to_alternate_screen(); | ||
state.restore_input(); | ||
// BUG: thread sends input event after one received key | ||
state.update_size(); | ||
state.render(); | ||
state.redraw(true); | ||
}, | ||
ThreadEvent::Input(k) => { | ||
match k { | ||
Key::Char('q') | Key::Char('Q') => { | ||
drop(state); | ||
break 'main; | ||
}, | ||
key => { | ||
state.rcv_event(UIEvent::Input(key)); | ||
state.redraw(false); | ||
}, | ||
} | ||
}, | ||
ThreadEvent::UIEvent(_) => { | ||
}, | ||
} | ||
}, | ||
} | ||
} // end of 'inner | ||
} | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* meli - ui crate. | ||
* | ||
* Copyright 2017-2018 Manos Pitsidianakis | ||
* | ||
* This file is part of meli. | ||
* | ||
* meli is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* meli is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with meli. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/*! | ||
* This library exports the public types and methods of its modules | ||
*/ | ||
|
||
mod text_processing; | ||
pub use crate::ui::text_processing::*; | ||
#[macro_use] | ||
mod types; | ||
pub use crate::ui::types::*; | ||
|
||
#[macro_use] | ||
mod terminal; | ||
pub use crate::ui::terminal::*; | ||
|
||
pub mod state; | ||
pub use crate::ui::state::*; | ||
|
||
pub mod components; | ||
pub use crate::ui::components::*; | ||
pub use crate::ui::username::*; | ||
pub mod username { | ||
use libc; | ||
use std::ptr::null_mut; | ||
/* taken from whoami-0.1.1 */ | ||
fn getpwuid() -> libc::passwd { | ||
let mut pwentp = null_mut(); | ||
let mut buffer = [0i8; 16384]; // from the man page | ||
#[cfg(any( | ||
target_os = "macos", | ||
target_os = "ios", | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
target_os = "openbsd", | ||
target_os = "netbsd" | ||
))] | ||
{ | ||
let mut pwent = libc::passwd { | ||
pw_name: null_mut(), | ||
pw_passwd: null_mut(), | ||
pw_uid: 0, | ||
pw_gid: 0, | ||
pw_change: 0, | ||
pw_class: null_mut(), | ||
pw_gecos: null_mut(), | ||
pw_dir: null_mut(), | ||
pw_shell: null_mut(), | ||
pw_expire: 0, | ||
}; | ||
unsafe { | ||
libc::getpwuid_r( | ||
libc::geteuid(), | ||
&mut pwent, | ||
&mut buffer[0], | ||
16384, | ||
&mut pwentp, | ||
); | ||
} | ||
|
||
pwent | ||
} | ||
#[cfg(target_os = "linux")] | ||
{ | ||
let mut pwent = libc::passwd { | ||
pw_name: null_mut(), | ||
pw_passwd: null_mut(), | ||
pw_uid: 0, | ||
pw_gid: 0, | ||
pw_gecos: null_mut(), | ||
pw_dir: null_mut(), | ||
pw_shell: null_mut(), | ||
}; | ||
|
||
unsafe { | ||
libc::getpwuid_r( | ||
libc::geteuid(), | ||
&mut pwent, | ||
&mut buffer[0], | ||
16384, | ||
&mut pwentp, | ||
); | ||
} | ||
|
||
pwent | ||
} | ||
} | ||
fn ptr_to_string(name: *mut i8) -> String { | ||
let uname = name as *mut _ as *mut u8; | ||
|
||
let s; | ||
let string; | ||
|
||
unsafe { | ||
s = ::std::slice::from_raw_parts(uname, libc::strlen(name)); | ||
string = String::from_utf8_lossy(s).to_string(); | ||
} | ||
|
||
string | ||
} | ||
pub fn username() -> String { | ||
let pwent = getpwuid(); | ||
|
||
ptr_to_string(pwent.pw_name) | ||
} | ||
} |
Oops, something went wrong.