Skip to content

Commit f3ecd7e

Browse files
authored
feat(command): support passing additional arguments to the command (#447)
1 parent 4151857 commit f3ecd7e

File tree

18 files changed

+533
-286
lines changed

18 files changed

+533
-286
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Execute the last executed command(By running `fzf-make --repeat`.)
1919
- Command history
2020
- Support [**make**](https://www.gnu.org/software/make/), [**pnpm**](https://github.com/pnpm/pnpm), [**yarn**](https://github.com/yarnpkg/berry), [**just**](https://github.com/casey/just). **Scheduled to be developed: npm.**
21+
- Support passing additional arguments to the command using popup window. The UI looks like: https://github.com/kyu08/fzf-make/pull/447
2122
- [make] Support `include` directive
2223
- [pnpm] Support workspace(collect scripts all of `package.json` in the directory where fzf-make is launched.)
2324
- [yarn] Support workspace(collect all scripts which is defined in `workspaces` field in root `package.json`.)

docs/MANUAL_TEST_CASES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## Test cases
22
- [ ] `fzf-make`
33
- [ ] Execution
4-
- [ ] A command name executing is shown
4+
- [ ] A command name executing is shown
55
- [ ] Selected command is executed
66
- [ ] Narrowing down
77
- [ ] Placeholder is shown when no characters are typed.

src/file/toml.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl Histories {
4444
Self { histories }
4545
}
4646

47+
// TODO: impl as From trait
4748
fn from(histories: histories::Histories) -> Self {
4849
let mut result: Vec<History> = vec![];
4950
for h in histories.histories {
@@ -68,6 +69,7 @@ pub struct History {
6869
}
6970

7071
impl History {
72+
// TODO: impl as From trait
7173
fn from(history: histories::History) -> Self {
7274
let mut commands: Vec<HistoryCommand> = vec![];
7375
for h in history.commands {
@@ -110,6 +112,7 @@ impl HistoryCommand {
110112
Self { runner_type, args }
111113
}
112114

115+
// TODO: impl as From trait
113116
fn from(command: histories::HistoryCommand) -> Self {
114117
Self {
115118
runner_type: command.runner_type,

src/model/command.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
use super::runner_type;
1+
use super::{histories, runner_type};
22
use std::{fmt, path::PathBuf};
33

44
#[derive(PartialEq, Clone, Debug)]
5-
pub struct Command {
5+
pub struct CommandWithPreview {
66
pub runner_type: runner_type::RunnerType,
77
pub args: String,
88
pub file_path: PathBuf,
99
pub line_number: u32,
1010
}
1111

12-
impl Command {
12+
impl CommandWithPreview {
1313
pub fn new(runner_type: runner_type::RunnerType, args: String, file_path: PathBuf, line_number: u32) -> Self {
1414
Self {
1515
runner_type,
@@ -20,7 +20,37 @@ impl Command {
2020
}
2121
}
2222

23-
impl fmt::Display for Command {
23+
impl fmt::Display for CommandWithPreview {
24+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25+
write!(f, "{} {}", self.runner_type, self.args)
26+
}
27+
}
28+
29+
#[derive(PartialEq, Clone, Debug)]
30+
pub struct CommandForExec {
31+
pub runner_type: runner_type::RunnerType,
32+
pub args: String,
33+
}
34+
35+
impl From<CommandWithPreview> for CommandForExec {
36+
fn from(c: CommandWithPreview) -> CommandForExec {
37+
CommandForExec {
38+
runner_type: c.runner_type.clone(),
39+
args: c.args.clone(),
40+
}
41+
}
42+
}
43+
44+
impl From<histories::HistoryCommand> for CommandForExec {
45+
fn from(c: histories::HistoryCommand) -> CommandForExec {
46+
CommandForExec {
47+
runner_type: c.runner_type.clone(),
48+
args: c.args.clone(),
49+
}
50+
}
51+
}
52+
53+
impl fmt::Display for CommandForExec {
2454
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2555
write!(f, "{} {}", self.runner_type, self.args)
2656
}

src/model/histories.rs

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub struct Histories {
1010
}
1111

1212
impl Histories {
13-
pub fn append(&self, current_dir: PathBuf, command: command::Command) -> Self {
13+
pub fn append(&self, current_dir: PathBuf, command: command::CommandForExec) -> Self {
1414
// Update the command history for the current directory.
1515
let new_history = {
1616
match self.histories.iter().find(|h| h.path == current_dir) {
@@ -48,7 +48,7 @@ pub struct History {
4848
}
4949

5050
impl History {
51-
fn append(&self, executed_command: command::Command) -> Self {
51+
fn append(&self, executed_command: command::CommandForExec) -> Self {
5252
let mut updated_commands = self.commands.clone();
5353
// removes the executed_command from the history
5454
updated_commands.retain(|t| *t != HistoryCommand::from(executed_command.clone()));
@@ -76,8 +76,8 @@ pub struct HistoryCommand {
7676
pub args: String,
7777
}
7878

79-
impl HistoryCommand {
80-
pub fn from(command: command::Command) -> Self {
79+
impl From<command::CommandForExec> for HistoryCommand {
80+
fn from(command: command::CommandForExec) -> Self {
8181
Self {
8282
runner_type: command.runner_type,
8383
args: command.args,
@@ -96,7 +96,7 @@ mod test {
9696
struct Case {
9797
title: &'static str,
9898
before: Histories,
99-
command_to_append: command::Command,
99+
command_to_append: command::CommandForExec,
100100
after: Histories,
101101
}
102102

@@ -124,11 +124,9 @@ mod test {
124124
},
125125
],
126126
},
127-
command_to_append: command::Command {
127+
command_to_append: command::CommandForExec {
128128
runner_type: runner_type::RunnerType::Make,
129129
args: "append".to_string(),
130-
file_path: PathBuf::from("Makefile"),
131-
line_number: 1,
132130
},
133131
after: Histories {
134132
histories: vec![
@@ -166,11 +164,9 @@ mod test {
166164
}],
167165
}],
168166
},
169-
command_to_append: command::Command {
167+
command_to_append: command::CommandForExec {
170168
runner_type: runner_type::RunnerType::Make,
171169
args: "append".to_string(),
172-
file_path: PathBuf::from("Makefile"),
173-
line_number: 1,
174170
},
175171
after: Histories {
176172
histories: vec![
@@ -208,7 +204,7 @@ mod test {
208204
struct Case {
209205
title: &'static str,
210206
before: History,
211-
command_to_append: command::Command,
207+
command_to_append: command::CommandForExec,
212208
after: History,
213209
}
214210
let path = PathBuf::from("/Users/user/code/fzf-make".to_string());
@@ -228,12 +224,10 @@ mod test {
228224
},
229225
],
230226
},
231-
command_to_append: command::Command::new(
232-
runner_type::RunnerType::Make,
233-
"history2".to_string(),
234-
PathBuf::from("Makefile"),
235-
1,
236-
),
227+
command_to_append: command::CommandForExec {
228+
runner_type: runner_type::RunnerType::Make,
229+
args: "history2".to_string(),
230+
},
237231
after: History {
238232
path: path.clone(),
239233
commands: vec![
@@ -258,12 +252,10 @@ mod test {
258252
path: path.clone(),
259253
commands: vec![],
260254
},
261-
command_to_append: command::Command::new(
262-
runner_type::RunnerType::Make,
263-
"history0".to_string(),
264-
PathBuf::from("Makefile"),
265-
4,
266-
),
255+
command_to_append: command::CommandForExec {
256+
runner_type: runner_type::RunnerType::Make,
257+
args: "history0".to_string(),
258+
},
267259
after: History {
268260
path: path.clone(),
269261
commands: vec![HistoryCommand {
@@ -291,12 +283,10 @@ mod test {
291283
},
292284
],
293285
},
294-
command_to_append: command::Command::new(
295-
runner_type::RunnerType::Make,
296-
"history2".to_string(),
297-
PathBuf::from("Makefile"),
298-
1,
299-
),
286+
command_to_append: command::CommandForExec {
287+
runner_type: runner_type::RunnerType::Make,
288+
args: "history2".to_string(),
289+
},
300290
after: History {
301291
path: path.clone(),
302292
commands: vec![
@@ -362,12 +352,10 @@ mod test {
362352
},
363353
],
364354
},
365-
command_to_append: command::Command::new(
366-
runner_type::RunnerType::Make,
367-
"history10".to_string(),
368-
PathBuf::from("Makefile"),
369-
1,
370-
),
355+
command_to_append: command::CommandForExec {
356+
runner_type: runner_type::RunnerType::Make,
357+
args: "history10".to_string(),
358+
},
371359
after: History {
372360
path: path.clone(),
373361
commands: vec![

src/model/js_package_manager/js_package_manager_main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ pub enum JsPackageManager {
1717
}
1818

1919
impl JsPackageManager {
20-
pub fn command_to_run(&self, command: &command::Command) -> Result<String> {
20+
pub fn command_to_run(&self, command: &command::CommandForExec) -> Result<String> {
2121
match self {
2222
JsPackageManager::JsPnpm(pnpm) => pnpm.command_to_run(command),
2323
JsPackageManager::JsYarn(yarn) => yarn.command_to_run(command),
2424
}
2525
}
2626

27-
pub fn to_commands(&self) -> Vec<command::Command> {
27+
pub fn to_commands(&self) -> Vec<command::CommandWithPreview> {
2828
match self {
2929
JsPackageManager::JsPnpm(pnpm) => pnpm.to_commands(),
3030
JsPackageManager::JsYarn(yarn) => yarn.to_commands(),
3131
}
3232
}
3333

34-
pub fn execute(&self, command: &command::Command) -> Result<()> {
34+
pub fn execute(&self, command: &command::CommandForExec) -> Result<()> {
3535
match self {
3636
JsPackageManager::JsPnpm(pnpm) => pnpm.execute(command),
3737
JsPackageManager::JsYarn(yarn) => yarn.execute(command),

src/model/js_package_manager/pnpm.rs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,15 @@ const PNPM_LOCKFILE_NAME: &str = "pnpm-lock.yaml";
1111
#[derive(Clone, Debug, PartialEq)]
1212
pub struct Pnpm {
1313
pub path: PathBuf,
14-
commands: Vec<command::Command>,
14+
commands: Vec<command::CommandWithPreview>,
1515
}
1616

1717
impl Pnpm {
18-
pub fn command_to_run(&self, command: &command::Command) -> Result<String> {
19-
// To ensure that the command exists, it is necessary to check the command name.
20-
// If implementation is wrong, developers can notice it here.
21-
let command = match self.get_command(command.clone()) {
22-
Some(c) => c,
23-
None => return Err(anyhow!("command not found")),
24-
};
25-
18+
pub fn command_to_run(&self, command: &command::CommandForExec) -> Result<String> {
2619
Ok(format!("pnpm {}", command.args))
2720
}
2821

29-
pub fn execute(&self, command: &command::Command) -> Result<()> {
30-
let command = match self.get_command(command.clone()) {
31-
Some(c) => c,
32-
None => return Err(anyhow!("command not found")),
33-
};
34-
22+
pub fn execute(&self, command: &command::CommandForExec) -> Result<()> {
3523
let child = process::Command::new("pnpm")
3624
.stdin(process::Stdio::inherit())
3725
.args(command.args.split_whitespace().collect::<Vec<&str>>())
@@ -74,7 +62,7 @@ impl Pnpm {
7462
// 1. Collect scripts defined in package.json in the current directory(which fzf-make is launched)
7563
// 2. Collect the paths of all `package.json` in the workspace.
7664
// 3. Collect all scripts defined in given `package.json` paths.
77-
fn collect_workspace_scripts(current_dir: PathBuf) -> Option<Vec<command::Command>> {
65+
fn collect_workspace_scripts(current_dir: PathBuf) -> Option<Vec<command::CommandWithPreview>> {
7866
// Collect scripts defined in package.json in the current directory(which fzf-make is launched)
7967
let mut result = Self::collect_scripts_in_package_json(current_dir.clone())?;
8068

@@ -92,7 +80,7 @@ impl Pnpm {
9280
if Self::use_filtering(value) {
9381
continue;
9482
}
95-
result.push(command::Command::new(
83+
result.push(command::CommandWithPreview::new(
9684
runner_type::RunnerType::JsPackageManager(runner_type::JsPackageManager::Pnpm),
9785
// pnpm executes workspace script following format: `pnpm --filter {package_name} {script_name}`
9886
// e.g. `pnpm --filter app4 build`
@@ -108,7 +96,7 @@ impl Pnpm {
10896
Some(result)
10997
}
11098

111-
fn collect_scripts_in_package_json(current_dir: PathBuf) -> Option<Vec<command::Command>> {
99+
fn collect_scripts_in_package_json(current_dir: PathBuf) -> Option<Vec<command::CommandWithPreview>> {
112100
let parsed_scripts_part_of_package_json =
113101
match path_to_content::path_to_content(&current_dir.join(js::METADATA_FILE_NAME)) {
114102
Ok(c) => match js::JsPackageManager::parse_package_json(&c) {
@@ -123,7 +111,7 @@ impl Pnpm {
123111
.iter()
124112
.filter(|(_, value, _)| !Self::use_filtering(value.to_string()))
125113
.map(|(key, _value, line_number)| {
126-
command::Command::new(
114+
command::CommandWithPreview::new(
127115
runner_type::RunnerType::JsPackageManager(runner_type::JsPackageManager::Pnpm),
128116
key.to_string(),
129117
current_dir.clone().join(js::METADATA_FILE_NAME),
@@ -158,14 +146,10 @@ impl Pnpm {
158146
.collect())
159147
}
160148

161-
pub fn to_commands(&self) -> Vec<command::Command> {
149+
pub fn to_commands(&self) -> Vec<command::CommandWithPreview> {
162150
self.commands.clone()
163151
}
164152

165-
fn get_command(&self, command: command::Command) -> Option<&command::Command> {
166-
self.commands.iter().find(|c| **c == command)
167-
}
168-
169153
// ref: https://pnpm.io/filtering
170154
fn use_filtering(value: String) -> bool {
171155
let args = value.split_whitespace().collect::<Vec<&str>>();

0 commit comments

Comments
 (0)