mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-18 18:08:07 +03:00
Move NumericPrefixWithSuffix
into utils
This commit is contained in:
parent
96d9df073e
commit
ca092fb694
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -10487,6 +10487,7 @@ dependencies = [
|
|||||||
"take-until",
|
"take-until",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tendril",
|
"tendril",
|
||||||
|
"unicase",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -294,6 +294,7 @@ tree-sitter-vue = { git = "https://github.com/zed-industries/tree-sitter-vue", r
|
|||||||
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "f545a41f57502e1b5ddf2a6668896c1b0620f930" }
|
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "f545a41f57502e1b5ddf2a6668896c1b0620f930" }
|
||||||
tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4c3f426ec61695d7617415fff97029bd" }
|
tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4c3f426ec61695d7617415fff97029bd" }
|
||||||
unindent = "0.1.7"
|
unindent = "0.1.7"
|
||||||
|
unicase = "2.6"
|
||||||
url = "2.2"
|
url = "2.2"
|
||||||
uuid = { version = "1.1.2", features = ["v4"] }
|
uuid = { version = "1.1.2", features = ["v4"] }
|
||||||
wasmtime = "18.0"
|
wasmtime = "18.0"
|
||||||
|
@ -26,7 +26,7 @@ serde_json.workspace = true
|
|||||||
settings.workspace = true
|
settings.workspace = true
|
||||||
theme.workspace = true
|
theme.workspace = true
|
||||||
ui.workspace = true
|
ui.workspace = true
|
||||||
unicase = "2.6"
|
unicase.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
client.workspace = true
|
client.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
|
@ -27,7 +27,7 @@ use std::{cmp::Ordering, ffi::OsStr, ops::Range, path::Path, sync::Arc};
|
|||||||
use theme::ThemeSettings;
|
use theme::ThemeSettings;
|
||||||
use ui::{prelude::*, v_flex, ContextMenu, Icon, KeyBinding, Label, ListItem};
|
use ui::{prelude::*, v_flex, ContextMenu, Icon, KeyBinding, Label, ListItem};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
use util::{maybe, ResultExt, TryFutureExt};
|
use util::{maybe, NumericPrefixWithSuffix, ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel, PanelEvent},
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
notifications::DetachAndPromptErr,
|
notifications::DetachAndPromptErr,
|
||||||
@ -1498,35 +1498,6 @@ impl ProjectPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
struct NumericPrefixWithSuffix<'a>(i32, &'a str);
|
|
||||||
|
|
||||||
impl<'a> NumericPrefixWithSuffix<'a> {
|
|
||||||
fn from_str(str: &'a str) -> Option<Self> {
|
|
||||||
let mut chars = str.chars();
|
|
||||||
let prefix: String = chars.by_ref().take_while(|c| c.is_digit(10)).collect();
|
|
||||||
let remainder = chars.as_str();
|
|
||||||
|
|
||||||
match prefix.parse::<i32>() {
|
|
||||||
Ok(prefix) => Some(NumericPrefixWithSuffix(prefix, remainder)),
|
|
||||||
Err(_) => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> PartialOrd for NumericPrefixWithSuffix<'a> {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
let NumericPrefixWithSuffix(num_a, remainder_a) = self;
|
|
||||||
let NumericPrefixWithSuffix(num_b, remainder_b) = other;
|
|
||||||
|
|
||||||
Some(
|
|
||||||
num_a
|
|
||||||
.cmp(&num_b)
|
|
||||||
.then_with(|| UniCase::new(remainder_a).cmp(&UniCase::new(remainder_b))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for ProjectPanel {
|
impl Render for ProjectPanel {
|
||||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
|
||||||
let has_worktree = self.visible_entries.len() != 0;
|
let has_worktree = self.visible_entries.len() != 0;
|
||||||
|
@ -31,6 +31,7 @@ serde_json.workspace = true
|
|||||||
smol.workspace = true
|
smol.workspace = true
|
||||||
take-until = "0.2.0"
|
take-until = "0.2.0"
|
||||||
tempfile = { workspace = true, optional = true }
|
tempfile = { workspace = true, optional = true }
|
||||||
|
unicase.workspace = true
|
||||||
url.workspace = true
|
url.workspace = true
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
@ -22,6 +22,7 @@ use std::{
|
|||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
use unicase::UniCase;
|
||||||
|
|
||||||
pub use take_until::*;
|
pub use take_until::*;
|
||||||
|
|
||||||
@ -487,6 +488,43 @@ impl<T: Ord + Clone> RangeExt<T> for RangeInclusive<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A way to sort strings with starting numbers numerically first, falling back to alphanumeric one,
|
||||||
|
/// case-insensitive.
|
||||||
|
///
|
||||||
|
/// This is useful for turning regular alphanumerically sorted sequences as `1-abc, 10, 11-def, .., 2, 21-abc`
|
||||||
|
/// into `1-abc, 2, 10, 11-def, .., 21-abc`
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct NumericPrefixWithSuffix<'a>(i32, &'a str);
|
||||||
|
|
||||||
|
impl<'a> NumericPrefixWithSuffix<'a> {
|
||||||
|
pub fn from_str(str: &'a str) -> Option<Self> {
|
||||||
|
let mut chars = str.chars();
|
||||||
|
let prefix: String = chars.by_ref().take_while(|c| c.is_digit(10)).collect();
|
||||||
|
let remainder = chars.as_str();
|
||||||
|
|
||||||
|
match prefix.parse::<i32>() {
|
||||||
|
Ok(prefix) => Some(NumericPrefixWithSuffix(prefix, remainder)),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for NumericPrefixWithSuffix<'_> {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let NumericPrefixWithSuffix(num_a, remainder_a) = self;
|
||||||
|
let NumericPrefixWithSuffix(num_b, remainder_b) = other;
|
||||||
|
num_a
|
||||||
|
.cmp(&num_b)
|
||||||
|
.then_with(|| UniCase::new(remainder_a).cmp(&UniCase::new(remainder_b)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PartialOrd for NumericPrefixWithSuffix<'a> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -526,4 +564,23 @@ mod tests {
|
|||||||
assert_eq!(truncate_and_trailoff("èèèèèè", 6), "èèèèèè");
|
assert_eq!(truncate_and_trailoff("èèèèèè", 6), "èèèèèè");
|
||||||
assert_eq!(truncate_and_trailoff("èèèèèè", 5), "èèèèè…");
|
assert_eq!(truncate_and_trailoff("èèèèèè", 5), "èèèèè…");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_numeric_prefix_with_suffix() {
|
||||||
|
let mut sorted = vec!["1-abc", "10", "11def", "2", "21-abc"];
|
||||||
|
sorted.sort_by_key(|s| {
|
||||||
|
NumericPrefixWithSuffix::from_str(s).unwrap_or_else(|| {
|
||||||
|
panic!("Cannot convert string `{s}` into NumericPrefixWithSuffix")
|
||||||
|
})
|
||||||
|
});
|
||||||
|
assert_eq!(sorted, ["1-abc", "2", "10", "11def", "21-abc"]);
|
||||||
|
|
||||||
|
for numeric_prefix_less in ["numeric_prefix_less", "aaa", "~™£"] {
|
||||||
|
assert_eq!(
|
||||||
|
NumericPrefixWithSuffix::from_str(numeric_prefix_less),
|
||||||
|
None,
|
||||||
|
"String without numeric prefix `{numeric_prefix_less}` should not be converted into NumericPrefixWithSuffix"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user