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",
|
||||
//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
|
||||
//enviroment. Use `:` to seperate multiple values.
|
||||
"env": {
|
||||
|
|
|
@ -83,6 +83,22 @@ pub struct TerminalSettings {
|
|||
pub font_size: Option<f32>,
|
||||
pub font_family: Option<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)]
|
||||
|
|
|
@ -21,7 +21,7 @@ use gpui::{
|
|||
};
|
||||
use itertools::Itertools;
|
||||
use ordered_float::OrderedFloat;
|
||||
use settings::Settings;
|
||||
use settings::{Settings, TerminalBlink};
|
||||
use theme::TerminalStyle;
|
||||
use util::ResultExt;
|
||||
|
||||
|
@ -201,6 +201,7 @@ pub struct TerminalEl {
|
|||
view: WeakViewHandle<ConnectedView>,
|
||||
modal: bool,
|
||||
focused: bool,
|
||||
blink_state: bool,
|
||||
}
|
||||
|
||||
impl TerminalEl {
|
||||
|
@ -209,12 +210,14 @@ impl TerminalEl {
|
|||
terminal: WeakModelHandle<Terminal>,
|
||||
modal: bool,
|
||||
focused: bool,
|
||||
blink_state: bool,
|
||||
) -> TerminalEl {
|
||||
TerminalEl {
|
||||
view,
|
||||
terminal,
|
||||
modal,
|
||||
focused,
|
||||
blink_state,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,6 +571,33 @@ impl TerminalEl {
|
|||
|
||||
(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 {
|
||||
|
@ -580,6 +610,7 @@ impl Element for TerminalEl {
|
|||
cx: &mut gpui::LayoutContext,
|
||||
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
|
||||
let settings = cx.global::<Settings>();
|
||||
let blink_settings = settings.terminal_overrides.blinking.clone();
|
||||
let font_cache = cx.font_cache();
|
||||
|
||||
//Setup layout information
|
||||
|
@ -598,13 +629,13 @@ impl Element for TerminalEl {
|
|||
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
|
||||
.upgrade(cx)
|
||||
.unwrap()
|
||||
.update(cx.app, |terminal, mcx| {
|
||||
terminal.set_size(dimensions);
|
||||
terminal.render_lock(mcx, |content, cursor_text| {
|
||||
terminal.render_lock(mcx, |content, cursor_text, style| {
|
||||
let mut cells = vec![];
|
||||
cells.extend(
|
||||
content
|
||||
|
@ -628,6 +659,7 @@ impl Element for TerminalEl {
|
|||
content.cursor,
|
||||
content.display_offset,
|
||||
cursor_text,
|
||||
style,
|
||||
)
|
||||
})
|
||||
});
|
||||
|
@ -643,19 +675,13 @@ impl Element for TerminalEl {
|
|||
);
|
||||
|
||||
//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 = {
|
||||
if show_cursor {
|
||||
if !TerminalEl::should_show_cursor(
|
||||
blink_settings,
|
||||
blink_mode,
|
||||
self.focused,
|
||||
self.blink_state,
|
||||
) {
|
||||
None
|
||||
} else {
|
||||
let cursor_point = DisplayCursor::from(cursor.point, display_offset);
|
||||
|
|
|
@ -132,7 +132,7 @@ impl ConnectedView {
|
|||
}
|
||||
|
||||
//Following code copied from editor cursor
|
||||
pub fn show_cursor(&self) -> bool {
|
||||
pub fn blink_show(&self) -> bool {
|
||||
self.blinking_paused || self.show_cursor
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,13 @@ impl View for ConnectedView {
|
|||
|
||||
Stack::new()
|
||||
.with_child(
|
||||
TerminalEl::new(cx.handle(), terminal_handle, self.modal, focused)
|
||||
TerminalEl::new(
|
||||
cx.handle(),
|
||||
terminal_handle,
|
||||
self.modal,
|
||||
focused,
|
||||
self.blink_show(),
|
||||
)
|
||||
.contained()
|
||||
.boxed(),
|
||||
)
|
||||
|
|
|
@ -25,7 +25,7 @@ use futures::{
|
|||
};
|
||||
|
||||
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 thiserror::Error;
|
||||
|
||||
|
@ -254,6 +254,7 @@ impl TerminalBuilder {
|
|||
shell: Option<Shell>,
|
||||
env: Option<HashMap<String, String>>,
|
||||
initial_size: TerminalSize,
|
||||
blink_settings: Option<TerminalBlink>,
|
||||
) -> Result<TerminalBuilder> {
|
||||
let pty_config = {
|
||||
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
|
||||
let (events_tx, events_rx) = unbounded();
|
||||
//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));
|
||||
|
||||
//Setup the pty...
|
||||
|
@ -322,7 +334,7 @@ impl TerminalBuilder {
|
|||
//And connect them together
|
||||
let event_loop = EventLoop::new(
|
||||
term.clone(),
|
||||
ZedListener(events_tx),
|
||||
ZedListener(events_tx.clone()),
|
||||
pty,
|
||||
pty_config.hold,
|
||||
false,
|
||||
|
@ -583,7 +595,7 @@ impl Terminal {
|
|||
|
||||
pub fn render_lock<F, T>(&mut self, cx: &mut ModelContext<Self>, f: F) -> T
|
||||
where
|
||||
F: FnOnce(RenderableContent, char) -> T,
|
||||
F: FnOnce(RenderableContent, char, bool) -> T,
|
||||
{
|
||||
let m = self.term.clone(); //Arc clone
|
||||
let mut term = m.lock();
|
||||
|
@ -599,7 +611,7 @@ impl Terminal {
|
|||
|
||||
let cursor_text = term.grid()[content.cursor.point].c;
|
||||
|
||||
f(content, cursor_text)
|
||||
f(content, cursor_text, term.cursor_style().blinking)
|
||||
}
|
||||
|
||||
///Scroll the terminal
|
||||
|
|
|
@ -94,8 +94,13 @@ impl TerminalView {
|
|||
let shell = settings.terminal_overrides.shell.clone();
|
||||
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) => {
|
||||
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
||||
let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue