web-dev-qa-db-fra.com

Plusieurs commandes / tâches avec Visual Studio Code

J'ai un dossier local que j'utilise comme bloc-notes pour plusieurs petits exemples de code et des jouets. Je stocke un hôte de scripts python, C++, Shell, etc. dans ce répertoire.

J'utilise Visual Studio Code (sur OS X) et j'examine ses tâches pour exécuter/compiler les extraits de code sans avoir à basculer vers un terminal.

Par exemple, j'ai trouvé cette tâche suivante exécutera python sur le fichier actuellement ouvert.

// A task runner that runs a python program
{
    "version": "0.1.0",
    "command": "/usr/bin/python",
    "args": ["${file}"]
}

Cette tâche utilisera python comme exécuteur de tâches quel que soit le type de fichier que je modifie actuellement.

Comment puis-je implémenter une tâche pour exécuter une commande basée sur le type de fichier (ou sélectionner entre plusieurs commandes)? C'est à dire. si je modifie un fichier C++, il exécutera clang ++.

  • Si je ne peux pas le faire en fonction du type de fichier; existe-t-il des alternatives à cela?
  • Une alternative serait; plusieurs commandes sont-elles prises en charge?
24
Niall

Vous pouvez toujours utiliser bash comme exécuteur de tâches, puis attribuer des commandes de terminal arbitraires comme tâches.

{
    "version": "0.1.0",
    "command": "bash",
    "isShellCommand": true,
    "showOutput": "always",
    "args": [
        "-c"
    ],
    "tasks": [
        {
            "taskName": "My First Command",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "args": ["echo cmd1"]
        },
        {
            "taskName": "My Command Requiring .bash_profile",
            "suppressTaskName": true,
            "args": ["source ~/.bash_profile && echo cmd2"]
        },
        {
            "taskName": "My Python task",
            "suppressTaskName": true,
            "args": ["/usr/bin/python ${file}"]
        }
    ]
}

Quelques notes sur ce qui se passe ici:

  • Utilisation de bash -c pour toutes les tâches en le mettant dans args liste de la commande afin que nous puissions exécuter des commandes arbitraires. Les instructions echo ne sont que des exemples mais peuvent être n'importe quoi exécutable à partir de votre terminal bash.
  • Le tableau args contiendra une seule chaîne à transmettre à bash -c (les éléments séparés seraient traités comme plusieurs arguments de la commande bash et non de la commande associée à -c arg).
  • suppressTaskName est utilisé pour garder le taskName hors du mix
  • La deuxième commande montre comment charger votre ~/.bash_profile si vous avez besoin de quelque chose qu'il fournit comme des alias, des variables env, peu importe
  • La troisième commande montre comment utiliser la commande Python que vous avez mentionnée

Cela ne vous donnera aucune sorte de détection d'extension de fichier, mais vous pouvez au moins utiliser cmd+p puis tapez "tâche" pour obtenir une liste de vos tâches. Vous pouvez toujours marquer vos 2 commandes les plus courantes avec isBuildCommand et isTestCommand pour les exécuter via cmd+shift+b ou cmd+shift+t respectivement.

Cette réponse contient des informations utiles qui pourraient également vous être utiles.

33
bingles

Cette réponse visait à l'origine une solution plus complexe, mais le format de tâche de runner Shell simple présenté dans la réponse acceptée s'est avéré plus utile. Voir ci-dessous à quoi cela ressemble maintenant.


La limitation ici est que VS Code est limité à une seule tâche/commande de génération de haut niveau pour un espace de travail donné. Plusieurs sous-tâches sont autorisées, mais elles sont limitées à l'utilisation de la "commande" de niveau supérieur mais peuvent fournir différents "arguments". Ce serait bien adapté à un environnement qui utilise un système de construction semblable à make, ant ou msbuild. Par exemple.;

{
    "version": "0.1.0",
    "command": "make", // command must appear here
    "tasks" : [
        {
            "taskName": "clean",
            "suppressTaskName": false, // false by default
            //"command": "somethingelse", // not valid here
            "args": ["${file}"] // if required
        },
        {
            "taskName": "install"
            // ...
        }
    ]
}

Deux alternatives sont disponibles;

  • Demandez à un script personnalisé d'essayer d'exécuter la compilation/exécution uniquement en fonction des arguments dans task.json.

    -- the Shell file would be a simple
    "$@" # run what I get
    -- the tasks.json
    "args": ["clang++", "-std=c++14", "-O2", "${file}"]
    

    Obtenir l'exectuable à exécuter (./a.out) était plus d'effort. L'ajouter simplement comme argument n'a pas fonctionné, le script Shell était nécessaire pour l'exécuter s'il était là.

  • Décortiquez la commutation et l'exécution de la sortie vers un script personnalisé, compte tenu de l'extension et du nom de fichier. Cela s'est avéré plus facile à implémenter et a offert plus de contrôle dans le script Shell.

    {
        "version": "0.1.0",
        "isShellCommand": true,
        "taskName": "generic build",
        "showOutput": "always",
        "args": ["${fileExtname}", "${file}"]
        "command": "./.vscode/compileme.sh", // expected in the "local settings" folder
        //"command": "~/compileme.sh", // if in HOME folder
    }
    

    Et le script Shell, compileme.sh;

    #!/bin/sh
    # basic error checking not shown...
    echo "compilation being executed with the arguments;"
    echo "$@"
    filetype=$1
    file=$2
    if [ $filetype = ".cpp" -o $filetype = ".cxx" ] ; then 
        clang++ -std=c++14 -Wall -Wextra -pedantic -pthread $file && ./a.out
    Elif [ $filetype = ".c" ]
        then 
        clang -std=c11 -Wall -Wextra -pedantic -pthread $file && ./a.out
    Elif [ $filetype = ".sh" ]
        then
        $file
    Elif [ $filetype = ".py" ]
        then
        python $file
    else
        echo "file type not supported..."
        exit 1
    fi
    

Compte tenu des options énumérées ci-dessus, la deuxième option est préférable. Cette implémentation fonctionne sur OS X, mais elle pourrait être facilement portée sur Linux et Windows selon les besoins. Je garderai un œil sur cela et j'essaierai de suivre les modifications apportées aux tâches de construction de VS Code, aux constructions basées sur des fichiers ou à la prise en charge de plusieurs commandes.


My tasks.json prend en charge quelques coureurs, et une valeur par défaut pour la version qui imprime le message comme rappel. Il utilise le Shell comme coureur et ressemble maintenant à ...

{
    "version": "0.1.0",
    "isShellCommand": true,
    "taskName": "GenericBuild",
    "showOutput": "always",
    "command": "sh",
    "suppressTaskName": false,
    "args": ["-c"],
    "tasks": [
        {
            "taskName": "no build",
            "suppressTaskName": true,
            "isBuildCommand": true,
            "args": [
                "echo There is no default build task, run a task by name..."
            ]
        },
        {
            "taskName": "cpp",
            "suppressTaskName": true,
            "args": [
                "clang++ -std=c++14 -Wall -Wextra -pedantic -pthread \"${file}\" && ./a.out"
            ]
        },
        {
            "taskName": "Shell",
            "suppressTaskName": true,
            "args": [
                "\"${file}\""
            ]
        },
        {
            "taskName": "python",
            "suppressTaskName": true,
            "args": [
                "python \"${file}\""
            ]
        },
        {
            "taskName": "c",
            "suppressTaskName": true,
            "args": [
                "clang -std=c11 -Wall -Wextra -pedantic -pthread \"${file}\" && ./a.out"
            ]
        }
    ]
}
6
Niall