first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
use galaxy_util::path::user_friendly_path;
|
||||
use galaxyui::{
|
||||
elements::{
|
||||
Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, MainAxisSize,
|
||||
MouseStateHandle, ParentElement, Radius, Text,
|
||||
},
|
||||
platform::Cursor,
|
||||
ui_components::{
|
||||
button::{ButtonTooltipPosition, ButtonVariant},
|
||||
components::{UiComponent, UiComponentStyles},
|
||||
},
|
||||
AppContext, Element, SingletonEntity,
|
||||
use galaxyui::elements::{
|
||||
Border, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Flex, MainAxisSize,
|
||||
MouseStateHandle, ParentElement, Radius, Text,
|
||||
};
|
||||
use warpui::platform::Cursor;
|
||||
use warpui::ui_components::button::{ButtonTooltipPosition, ButtonVariant};
|
||||
use warpui::ui_components::components::{UiComponent, UiComponentStyles};
|
||||
use warpui::{AppContext, Element, SingletonEntity};
|
||||
|
||||
use crate::{
|
||||
appearance::Appearance, settings::ai::DefaultSessionMode, tab_configs::TabConfig,
|
||||
terminal::available_shells::AvailableShell, workspace::WorkspaceAction,
|
||||
};
|
||||
use crate::appearance::Appearance;
|
||||
use crate::settings::ai::DefaultSessionMode;
|
||||
use crate::tab_configs::TabConfig;
|
||||
use crate::terminal::available_shells::AvailableShell;
|
||||
use crate::workspace::WorkspaceAction;
|
||||
|
||||
pub(crate) const SIDECAR_WIDTH: f32 = 260.;
|
||||
const SIDECAR_PADDING: f32 = 12.;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use galaxyui::{
|
||||
elements::ChildView, ui_components::components::UiComponentStyles, AppContext, Element, Entity,
|
||||
TypedActionView, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use galaxyui::elements::ChildView;
|
||||
use galaxyui::ui_components::components::UiComponentStyles;
|
||||
use galaxyui::{AppContext, Element, Entity, TypedActionView, View, ViewContext, ViewHandle};
|
||||
|
||||
use crate::{
|
||||
code_review::diff_state::DiffStateModel,
|
||||
tab_configs::PickerStyle,
|
||||
util::git::detect_current_branch,
|
||||
view_components::{DropdownItem, FilterableDropdown},
|
||||
use crate::tab_configs::PickerStyle;
|
||||
use crate::util::git::{
|
||||
detect_current_branch, get_all_branches, get_all_branches_with_known_main,
|
||||
sort_branches_main_first, BranchEntry,
|
||||
};
|
||||
use crate::view_components::{DropdownItem, FilterableDropdown};
|
||||
|
||||
const DEFAULT_DROPDOWN_WIDTH: f32 = 380.;
|
||||
/// Placeholder text shown in the dropdown top bar while branches are loading.
|
||||
@@ -137,10 +136,9 @@ impl BranchPicker {
|
||||
async move {
|
||||
let branches = match known_main {
|
||||
Some(ref main) => {
|
||||
DiffStateModel::get_all_branches_with_known_main(&cwd, main, None, false)
|
||||
.await
|
||||
get_all_branches_with_known_main(&cwd, main, None, false).await
|
||||
}
|
||||
None => DiffStateModel::get_all_branches(&cwd, None, false).await,
|
||||
None => get_all_branches(&cwd, None, false).await,
|
||||
};
|
||||
|
||||
// git for-each-ref only lists refs backed by actual commits,
|
||||
@@ -153,7 +151,10 @@ impl BranchPicker {
|
||||
if let Ok(current) = detect_current_branch(&cwd).await {
|
||||
let trimmed = current.trim().to_string();
|
||||
if !trimmed.is_empty() {
|
||||
return Ok(vec![(trimmed, true)]);
|
||||
return Ok(vec![BranchEntry {
|
||||
name: trimmed,
|
||||
is_main: true,
|
||||
}]);
|
||||
}
|
||||
}
|
||||
branches
|
||||
@@ -185,20 +186,19 @@ impl BranchPicker {
|
||||
if me.cached_main_branch.is_none() {
|
||||
me.cached_main_branch = branches
|
||||
.iter()
|
||||
.find(|(_, is_main)| *is_main)
|
||||
.map(|(name, _)| name.clone());
|
||||
.find(|entry| entry.is_main)
|
||||
.map(|entry| entry.name.clone());
|
||||
}
|
||||
|
||||
// Main branches first, then the rest in recency order.
|
||||
let mut items: Vec<DropdownItem<String>> =
|
||||
DiffStateModel::sort_branches_main_first(&branches)
|
||||
.map(|(name, _)| DropdownItem::new(name.clone(), name.clone()))
|
||||
.collect();
|
||||
let mut items: Vec<DropdownItem<String>> = sort_branches_main_first(&branches)
|
||||
.map(|entry| DropdownItem::new(entry.name.clone(), entry.name.clone()))
|
||||
.collect();
|
||||
|
||||
// Add the default as the first item if it isn't already in the list
|
||||
// (e.g. the user typed a branch name that doesn't exist locally yet).
|
||||
if let Some(ref default) = me.default_value {
|
||||
if !branches.iter().any(|(name, _)| name == default) {
|
||||
if !branches.iter().any(|entry| entry.name == *default) {
|
||||
items.insert(0, DropdownItem::new(default.clone(), default.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ pub mod session_config_rendering;
|
||||
pub mod tab_config;
|
||||
pub mod telemetry;
|
||||
|
||||
use galaxy_core::ui::theme::Fill;
|
||||
|
||||
pub use new_worktree_modal::{NewWorktreeModal, NewWorktreeModalEvent};
|
||||
pub use params_modal::{TabConfigParamsModal, TabConfigParamsModalEvent};
|
||||
#[cfg(feature = "local_fs")]
|
||||
@@ -19,6 +17,7 @@ pub(crate) use tab_config::build_worktree_config_toml;
|
||||
pub use tab_config::{
|
||||
render_tab_config, TabConfig, TabConfigError, TabConfigParam, TabConfigParamType,
|
||||
};
|
||||
use galaxy_core::ui::theme::Fill;
|
||||
|
||||
/// Optional visual overrides for BranchPicker / RepoPicker dropdowns.
|
||||
pub struct PickerStyle {
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use galaxyui::{
|
||||
elements::{
|
||||
Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element,
|
||||
Fill as ElementFill, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, Padding,
|
||||
ParentElement, Radius, Shrinkable, Text,
|
||||
},
|
||||
fonts::{Properties, Weight},
|
||||
keymap::FixedBinding,
|
||||
platform::Cursor,
|
||||
ui_components::{
|
||||
button::ButtonVariant,
|
||||
checkbox::Checkbox,
|
||||
components::{Coords, UiComponent, UiComponentStyles},
|
||||
},
|
||||
AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle,
|
||||
use galaxyui::elements::{
|
||||
Border, ChildView, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Element,
|
||||
Fill as ElementFill, Flex, MainAxisAlignment, MainAxisSize, MouseStateHandle, Padding,
|
||||
ParentElement, Radius, Shrinkable, Text,
|
||||
};
|
||||
use warpui::fonts::{Properties, Weight};
|
||||
use warpui::keymap::FixedBinding;
|
||||
use warpui::platform::Cursor;
|
||||
use warpui::ui_components::button::ButtonVariant;
|
||||
use warpui::ui_components::checkbox::Checkbox;
|
||||
use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
|
||||
use warpui::{AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle};
|
||||
|
||||
/// Registers keybindings for the new-worktree modal (ESC to close).
|
||||
pub fn init(app: &mut AppContext) {
|
||||
@@ -29,16 +25,12 @@ pub fn init(app: &mut AppContext) {
|
||||
|
||||
use galaxy_core::ui::theme::color::internal_colors;
|
||||
|
||||
use crate::{
|
||||
ai::persisted_workspace::PersistedWorkspace,
|
||||
appearance::Appearance,
|
||||
editor::{EditorView, Event as EditorEvent, SingleLineEditorOptions},
|
||||
modal::ModalAction,
|
||||
tab_configs::{
|
||||
branch_picker::BranchPicker,
|
||||
repo_picker::{RepoPicker, RepoPickerEvent},
|
||||
},
|
||||
};
|
||||
use crate::ai::persisted_workspace::PersistedWorkspace;
|
||||
use crate::appearance::Appearance;
|
||||
use crate::editor::{EditorView, Event as EditorEvent, SingleLineEditorOptions};
|
||||
use crate::modal::ModalAction;
|
||||
use crate::tab_configs::branch_picker::BranchPicker;
|
||||
use crate::tab_configs::repo_picker::{RepoPicker, RepoPickerEvent};
|
||||
|
||||
/// Gap between sections in the modal body (repo picker, branch picker, checkbox).
|
||||
const SECTION_GAP: f32 = 16.;
|
||||
|
||||
@@ -1,38 +1,36 @@
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use galaxy_core::ui::theme::color::internal_colors;
|
||||
use galaxy_core::ui::Icon;
|
||||
use galaxy_editor::editor::NavigationKey;
|
||||
use galaxyui::elements::{
|
||||
Border, ChildView, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container,
|
||||
CornerRadius, CrossAxisAlignment, Fill, Flex, Hoverable, MainAxisAlignment, MainAxisSize,
|
||||
MouseStateHandle, Padding, ParentElement, Radius, SavePosition, ScrollTarget,
|
||||
ScrollToPositionMode, ScrollbarWidth, Shrinkable, Text,
|
||||
};
|
||||
use galaxyui::fonts::{Properties, Weight};
|
||||
use galaxyui::keymap::macros::*;
|
||||
use galaxyui::keymap::{FixedBinding, Keystroke};
|
||||
use galaxyui::platform::Cursor;
|
||||
use galaxyui::ui_components::components::UiComponent;
|
||||
use galaxyui::{
|
||||
elements::{
|
||||
Border, ChildView, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox, Container,
|
||||
CornerRadius, CrossAxisAlignment, Fill, Flex, Hoverable, MainAxisAlignment, MainAxisSize,
|
||||
MouseStateHandle, Padding, ParentElement, Radius, SavePosition, ScrollTarget,
|
||||
ScrollToPositionMode, ScrollbarWidth, Shrinkable, Text,
|
||||
},
|
||||
fonts::{Properties, Weight},
|
||||
keymap::{macros::*, FixedBinding, Keystroke},
|
||||
platform::Cursor,
|
||||
ui_components::components::UiComponent,
|
||||
AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext,
|
||||
ViewHandle,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
appearance::Appearance,
|
||||
editor::{
|
||||
EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys, SingleLineEditorOptions,
|
||||
TextOptions,
|
||||
},
|
||||
modal::ModalAction,
|
||||
tab_configs::{
|
||||
branch_picker::BranchPicker,
|
||||
repo_picker::{RepoPicker, RepoPickerEvent},
|
||||
PickerStyle, TabConfig, TabConfigParam, TabConfigParamType,
|
||||
},
|
||||
view_components::action_button::{
|
||||
ActionButton, DisabledTheme, KeystrokeSource, NakedTheme, PrimaryTheme,
|
||||
},
|
||||
use crate::appearance::Appearance;
|
||||
use crate::editor::{
|
||||
EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys, SingleLineEditorOptions,
|
||||
TextOptions,
|
||||
};
|
||||
use crate::modal::ModalAction;
|
||||
use crate::tab_configs::branch_picker::BranchPicker;
|
||||
use crate::tab_configs::repo_picker::{RepoPicker, RepoPickerEvent};
|
||||
use crate::tab_configs::{PickerStyle, TabConfig, TabConfigParam, TabConfigParamType};
|
||||
use crate::view_components::action_button::{
|
||||
ActionButton, DisabledTheme, KeystrokeSource, NakedTheme, PrimaryTheme,
|
||||
};
|
||||
|
||||
pub fn init(app: &mut AppContext) {
|
||||
@@ -42,20 +40,16 @@ pub fn init(app: &mut AppContext) {
|
||||
TabConfigParamsModalAction::Escape,
|
||||
id!("TabConfigParamsModal"),
|
||||
),
|
||||
// Enter and Space only fire when no EditorView descendant is focused.
|
||||
// When a text field or picker filter editor has focus, the editor
|
||||
// consumes these keys and the modal handles them via event
|
||||
// subscriptions instead (see handle_editor_event).
|
||||
// Enter only fires when no EditorView descendant is focused. When a
|
||||
// text field or picker filter editor has focus, the editor consumes
|
||||
// it and the modal handles submit via event subscriptions instead
|
||||
// (see handle_editor_event). Space is owned by FilterableDropdown
|
||||
// itself when a picker is focused, so the modal no longer binds it.
|
||||
FixedBinding::new(
|
||||
"enter",
|
||||
TabConfigParamsModalAction::Submit,
|
||||
id!("TabConfigParamsModal") & !id!("EditorView"),
|
||||
),
|
||||
FixedBinding::new(
|
||||
"space",
|
||||
TabConfigParamsModalAction::ToggleDropdown,
|
||||
id!("TabConfigParamsModal") & !id!("EditorView"),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -149,7 +143,6 @@ pub enum TabConfigParamsModalAction {
|
||||
Cancel,
|
||||
Submit,
|
||||
Escape,
|
||||
ToggleDropdown,
|
||||
}
|
||||
|
||||
impl TabConfigParamsModal {
|
||||
@@ -324,10 +317,9 @@ impl TabConfigParamsModal {
|
||||
|
||||
self.pending_config = Some(config);
|
||||
|
||||
// When the only fields are dropdowns, focus the modal itself so
|
||||
// Enter (submit) and Space (toggle dropdown) fixed bindings fire.
|
||||
// When there are text fields, focus the first one so the user can
|
||||
// start typing immediately.
|
||||
// When the only fields are dropdowns, focus the modal itself so the
|
||||
// Enter (submit) fixed binding fires. When there are text fields,
|
||||
// focus the first one so the user can start typing immediately.
|
||||
if self.has_text_fields() {
|
||||
self.focus_field(0, ctx);
|
||||
} else {
|
||||
@@ -405,35 +397,6 @@ impl TabConfigParamsModal {
|
||||
.any(|(_, _, field)| matches!(field, ParamField::Text(_)))
|
||||
}
|
||||
|
||||
fn dropdown_count(&self) -> usize {
|
||||
self.param_fields
|
||||
.iter()
|
||||
.filter(|(_, _, field)| !matches!(field, ParamField::Text(_)))
|
||||
.count()
|
||||
}
|
||||
|
||||
fn toggle_single_dropdown(&mut self, ctx: &mut ViewContext<Self>) {
|
||||
let mut opened = false;
|
||||
for (_, _, field) in &self.param_fields {
|
||||
match field {
|
||||
ParamField::Branch { picker, .. } => {
|
||||
opened = picker.update(ctx, |p, ctx| p.toggle_dropdown(ctx));
|
||||
break;
|
||||
}
|
||||
ParamField::Repo { picker, .. } => {
|
||||
opened = picker.update(ctx, |p, ctx| p.toggle_dropdown(ctx));
|
||||
break;
|
||||
}
|
||||
ParamField::Text(_) => {}
|
||||
}
|
||||
}
|
||||
// When the dropdown just closed, reclaim focus so Enter/Space
|
||||
// fixed bindings continue to work.
|
||||
if !opened && !self.has_text_fields() {
|
||||
ctx.focus_self();
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_field(&self, index: usize, ctx: &mut ViewContext<Self>) {
|
||||
if let Some((_, _, field)) = self.param_fields.get(index) {
|
||||
match field {
|
||||
@@ -505,8 +468,8 @@ impl View for TabConfigParamsModal {
|
||||
|
||||
fn on_focus(&mut self, focus_ctx: &FocusContext, ctx: &mut ViewContext<Self>) {
|
||||
// When focus arrives directly at this view (not at a child), keep
|
||||
// self-focus so the Enter/Space fixed bindings fire. This happens
|
||||
// on initial open (via focus_self in on_open) and when the Modal
|
||||
// self-focus so the Enter fixed binding fires. This happens on
|
||||
// initial open (via focus_self in on_open) and when the Modal
|
||||
// wrapper re-focuses the body after a child (like a dropdown)
|
||||
// releases focus.
|
||||
if focus_ctx.is_self_focused() && !self.has_text_fields() {
|
||||
@@ -729,11 +692,6 @@ impl TypedActionView for TabConfigParamsModal {
|
||||
ctx.emit(TabConfigParamsModalEvent::Close);
|
||||
}
|
||||
TabConfigParamsModalAction::Submit => self.try_submit(ctx),
|
||||
TabConfigParamsModalAction::ToggleDropdown => {
|
||||
if self.dropdown_count() <= 1 {
|
||||
self.toggle_single_dropdown(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
use galaxy_core::ui::theme::Fill;
|
||||
use galaxyui::elements::{
|
||||
Align, ChildAnchor, ChildView, Container, OffsetPositioning, ParentAnchor, ParentOffsetBounds,
|
||||
Stack,
|
||||
};
|
||||
use galaxyui::keymap::{FixedBinding, Keystroke};
|
||||
use galaxyui::ui_components::components::{UiComponent, UiComponentStyles};
|
||||
use galaxyui::{
|
||||
elements::{
|
||||
Align, ChildAnchor, ChildView, Container, OffsetPositioning, ParentAnchor,
|
||||
ParentOffsetBounds, Stack,
|
||||
},
|
||||
keymap::{FixedBinding, Keystroke},
|
||||
ui_components::components::{UiComponent, UiComponentStyles},
|
||||
AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
|
||||
use crate::{
|
||||
appearance::Appearance,
|
||||
ui_components::dialog::{dialog_styles, Dialog},
|
||||
view_components::action_button::{
|
||||
ActionButton, DangerPrimaryTheme, KeystrokeSource, NakedTheme,
|
||||
},
|
||||
use crate::appearance::Appearance;
|
||||
use crate::ui_components::dialog::{dialog_styles, Dialog};
|
||||
use crate::view_components::action_button::{
|
||||
ActionButton, DangerPrimaryTheme, KeystrokeSource, NakedTheme,
|
||||
};
|
||||
|
||||
pub(crate) fn init(app: &mut AppContext) {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use galaxy_util::path::user_friendly_path;
|
||||
use galaxyui::elements::{Border, ChildView, Container, Hoverable, MouseStateHandle, Text};
|
||||
use galaxyui::platform::Cursor;
|
||||
use galaxyui::text_layout::ClipConfig;
|
||||
use galaxyui::ui_components::components::UiComponentStyles;
|
||||
use galaxyui::{
|
||||
elements::{Border, ChildView, Container, Hoverable, MouseStateHandle, Text},
|
||||
platform::Cursor,
|
||||
ui_components::components::UiComponentStyles,
|
||||
AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ai::persisted_workspace::{PersistedWorkspace, PersistedWorkspaceEvent},
|
||||
appearance::Appearance,
|
||||
tab_configs::PickerStyle,
|
||||
view_components::{DropdownItem, FilterableDropdown},
|
||||
};
|
||||
use crate::ai::persisted_workspace::{PersistedWorkspace, PersistedWorkspaceEvent};
|
||||
use crate::appearance::Appearance;
|
||||
use crate::tab_configs::PickerStyle;
|
||||
use crate::view_components::{DropdownItem, FilterableDropdown};
|
||||
|
||||
const DEFAULT_DROPDOWN_WIDTH: f32 = 380.;
|
||||
|
||||
@@ -147,22 +147,46 @@ impl RepoPicker {
|
||||
// workspaces() already returns entries sorted by most-recently-touched.
|
||||
// "+ Add new repo..." is a sticky footer (not a list item) so it is
|
||||
// not included here.
|
||||
//
|
||||
// Each item's `display_text` is the full user-friendly form
|
||||
// (`~`-prefixed). The dropdown clips it at render width via
|
||||
// `ClipConfig::start()`, so distinct paths with shared trailing
|
||||
// segments stay readable without character-count approximation.
|
||||
// The action carries the *raw* absolute path so consumers reading
|
||||
// `RepoPickerEvent::Selected` keep getting a real filesystem path.
|
||||
let home = dirs::home_dir().map(|p| p.display().to_string());
|
||||
let items: Vec<DropdownItem<RepoPickerAction>> = PersistedWorkspace::as_ref(ctx)
|
||||
.workspaces()
|
||||
.filter(|ws| ws.path.exists())
|
||||
.map(|ws| {
|
||||
let path_str = ws.path.to_string_lossy().into_owned();
|
||||
DropdownItem::new(path_str.clone(), RepoPickerAction::Select(path_str))
|
||||
let display = user_friendly_path(&path_str, home.as_deref()).into_owned();
|
||||
DropdownItem::new(display, RepoPickerAction::Select(path_str.clone()))
|
||||
.with_clip_config(ClipConfig::start())
|
||||
.with_tooltip(path_str)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let path_to_select = select_path
|
||||
let raw_to_select = select_path
|
||||
.or(self.selected.as_deref())
|
||||
.map(|s| s.to_owned());
|
||||
|
||||
// Mirror the raw path into `self.selected` so `selected_value()`
|
||||
// returns a real filesystem path even before the user explicitly
|
||||
// picks something. Load-bearing for `new_worktree_modal::on_open`,
|
||||
// which reads `repo_picker.selected_value()` at modal-open time when
|
||||
// its own `selected_repo` is still `None`.
|
||||
if let Some(ref raw) = raw_to_select {
|
||||
self.selected = Some(raw.clone());
|
||||
}
|
||||
|
||||
self.dropdown.update(ctx, |dropdown, ctx| {
|
||||
dropdown.set_items(items, ctx);
|
||||
if let Some(ref path) = path_to_select {
|
||||
dropdown.set_selected_by_name(path.as_str(), ctx);
|
||||
// Match by the action (which carries the raw absolute path) so two
|
||||
// repos that left-clip to identical-looking labels can't be
|
||||
// confused at preselection time.
|
||||
if let Some(ref raw) = raw_to_select {
|
||||
dropdown.set_selected_by_action(RepoPickerAction::Select(raw.clone()), ctx);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -176,11 +200,14 @@ impl RepoPicker {
|
||||
self.dropdown.as_ref(ctx).is_expanded()
|
||||
}
|
||||
|
||||
/// Returns the currently shown selected repo path.
|
||||
pub fn selected_value(&self, app: &AppContext) -> Option<String> {
|
||||
self.selected
|
||||
.clone()
|
||||
.or_else(|| self.dropdown.as_ref(app).selected_item_label())
|
||||
/// Returns the currently shown selected repo path (raw absolute path).
|
||||
///
|
||||
/// `refresh_items` eagerly mirrors any pre-selected raw path into
|
||||
/// `self.selected`, so we never need to fall back to the dropdown's
|
||||
/// `selected_item_label` — that would return the `~`-abbreviated display
|
||||
/// string, not a usable filesystem path.
|
||||
pub fn selected_value(&self, _app: &AppContext) -> Option<String> {
|
||||
self.selected.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[cfg(feature = "local_fs")]
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::app_state::{BranchSnapshot, LeafContents, LeafSnapshot, PaneNodeSnapshot};
|
||||
use crate::launch_configs::launch_config::SplitDirection;
|
||||
use crate::terminal::cli_agent::CLIAgent;
|
||||
use crate::themes::theme::AnsiColorIdentifier;
|
||||
use crate::ui_components::icons::Icon;
|
||||
|
||||
use super::tab_config::{
|
||||
generated_worktree_path_string, TabConfig, TabConfigPaneNode, TabConfigPaneType,
|
||||
TabConfigParam, TabConfigParamType, AUTOGENERATED_BRANCH_NAME_PARAM,
|
||||
};
|
||||
use crate::app_state::{BranchSnapshot, LeafContents, LeafSnapshot, PaneNodeSnapshot};
|
||||
use crate::launch_configs::launch_config::SplitDirection;
|
||||
use crate::terminal::cli_agent::CLIAgent;
|
||||
use crate::themes::theme::AnsiColorIdentifier;
|
||||
use crate::ui_components::icons::Icon;
|
||||
|
||||
/// The type of session the user wants to start.
|
||||
///
|
||||
|
||||
@@ -7,24 +7,22 @@ use galaxyui::elements::{
|
||||
};
|
||||
use galaxyui::fonts::Weight;
|
||||
use galaxyui::keymap::macros::id;
|
||||
use galaxyui::keymap::FixedBinding;
|
||||
use galaxyui::keymap::Keystroke;
|
||||
use galaxyui::keymap::{FixedBinding, Keystroke};
|
||||
use galaxyui::platform::file_picker::FilePickerConfiguration;
|
||||
use galaxyui::FocusContext;
|
||||
use galaxyui::{
|
||||
AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext, ViewHandle,
|
||||
AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext,
|
||||
ViewHandle,
|
||||
};
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
|
||||
use super::session_config::{is_git_repo, SessionConfigSelection, SessionType};
|
||||
use super::session_config_rendering;
|
||||
use crate::appearance::Appearance;
|
||||
use crate::ui_components::blended_colors;
|
||||
use crate::view_components::action_button::{
|
||||
ActionButton, ButtonSize, KeystrokeSource, NakedTheme, PrimaryTheme,
|
||||
};
|
||||
|
||||
use super::session_config::{is_git_repo, SessionConfigSelection, SessionType};
|
||||
use super::session_config_rendering;
|
||||
|
||||
pub fn init(app: &mut galaxyui::AppContext) {
|
||||
app.register_fixed_bindings([FixedBinding::new(
|
||||
"enter",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
use galaxy_core::ui::theme::{Fill, WarpTheme};
|
||||
use galaxyui::elements::{
|
||||
Border, ChildAnchor, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Expanded,
|
||||
Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning,
|
||||
@@ -10,13 +13,7 @@ use galaxyui::fonts::{Properties, Weight};
|
||||
use galaxyui::geometry::vector::Vector2F;
|
||||
use galaxyui::platform::Cursor;
|
||||
use galaxyui::ui_components::components::UiComponent;
|
||||
use galaxyui::Element;
|
||||
use galaxyui::EventContext;
|
||||
use pathfinder_color::ColorU;
|
||||
use pathfinder_geometry::vector::vec2f;
|
||||
|
||||
use galaxy_core::ui::theme::Fill;
|
||||
use galaxy_core::ui::theme::GalaxyTheme;
|
||||
use galaxyui::{Element, EventContext};
|
||||
|
||||
use crate::appearance::Appearance;
|
||||
use crate::tab_configs::session_config::SessionType;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::terminal::cli_agent::CLIAgent;
|
||||
|
||||
use super::*;
|
||||
use crate::terminal::cli_agent::CLIAgent;
|
||||
|
||||
fn generated_worktree_path_string(repo: &str, worktree_name: &str) -> String {
|
||||
super::super::tab_config::generated_worktree_path(Path::new(repo), worktree_name)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::launch_configs::launch_config::{PaneTemplateType, SplitDirection};
|
||||
|
||||
use super::*;
|
||||
use crate::launch_configs::launch_config::{PaneTemplateType, SplitDirection};
|
||||
|
||||
const WORKTREE_TOML: &str = r#"
|
||||
name = "New Worktree"
|
||||
|
||||
Reference in New Issue
Block a user