mirror of https://github.com/lapce/lapce.git
add palette kind symbol
This commit is contained in:
parent
89f19a2356
commit
d0bbeff1f6
|
@ -1587,7 +1587,7 @@ dependencies = [
|
|||
"leptos_reactive",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.1",
|
||||
"parley 0.1.0 (git+https://github.com/lapce/parley?rev=421e5c1eb07d108a9c05da4f021a34f5bd6532cd)",
|
||||
"parley 0.1.0 (git+https://github.com/lapce/parley?rev=dd30cc9e4ae733d80650ad3ab0db0462ccd67e57)",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
"taffy",
|
||||
|
@ -1733,8 +1733,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "fount"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lapce/fount?rev=0ac37ef400d4048e2dbebe34b1a74f55dab4654d#0ac37ef400d4048e2dbebe34b1a74f55dab4654d"
|
||||
source = "git+https://github.com/lapce/fount?rev=7952647649c119be454691764c20768330a6e8f2#7952647649c119be454691764c20768330a6e8f2"
|
||||
dependencies = [
|
||||
"peniko",
|
||||
"swash 0.1.6 (git+https://github.com/dfrg/swash)",
|
||||
]
|
||||
|
||||
|
@ -4201,9 +4202,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "parley"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lapce/parley?rev=421e5c1eb07d108a9c05da4f021a34f5bd6532cd#421e5c1eb07d108a9c05da4f021a34f5bd6532cd"
|
||||
source = "git+https://github.com/lapce/parley?rev=dd30cc9e4ae733d80650ad3ab0db0462ccd67e57#dd30cc9e4ae733d80650ad3ab0db0462ccd67e57"
|
||||
dependencies = [
|
||||
"fount 0.1.0 (git+https://github.com/lapce/fount?rev=0ac37ef400d4048e2dbebe34b1a74f55dab4654d)",
|
||||
"fount 0.1.0 (git+https://github.com/lapce/fount?rev=7952647649c119be454691764c20768330a6e8f2)",
|
||||
"once_cell",
|
||||
"swash 0.1.6 (git+https://github.com/dfrg/swash)",
|
||||
]
|
||||
|
@ -4257,7 +4258,7 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
|||
[[package]]
|
||||
name = "peniko"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/linebender/peniko?rev=8cb710f#8cb710ffcb0f04fa24648440f9b9fb038174a341"
|
||||
source = "git+https://github.com/linebender/peniko?rev=cafdac9a211a0fb2fec5656bd663d1ac770bcc81#cafdac9a211a0fb2fec5656bd663d1ac770bcc81"
|
||||
dependencies = [
|
||||
"kurbo 0.9.0",
|
||||
"smallvec",
|
||||
|
@ -6575,8 +6576,8 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|||
|
||||
[[package]]
|
||||
name = "vello"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/linebender/vello#020a7f5c016ab5c572cefbe169f19082a0e34ffe"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/linebender/vello?rev=2f268d4e0f8596c2c05f4982ddc558e1cae0ffa2#2f268d4e0f8596c2c05f4982ddc558e1cae0ffa2"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"futures-intrusive",
|
||||
|
@ -6590,8 +6591,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "vello_svg"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/linebender/vello#020a7f5c016ab5c572cefbe169f19082a0e34ffe"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/linebender/vello?rev=2f268d4e0f8596c2c05f4982ddc558e1cae0ffa2#2f268d4e0f8596c2c05f4982ddc558e1cae0ffa2"
|
||||
dependencies = [
|
||||
"usvg 0.28.0",
|
||||
"vello",
|
||||
|
|
|
@ -1503,6 +1503,7 @@ fn palette_content(cx: AppContext, window_tab_data: WindowTabData) -> impl View
|
|||
let index = window_tab_data.palette.index.read_only();
|
||||
let config = window_tab_data.palette.config;
|
||||
let run_id = window_tab_data.palette.run_id;
|
||||
let input = window_tab_data.palette.input.read_only();
|
||||
let palette_item_height = 24.0;
|
||||
container(cx, |cx| {
|
||||
scroll(cx, |cx| {
|
||||
|
@ -1510,7 +1511,9 @@ fn palette_content(cx: AppContext, window_tab_data: WindowTabData) -> impl View
|
|||
cx,
|
||||
VirtualListDirection::Vertical,
|
||||
move || PaletteItems(items.get()),
|
||||
move |(i, _item)| (run_id.get_untracked(), *i),
|
||||
move |(i, _item)| {
|
||||
(run_id.get_untracked(), *i, input.get_untracked().input)
|
||||
},
|
||||
move |cx, (i, item)| {
|
||||
palette_item(cx, i, item, index, palette_item_height, config)
|
||||
},
|
||||
|
@ -1636,15 +1639,14 @@ fn completion(cx: AppContext, window_tab_data: WindowTabData) -> impl View {
|
|||
let completion_data = window_tab_data.completion;
|
||||
let config = window_tab_data.config;
|
||||
let active = completion_data.with_untracked(|c| c.active);
|
||||
let request_id = create_memo(cx.scope, move |_| {
|
||||
completion_data.with(|c| (c.request_id, c.input_id))
|
||||
});
|
||||
let request_id =
|
||||
move || completion_data.with_untracked(|c| (c.request_id, c.input_id));
|
||||
scroll(cx, move |cx| {
|
||||
virtual_list(
|
||||
cx,
|
||||
VirtualListDirection::Vertical,
|
||||
move || completion_data.with(|c| VectorItems(c.filtered_items.clone())),
|
||||
move |(i, item)| (request_id.get_untracked(), *i),
|
||||
move |(i, item)| (request_id(), *i),
|
||||
move |cx, (i, item)| {
|
||||
stack(cx, |cx| {
|
||||
(
|
||||
|
|
|
@ -75,7 +75,6 @@ pub fn receive(
|
|||
return;
|
||||
}
|
||||
|
||||
println!("receive completion");
|
||||
let items = match resp {
|
||||
CompletionResponse::Array(items) => items,
|
||||
CompletionResponse::List(list) => &list.items,
|
||||
|
|
|
@ -282,7 +282,6 @@ fn run_focus_command(
|
|||
}
|
||||
}
|
||||
FocusCommand::SplitExchange => {
|
||||
println!("split exchage");
|
||||
if let Some(editor_tab_id) = self.editor_tab_id {
|
||||
self.internal_command
|
||||
.set(Some(InternalCommand::SplitExchange { editor_tab_id }));
|
||||
|
@ -575,7 +574,6 @@ fn update_completion(&self, display_if_empty_input: bool) {
|
|||
});
|
||||
return;
|
||||
}
|
||||
println!("offset {offset} start offset {start_offset} input {input}");
|
||||
|
||||
if self.completion.with_untracked(|completion| {
|
||||
completion.status != CompletionStatus::Inactive
|
||||
|
@ -608,7 +606,6 @@ fn update_completion(&self, display_if_empty_input: bool) {
|
|||
}
|
||||
|
||||
self.completion.update(|completion| {
|
||||
println!("new completion");
|
||||
completion.path = path.clone();
|
||||
completion.offset = start_offset;
|
||||
completion.input = input.clone();
|
||||
|
@ -689,7 +686,6 @@ fn apply_completion_item(&self, item: &CompletionItem) -> Result<()> {
|
|||
&selection,
|
||||
additional_edit,
|
||||
start_offset,
|
||||
edit_start,
|
||||
)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -725,7 +721,6 @@ fn completion_apply_snippet(
|
|||
selection: &Selection,
|
||||
additional_edit: Vec<(Selection, &str)>,
|
||||
start_offset: usize,
|
||||
edit_start: usize,
|
||||
) -> Result<()> {
|
||||
let snippet = Snippet::from_str(snippet)?;
|
||||
let text = snippet.text();
|
||||
|
@ -747,13 +742,6 @@ fn completion_apply_snippet(
|
|||
|
||||
let selection = selection.apply_delta(&delta, true, InsertDrift::Default);
|
||||
|
||||
let start_offset = additional_edit
|
||||
.iter()
|
||||
.map(|(selection, _)| selection.min_offset())
|
||||
.min()
|
||||
.map(|offset| offset.min(start_offset).min(edit_start))
|
||||
.unwrap_or(start_offset);
|
||||
|
||||
let mut transformer = Transformer::new(&delta);
|
||||
let offset = transformer.transform(start_offset, false);
|
||||
let snippet_tabs = snippet.tabs(offset);
|
||||
|
|
|
@ -62,19 +62,32 @@ pub enum PaletteStatus {
|
|||
Done,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PaletteInput {
|
||||
pub input: String,
|
||||
pub kind: PaletteKind,
|
||||
}
|
||||
|
||||
impl PaletteInput {
|
||||
pub fn update_input(&mut self, input: String) {
|
||||
self.kind = self.kind.get_palette_kind(&input);
|
||||
self.input = self.kind.get_input(&input).to_string();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PaletteData {
|
||||
run_id_counter: Arc<AtomicU64>,
|
||||
run_tx: Sender<(u64, String, im::Vector<PaletteItem>)>,
|
||||
internal_command: WriteSignal<Option<InternalCommand>>,
|
||||
pub run_id: ReadSignal<u64>,
|
||||
pub run_id: RwSignal<u64>,
|
||||
pub workspace: Arc<LapceWorkspace>,
|
||||
pub status: RwSignal<PaletteStatus>,
|
||||
pub index: RwSignal<usize>,
|
||||
pub kind: RwSignal<PaletteKind>,
|
||||
pub items: RwSignal<im::Vector<PaletteItem>>,
|
||||
pub filtered_items: ReadSignal<im::Vector<PaletteItem>>,
|
||||
pub proxy_rpc: ProxyRpcHandler,
|
||||
pub input: RwSignal<PaletteInput>,
|
||||
pub editor: EditorData,
|
||||
pub focus: RwSignal<Focus>,
|
||||
pub keypress: ReadSignal<KeyPressData>,
|
||||
|
@ -95,9 +108,15 @@ pub fn new(
|
|||
config: ReadSignal<Arc<LapceConfig>>,
|
||||
) -> Self {
|
||||
let status = create_rw_signal(cx.scope, PaletteStatus::Inactive);
|
||||
let kind = create_rw_signal(cx.scope, PaletteKind::File);
|
||||
let items = create_rw_signal(cx.scope, im::Vector::new());
|
||||
let index = create_rw_signal(cx.scope, 0);
|
||||
let input = create_rw_signal(
|
||||
cx.scope,
|
||||
PaletteInput {
|
||||
input: "".to_string(),
|
||||
kind: PaletteKind::File,
|
||||
},
|
||||
);
|
||||
let editor = EditorData::new_local(
|
||||
cx,
|
||||
EditorId::next(),
|
||||
|
@ -107,19 +126,43 @@ pub fn new(
|
|||
proxy_rpc.clone(),
|
||||
config,
|
||||
);
|
||||
let run_id = create_rw_signal(cx.scope, 0);
|
||||
let run_id_counter = Arc::new(AtomicU64::new(0));
|
||||
|
||||
let (run_tx, run_rx) = crossbeam_channel::unbounded();
|
||||
{
|
||||
let run_id = run_id_counter.clone();
|
||||
let doc = editor.doc.read_only();
|
||||
let run_id = run_id.read_only();
|
||||
let input = input.read_only();
|
||||
let items = items.read_only();
|
||||
let tx = run_tx.clone();
|
||||
create_effect(cx.scope, move |_| {
|
||||
let run_id = run_id.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
let input = doc.with(|doc| doc.buffer().text().to_string());
|
||||
let items = items.get();
|
||||
let _ = tx.send((run_id, input, items));
|
||||
|
||||
{
|
||||
let tx = tx.clone();
|
||||
// this effect only monitors items change
|
||||
create_effect(cx.scope, move |_| {
|
||||
let items = items.get();
|
||||
println!("filter items when items change");
|
||||
let input = input.get_untracked();
|
||||
let run_id = run_id.get_untracked();
|
||||
let _ = tx.send((run_id, input.input, items));
|
||||
});
|
||||
}
|
||||
|
||||
// this effect only monitors input change
|
||||
create_effect(cx.scope, move |last_kind| {
|
||||
let input = input.get();
|
||||
println!("new input {input:?}");
|
||||
let kind = input.kind;
|
||||
if last_kind != Some(kind) {
|
||||
println!("got new kind {kind:?}");
|
||||
return kind;
|
||||
}
|
||||
|
||||
println!("filter items when input change");
|
||||
let items = items.get_untracked();
|
||||
let run_id = run_id.get_untracked();
|
||||
let _ = tx.send((run_id, input.input, items));
|
||||
kind
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -131,20 +174,18 @@ pub fn new(
|
|||
});
|
||||
}
|
||||
|
||||
let (run_id, set_run_id) = create_signal(cx.scope, 0);
|
||||
|
||||
let (filtered_items, set_filtered_items) =
|
||||
create_signal(cx.scope, im::Vector::new());
|
||||
{
|
||||
let resp = create_signal_from_channel(cx, resp_rx);
|
||||
let run_id = run_id_counter.clone();
|
||||
let run_id = run_id.read_only();
|
||||
let input = input.read_only();
|
||||
let index = index.write_only();
|
||||
create_effect(cx.scope, move |_| {
|
||||
if let Some((current_run_id, items)) = resp.get() {
|
||||
if run_id.load(std::sync::atomic::Ordering::Acquire)
|
||||
== current_run_id
|
||||
if let Some((filter_run_id, filter_input, items)) = resp.get() {
|
||||
if run_id.get_untracked() == filter_run_id
|
||||
&& input.get_untracked().input == filter_input
|
||||
{
|
||||
set_run_id.set(current_run_id);
|
||||
set_filtered_items.set(items);
|
||||
index.set(0);
|
||||
}
|
||||
|
@ -152,7 +193,7 @@ pub fn new(
|
|||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
let palette = Self {
|
||||
run_id_counter,
|
||||
run_tx,
|
||||
internal_command,
|
||||
|
@ -160,26 +201,80 @@ pub fn new(
|
|||
focus,
|
||||
workspace,
|
||||
status,
|
||||
kind,
|
||||
index,
|
||||
items,
|
||||
filtered_items,
|
||||
editor,
|
||||
input,
|
||||
proxy_rpc,
|
||||
keypress,
|
||||
config,
|
||||
executed_commands: Rc::new(RefCell::new(HashMap::new())),
|
||||
};
|
||||
|
||||
{
|
||||
let palette = palette.clone();
|
||||
let doc = palette.editor.doc.read_only();
|
||||
let input = palette.input.write_only();
|
||||
let status = palette.status.read_only();
|
||||
// this effect monitors the document change in the palette input editor
|
||||
create_effect(cx.scope, move |last_input| {
|
||||
let new_input = doc.with(|doc| doc.buffer().text().to_string());
|
||||
let status = status.get_untracked();
|
||||
if status == PaletteStatus::Inactive {
|
||||
// If the status is inactive, we set the input to None,
|
||||
// so that when we actually run the palette, the input
|
||||
// can be compared with this None.
|
||||
return None;
|
||||
}
|
||||
|
||||
let last_input_is_none = !matches!(last_input, Some(Some(_)));
|
||||
|
||||
let changed = match last_input {
|
||||
None => true,
|
||||
Some(last_input) => {
|
||||
Some(new_input.as_str()) != last_input.as_deref()
|
||||
}
|
||||
};
|
||||
|
||||
if changed {
|
||||
let new_kind = input
|
||||
.update_returning(|input| {
|
||||
let kind = input.kind;
|
||||
input.update_input(new_input.clone());
|
||||
if last_input_is_none || kind != input.kind {
|
||||
Some(input.kind)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
if let Some(new_kind) = new_kind {
|
||||
palette.run_inner(cx, new_kind);
|
||||
}
|
||||
}
|
||||
Some(new_input)
|
||||
});
|
||||
}
|
||||
|
||||
palette
|
||||
}
|
||||
|
||||
pub fn run(&self, cx: AppContext, kind: PaletteKind) {
|
||||
self.status.set(PaletteStatus::Started);
|
||||
let symbol = kind.symbol();
|
||||
self.editor
|
||||
.doc
|
||||
.update(|doc| doc.reload(Rope::from(""), true));
|
||||
.update(|doc| doc.reload(Rope::from(symbol), true));
|
||||
self.editor
|
||||
.cursor
|
||||
.update(|cursor| cursor.set_insert(Selection::caret(0)));
|
||||
.update(|cursor| cursor.set_insert(Selection::caret(symbol.len())));
|
||||
}
|
||||
|
||||
fn run_inner(&self, cx: AppContext, kind: PaletteKind) {
|
||||
println!("palette run inner");
|
||||
let run_id = self.run_id_counter.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
self.run_id.set(run_id);
|
||||
match kind {
|
||||
PaletteKind::File => {
|
||||
self.get_files(cx);
|
||||
|
@ -188,7 +283,6 @@ pub fn run(&self, cx: AppContext, kind: PaletteKind) {
|
|||
self.get_commands(cx);
|
||||
}
|
||||
}
|
||||
self.kind.set(kind);
|
||||
}
|
||||
|
||||
fn get_files(&self, cx: AppContext) {
|
||||
|
@ -299,13 +393,13 @@ fn select(&self, cx: AppContext) {
|
|||
fn cancel(&self, cx: AppContext) {
|
||||
self.status.set(PaletteStatus::Inactive);
|
||||
self.focus.set(Focus::Workbench);
|
||||
self.items.update(|items| items.clear());
|
||||
self.editor
|
||||
.doc
|
||||
.update(|doc| doc.reload(Rope::from(""), true));
|
||||
self.editor
|
||||
.cursor
|
||||
.update(|cursor| cursor.set_insert(Selection::caret(0)));
|
||||
self.items.update(|items| items.clear());
|
||||
}
|
||||
|
||||
fn next(&self) {
|
||||
|
@ -384,9 +478,11 @@ fn filter_items(
|
|||
}
|
||||
|
||||
filtered_items.sort_by(|a, b| {
|
||||
b.score
|
||||
.partial_cmp(&a.score)
|
||||
.unwrap_or(std::cmp::Ordering::Less)
|
||||
let order = b.score.cmp(&a.score);
|
||||
match order {
|
||||
std::cmp::Ordering::Equal => a.filter_text.cmp(&b.filter_text),
|
||||
_ => order,
|
||||
}
|
||||
});
|
||||
|
||||
if run_id.load(std::sync::atomic::Ordering::Acquire) != current_run_id {
|
||||
|
@ -398,7 +494,7 @@ fn filter_items(
|
|||
fn update_process(
|
||||
run_id: Arc<AtomicU64>,
|
||||
receiver: Receiver<(u64, String, im::Vector<PaletteItem>)>,
|
||||
resp_tx: Sender<(u64, im::Vector<PaletteItem>)>,
|
||||
resp_tx: Sender<(u64, String, im::Vector<PaletteItem>)>,
|
||||
) {
|
||||
fn receive_batch(
|
||||
receiver: &Receiver<(u64, String, im::Vector<PaletteItem>)>,
|
||||
|
@ -428,7 +524,7 @@ fn receive_batch(
|
|||
items,
|
||||
&matcher,
|
||||
) {
|
||||
let _ = resp_tx.send((current_run_id, filtered_items));
|
||||
let _ = resp_tx.send((current_run_id, input, filtered_items));
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
|
|
|
@ -1,5 +1,77 @@
|
|||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum PaletteKind {
|
||||
File,
|
||||
Command,
|
||||
}
|
||||
|
||||
impl PaletteKind {
|
||||
pub fn symbol(&self) -> &'static str {
|
||||
match &self {
|
||||
// PaletteKind::Line => "/",
|
||||
// PaletteKind::DocumentSymbol => "@",
|
||||
// PaletteKind::WorkspaceSymbol => "#",
|
||||
// PaletteKind::GlobalSearch => "?",
|
||||
// PaletteKind::Workspace => ">",
|
||||
PaletteKind::Command => ":",
|
||||
PaletteKind::File
|
||||
// | PaletteKind::Reference
|
||||
// | PaletteKind::ColorTheme
|
||||
// | PaletteKind::IconTheme
|
||||
// | PaletteKind::SshHost
|
||||
// | PaletteKind::RunAndDebug
|
||||
// | PaletteKind::Language
|
||||
=> "",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_input(input: &str) -> PaletteKind {
|
||||
match input {
|
||||
// _ if input.starts_with('/') => PaletteKind::Line,
|
||||
// _ if input.starts_with('@') => PaletteKind::DocumentSymbol,
|
||||
// _ if input.starts_with('#') => PaletteKind::WorkspaceSymbol,
|
||||
// _ if input.starts_with('>') => PaletteKind::Workspace,
|
||||
_ if input.starts_with(':') => PaletteKind::Command,
|
||||
_ => PaletteKind::File,
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn has_preview(&self) -> bool {
|
||||
// matches!(
|
||||
// self,
|
||||
// PaletteType::Line
|
||||
// | PaletteType::DocumentSymbol
|
||||
// | PaletteType::WorkspaceSymbol
|
||||
// | PaletteType::GlobalSearch
|
||||
// | PaletteType::Reference
|
||||
// )
|
||||
// }
|
||||
|
||||
pub fn get_input<'a>(&self, input: &'a str) -> &'a str {
|
||||
match self {
|
||||
PaletteKind::File
|
||||
// | PaletteKind::Reference
|
||||
// | PaletteKind::ColorTheme
|
||||
// | PaletteKind::IconTheme
|
||||
// | PaletteKind::Language
|
||||
// | PaletteKind::RunAndDebug
|
||||
// | PaletteKind::SshHost
|
||||
=> input,
|
||||
PaletteKind::Command
|
||||
// | PaletteType::DocumentSymbol
|
||||
// | PaletteType::WorkspaceSymbol
|
||||
// | PaletteType::Workspace
|
||||
// | PaletteType::Line
|
||||
// | PaletteType::GlobalSearch
|
||||
=> if !input.is_empty() {&input[1..]} else {input},
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the palette kind that it should be considered as based on the current
|
||||
/// [`PaletteKind`] and the current input.
|
||||
pub fn get_palette_kind(&self, input: &str) -> PaletteKind {
|
||||
if self != &PaletteKind::File && self.symbol() == "" {
|
||||
return self.clone();
|
||||
}
|
||||
PaletteKind::from_input(input)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue