9 个版本
0.2.8 | 2023 年 6 月 27 日 |
---|---|
0.2.7 | 2023 年 6 月 26 日 |
#608 在 文件系统
54 每月下载量
100KB
2.5K SLoC
FindFile (FF)
一个简单、便捷且强大的 find
替代品。
注意:此存储库处于积极开发中
语法(大部分)已经确定,但语法的内部实现需要大量工作。路线图
- 基本词法分析器
- 字符串字面量(带有插值):
"..."
- Perl 正则表达式字面量(带有插值):
$/.../
- 路径字面量(有点像带有插值):
foo/*.txt
- 文件大小字面量:
12kb
,4.9mib
-
$env
变量和$1
命令行变量 - 日期和时间字面量
- 在路径字面量中,
+
的位置从搜索根开始,而不是总是从当前工作目录根开始。
- 字符串字面量(带有插值):
- 基本抽象语法树 (AST) 构建器
- 数学和逻辑二元运算符(大多数在运行时不工作)
- 代码块
- 基本赋值
-
-Xk
和+Xk
需要实现较大和较小的功能 - 复合赋值
- 逻辑赋值
- 数组与哈希表(它们将是相同的类型)
- 函数调用
- 函数声明
- 基本运行时
- 确定起始位置(大部分工作)
- 为大多数类型添加基本数学
- 清理变量访问方式
- 支持
^{}
和${}
以用于开始和结束块 - 一种在不同类型之间转换的方法
- 添加更多支持的功能
- 完善此文件中已有的功能
- 添加
depth
和 "目录中的子项数量"
- 将其转换为虚拟机
- 添加 JIT
- 参数解析器
- 大多数参数(目前实现和待办事项)都已添加
- 打印出匹配行及其文件内容(类似于 ripgrep)
- 进行美化,使其看起来非常漂亮(clap 大多数时候都能做得很好)
- 杂项
- 优化文件读取,避免读取整个文件来匹配第一行
- 清理类型表示
- 可能需要从文件大小中移除重要位?
- 明确我在使用
Vec<u8>
与OsString
或String
时的差异。 - 找出如何协调
${}
用于开始块和${}
用于环境变量 - 未知变量应该警告吗?
以下是我最终希望支持的示例
- 列出目录中的所有文件:
ff 'isfile && depth=1'
- 制作文件及其目录的 "树":
ff -n 'print "\t"*depth_from(start), basename'
- 查找至少1GB或10天前更新的所有文件:
ff 'size > 1g || modify > -10d'
- 将后缀
-YYYY-MM-DD
添加到所有文件,但保留扩展名:ff -n 'isfile && mv(file, "{dir}{base}-{ymd_date}.{suffix})'
- 查找所属文件夹为
log
且10天内的所有文件:ff 'isfile && modify > -10d && basename(parent) = "log"'
- 查找包含 "hello" 和 "world" 的所有文件,可能位于不同的行:
ff 'contents =~ /hello/ && contents =~ /world/'
- 通过直接文件大小查找最大的文件夹:(
${}
在脚本结束时运行):ff -n '${print maxdir} dirsize > dirsize(maxdir) then maxdir=dirsize'
关键词
true
等同于1
false
等同于0
if else while continue break def return skip
/next
函数
如果一个函数不接受任何参数,你可以省略括号。例如,file?
与 file?()
相同,因为 file?()
等同于 file?(path)
。
查询信息
名称和参数 | 别名 | 功能描述 |
---|---|---|
文件?(p=路径) |
f? |
返回 p 是否是文件。 |
目录?(p=路径) |
d? dir? |
返回 p 是否是目录。 |
可执行文件?(p=路径) |
e? exe? |
返回 p 是否是可执行文件。 |
符号链接?(p=路径) |
s? sym? |
返回 p 是否是符号链接。 |
二进制文件?(p=路径) |
b? bin? |
返回 p 是否是二进制文件。 |
gitignore?(p=路径) |
gi? |
返回 p 是否被 gitignore 文件忽略。 |
隐藏?(p=路径) |
gi? |
返回 p 是否以 . 开头。 |
ok?(msg) |
打印 msg ,然后请求确认。 |
|
macos(...) |
未来想法:类似 macos 标签等功能 |
路径相关函数
| root()
| r
| 开始查看的根目录 | | path()
| p
| 当前路径 | | dirname(p=path)
| d
dir
parent
| 父目录 | | extname(p=path)
| e
ext
extension
| 扩展名,如果有,不包含 .
| | extnamed(p=path)
| ed
extd
extensiond
| 扩展名,如果有,包含 .
| | basename(p=path)
| b
bn
base
| 除 p
的父目录之外的所有内容 | | stemname(p=path)
| s
stem
| basename,如果没有扩展名(如果有) |
杂项
| print(...)
| pr
| 打印其参数(之间没有空格),后跟换行符 | | printn(...)
| prn
| 打印其参数(之间没有空格),不跟换行符 | | next
| skip
| 忽略当前参数并继续 | | exit(status)
| quit
| 停止整个脚本 | | pwd()
| 当前工作目录 | | depth(src=path, dst=root)
| 从 dst
出发,有多少个目录层级。 | | date(<...>)
| 当前日期,格式化为时间 | | sleep(<...>)
| 睡眠 |
可执行函数
这些函数中的一些是“破坏性的”(例如 mv
):如果破坏性文件会覆盖另一个文件,它将检查命令行参数以确定如何操作(--interactive
表示总是询问,--force
表示永不询问;如果两者都没有给出,则默认为 --force
)。您可以使用 <fn>i
总是进行交互式操作或使用 <fn>f
总是强制执行(类似于 mvf
)。
所有这些都必须用括号调用(可能是?)
名称和参数 | 功能描述 |
---|---|
exec(...) | .. |
mv{,f,i}(src=路径,dst) |
将 src 移动到 dst ;仅在交互式时确认是否覆盖文件 |
rm{,f,i}(src=路径) |
删除位于 src 的文件;在交互式时始终确认。如果给出空目录,rm 的行为类似于 rmdir 。 |
rmr{,f,i}(src=路径) |
递归删除位于 src 的文件;在交互式时始终确认 |
cp{,f,i}(src=路径,dst) |
将 src 复制到 dst ;仅在交互式时确认是否覆盖文件 |
ln... |
|
mkdir(p) |
在 p 处创建一个目录;它还会创建所有父目录。 |
touch(src=路径) |
在 p 处创建一个目录;它还会创建所有父目录。 |
IDEAS
移动文件时出现问题。您想做什么:(Q)uit:停止整个程序,(C)ontinue:继续进行,(R)etry:再次尝试(可能是在您修复某些内容之后),(S)hell:进入一个shell,其中 $cpath
是当前路径的变量
依赖项
~6–17MB
~219K SLoC