为了生成目录结构方便,我写了个vscode插件

2,035 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

前言

大家好,我是小阵 🔥,一路奔波不停的码字业务员
身为一个前端小菜鸟,总是有一个飞高飞远的梦想,因此,每点小成长,我都想要让它变得更有意义,为了自己,也为了更多值得的人
如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~😋
加我微信:zzz886885,邀你进群,一起学习交流,摸鱼学习两不误🌟

开开心心学技术大法~~

开心

来了来了,他真的来了~

正文

起因

因为最近掘金活动比较给力,所以更文比较频繁

因为更文比较频繁,所以引用目录结构比较频繁

之前我都是靠口述简单结构,贴图复杂结构一路蒙混过来的

终于我受不了这么不标准的目录结构啦。(目录结构:我也是这样想的!😭)

于是我用node自己写了个目录生成的脚本

但是写完之后还得复制内容再粘贴

于是我又加上了个生成目录自动复制的功能

但是我写文的时候还得专门找到脚本,并且用的时候要复制「目标目录路径」,再粘贴回来,不够简便

。。。

在一系列的「不、便、利」下,我最终还是写成了vscode插件

生成框架

依据vscode插件指南官网,下载生成框架的包

// 安装需要的包
npm install  yo generator-code -D

// 生成框架代码
npx yo code

之后选择我们要生成的框架,我这里一切从简,直接all in了。

具体可以选择哪些大家自己上手时就能明白,根本不用我在这里多说,多说一句都感觉侮辱了大家智商。。哈哈哈哈

哈哈

插件编写

目录准备

因为生成的目录要尽量让大家看明白,所以需要借助一些字符串来做分隔

let dirstr = '├── '
let linkDirStr = '│   '
let blankDirStr = '    '
let lastDirStr = '└── '
let allDirStr = ``

生成目录

需要递归查找,并根据文件所处与该目录的位置来决定用哪种字符串来做分隔

const traverse = (dirname, level = 1) => {
        const dirs = fs.readdirSync(dirname)
        dirs.forEach((item, index) => {
                const itemStat = fs.statSync(path.join(dirname, item))
                const _dirstr = index === dirs.length - 1 ? lastDirStr : dirstr
                const currentDirStr = `${linkDirStr.repeat(level > 1 ? 1 : 0)}${blankDirStr.repeat(Math.max(0, level - 2))}${_dirstr}${item}\n`

                if (itemStat.isDirectory()) {
                        allDirStr += currentDirStr
                        traverse(path.resolve(dirname, item), level + 1)
                } else {
                        allDirStr += currentDirStr
                }

        })
}
// fsPath是后面从vscode里拿到的路径,这个待会儿在说
traverse(fsPath)

复制目标结构

这里借助了个node包``

var ncp2 = require('node-clipboardy');

// allDirStr 是前面生成的目录结构字符串
ncp2.writeSync(allDirStr);

注意,这里的node包有坑,我之前用的是copy-paste包,这个在node环境下也是ok的,但是到vscode插件环境下复制时就不能带上各种奇怪的字符串了,也不能带中文,所以找了一圈,最终用了node-clipboardy

vscode注册命令

"activationEvents": [
    "onCommand:getFileState"
  ],
"contributes": {
    "commands": [
      {
        "command": "getFileState",
        "title": "generate directory graph"
      }
    ],
    "menus": {
      "explorer/context": [
        {
          "command": "getFileState",
          "group": "navigation",
          "when": "explorerResourceIsFolder"
        }
      ],
      "commandPalette": [
        {
          "command": "getFileState",
          "when": "explorerResourceIsFolder"
        }
      ]
    }
  },

activationEvents里要注册我们定义的事件,这样在激活插件时才可以正确识别

commandscommand就是activationEvents中定义的事件名称,也是我们要在插件中实现和订阅的事件名称

commandstitle是展现给用户的,所以尽量看其名,知其意

menusexplorer/context是为了在右键目录时唤出的菜单上添加上我们commands中定义的title,为给我们的生成目录事件提供入口

menuscommandPalette限制了只有在聚焦到目录时才允许用户看到我们插件相关的操作信息

vscode获取目录路径

因为我们要生成目录结构,所以肯定要有一个目录入口给我们去遍历,因此需要通过vscode来获取。

我这里偷了个懒,因为完全舍弃command + shfit + p命令窗口调用插件功能,所以也就没有做命令行调起的适配,只做了右键复制的适配功能。

function activate(context) {
let disposable = vscode.commands.registerCommand('getFileState', function (source) {
    const { path: fsPath } = source || {};
                
}

    context.subscriptions.push(disposable);
        
}

上面的fsPath就是我们需要的目录路径

结合node实现完整插件功能

标题起的挺好,实际上我们只需要做个提示即可,比如复制成功的提示和获取不到文件路径的提示即可

 if (fsPath) {
        let dirstr = '├── '
        let linkDirStr = '│   '
        let blankDirStr = '    '
        let lastDirStr = '└── '
        let allDirStr = ``

        const traverse = (dirname, level = 1) => {
                const dirs = fs.readdirSync(dirname)
                dirs.forEach((item, index) => {
                        const itemStat = fs.statSync(path.join(dirname, item))
                        const _dirstr = index === dirs.length - 1 ? lastDirStr : dirstr
                        const currentDirStr = `${linkDirStr.repeat(level > 1 ? 1 : 0)}${blankDirStr.repeat(Math.max(0, level - 2))}${_dirstr}${item}\n`

                        if (itemStat.isDirectory()) {
                                allDirStr += currentDirStr
                                traverse(path.resolve(dirname, item), level + 1)
                        } else {
                                allDirStr += currentDirStr
                        }

                })
        }
        traverse(fsPath)

        ncp2.writeSync(allDirStr);
        vscode.window.showInformationMessage('复制成功!');
} else {
        vscode.window.showErrorMessage('请选择文件目录');
}

以上,我们就完成了我们预期的工作啦,接下来就是美滋滋的享受成果大戏。

享受成果

create.gif

完整代码传送门

想要体验一下的小伙伴们可以安装使用一波,具体安装+使用教程在github的README.md里。

喜欢的小伙伴们也可以follow下,star下哟,当然,如果感觉目录结构太丑的话也可以pr,欢迎各位共同加入创新创造!

比心

安装使用

我已经上传到vscode插件市场,改了下插件名字,只需要搜索Generate Directory Graph即可

image.png

后续

有小伙伴反映生成目录结构的时候会把node_modules文件也遍历下,导致时间太长并且也没必要打印node_modules的目录结构,还希望可以增加一个可以设置遍历深度的配置,因此我后续又增加了以下功能

1、新增ignoreFiles属性配置

  • generateDirGraph.ignorefiles
    • 默认忽略node_modules
    • 可以通过新增string来手动控制其他要忽略的文件

ignorefiles配置示例图

2、新增recursionDepth属性配置

  • generateDirGraph.recursionDepth
    • 递归深度,默认为递归到底
    • 可以输入number来指定递归深度

recursionDepth配置示例图

欢迎有其他建议的小伙伴踊跃提issue呀,欢迎欢迎哟👏🏻

结语

如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~

加油!

往期好文推荐「我不推荐下,大家可能就错过了史上最牛逼vscode插件集合啦!!!(嘎嘎~)😄」