当前位置:网站首页>Encapsulates a console file selector based on inquirer
Encapsulates a console file selector based on inquirer
2022-07-30 19:13:00 【JYeontu】
说在前面
When we initialize the project with scaffolding,There is often some command interaction,用过vue或者reactThose who use scaffolding to create new projects should have interacted with commands,vueIt will give you the choice when you create itvue2还是vue3,You can also choose what configuration you want,也有输入y或者n选择是否用history路由等,These simple interactions are usefulinquireThis package does it all,But recently when I was making a small tool,Want to make file and folder selections,这时我发现inquireThere is no such interactive function in it,So try it yourselfinquireThis library implements two types of interactions, file selection and folder selection.
插件效果
通过该插件,We can use the arrow keys to select files and folders in the console,具体效果如下:
插件实现
Inquirer.js
Inquirer.js试图为NodeJsMake an embeddable beautiful command line interface.如下图:
inquirer原有参数
- type
表示提问的类型,包括:input、confirm、 list、rawlist、expand、checkbox、password、editor.
- name
存储当前输入的值.
- message
问题的描述.
- default
默认值.
- choices
列表选项,在某些type下可用,并且包含一个分隔符(separator);
- validate
对用户的回答进行校验.
- filter
对用户的回答进行过滤处理,返回处理后的值.
- when
根据前面问题的回答,判断当前问题是否需要被回答.
- pageSize
修改某些type类型下的渲染行数.
- prefix
修改message默认前缀.
- suffix
修改message默认后缀.
二次封装
基于inquirerOriginal functions and parameters,Add some extended functions and parameters
新增参数
- notNull
是否不能为空,默认为false,设置为trueAfter this parameter can not enter empty,And there will be a prompt that cannot be empty,You must enter characters before you can press Enter to confirm and proceed to the next step,如下图:
{
type:"input",
message:"请输入你的姓名:",
name:"name",
notNull:true
}
- type
Two new types have been added to the original types:file、folder,File selector and directory selector, respectively,效果如下图:
{
type:"file",
message:"请选择文件:",
name:"fileName",
default:"",
},
{
type:"folder",
message:"请选择文件夹:",
name:"folderName",
default:"",
pathType:'absolute'
},
- pathType
This item is a new configuration,Sets the format for the output of the directory and file selector selected paths,默认为相对路径,可以设置为absolute,The absolute path is output,效果如下图:
{
type:"file",
message:"请选择文件:",
name:"fileName",
default:"",
},
{
type:"folder",
message:"请选择文件夹:",
name:"folderName",
default:"",
pathType:'absolute'
},
代码实现
获取指定路径下的文件列表
使用fs
中的readdirSync
method to get a list of files in the specified directory,具体代码如下:
getFileList = (dirPath)=>{
const list = fs.readdirSync(dirPath);
return ['../(返回上一级)',...list];
}
Get a list of directories under the specified path
使用fs
中的readdirSync
method to get a list of files in the specified directory,通过isDirectory
The method can determine whether the file is a directory file,具体代码如下:
getFolderList = (dirPath)=>{
const list = fs.readdirSync(dirPath);
let resList = [];
list.map(item=>{
const fullPath = path.join(dirPath,item);
if(fs.statSync(fullPath).isDirectory()){
resList.push(item + '(进入文件夹)');
resList.push(item + '(选择文件夹)');
}
});
return ['../(返回上一级)',...resList];
}
Interactive type response control
新增的file
和folder
Types use their own repackaging methods,Others are still usedInquirer中的响应方法,具体代码如下:
run(option){
if(option.type === 'file'){
return this.chooseFile(option);
}else if(option.type === 'folder'){
return this.chooseFolder(option);
}else{
if(option.notNull){
const flag = option.message.slice(-1);
if([":",":"].includes(flag)){
option.message = option.message.slice(0,-1) + '(不能为空)' + flag;
}
}
return this.defaultType(option);
}
}
选择文件
- 选择的为
返回上一级
,The current directory will be rolled back one level:
this.clear(2);
return this.chooseFile(option,path.join(dirPath,'/../'));
- Select the directory to enter the selected directory:
return path.join(dirPath, answer[option.name]);
- If a file is selected, it returns the selected file path and ends the operation:
this.clear(2);
return this.chooseFile(option,fullPath);
- 完整代码如下
chooseFile(option,dirPath = './'){
option.type = 'list';
option.suffix = "(Currently browsing directory:" + path.join(__dirname,dirPath) + ')';
option.pageSize = fs.readdirSync('./').length + 1;
option.choices = [...this.getFileList(dirPath)];
const answer = await inquirer.prompt([
option
]);
if(answer[option.name] == '../(返回上一级)'){
this.clear(2);
return this.chooseFile(option,path.join(dirPath,'/../'));
}else{
const fullPath = path.join(dirPath, answer[option.name]);
if(!fs.statSync(fullPath).isFile()){
this.clear(2);
return this.chooseFile(option,fullPath);
}else{
return path.join(dirPath, answer[option.name]);
}
}
}
选择目录
- 选择的为
返回上一级
,The current directory will be rolled back one level:
this.clear(2);
return this.chooseFile(option,path.join(dirPath,'/../'));
- The choice is to enter the folder,enter this directory,Here, the suffix added for differentiation needs to be removed and returned:
return path.join(dirPath, answer[option.name].slice(0,-7));
- If you choose to select a folder, it will return to the selected folder path and end the operation:
this.clear(2);
return this.chooseFile(option,fullPath);
- 完整代码如下
chooseFile(option,dirPath = './'){
option.type = 'list';
option.suffix = "(Currently browsing directory:" + path.join(__dirname,dirPath) + ')';
option.pageSize = fs.readdirSync('./').length + 1;
option.choices = [...this.getFileList(dirPath)];
const answer = await inquirer.prompt([
option
]);
if(answer[option.name] == '../(返回上一级)'){
this.clear(2);
return this.chooseFile(option,path.join(dirPath,'/../'));
}else{
const fullPath = path.join(dirPath, answer[option.name]);
if(!fs.statSync(fullPath).isFile()){
this.clear(2);
return this.chooseFile(option,fullPath);
}else{
return path.join(dirPath, answer[option.name]);
}
}
}
基本类型调用Inquirer处理
这里增加了notNull
(是否不能为空)的参数,代码如下:
defaultType(option){
const answer = await inquirer.prompt([
option
]);
if(option.notNull && answer[option.name] === ''){
this.clear(2);
return this.defaultType(option);
}
return answer[option.name];
}
插件使用
1、安装依赖
npm install @jyeontu/j-inquirer
2、在代码中引用
const JInquirer = require('@jyeontu/j-inquirer');
3、示例代码
const JInquirer = require('@jyeontu/j-inquirer');
let options = [
{
type:"input",
message:"请输入你的姓名:",
name:"name",
notNull:true
},{
type:"input",
message:"请输入你的年龄:",
name:"age",
default:18,
validate:(val)=>{
if(val < 0 || val > 150){
return "请输入0~150之间的数字";
}
return true;
}
},{
type:"file",
message:"请选择文件:",
name:"fileName",
default:"",
},{
type:"folder",
message:"请选择文件夹:",
name:"folderName",
default:"",
pathType:'absolute'
},{
type:"list",
message:"请选择你喜欢的水果:",
name:"fruit",
default:"Apple",
choices:[
"Apple",
"pear",
"Banana"
],
},{
type:"expand",
message:"请选择一个颜色:",
name:"color",
default:"red",
choices:[
{
key : 'R',
value : "red"
},
{
key : 'B',
value : "blue"
},
{
key : 'G',
value : "green"
}
]
},{
type:"checkbox",
message:"Choose one or more colors:",
name:"color2",
choices:[
"red",
"blue",
"green",
"pink",
"orange"
]
},{
type:"password",
message:"请输入你的密码:",
name:"pwd"
},{
type:"editor",
message:"Write down what you want to write:",
name:"editor"
}
];
let j = new JInquirer(options);
let res = j.prompt().then(res=>{
console.log(res);
});
源码地址
https://gitee.com/zheng_yongtao/node-scripting-tool/tree/master/src/JInquirer
觉得有帮助的同学可以帮忙给我点个star,感激不尽~~~
有什么想法或者改良可以给我提个pr,十分欢迎~~~
有什么问题都可以在评论告诉我~~~
往期精彩
nodeEncapsulates a console progress bar plugin
vueImplement a mouse sliding preview video cover component
说在后面
这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油.毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球 ,也喜欢写些东西,既为自己记录,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解,写错的地方望指出,定会认真改进,在此谢谢大家的支持,我们下文再见.
边栏推荐
- NC | Tao Liang Group of West Lake University - TMPRSS2 "assists" virus infection and mediates the host invasion of Clostridium sothrix hemorrhagic toxin...
- Alibaba Cloud Martial Arts Headline Event Sharing
- AI Basics: Graphical Transformer
- Hello, my new name is "Bronze Lock/Tongsuo"
- 生物医学论文有何价值 论文中译英怎样翻译效果好
- The advanced version of the cattle brushing series (search for rotating sorted arrays, inversion of the specified range in the linked list)
- JsonUtil基于字符串操作josn
- 【剑指 Offer】剑指 Offer 22. 链表中倒数第k个节点
- [Prometheus] An optimization record of the Prometheus federation [continued]
- 【网站放大镜效果】两种方式实现
猜你喜欢
【Prometheus】Prometheus联邦的一次优化记录[续]
Swiper rotates pictures and plays background music
MindSpore:ImageFolderDataset数据读取问题
【Swords Offer】Swords Offer 17. Print n digits from 1 to the largest
MindSpore:【模型训练】【mindinsight】timeline的时间和实际用时相差很远
kotlin by lazy
部分分类网络性能对比
浅聊对比学习(Contrastive Learning)第一弹
MindSpore:【Resolve node failed】解析节点失败的问题
Critical Reviews | 南农邹建文组综述全球农田土壤抗生素与耐药基因分布
随机推荐
Does the satellite phone communicate directly with the satellite or through a ground station?
第一次进入小程序判断
VBA batch import Excel data into Access database
Recommendation | People who are kind to you, don't repay them by inviting them to eat
Range.CopyFromRecordset 方法 (Excel)
实体中增加操作方法
How do radio waves transmit information?
SwiftUI iOS Boutique Open Source Project Complete Baked Food Recipe App based on SQLite (tutorial including source code)
MindSpore:【Resolve node failed】解析节点失败的问题
【剑指 Offer】剑指 Offer 22. 链表中倒数第k个节点
crontab中写go run不执行的问题
【MindSpore1.2.0-rc1产品】num_workers问题
谷歌AlphaFold近日宣称预测出地球上几乎所有蛋白质结构
Scala学习:breakable
不同的路径依赖
What is the value of biomedical papers? How to translate the papers into Chinese and English?
还有三天忙完
VBA批量将Excel数据导入Access数据库
Swiper rotates pictures and plays background music
Go 系统收集