Skip to content

VSCode 自定义 tasks

创建 tasks.json 文件

在 Windows 下,位于:

  • C:\Users\<username>\AppData\Roaming\Code\User\tasks.json

例如,需要创建一个自动复制当前文件相对路径和文件内容的任务,可以使用以下配置:

json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
        },
        {
            "label": "Copy Relative Path and Content to Clipboard",
            "type": "shell",
            "command": "python",
            "args": [
                "~/scripts/copy_path_and_content.py",
                "${workspaceFolder}",
                "${relativeFile}",
                "${input:selectedFiles}"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ],
    "inputs": [
        {
            "id": "selectedFiles",
            "type": "promptString",
            "description": "Enter one or more relative file paths, separated by comma (`,`)",
            "default": " "
        }
    ]
}

创建脚本

假如当前 vscode 窗口运行于远程 Linux 下,那么需要将脚本放置在远程服务器上:

  • ~/scripts/copy_path_and_content.py
py
import sys
import os


def get_file_path_by_name(
    workspace_folder: str,
    filename: str,
    ignore_case: bool = True,
    ignore_ext: bool = True,
) -> str:
    filename = filename.strip()
    for root, dirs, files in os.walk(workspace_folder):
        for file in files:
            if ignore_case:
                src = filename.lower()
                dst = file.lower()
            else:
                src = filename
                dst = file
            if ignore_ext:
                src = os.path.splitext(src)[0]
                dst = os.path.splitext(dst)[0]
            if src == dst:
                return os.path.join(root, file)
    return None


def get_selected_paths(workspace_folder: str, selected_files_arg: str) -> list[str]:
    selected_files = selected_files_arg.split(",")
    selected_paths = []
    for filename in selected_files:
        filepath = get_file_path_by_name(workspace_folder, filename)
        if filepath:
            selected_paths.append(filepath)
            print(f"  + {filepath}")
        else:
            print(f"  × {filename}")
    return selected_paths


def get_relative_paths(workspace_folder: str) -> list[str]:
    relative_file = sys.argv[2]
    relative_path = os.path.join(workspace_folder, relative_file)
    file_paths = [relative_path]
    print(f"  * {relative_path}")
    return file_paths


def dump_contexts(context_paths: list[str]) -> str:
    context_str = ""
    output_path = os.path.expanduser("~/scripts/copied.txt")
    for context_path in context_paths:
        try:
            with open(context_path, "r") as file:
                context_content = file.read()
        except Exception as e:
            print(f"× Error reading file: {e}")
            return
        context_str += f"here is `{context_path}`:\n```\n{context_content}\n```\n\n"

    print(f"> dump contexts to:")
    try:
        with open(output_path, "w") as output_file:
            output_file.write(context_str)
        print(f"  * {output_path}")
    except Exception as e:
        print(f"  × Error writing to file: {e}")


def main():
    workspace_folder = sys.argv[1]
    selected_files_arg = sys.argv[3]
    print(f"> select files:")
    if not selected_files_arg.strip():
        file_paths = get_relative_paths(workspace_folder)
    else:
        file_paths = get_selected_paths(workspace_folder, selected_files_arg)

    dump_contexts(file_paths)


if __name__ == "__main__":
    main()

运行

ctrl + shift + p,选择 Tasks: Run task > copy_path_and_content

或者按 ctrl + shift + b 快速运行上次使用的任务。