Skip to content

Commit

Permalink
Copy text from a specified range!🥳 (#11)
Browse files Browse the repository at this point in the history
* rebased

* fixed stdin

* copy things in a range

* fixed the import error

* formatted

* fixed the test

* updated the readme

* fixed the help section
  • Loading branch information
bahdotsh authored Apr 13, 2023
1 parent 7805677 commit 03d430d
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 30 deletions.
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
# zp

The "zp" command is a custom command that takes one argument, which is the name of the source file. The purpose of this command is to copy the contents of the source file to the clipboard, allowing users to easily paste the contents into another file or program.
The "zp" command is a custom command that takes one argument, which is the name of the source file. The purpose of this command is to copy the contents of the source file or of the std output buffer to the clipboard, allowing users to easily paste the contents into another file or program.

To use the "zp" command, simply open your terminal or command prompt and type "zp" followed by the name of the source file. For example:

```
zp myFile.txt
zp my_file.txt
```

To get the first `n` (n is an integer) words of the file :
```
zp my_file.txt n
```
To get the lines between a range, i.e., to get lines from `n` till `m` (n and m are integers) of the file:
```
zp my_file.txt n m
```
Also you can use zp to copy from the std output buffer :
```
cat sample_file.txt | zp
```
This copies the entire output of the file.

You can use get a range of lines and the first n words also from the std output buffer :
```
cat sample_file.txt | zp 2
cat sample_file.txt | zp 2 5
```

This gets the first 2 words and lines from 2 to 5 of the sample_file.txt respectively

This will copy the contents of "myFile.txt" to the clipboard.

The "zp" command is particularly useful for quickly copying text or data from one file to another without having to manually select and copy the text. This can save time and effort, especially when working with large or complex files.
Expand Down
110 changes: 86 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,77 @@
use arboard::Clipboard;
use atty::Stream;
use std::fs::File;
use std::process;
use std::io::{self, Read};
use atty::Stream;
use std::process;

#[derive(Debug)]
pub struct Query {
pub source: String,
pub start: usize,
pub end: usize,
}

impl Query {
pub fn build(mut args: impl Iterator<Item = String>) -> Result<Query, &'static str> {
args.next();
if atty::is(Stream::Stdout) && atty::is(Stream::Stderr) && atty::isnt(Stream::Stdin) {
let mut buffer = io::stdin();
let mut contents = String::new();
let start = match args.next() {
Some(arg) => arg,
None => "0".to_string(),
}
.parse::<usize>()
.unwrap_or_else(|err| {
eprintln!("Parsing error! {} ", err);
process::exit(1);
});

let source = match args.next() {
Some(arg) => arg,
None => {
if atty::is(Stream::Stdout) && atty::is(Stream::Stderr) && atty::isnt(Stream::Stdin) {
let mut buffer = io::stdin();
let mut contents = String::new();
while let Ok(n) = buffer.read_to_string(&mut contents) {
if n == 0 {break;}
}
cpy(&contents);
process::exit(1);
}else{
return Err("No source to copy from");
let end = match args.next() {
Some(arg) => arg,
None => "0".to_string(),
}
.parse::<usize>()
.unwrap_or_else(|err| {
eprintln!("Parsing error! {}", err);
process::exit(1);
});

while let Ok(n) = buffer.read_to_string(&mut contents) {
if n == 0 {
break;
}
},
}
cpy(&contents, start as usize, end as usize);
process::exit(1);
}

let source = match args.next() {
Some(args) => args,
None => return Err("No source to copy from"),
};

Ok(Query { source })
let start = match args.next() {
Some(arg) => arg,
None => "0".to_string(),
}
.parse::<usize>()
.unwrap_or_else(|err| {
eprintln!("Parsing error! {} ", err);
process::exit(1);
});

let end = match args.next() {
Some(arg) => arg,
None => "0".to_string(),
}
.parse::<usize>()
.unwrap_or_else(|err| {
eprintln!("Parsing error! {}", err);
process::exit(1);
});

Ok(Query { source, start, end })
}
}

Expand All @@ -53,18 +94,39 @@ pub fn run(query: Query) -> Result<(), std::io::Error> {
Ok(data) => data,
Err(error) => return Err(error),
};
cpy(&contents);
cpy(&contents, query.start, query.end);

Ok(())
}

pub fn cpy<'a>(contents: &'a str) {
pub fn cpy<'a>(contents: &'a str, start: usize, end: usize) {
let mut clipboard = Clipboard::new().unwrap();

clipboard.set_text(contents).unwrap_or_else(|err| {
eprintln!("Couldn't copy to clipboard: {}", err);
process::exit(1);
});
if end == 0 as usize {
if start == 0 as usize {
clipboard.set_text(contents).unwrap_or_else(|err| {
eprintln!("Couldn't copy to clipboard: {}", err);
process::exit(1);
});
} else {
let words: Vec<&str> = contents.split_whitespace().take(start).collect();
clipboard.set_text(words.join(" ")).unwrap_or_else(|err| {
eprintln!("Couldn't copy to clipboard: {}", err);
process::exit(1);
});
}
} else {
let lines: Vec<&str> = contents
.lines()
.enumerate()
.filter(|&(i, _)| i >= start && i <= end)
.map(|(_, line)| line)
.collect();
clipboard.set_text(lines.join("\n")).unwrap_or_else(|err| {
eprintln!("Couldn't copy to clipboard: {}", err);
process::exit(1);
});
}
}

#[cfg(test)]
Expand All @@ -74,7 +136,7 @@ mod tests {
#[test]
fn one_result() {
let mut clipboard = Clipboard::new().unwrap();
let _ = cpy("Hello, world!");
let _ = cpy("Hello, world!", 0 as usize, 0 as usize);
assert_eq!(clipboard.get_text().unwrap(), "Hello, world!");
}
}
10 changes: 6 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use zp::Query;
use clap::Parser;
use std::env;
use std::process;
use clap::Parser;
use zp::Query;

const VERSION: &str = env!("CARGO_PKG_VERSION");

/// Copy file contents
#[derive(Parser)]
#[command(
author = "Gokul <@bahdotsh>",
Expand All @@ -14,7 +13,10 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
)]
struct Zp {
file_name: Vec<String>,
///
file_name: Option<String>,
start: Option<usize>,
end: Option<usize>,
}

fn main() {
Expand Down

0 comments on commit 03d430d

Please sign in to comment.