Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
fuchsia.googlesource.com-third_party-rust-mirrors-rustyline
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
fuchsia-mirror
fuchsia.googlesource.com-third_party-rust-mirrors-rustyline
Commits
dccd5c42
Commit
dccd5c42
authored
8 years ago
by
gwenn
Browse files
Options
Downloads
Patches
Plain Diff
Move enbale/disable_raw_mode in traits
parent
cbbd858d
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
src/lib.rs
+5
-5
5 additions, 5 deletions
src/lib.rs
src/tty/mod.rs
+8
-0
8 additions, 0 deletions
src/tty/mod.rs
src/tty/test.rs
+10
-6
10 additions, 6 deletions
src/tty/test.rs
src/tty/unix.rs
+43
-54
43 additions, 54 deletions
src/tty/unix.rs
src/tty/windows.rs
+65
-62
65 additions, 62 deletions
src/tty/windows.rs
with
131 additions
and
127 deletions
src/lib.rs
+
5
−
5
View file @
dccd5c42
...
...
@@ -46,7 +46,7 @@ use std::path::Path;
use
std
::
result
;
#[cfg(unix)]
use
nix
::
sys
::
signal
;
use
tty
::{
RawReader
,
Terminal
,
Term
};
use
tty
::{
RawMode
,
RawReader
,
Terminal
,
Term
};
use
encode_unicode
::
CharExt
;
use
completion
::{
Completer
,
longest_common_prefix
};
...
...
@@ -931,9 +931,9 @@ fn readline_edit<C: Completer>(prompt: &str,
}
#[cfg(unix)]
KeyPress
::
Ctrl
(
'Z'
)
=>
{
try
!
(
tty
::
disable_raw_mode
(
original_mode
));
try
!
(
original_mode
.
disable_raw_mode
());
try
!
(
signal
::
raise
(
signal
::
SIGSTOP
));
try
!
(
tty
::
enable_raw_mode
());
// TODO original_mode may have changed
try
!
(
s
.term
.
enable_raw_mode
());
// TODO original_mode may have changed
try
!
(
s
.refresh_line
())
}
// TODO CTRL-_ // undo
...
...
@@ -1024,14 +1024,14 @@ struct Guard(tty::Mode);
impl
Drop
for
Guard
{
fn
drop
(
&
mut
self
)
{
let
Guard
(
mode
)
=
*
self
;
tty
::
disable_raw_mode
(
mode
);
mode
.
disable_raw_mode
();
}
}
/// Readline method that will enable RAW mode, call the `readline_edit()`
/// method and disable raw mode
fn
readline_raw
<
C
:
Completer
>
(
prompt
:
&
str
,
editor
:
&
mut
Editor
<
C
>
)
->
Result
<
String
>
{
let
original_mode
=
try
!
(
tty
::
enable_raw_mode
());
let
original_mode
=
try
!
(
editor
.term
.
enable_raw_mode
());
let
guard
=
Guard
(
original_mode
);
let
user_input
=
readline_edit
(
prompt
,
editor
,
original_mode
);
drop
(
guard
);
// try!(disable_raw_mode(original_mode));
...
...
This diff is collapsed.
Click to expand it.
src/tty/mod.rs
+
8
−
0
View file @
dccd5c42
...
...
@@ -3,6 +3,11 @@ use std::io::Write;
use
::
Result
;
use
consts
::
KeyPress
;
pub
trait
RawMode
:
Copy
+
Sized
{
/// Disable RAW mode for the terminal.
fn
disable_raw_mode
(
&
self
)
->
Result
<
()
>
;
}
pub
trait
RawReader
:
Sized
{
/// Blocking read of key pressed.
fn
next_key
(
&
mut
self
,
timeout_ms
:
i32
)
->
Result
<
KeyPress
>
;
...
...
@@ -14,6 +19,7 @@ pub trait RawReader: Sized {
/// Terminal contract
pub
trait
Term
:
Clone
{
type
Reader
:
RawReader
;
type
Mode
;
fn
new
()
->
Self
;
/// Check if current terminal can provide a rich line-editing user interface.
...
...
@@ -26,6 +32,8 @@ pub trait Term: Clone {
fn
get_rows
(
&
self
)
->
usize
;
/// Check if a SIGWINCH signal has been received
fn
sigwinch
(
&
self
)
->
bool
;
/// Enable RAW mode for the terminal.
fn
enable_raw_mode
(
&
self
)
->
Result
<
Self
::
Mode
>
;
/// Create a RAW reader
fn
create_reader
(
&
self
)
->
Result
<
Self
::
Reader
>
;
/// Clear the screen. Used to handle ctrl+l
...
...
This diff is collapsed.
Click to expand it.
src/tty/test.rs
+
10
−
6
View file @
dccd5c42
...
...
@@ -10,15 +10,14 @@ use winapi;
use
consts
::
KeyPress
;
use
::
error
::
ReadlineError
;
use
::
Result
;
use
super
::{
RawReader
,
Term
};
use
super
::{
RawMode
,
RawReader
,
Term
};
pub
type
Mode
=
();
pub
fn
enable_raw_mode
()
->
Result
<
Mode
>
{
Ok
(())
}
pub
fn
disable_raw_mode
(
_
:
Mode
)
->
Result
<
()
>
{
Ok
(())
impl
RawMode
for
Mode
{
fn
disable_raw_mode
(
&
self
)
->
Result
<
()
>
{
Ok
(())
}
}
impl
<
'a
>
RawReader
for
Iter
<
'a
,
KeyPress
>
{
...
...
@@ -91,6 +90,7 @@ impl DummyTerminal {
impl
Term
for
DummyTerminal
{
type
Reader
=
IntoIter
<
KeyPress
>
;
type
Mode
=
Mode
;
fn
new
()
->
DummyTerminal
{
DummyTerminal
{
keys
:
Vec
::
new
()
}
...
...
@@ -125,6 +125,10 @@ impl Term for DummyTerminal {
false
}
fn
enable_raw_mode
(
&
self
)
->
Result
<
Mode
>
{
Ok
(())
}
/// Create a RAW reader
fn
create_reader
(
&
self
)
->
Result
<
IntoIter
<
KeyPress
>>
{
Ok
(
self
.keys
.clone
()
.into_iter
())
...
...
This diff is collapsed.
Click to expand it.
src/tty/unix.rs
+
43
−
54
View file @
dccd5c42
...
...
@@ -13,9 +13,8 @@ use char_iter;
use
consts
::{
self
,
KeyPress
};
use
::
Result
;
use
::
error
;
use
super
::{
RawReader
,
Term
};
use
super
::{
RawMode
,
RawReader
,
Term
};
pub
type
Mode
=
termios
::
Termios
;
const
STDIN_FILENO
:
libc
::
c_int
=
libc
::
STDIN_FILENO
;
const
STDOUT_FILENO
:
libc
::
c_int
=
libc
::
STDOUT_FILENO
;
...
...
@@ -31,20 +30,6 @@ const TIOCGWINSZ: libc::c_ulong = 0x5413;
#[cfg(all(target_os
=
"linux"
,
target_env
=
"musl"
))]
const
TIOCGWINSZ
:
libc
::
c_int
=
0x5413
;
/// Try to get the number of columns in the current terminal,
/// or assume 80 if it fails.
fn
get_columns
()
->
usize
{
let
(
cols
,
_
)
=
get_win_size
();
cols
}
/// Try to get the number of rows in the current terminal,
/// or assume 24 if it fails.
fn
get_rows
()
->
usize
{
let
(
_
,
rows
)
=
get_win_size
();
rows
}
fn
get_win_size
()
->
(
usize
,
usize
)
{
use
std
::
mem
::
zeroed
;
use
libc
::
c_ushort
;
...
...
@@ -89,40 +74,14 @@ fn is_a_tty(fd: libc::c_int) -> bool {
unsafe
{
libc
::
isatty
(
fd
)
!=
0
}
}
/// Enable RAW mode for the terminal.
pub
fn
enable_raw_mode
()
->
Result
<
Mode
>
{
use
nix
::
errno
::
Errno
::
ENOTTY
;
use
nix
::
sys
::
termios
::{
BRKINT
,
CS8
,
ECHO
,
ICANON
,
ICRNL
,
IEXTEN
,
INPCK
,
ISIG
,
ISTRIP
,
IXON
,
/* OPOST, */
VMIN
,
VTIME
};
if
!
is_a_tty
(
STDIN_FILENO
)
{
try
!
(
Err
(
nix
::
Error
::
from_errno
(
ENOTTY
)));
}
let
original_mode
=
try
!
(
termios
::
tcgetattr
(
STDIN_FILENO
));
let
mut
raw
=
original_mode
;
// disable BREAK interrupt, CR to NL conversion on input,
// input parity check, strip high bit (bit 8), output flow control
raw
.c_iflag
=
raw
.c_iflag
&
!
(
BRKINT
|
ICRNL
|
INPCK
|
ISTRIP
|
IXON
);
// we don't want raw output, it turns newlines into straight linefeeds
// raw.c_oflag = raw.c_oflag & !(OPOST); // disable all output processing
raw
.c_cflag
=
raw
.c_cflag
|
(
CS8
);
// character-size mark (8 bits)
// disable echoing, canonical mode, extended input processing and signals
raw
.c_lflag
=
raw
.c_lflag
&
!
(
ECHO
|
ICANON
|
IEXTEN
|
ISIG
);
raw
.c_cc
[
VMIN
]
=
1
;
// One character-at-a-time input
raw
.c_cc
[
VTIME
]
=
0
;
// with blocking read
try
!
(
termios
::
tcsetattr
(
STDIN_FILENO
,
termios
::
TCSAFLUSH
,
&
raw
));
Ok
(
original_mode
)
}
/// Disable RAW mode for the terminal.
pub
fn
disable_raw_mode
(
original_mode
:
Mode
)
->
Result
<
()
>
{
try
!
(
termios
::
tcsetattr
(
STDIN_FILENO
,
termios
::
TCSAFLUSH
,
&
original_mode
));
Ok
(())
}
pub
type
Mode
=
termios
::
Termios
;
fn
clear_screen
(
w
:
&
mut
Write
)
->
Result
<
()
>
{
try
!
(
w
.write_all
(
b"
\x1b
[H
\x1b
[2J"
));
try
!
(
w
.flush
());
Ok
(())
impl
RawMode
for
Mode
{
/// Disable RAW mode for the terminal.
fn
disable_raw_mode
(
&
self
)
->
Result
<
()
>
{
try
!
(
termios
::
tcsetattr
(
STDIN_FILENO
,
termios
::
TCSADRAIN
,
self
));
Ok
(())
}
}
// Rust std::io::Stdin is buffered with no way to know if bytes are available.
...
...
@@ -285,6 +244,7 @@ pub struct PosixTerminal {
impl
Term
for
PosixTerminal
{
type
Reader
=
PosixRawReader
;
type
Mode
=
Mode
;
fn
new
()
->
PosixTerminal
{
let
term
=
PosixTerminal
{
...
...
@@ -311,14 +271,41 @@ impl Term for PosixTerminal {
// Interactive loop:
/// Get the number of columns in the current terminal.
/// Try to get the number of columns in the current terminal,
/// or assume 80 if it fails.
fn
get_columns
(
&
self
)
->
usize
{
get_columns
()
let
(
cols
,
_
)
=
get_win_size
();
cols
}
/// Get the number of rows in the current terminal.
/// Try to get the number of rows in the current terminal,
/// or assume 24 if it fails.
fn
get_rows
(
&
self
)
->
usize
{
get_rows
()
let
(
_
,
rows
)
=
get_win_size
();
rows
}
fn
enable_raw_mode
(
&
self
)
->
Result
<
Mode
>
{
use
nix
::
errno
::
Errno
::
ENOTTY
;
use
nix
::
sys
::
termios
::{
BRKINT
,
CS8
,
ECHO
,
ICANON
,
ICRNL
,
IEXTEN
,
INPCK
,
ISIG
,
ISTRIP
,
IXON
,
/* OPOST, */
VMIN
,
VTIME
};
if
!
self
.stdin_isatty
{
try
!
(
Err
(
nix
::
Error
::
from_errno
(
ENOTTY
)));
}
let
original_mode
=
try
!
(
termios
::
tcgetattr
(
STDIN_FILENO
));
let
mut
raw
=
original_mode
;
// disable BREAK interrupt, CR to NL conversion on input,
// input parity check, strip high bit (bit 8), output flow control
raw
.c_iflag
=
raw
.c_iflag
&
!
(
BRKINT
|
ICRNL
|
INPCK
|
ISTRIP
|
IXON
);
// we don't want raw output, it turns newlines into straight linefeeds
// raw.c_oflag = raw.c_oflag & !(OPOST); // disable all output processing
raw
.c_cflag
=
raw
.c_cflag
|
(
CS8
);
// character-size mark (8 bits)
// disable echoing, canonical mode, extended input processing and signals
raw
.c_lflag
=
raw
.c_lflag
&
!
(
ECHO
|
ICANON
|
IEXTEN
|
ISIG
);
raw
.c_cc
[
VMIN
]
=
1
;
// One character-at-a-time input
raw
.c_cc
[
VTIME
]
=
0
;
// with blocking read
try
!
(
termios
::
tcsetattr
(
STDIN_FILENO
,
termios
::
TCSAFLUSH
,
&
raw
));
Ok
(
original_mode
)
}
/// Create a RAW reader
...
...
@@ -333,7 +320,9 @@ impl Term for PosixTerminal {
/// Clear the screen. Used to handle ctrl+l
fn
clear_screen
(
&
mut
self
,
w
:
&
mut
Write
)
->
Result
<
()
>
{
clear_screen
(
w
)
try
!
(
w
.write_all
(
b"
\x1b
[H
\x1b
[2J"
));
try
!
(
w
.flush
());
Ok
(())
}
}
...
...
This diff is collapsed.
Click to expand it.
src/tty/windows.rs
+
65
−
62
View file @
dccd5c42
...
...
@@ -10,9 +10,8 @@ use winapi;
use
consts
::{
self
,
KeyPress
};
use
::
error
;
use
::
Result
;
use
super
::{
RawReader
,
Term
};
use
super
::{
RawMode
,
RawReader
,
Term
};
pub
type
Mode
=
winapi
::
DWORD
;
const
STDIN_FILENO
:
winapi
::
DWORD
=
winapi
::
STD_INPUT_HANDLE
;
const
STDOUT_FILENO
:
winapi
::
DWORD
=
winapi
::
STD_OUTPUT_HANDLE
;
...
...
@@ -40,16 +39,6 @@ macro_rules! check {
};
}
fn
get_columns
(
handle
:
winapi
::
HANDLE
)
->
usize
{
let
(
cols
,
_
)
=
get_win_size
(
handle
);
cols
}
fn
get_rows
(
handle
:
winapi
::
HANDLE
)
->
usize
{
let
(
_
,
rows
)
=
get_win_size
(
handle
);
rows
}
fn
get_win_size
(
handle
:
winapi
::
HANDLE
)
->
(
usize
,
usize
)
{
let
mut
info
=
unsafe
{
mem
::
zeroed
()
};
match
unsafe
{
kernel32
::
GetConsoleScreenBufferInfo
(
handle
,
&
mut
info
)
}
{
...
...
@@ -58,60 +47,26 @@ fn get_win_size(handle: winapi::HANDLE) -> (usize, usize) {
}
}
fn
get_console_mode
(
handle
:
winapi
::
HANDLE
)
->
Result
<
Mode
>
{
fn
get_console_mode
(
handle
:
winapi
::
HANDLE
)
->
Result
<
winapi
::
DWORD
>
{
let
mut
original_mode
=
0
;
check!
(
kernel32
::
GetConsoleMode
(
handle
,
&
mut
original_mode
));
Ok
(
original_mode
)
}
/// Return whether or not STDIN, STDOUT or STDERR is a TTY
fn
is_a_tty
(
fd
:
winapi
::
DWORD
)
->
bool
{
let
handle
=
get_std_handle
(
fd
);
match
handle
{
Ok
(
handle
)
=>
{
// If this function doesn't fail then fd is a TTY
get_console_mode
(
handle
)
.is_ok
()
}
Err
(
_
)
=>
false
,
}
}
/// Enable raw mode for the TERM
pub
fn
enable_raw_mode
()
->
Result
<
Mode
>
{
let
handle
=
try
!
(
get_std_handle
(
STDIN_FILENO
));
let
original_mode
=
try
!
(
get_console_mode
(
handle
));
// Disable these modes
let
raw
=
original_mode
&
!
(
winapi
::
wincon
::
ENABLE_LINE_INPUT
|
winapi
::
wincon
::
ENABLE_ECHO_INPUT
|
winapi
::
wincon
::
ENABLE_PROCESSED_INPUT
);
// Enable these modes
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_EXTENDED_FLAGS
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_INSERT_MODE
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_QUICK_EDIT_MODE
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_WINDOW_INPUT
;
check!
(
kernel32
::
SetConsoleMode
(
handle
,
raw
));
Ok
(
original_mode
)
}
pub
type
Mode
=
ConsoleMode
;
/// Disable Raw mode for the term
pub
fn
disable_raw_mode
(
original_mode
:
Mode
)
->
Result
<
()
>
{
let
handle
=
try
!
(
get_std_handle
(
STDIN_FILENO
));
check!
(
kernel32
::
SetConsoleMode
(
handle
,
original_mode
));
Ok
(())
#[derive(Clone,Copy,Debug)]
pub
struct
ConsoleMode
{
original_mode
:
winapi
::
DWORD
,
stdin_handle
:
winapi
::
HANDLE
,
}
/// Clear the screen. Used to handle ctrl+l
fn
clear_screen
(
info
:
winapi
::
CONSOLE_SCREEN_BUFFER_INFO
,
handle
:
winapi
::
HANDLE
)
->
Result
<
()
>
{
let
coord
=
winapi
::
COORD
{
X
:
0
,
Y
:
0
};
check!
(
kernel32
::
SetConsoleCursorPosition
(
handle
,
coord
));
let
mut
_count
=
0
;
let
n
=
info
.dwSize.X
as
winapi
::
DWORD
*
info
.dwSize.Y
as
winapi
::
DWORD
;
check!
(
kernel32
::
FillConsoleOutputCharacterA
(
handle
,
' '
as
winapi
::
CHAR
,
n
,
coord
,
&
mut
_count
));
Ok
(())
impl
RawMode
for
Mode
{
/// Disable RAW mode for the terminal.
fn
disable_raw_mode
(
&
self
)
->
Result
<
()
>
{
check!
(
kernel32
::
SetConsoleMode
(
self
.stdin_handle
,
self
.original_mode
));
Ok
(())
}
}
/// Console input reader
...
...
@@ -229,6 +184,7 @@ pub type Terminal = Console;
#[derive(Clone,Debug)]
pub
struct
Console
{
stdin_isatty
:
bool
,
stdin_handle
:
winapi
::
HANDLE
,
stdout_handle
:
winapi
::
HANDLE
,
}
...
...
@@ -260,12 +216,23 @@ impl Console {
impl
Term
for
Console
{
type
Reader
=
ConsoleRawReader
;
type
Mode
=
Mode
;
fn
new
()
->
Console
{
use
std
::
ptr
;
let
stdin_handle
=
get_std_handle
(
STDIN_FILENO
);
let
stdin_isatty
=
match
stdin_handle
{
Ok
(
handle
)
=>
{
// If this function doesn't fail then fd is a TTY
get_console_mode
(
handle
)
.is_ok
()
}
Err
(
_
)
=>
false
,
};
let
stdout_handle
=
get_std_handle
(
STDOUT_FILENO
)
.unwrap_or
(
ptr
::
null_mut
());
Console
{
stdin_isatty
:
is_a_tty
(
STDIN_FILENO
),
stdin_isatty
:
stdin_isatty
,
stdin_handle
:
stdin_handle
.unwrap_or
(
ptr
::
null_mut
()),
stdout_handle
:
stdout_handle
,
}
}
...
...
@@ -286,15 +253,41 @@ impl Term for Console {
/// Try to get the number of columns in the current terminal,
/// or assume 80 if it fails.
fn
get_columns
(
&
self
)
->
usize
{
get_columns
(
self
.stdout_handle
)
let
(
cols
,
_
)
=
get_win_size
(
self
.stdout_handle
);
cols
}
/// Try to get the number of rows in the current terminal,
/// or assume 24 if it fails.
fn
get_rows
(
&
self
)
->
usize
{
get_rows
(
self
.stdout_handle
)
let
(
_
,
rows
)
=
get_win_size
(
self
.stdout_handle
);
rows
}
/// Enable RAW mode for the terminal.
fn
enable_raw_mode
(
&
self
)
->
Result
<
Mode
>
{
if
!
self
.stdin_isatty
{
try
!
(
Err
(
io
::
Error
::
new
(
io
::
ErrorKind
::
Other
,
"no stdio handle available for this process"
)));
}
let
original_mode
=
try
!
(
get_console_mode
(
self
.stdin_handle
));
// Disable these modes
let
raw
=
original_mode
&
!
(
winapi
::
wincon
::
ENABLE_LINE_INPUT
|
winapi
::
wincon
::
ENABLE_ECHO_INPUT
|
winapi
::
wincon
::
ENABLE_PROCESSED_INPUT
);
// Enable these modes
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_EXTENDED_FLAGS
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_INSERT_MODE
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_QUICK_EDIT_MODE
;
let
raw
=
raw
|
winapi
::
wincon
::
ENABLE_WINDOW_INPUT
;
check!
(
kernel32
::
SetConsoleMode
(
self
.stdin_handle
,
raw
));
Ok
(
Mode
{
original_mode
:
original_mode
,
stdin_handle
:
self
.stdin_handle
,
})
}
fn
create_reader
(
&
self
)
->
Result
<
ConsoleRawReader
>
{
ConsoleRawReader
::
new
()
}
...
...
@@ -303,8 +296,18 @@ impl Term for Console {
SIGWINCH
.compare_and_swap
(
true
,
false
,
atomic
::
Ordering
::
SeqCst
)
}
/// Clear the screen. Used to handle ctrl+l
fn
clear_screen
(
&
mut
self
,
_
:
&
mut
Write
)
->
Result
<
()
>
{
let
info
=
try
!
(
self
.get_console_screen_buffer_info
());
clear_screen
(
info
,
self
.stdout_handle
)
let
coord
=
winapi
::
COORD
{
X
:
0
,
Y
:
0
};
check!
(
kernel32
::
SetConsoleCursorPosition
(
self
.stdout_handle
,
coord
));
let
mut
_count
=
0
;
let
n
=
info
.dwSize.X
as
winapi
::
DWORD
*
info
.dwSize.Y
as
winapi
::
DWORD
;
check!
(
kernel32
::
FillConsoleOutputCharacterA
(
self
.stdout_handle
,
' '
as
winapi
::
CHAR
,
n
,
coord
,
&
mut
_count
));
Ok
(())
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment