Repository: alexpasmantier/television (language: rust)

Issue:
Make quotes consistent for output value
**Description**

When you select a path (and only an _existing_ path) the output value is single-quoted.

**Example**

```shell
# Create an example directory
mkdir /tmp/example
cd /tmp/example

# Create a few directories
mkdir a
mkdir 'b c'

# Select through 'tv'
echo 'a\nb c\nd e' | tv
```

* If we select the option `a` the output value is `a`
* If we select the option `b c` the output value is `'b c'`
* If we select the option `d e` the output value is `d e`

As you can see, the output value is single-quoted only if the selected option contains a space **and if the path actually exists**. Which is a really weird behavior, especially when we're doing something else than selecting directories. This is inconsistent and makes it hard to provide the value to other commands.

**Expected behavior**

Values should either:

* Neither be quoted
* Always be quoted
* Quoted only if there is a space (or special character) in the string

But *not* quoted in some filesystem-related cases and not others like it is currently.

**Environment**
 - OS: Ubuntu 24.10
 - Project version: 0.9.2


Discussion / hints:
@alexpasmantier, what would the expected behavior in this case?

IMO, the most sensible option would be to always quote, since it would make the output more predictable. But I don't know if this could mess something up.
Actually I think the most sensible options on would be to never quote. You can easily quote an output in a shell but it's harder to unquote it. When you want the output to be quoted you can just do `echo "$(tv .....)"`.
That makes more sense, @ClementNerma.

Fix patch:
diff --git a/television/app.rs b/television/app.rs
index 3c7c2ee..8acbf22 100644
--- a/television/app.rs
+++ b/television/app.rs
@@ -271,6 +271,7 @@ impl App {
                     {
                         return Ok(ActionOutcome::Entries(entries));
                     }
+
                     return Ok(ActionOutcome::Input(
                         self.television.lock().await.current_pattern.clone(),
                     ));
diff --git a/television/channels/alias.rs b/television/channels/alias.rs
index a2a4b98..19a8f5e 100644
--- a/television/channels/alias.rs
+++ b/television/channels/alias.rs
@@ -170,7 +170,7 @@ async fn load_aliases(injector: Injector<Alias>) {
             None
         })
         .for_each(|alias| {
-            let () = injector.push(alias.clone(), |e, cols| {
+            let () = injector.push(alias, |e, cols| {
                 cols[0] = (e.name.clone() + &e.value).into();
             });
         });
diff --git a/television/channels/cable.rs b/television/channels/cable.rs
index aa66230..22189f7 100644
--- a/television/channels/cable.rs
+++ b/television/channels/cable.rs
@@ -159,7 +159,7 @@ impl OnAir for Channel {
             .map(|item| {
                 let path = item.matched_string;
                 Entry::new(
-                    path.clone(),
+                    path,
                     match &self.preview_kind {
                         PreviewKind::Command(ref preview_command) => {
                             PreviewType::Command(preview_command.clone())
@@ -179,7 +179,7 @@ impl OnAir for Channel {
         self.matcher.get_result(index).map(|item| {
             let path = item.matched_string;
             Entry::new(
-                path.clone(),
+                path,
                 match &self.preview_kind {
                     PreviewKind::Command(ref preview_command) => {
                         PreviewType::Command(preview_command.clone())
diff --git a/television/channels/entry.rs b/television/channels/entry.rs
index 3cee902..24a0175 100644
--- a/television/channels/entry.rs
+++ b/television/channels/entry.rs
@@ -1,7 +1,6 @@
 use std::{
     fmt::Display,
     hash::{Hash, Hasher},
-    path::PathBuf,
 };
 
 use devicons::FileIcon;
@@ -143,12 +142,6 @@ impl Entry {
 
     pub fn stdout_repr(&self) -> String {
         let mut repr = self.name.clone();
-        if PathBuf::from(&repr).exists()
-            && repr.contains(|c| char::is_ascii_whitespace(&c))
-        {
-            repr.insert(0, '\'');
-            repr.push('\'');
-        }
         if let Some(line_number) = self.line_number {
             repr.push_str(&format!(":{line_number}"));
         }
@@ -226,4 +219,32 @@ mod tests {
         let ranges = vec![(1, 2), (3, 4), (5, 6)];
         assert_eq!(merge_ranges(&ranges), vec![(1, 2), (3, 4), (5, 6)]);
     }
+
+    #[test]
+    fn test_leaves_name_intact() {
+        let entry = Entry {
+            name: "test name with spaces".to_string(),
+            value: None,
+            name_match_ranges: None,
+            value_match_ranges: None,
+            icon: None,
+            line_number: None,
+            preview_type: PreviewType::Basic,
+        };
+        assert_eq!(entry.stdout_repr(), "test name with spaces");
+    }
+    #[test]
+    fn test_uses_line_number_information() {
+        let a: usize = 10;
+        let entry = Entry {
+            name: "test_file_name.rs".to_string(),
+            value: None,
+            name_match_ranges: None,
+            value_match_ranges: None,
+            icon: None,
+            line_number: Some(a),
+            preview_type: PreviewType::Basic,
+        };
+        assert_eq!(entry.stdout_repr(), "test_file_name.rs:10");
+    }
 }
diff --git a/television/channels/git_repos.rs b/television/channels/git_repos.rs
index d3b574d..fec62f0 100644
--- a/television/channels/git_repos.rs
+++ b/television/channels/git_repos.rs
@@ -64,12 +64,9 @@ impl OnAir for Channel {
             .into_iter()
             .map(|item| {
                 let path = item.matched_string;
-                Entry::new(
-                    path.clone(),
-                    PreviewType::Command(PREVIEW_COMMAND.clone()),
-                )
-                .with_name_match_ranges(&item.match_indices)
-                .with_icon(self.icon)
+                Entry::new(path, PreviewType::Command(PREVIEW_COMMAND.clone()))
+                    .with_name_match_ranges(&item.match_indices)
+                    .with_icon(self.icon)
             })
             .collect()
     }
@@ -77,11 +74,8 @@ impl OnAir for Channel {
     fn get_result(&self, index: u32) -> Option<Entry> {
         self.matcher.get_result(index).map(|item| {
             let path = item.matched_string;
-            Entry::new(
-                path.clone(),
-                PreviewType::Command(PREVIEW_COMMAND.clone()),
-            )
-            .with_icon(self.icon)
+            Entry::new(path, PreviewType::Command(PREVIEW_COMMAND.clone()))
+                .with_icon(self.icon)
         })
     }
 
diff --git a/television/channels/remote_control.rs b/television/channels/remote_control.rs
index 323ecaf..a6b6767 100644
--- a/television/channels/remote_control.rs
+++ b/television/channels/remote_control.rs
@@ -78,9 +78,9 @@ impl RemoteControl {
             .as_ref()
             .and_then(|channels| channels.get(channel_name).cloned())
         {
-            Some(prototype) => Ok(TelevisionChannel::Cable(
-                cable::Channel::from(prototype.clone()),
-            )),
+            Some(prototype) => {
+                Ok(TelevisionChannel::Cable(cable::Channel::from(prototype)))
+            }
             None => match UnitChannel::try_from(channel_name) {
                 Ok(channel) => Ok(channel.into()),
                 Err(_) => Err(color_eyre::eyre::eyre!(
diff --git a/television/channels/stdin.rs b/television/channels/stdin.rs
index 6acb760..581c84c 100644
--- a/television/channels/stdin.rs
+++ b/television/channels/stdin.rs
@@ -91,7 +91,7 @@ impl OnAir for Channel {
 
     fn get_result(&self, index: u32) -> Option<Entry> {
         self.matcher.get_result(index).map(|item| {
-            Entry::new(item.matched_string.clone(), self.preview_type.clone())
+            Entry::new(item.matched_string, self.preview_type.clone())
         })
     }
 
diff --git a/television/television.rs b/television/television.rs
index 9d5a914..625a170 100644
--- a/television/television.rs
+++ b/television/television.rs
@@ -423,9 +423,7 @@ impl Television {
                                 .iter()
                                 .map(|e| e.name.clone())
                                 .collect::<Vec<_>>()
-                                .join(" ")
-                                .to_string()
-                                .to_string(),
+                                .join(" "),
                         )
                         .unwrap();
                     }


Test patch: