Implemented the exec builtin
Fixed readline and terminal interactions using stdin instead of /dev/tty
This commit is contained in:
@@ -263,6 +263,9 @@ impl Completer {
|
||||
if let Some(eq_pos) = token_str.rfind('=') {
|
||||
// Adjust span to only replace the part after '='
|
||||
self.token_span.0 = cur_token.span.start + eq_pos + 1;
|
||||
cur_token
|
||||
.span
|
||||
.set_range(self.token_span.0..self.token_span.1);
|
||||
}
|
||||
|
||||
if ctx.last().is_some_and(|m| *m == markers::VAR_SUB) {
|
||||
|
||||
@@ -824,7 +824,7 @@ impl LineBuf {
|
||||
dir: Direction,
|
||||
) -> Box<dyn Iterator<Item = usize>> {
|
||||
self.update_graphemes_lazy();
|
||||
let skip = if pos == 0 { 0 } else { pos + 1 };
|
||||
let skip = pos + 1;
|
||||
match dir {
|
||||
Direction::Forward => Box::new(self.grapheme_indices().to_vec().into_iter().skip(skip))
|
||||
as Box<dyn Iterator<Item = usize>>,
|
||||
|
||||
@@ -6,6 +6,7 @@ use term::{KeyReader, Layout, LineWriter, PollReader, TermWriter, get_win_size};
|
||||
use vicmd::{CmdFlags, Motion, MotionCmd, RegisterName, Verb, VerbCmd, ViCmd};
|
||||
use vimode::{CmdReplay, ModeReport, ViInsert, ViMode, ViNormal, ViReplace, ViVisual};
|
||||
|
||||
use crate::libsh::sys::TTY_FILENO;
|
||||
use crate::prelude::*;
|
||||
use crate::{
|
||||
libsh::{
|
||||
@@ -112,10 +113,10 @@ pub struct FernVi {
|
||||
}
|
||||
|
||||
impl FernVi {
|
||||
pub fn new(prompt: Option<String>) -> ShResult<Self> {
|
||||
pub fn new(prompt: Option<String>, tty: RawFd) -> ShResult<Self> {
|
||||
let mut new = Self {
|
||||
reader: PollReader::new(),
|
||||
writer: Box::new(TermWriter::new(STDOUT_FILENO)),
|
||||
writer: Box::new(TermWriter::new(tty)),
|
||||
prompt: prompt.unwrap_or("$ ".styled(Style::Green)),
|
||||
completer: Completer::new(),
|
||||
highlighter: Highlighter::new(),
|
||||
@@ -294,7 +295,7 @@ impl FernVi {
|
||||
|
||||
pub fn get_layout(&mut self, line: &str) -> Layout {
|
||||
let to_cursor = self.editor.slice_to_cursor().unwrap_or_default();
|
||||
let (cols, _) = get_win_size(STDIN_FILENO);
|
||||
let (cols, _) = get_win_size(*TTY_FILENO);
|
||||
let tab_stop = crate::state::read_shopts(|s| s.prompt.tab_stop) as u16;
|
||||
Layout::from_parts(tab_stop, cols, &self.prompt, to_cursor, line)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
|
||||
use vte::{Parser, Perform};
|
||||
|
||||
use crate::{
|
||||
libsh::error::{ShErr, ShErrKind, ShResult},
|
||||
libsh::{error::{ShErr, ShErrKind, ShResult}, sys::TTY_FILENO},
|
||||
prompt::readline::keys::{KeyCode, ModKeys},
|
||||
};
|
||||
use crate::{
|
||||
@@ -30,7 +30,7 @@ use crate::{
|
||||
use super::{keys::KeyEvent, linebuf::LineBuf};
|
||||
|
||||
pub fn raw_mode() -> RawModeGuard {
|
||||
let orig = termios::tcgetattr(unsafe { BorrowedFd::borrow_raw(STDIN_FILENO) })
|
||||
let orig = termios::tcgetattr(unsafe { BorrowedFd::borrow_raw(*TTY_FILENO) })
|
||||
.expect("Failed to get terminal attributes");
|
||||
let mut raw = orig.clone();
|
||||
termios::cfmakeraw(&mut raw);
|
||||
@@ -39,17 +39,17 @@ pub fn raw_mode() -> RawModeGuard {
|
||||
// Keep OPOST enabled so \n is translated to \r\n on output
|
||||
raw.output_flags |= termios::OutputFlags::OPOST;
|
||||
termios::tcsetattr(
|
||||
unsafe { BorrowedFd::borrow_raw(STDIN_FILENO) },
|
||||
unsafe { BorrowedFd::borrow_raw(*TTY_FILENO) },
|
||||
termios::SetArg::TCSANOW,
|
||||
&raw,
|
||||
)
|
||||
.expect("Failed to set terminal to raw mode");
|
||||
|
||||
let (cols, rows) = get_win_size(STDIN_FILENO);
|
||||
let (cols, rows) = get_win_size(*TTY_FILENO);
|
||||
|
||||
RawModeGuard {
|
||||
orig,
|
||||
fd: STDIN_FILENO,
|
||||
fd: *TTY_FILENO,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,14 +286,14 @@ impl RawModeGuard {
|
||||
where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
let raw = tcgetattr(borrow_fd(STDIN_FILENO)).expect("Failed to get terminal attributes");
|
||||
let raw = tcgetattr(borrow_fd(*TTY_FILENO)).expect("Failed to get terminal attributes");
|
||||
let mut cooked = raw.clone();
|
||||
cooked.local_flags |= termios::LocalFlags::ICANON | termios::LocalFlags::ECHO;
|
||||
cooked.input_flags |= termios::InputFlags::ICRNL;
|
||||
tcsetattr(borrow_fd(STDIN_FILENO), termios::SetArg::TCSANOW, &cooked)
|
||||
tcsetattr(borrow_fd(*TTY_FILENO), termios::SetArg::TCSANOW, &cooked)
|
||||
.expect("Failed to set cooked mode");
|
||||
let res = f();
|
||||
tcsetattr(borrow_fd(STDIN_FILENO), termios::SetArg::TCSANOW, &raw)
|
||||
tcsetattr(borrow_fd(*TTY_FILENO), termios::SetArg::TCSANOW, &raw)
|
||||
.expect("Failed to restore raw mode");
|
||||
res
|
||||
}
|
||||
@@ -542,16 +542,10 @@ pub struct TermReader {
|
||||
buffer: BufReader<TermBuffer>,
|
||||
}
|
||||
|
||||
impl Default for TermReader {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl TermReader {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(tty: RawFd) -> Self {
|
||||
Self {
|
||||
buffer: BufReader::new(TermBuffer::new(1)),
|
||||
buffer: BufReader::new(TermBuffer::new(tty)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user