Skip to content

Instantly share code, notes, and snippets.

@zthxxx
Last active December 15, 2022 10:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zthxxx/6666bc328d0d6253e074b5b83e6f422f to your computer and use it in GitHub Desktop.
Save zthxxx/6666bc328d0d6253e074b5b83e6f422f to your computer and use it in GitHub Desktop.
import path from 'path'
import { spawn } from 'child_process'
import { promises as fs } from 'fs'
import readline from 'readline'
import { chunk } from 'lodash-es'
/**
* usage:
* tsx <path>/.sources.mts <target dir>
*/
let cwd: string = process.argv[2] ?? process.cwd()
if (!path.isAbsolute(cwd)) {
cwd = path.join(process.cwd(), cwd)
}
const dirname = path.basename(cwd)
const prompt = readline.createInterface({
input: process.stdin,
output: process.stdout
})
function ask({ index }: { index: number }): Promise<'yes' | 'no'> {
return new Promise(resolve => {
prompt.question(
`[${index}] continue? ('no' to re-copy) [yes]/no `,
input => resolve((input as 'yes' | 'no') || ''),
)
})
}
const pbcopy = async (data: string) => {
var proc = spawn('pbcopy')
await proc.stdin.write(data)
await proc.stdin.end()
}
const walk = async ({
dir,
prefix = '',
files = [],
}:{
dir: string;
prefix?: string;
files?: string[];
}): Promise<string[]> => {
for await (const entry of await fs.opendir(dir)) {
if (entry.isDirectory()) {
await walk({
dir: path.join(dir, entry.name),
prefix: path.join(prefix, entry.name),
files,
})
}
else if (entry.isFile() || entry.isSymbolicLink()) {
files.push(path.join(prefix, entry.name))
}
}
return files
}
const files = (await walk({ dir: cwd }))
.filter(name => /(?<!test)\.ts$/.test(name))
const pathOfFile = (name: string) => path.join('.', dirname, name)
const codes = await Promise.all(
files
.map(async file => ({
file,
code: await fs.readFile(path.join(cwd, file), { encoding: 'utf-8' }),
}))
)
type Item = {
file: string;
code: string;
}
const chunkSize = 10
const chunks: Item[][] = chunk(codes, chunkSize)
console.log(`
total files: ${files.length}
total chunks: ${chunks.length} (chunk size ${chunkSize})
`)
for (const [index, chunk] of chunks.entries()) {
const paste = chunk
.map(({ file, code }) => [
`// ${pathOfFile(file)}`,
code,
].join('\n'))
.join('\n-----\n')
await pbcopy(paste)
while (await ask({ index }) === 'no') {
await pbcopy(paste)
}
}
我会用多条消息向你输入一个 typescript 项目代码,
所有文件输入完成后,我会用单独消息向你说 `输入完毕` 并再次提出我的问题,
在我说输入完毕之前,你每次只需要回复 `get`, 不回复其他消息或提问;
项目涉及多个 typescript 文件,每条消息中包含多个文件,
不同文件之间会通过独立一行 `-----` 做分割,
每个文件会在开头用注释列出该文件路径,如 `// src/.../xxx.ts`
第一条消息与文件如下
-----
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment