Added cursor blink and settings
This commit is contained in:
parent
7b3a7727c6
commit
bba51c3ae6
6 changed files with 104 additions and 26 deletions
|
@ -102,6 +102,19 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
"working_directory": "current_project_directory",
|
"working_directory": "current_project_directory",
|
||||||
|
//Set the cursor blinking behavior in the terminal.
|
||||||
|
//May take 4 values:
|
||||||
|
// 1. Never blink the cursor, ignoring the terminal mode
|
||||||
|
// "blinking": "never",
|
||||||
|
// 2. Default the cursor blink to off, but allow the terminal to
|
||||||
|
// turn blinking on
|
||||||
|
// "blinking": "off",
|
||||||
|
// 3. Default the cursor blink to on, but allow the terminal to
|
||||||
|
// turn blinking off
|
||||||
|
// "blinking": "on",
|
||||||
|
// 4. Always blink the cursor, ignoring the terminal mode
|
||||||
|
// "blinking": "always",
|
||||||
|
"blinking": "on",
|
||||||
//Any key-value pairs added to this list will be added to the terminal's
|
//Any key-value pairs added to this list will be added to the terminal's
|
||||||
//enviroment. Use `:` to seperate multiple values.
|
//enviroment. Use `:` to seperate multiple values.
|
||||||
"env": {
|
"env": {
|
||||||
|
|
|
@ -83,6 +83,22 @@ pub struct TerminalSettings {
|
||||||
pub font_size: Option<f32>,
|
pub font_size: Option<f32>,
|
||||||
pub font_family: Option<String>,
|
pub font_family: Option<String>,
|
||||||
pub env: Option<HashMap<String, String>>,
|
pub env: Option<HashMap<String, String>>,
|
||||||
|
pub blinking: Option<TerminalBlink>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum TerminalBlink {
|
||||||
|
Never,
|
||||||
|
On,
|
||||||
|
Off,
|
||||||
|
Always,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TerminalBlink {
|
||||||
|
fn default() -> Self {
|
||||||
|
TerminalBlink::On
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||||
|
|
|
@ -21,7 +21,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use settings::Settings;
|
use settings::{Settings, TerminalBlink};
|
||||||
use theme::TerminalStyle;
|
use theme::TerminalStyle;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
|
@ -201,6 +201,7 @@ pub struct TerminalEl {
|
||||||
view: WeakViewHandle<ConnectedView>,
|
view: WeakViewHandle<ConnectedView>,
|
||||||
modal: bool,
|
modal: bool,
|
||||||
focused: bool,
|
focused: bool,
|
||||||
|
blink_state: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalEl {
|
impl TerminalEl {
|
||||||
|
@ -209,12 +210,14 @@ impl TerminalEl {
|
||||||
terminal: WeakModelHandle<Terminal>,
|
terminal: WeakModelHandle<Terminal>,
|
||||||
modal: bool,
|
modal: bool,
|
||||||
focused: bool,
|
focused: bool,
|
||||||
|
blink_state: bool,
|
||||||
) -> TerminalEl {
|
) -> TerminalEl {
|
||||||
TerminalEl {
|
TerminalEl {
|
||||||
view,
|
view,
|
||||||
terminal,
|
terminal,
|
||||||
modal,
|
modal,
|
||||||
focused,
|
focused,
|
||||||
|
blink_state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,6 +571,33 @@ impl TerminalEl {
|
||||||
|
|
||||||
(point, side)
|
(point, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn should_show_cursor(
|
||||||
|
settings: Option<TerminalBlink>,
|
||||||
|
blinking_on: bool,
|
||||||
|
focused: bool,
|
||||||
|
blink_show: bool,
|
||||||
|
) -> bool {
|
||||||
|
if !focused {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
match settings {
|
||||||
|
Some(setting) => match setting {
|
||||||
|
TerminalBlink::Never => true,
|
||||||
|
TerminalBlink::On | TerminalBlink::Off if blinking_on => blink_show,
|
||||||
|
TerminalBlink::On | TerminalBlink::Off /*if !blinking_on */ => true,
|
||||||
|
TerminalBlink::Always => focused && blink_show,
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
if blinking_on {
|
||||||
|
blink_show
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for TerminalEl {
|
impl Element for TerminalEl {
|
||||||
|
@ -580,6 +610,7 @@ impl Element for TerminalEl {
|
||||||
cx: &mut gpui::LayoutContext,
|
cx: &mut gpui::LayoutContext,
|
||||||
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
|
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
|
||||||
let settings = cx.global::<Settings>();
|
let settings = cx.global::<Settings>();
|
||||||
|
let blink_settings = settings.terminal_overrides.blinking.clone();
|
||||||
let font_cache = cx.font_cache();
|
let font_cache = cx.font_cache();
|
||||||
|
|
||||||
//Setup layout information
|
//Setup layout information
|
||||||
|
@ -598,13 +629,13 @@ impl Element for TerminalEl {
|
||||||
terminal_theme.colors.background
|
terminal_theme.colors.background
|
||||||
};
|
};
|
||||||
|
|
||||||
let (cells, selection, cursor, display_offset, cursor_text) = self
|
let (cells, selection, cursor, display_offset, cursor_text, blink_mode) = self
|
||||||
.terminal
|
.terminal
|
||||||
.upgrade(cx)
|
.upgrade(cx)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.update(cx.app, |terminal, mcx| {
|
.update(cx.app, |terminal, mcx| {
|
||||||
terminal.set_size(dimensions);
|
terminal.set_size(dimensions);
|
||||||
terminal.render_lock(mcx, |content, cursor_text| {
|
terminal.render_lock(mcx, |content, cursor_text, style| {
|
||||||
let mut cells = vec![];
|
let mut cells = vec![];
|
||||||
cells.extend(
|
cells.extend(
|
||||||
content
|
content
|
||||||
|
@ -628,6 +659,7 @@ impl Element for TerminalEl {
|
||||||
content.cursor,
|
content.cursor,
|
||||||
content.display_offset,
|
content.display_offset,
|
||||||
cursor_text,
|
cursor_text,
|
||||||
|
style,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -643,19 +675,13 @@ impl Element for TerminalEl {
|
||||||
);
|
);
|
||||||
|
|
||||||
//Layout cursor
|
//Layout cursor
|
||||||
//TODO: This logic can be a lot better
|
|
||||||
let show_cursor = if let Some(view_handle) = self.view.upgrade(cx) {
|
|
||||||
if view_handle.read(cx).show_cursor() {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
let cursor = {
|
let cursor = {
|
||||||
if show_cursor {
|
if !TerminalEl::should_show_cursor(
|
||||||
|
blink_settings,
|
||||||
|
blink_mode,
|
||||||
|
self.focused,
|
||||||
|
self.blink_state,
|
||||||
|
) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let cursor_point = DisplayCursor::from(cursor.point, display_offset);
|
let cursor_point = DisplayCursor::from(cursor.point, display_offset);
|
||||||
|
|
|
@ -132,7 +132,7 @@ impl ConnectedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Following code copied from editor cursor
|
//Following code copied from editor cursor
|
||||||
pub fn show_cursor(&self) -> bool {
|
pub fn blink_show(&self) -> bool {
|
||||||
self.blinking_paused || self.show_cursor
|
self.blinking_paused || self.show_cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,9 +253,15 @@ impl View for ConnectedView {
|
||||||
|
|
||||||
Stack::new()
|
Stack::new()
|
||||||
.with_child(
|
.with_child(
|
||||||
TerminalEl::new(cx.handle(), terminal_handle, self.modal, focused)
|
TerminalEl::new(
|
||||||
.contained()
|
cx.handle(),
|
||||||
.boxed(),
|
terminal_handle,
|
||||||
|
self.modal,
|
||||||
|
focused,
|
||||||
|
self.blink_show(),
|
||||||
|
)
|
||||||
|
.contained()
|
||||||
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_child(ChildView::new(&self.context_menu).boxed())
|
.with_child(ChildView::new(&self.context_menu).boxed())
|
||||||
.boxed()
|
.boxed()
|
||||||
|
|
|
@ -25,7 +25,7 @@ use futures::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use modal::deploy_modal;
|
use modal::deploy_modal;
|
||||||
use settings::{Settings, Shell};
|
use settings::{Settings, Shell, TerminalBlink};
|
||||||
use std::{collections::HashMap, fmt::Display, path::PathBuf, sync::Arc, time::Duration};
|
use std::{collections::HashMap, fmt::Display, path::PathBuf, sync::Arc, time::Duration};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
@ -254,6 +254,7 @@ impl TerminalBuilder {
|
||||||
shell: Option<Shell>,
|
shell: Option<Shell>,
|
||||||
env: Option<HashMap<String, String>>,
|
env: Option<HashMap<String, String>>,
|
||||||
initial_size: TerminalSize,
|
initial_size: TerminalSize,
|
||||||
|
blink_settings: Option<TerminalBlink>,
|
||||||
) -> Result<TerminalBuilder> {
|
) -> Result<TerminalBuilder> {
|
||||||
let pty_config = {
|
let pty_config = {
|
||||||
let alac_shell = shell.clone().and_then(|shell| match shell {
|
let alac_shell = shell.clone().and_then(|shell| match shell {
|
||||||
|
@ -290,7 +291,18 @@ impl TerminalBuilder {
|
||||||
//TODO: Remove with a bounded sender which can be dispatched on &self
|
//TODO: Remove with a bounded sender which can be dispatched on &self
|
||||||
let (events_tx, events_rx) = unbounded();
|
let (events_tx, events_rx) = unbounded();
|
||||||
//Set up the terminal...
|
//Set up the terminal...
|
||||||
let term = Term::new(&config, &initial_size, ZedListener(events_tx.clone()));
|
let mut term = Term::new(&config, &initial_size, ZedListener(events_tx.clone()));
|
||||||
|
|
||||||
|
//Start off blinking if we need to
|
||||||
|
match blink_settings {
|
||||||
|
Some(setting) => match setting {
|
||||||
|
TerminalBlink::On | TerminalBlink::Always => {
|
||||||
|
term.set_mode(alacritty_terminal::ansi::Mode::BlinkingCursor)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
None => term.set_mode(alacritty_terminal::ansi::Mode::BlinkingCursor),
|
||||||
|
}
|
||||||
let term = Arc::new(FairMutex::new(term));
|
let term = Arc::new(FairMutex::new(term));
|
||||||
|
|
||||||
//Setup the pty...
|
//Setup the pty...
|
||||||
|
@ -322,7 +334,7 @@ impl TerminalBuilder {
|
||||||
//And connect them together
|
//And connect them together
|
||||||
let event_loop = EventLoop::new(
|
let event_loop = EventLoop::new(
|
||||||
term.clone(),
|
term.clone(),
|
||||||
ZedListener(events_tx),
|
ZedListener(events_tx.clone()),
|
||||||
pty,
|
pty,
|
||||||
pty_config.hold,
|
pty_config.hold,
|
||||||
false,
|
false,
|
||||||
|
@ -583,7 +595,7 @@ impl Terminal {
|
||||||
|
|
||||||
pub fn render_lock<F, T>(&mut self, cx: &mut ModelContext<Self>, f: F) -> T
|
pub fn render_lock<F, T>(&mut self, cx: &mut ModelContext<Self>, f: F) -> T
|
||||||
where
|
where
|
||||||
F: FnOnce(RenderableContent, char) -> T,
|
F: FnOnce(RenderableContent, char, bool) -> T,
|
||||||
{
|
{
|
||||||
let m = self.term.clone(); //Arc clone
|
let m = self.term.clone(); //Arc clone
|
||||||
let mut term = m.lock();
|
let mut term = m.lock();
|
||||||
|
@ -599,7 +611,7 @@ impl Terminal {
|
||||||
|
|
||||||
let cursor_text = term.grid()[content.cursor.point].c;
|
let cursor_text = term.grid()[content.cursor.point].c;
|
||||||
|
|
||||||
f(content, cursor_text)
|
f(content, cursor_text, term.cursor_style().blinking)
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scroll the terminal
|
///Scroll the terminal
|
||||||
|
|
|
@ -94,8 +94,13 @@ impl TerminalView {
|
||||||
let shell = settings.terminal_overrides.shell.clone();
|
let shell = settings.terminal_overrides.shell.clone();
|
||||||
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
|
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
|
||||||
|
|
||||||
let content = match TerminalBuilder::new(working_directory.clone(), shell, envs, size_info)
|
let content = match TerminalBuilder::new(
|
||||||
{
|
working_directory.clone(),
|
||||||
|
shell,
|
||||||
|
envs,
|
||||||
|
size_info,
|
||||||
|
settings.terminal_overrides.blinking.clone(),
|
||||||
|
) {
|
||||||
Ok(terminal) => {
|
Ok(terminal) => {
|
||||||
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
||||||
let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx));
|
let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue