Neovim pour PHP et Laravel

Si vous avez déjà voulu utiliser Neovim pour le développement PHP et Laravel, ce guide devrait vous aider à démarrer. Si vous utilisez VSCode, consultez ce post.

Dans ce post, je vais utiliser Neovim avec LazyVim. LazyVim est une configuration fantastique de Neovim avec de nombreuses fonctionnalités et outils prêts à l’emploi. J’ai passé plus de temps que je ne voudrais l’admettre à configurer Vim et Neovim. LazyVim permet de gagner presque tout ce temps. Lorsque vous commencerez à être à l’aise avec la configuration de LazyVim, vous pourrez envisager de créer votre propre configuration à partir de zéro.

Ce billet suppose que vous utilisez la dernière version de Neovim (v0.10.0 à l’heure où nous publions cet article). Si vous avez besoin de l’installer, vous pouvez l’obtenir pour votre système d’exploitation ici.

Une fois Neovim installé, nous allons utiliser LazyVim. Vous pouvez utiliser votre configuration si vous préférez ne pas utiliser LazyVim, mais cette configuration est beaucoup plus complexe pour ce post.

Pour installer LazyVim, vous voudrez cloner le repo et le déplacer dans votre dossier de configuration Neovim, (~/.config/nvim sur MacOS/Linux).

git clone https://github.com/LazyVim/starter ~/.config/nvim

Une fois cloné, vous pouvez supprimer le dossier .git puisque vous n’en aurez pas besoin maintenant et que vous voudrez peut-être contrôler la version de vos changements de configuration.

rm -rf ~/.config/nvim/.git

Si vous utilisez Windows, vous pouvez suivre les instructions d’installation ici.

Une fois que c’est fait, vous pouvez lancer Neovim, et il sortira tous les plugins et dépendances pour LazyVim

Sortie de la boîte, LazyVim donne un menu agréable pour naviguer selon les besoins.

LazyVim a récemment ajouté une mise à jour pour ajouter rapidement le support PHP. Il suffit de cliquer sur x depuis l’écran d’accueil pour accéder au menu des extras ou de taper :LazyExtras.

Dans le menu, vous pouvez rechercher PHP en tapant d’abord une barre oblique, puis php, donc /php. Le / commence les recherches dans Neovim.

Avec votre curseur sur la ligne lang.php, tapez x pour basculer l’extra. Redémarrez ensuite Neovim. Maintenant, Neovim supportera la syntaxe PHP et installera le Phpactor LSP.

Pour tester le LSP, j’ai créé un nouveau projet Laravel avec Laravel Breeze. Depuis le répertoire du projet, ouvrez Neovim et ouvrez le ProfileController en utilisant <leader>ff. Dans Neovim, de nombreuses commandes clavier sont préfixées par la touche <leader>, qui est définie sur space par défaut. Ainsi, pour trouver un fichier, tapez space + f + f. Ensuite, vous pouvez simplement faire une recherche en utilisant le fuzzy finder.

Lors du premier chargement du contrôleur, Phpactor commencera à indexer votre base de code, typiquement à partir de la racine Git du projet.

Vous verrez également de nombreuses erreurs et autres diagnostics. Ceux-ci sont fournis par le LSP en plus de la complétion de code, aller à la définition, le refactoring et de nombreuses autres fonctionnalités.

Si vous souhaitez modifier le contrôleur de base, vous pouvez naviguer jusqu’à Controller et cliquer sur gd pour Aller à la Définition.

Après Aller à la Définition, vous pouvez revenir à la définition de la classe et cliquer sur gr pour Aller aux Références de la classe Controller. Ensuite, vous pouvez utiliser ctrl+o pour revenir à vos emplacements précédents.

N’hésitez pas à continuer à utiliser Phpactor s’il fonctionne pour vous. Il rencontre des difficultés avec certaines fonctionnalités magiques et les types manquants dans Laravel, mais il est entièrement gratuit et open source. Vous pouvez améliorer cela en utilisant quelque chose comme Laravel IDE Helper qui génère des stubs pour les modèles, les façades et d’autres fonctionnalités du framework afin de fournir une meilleure auto-complétion.

Personnellement, j’ai eu une meilleure expérience en utilisant le Intelephense LSP, que vous connaissez probablement si vous venez de VSCode. Malheureusement, vous perdez certaines fonctionnalités de Phpactor sans la version premium d’Intelephense, donc je recommande l’achat si vous utilisez Intelephense. Une seule licence fonctionne pour VSCode, Neovim et tout autre éditeur qui prend en charge les LSP.

Pour configurer Intelephense, vous devrez modifier la configuration de LazyVim. Dans le dossier ~/.config/nvim, ouvrez options.lua et ajoutez la ligne suivante :

vim.g.lazyvim_php_lsp = "intelephense"

Cela indique à LazyVim d’installer Intelephense. Vous devrez peut-être supprimer Phpactor, cependant. Pour ce faire, vous pouvez taper <leader>cm qui ouvre Mason. Mason est un outil permettant d’installer divers formateurs, linters et LSP. Dans le menu Mason, trouvez Phpactor et désinstallez-le en utilisant X.

Depuis que nous avons installé les Lazy Extras pour PHP, Laravel Pint et PHP-CS-Fixer ont été installés. Cependant, PHP-CS-Fixer est défini par défaut. Pour changer cela, nous pouvons créer un nouveau fichier dans la configuration de Neovim : ~/.config/nvim/lua/plugins/php.lua. Vous pouvez nommer ce fichier comme vous le souhaitez, mais pour ce billet, nous l’utiliserons pour toutes nos configurations liées à PHP/Laravel.

Dans le fichier, vous pouvez inclure ce qui suit:

return {
  {
    "stevearc/conform.nvim",
    optional = true,
    opts = {
      formatters_by_ft = {
        php = { { "pint", "php_cs_fixer" } },
      },
    },
  },
}

Cela fait de Pint le formateur par défaut, et il se rabattra sur PHP-CS-Fixer s’il n’est pas trouvé. Avec ce changement, je peux retourner dans le ProfileController et ajouter une importation inutilisée et une indentation désordonnée, et la sauvegarde déclenchera un format.

Une autre modification facultative que vous pouvez faire est de supprimer phpcs si vous ne l’utilisez pas. Dans le fichier php.lua, ajoutez simplement un autre bloc comme le suivant:

return {
  {
    -- Définissez Laravel Pint comme le formateur PHP par défaut avec PHP CS Fixer comme solution de repli.
    "stevearc/conform.nvim",
    optional = true,
    opts = {
      formatters_by_ft = {
        php = { { "pint", "php_cs_fixer" } },
      },
    },
  },
  {
    -- Supprimez le linter phpcs.
    "mfussenegger/nvim-lint",
    optional = true,
    opts = {
      linters_by_ft = {
        php = {},
      },
    },
  },
}

Je récupère ces configurations directement à partir de la Documentation de LazyVim.

Ensuite, nous allons configurer Neatest afin de pouvoir exécuter des tests directement dans Neovim. C’est un autre supplément de LazyVim qui peut être ajouté en tapant :LazyExtras puis en recherchant « test.core » et en basculant avec X.

Ensuite, nous devons installer le plugin Neotest Pest. Ajouter le bloc suivant à la configuration php.lua.

return {
  {
    ...
  },
  {
    -- Ajouter le plugin neotest-pest pour l'exécution des tests PHP.
    -- Un package est également disponible pour PHPUnit si nécessaire.
    "nvim-neotest/neotest",
    dependencies = { "V13Axel/neotest-pest" },
    opts = { adapters = { "neotest-pest" } },
  }
}

Avec la configuration de test en place, chargez un fichier de test, et vous pouvez exécuter des tests individuels avec <leader>tr ou le fichier entier avec <leader>tt.

Utilisez <leader>to pour faire basculer un résumé des résultats du test.

Ajouter le support de Laravel Blade est un peu plus compliqué. LazyVim a configuré Treesitter pour prendre en charge la coloration syntaxique pour la plupart des langues. Cependant, Blade n’est pas installé par défaut, nous devons donc l’ajouter.

return {
  {
    ...
  },  
  {
    -- Ajouter un parseur Treesitter pour Laravel Blade afin de fournir la coloration syntaxique de Blade.
    "nvim-treesitter/nvim-treesitter",
    opts = function(_, opts)
      vim.list_extend(opts.ensure_installed, {
        "blade",
        "php_only",
      })
    end,
    config = function(_, opts)
      vim.filetype.add({
        pattern = {
          [".*%.blade%.php"] = "blade",
        },
      })

      require("nvim-treesitter.configs").setup(opts)
      local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
      parser_config.blade = {
        install_info = {
          url = "https://github.com/EmranMR/tree-sitter-blade",
          files = { "src/parser.c" },
          branch = "main",
        },
        filetype = "blade",
      }
    end,
  },
}

Nous étendons la configuration par défaut de Treesitter pour définir un nouveau type de fichier et tirer vers le bas le parseur Blade.

Une fois que nous redémarrons Neovim, vous pouvez exécuter :TSInstall blade pour télécharger l’analyseur.

Par la suite, nous devons ajouter quelques requêtes Treesitter pour un meilleur support du code. Pour ce faire, nous devons créer de nouveaux fichiers à partir de Neovim.

Typez :TSEditQuery injections de lame et ajoutez le contenu suivant :

((text) @injection.content
    (#not-has-ancestor? @injection.content "envoy")
    (#set! injection.combined)
    (#set! injection.language php))

; tree-sitter-comment injection
; if available
((comment) @injection.content
 (#set! injection.language "comment"))

; could be bash or zsh
; or whatever tree-sitter grammar you have.
((text) @injection.content
    (#has-ancestor? @injection.content "envoy")
    (#set! injection.combined)
    (#set! injection.language bash))

((php_only) @injection.content
    (#set! injection.language php_only))

((parameter) @injection.content                                                                                                 
    (#set! injection.include-children) ; You may need this, depending on your editor e.g Helix                                                                                          
    (#set! injection.language "php-only"))

Tapez :TSEditQuery highlights blade et ajoutez:

(directive) @tag
(directive_start) @tag
(directive_end) @tag
(comment) @comment

Tapez :TSEditQuery folds blade et ajoutez:

((directive_start) @start
    (directive_end) @end.after
    (#set! role block))


((bracket_start) @start
    (bracket_end) @end
    (#set! role block))

Enfin, nous allons ajouter quelques requêtes d’injection pour le support d’Alpine. Tapez :TSEditQuery et ajoutez:

;; extends

; AlpineJS attributes
(attribute
  (attribute_name) @_attr
    (#lua-match? @_attr "^x%-%l")
  (quoted_attribute_value
    (attribute_value) @injection.content)
  (#set! injection.language "javascript"))

; Blade escaped JS attributes
; <x-foo ::bar="baz" />
(element
  (_
    (tag_name) @_tag
      (#lua-match? @_tag "^x%-%l")
  (attribute
    (attribute_name) @_attr
      (#lua-match? @_attr "^::%l")
    (quoted_attribute_value
      (attribute_value) @injection.content)
    (#set! injection.language "javascript"))))

; Blade PHP attributes
; <x-foo :bar="$baz" />
(element
  (_
    (tag_name) @_tag
      (#lua-match? @_tag "^x%-%l")
    (attribute
      (attribute_name) @_attr
        (#lua-match? @_attr "^:%l")
      (quoted_attribute_value
        (attribute_value) @injection.content)
      (#set! injection.language "php_only"))))

Après avoir tout ajouté, sauvegardé et redémarré, vous devriez maintenant avoir la coloration syntaxique pour les fichiers Blade !

Pour plus d’informations et d’instructions d’installation, visitez la repo pour l’analyseur Blade Treesitter.

LazyVim est livré avec un plugin pour créer facilement des snippets. Pour créer des snippets PHP, vous pouvez créer un nouveau fichier : ~/.config/nvim/snippets/php.json similaire à l’exemple ci-dessous:

{
  "strict types": {
    "prefix": "strict",
    "description": "Add strict types declaration",
    "body": [
      "declare(strict_types=1);"
    ]
  },
  "inv": {
    "prefix": "inv",
    "description": "Create PHP __invoke method",
    "body": [
      "public function __invoke(${1}): ${2:void}",
      "{",
      "    ${3}",
      "}",
      ""
    ]
  },
  "public method": {
    "prefix": "pubf",
    "description": "Create a public method",
    "body": [
      "public function ${1}(${2}): ${3:void}",
      "{",
      "    ${0}",
      "}",
      ""
    ]
  },
  "protected method": {
    "prefix": "prof",
    "description": "Create a protected method",
    "body": [
      "protected function ${1}(${2}): ${3:void}",
      "{",
      "    ${0}",
      "}",
      ""
    ]
  },
  "private method": {
    "prefix": "prif",
    "description": "Create a private method",
    "body": [
      "private function ${1}(${2}): ${3:void}",
      "{",
      "    ${0}",
      "}",
      ""
    ]
  },
  "public static method": {
    "prefix": "pubsf",
    "description": "Create a public static method",
    "body": [
      "public static function ${1}(${2}): ${3:void}",
      "{",
      "    ${0}",
      "}",
      ""
    ]
  },
  "pest test (it) method": {
    "prefix": "it",
    "description": "Create a pest test",
    "body": [
      "it('${1}', function () {",
      "    // Arrange",
      "    ${0}",
      "",
      "    // Act",
      "",
      "    // Assert",
      "",
      "});"
    ]
  }
}

Vous pouvez ajouter d’autres snippets que vous souhaitez à ce fichier, ou créer des fichiers pour d’autres langues afin d’ajouter des snippets.

Ce plugin peut être utilisé pour exécuter rapidement des commandes Artisan avec une grande fonction de recherche en utilisant <leader>la. Ou vous pouvez lister toutes les routes dans votre application en utilisant <leader>lr.

return { 
  {
    ...
  },
  {
    -- Ajouter le plugin Laravel.nvim qui donne la possibilité d'exécuter des commandes Artisan
    -- à partir de Neovim.
    "adalessa/laravel.nvim",
    dependencies = {
      "nvim-telescope/telescope.nvim",
      "tpope/vim-dotenv",
      "MunifTanjim/nui.nvim",
      "nvimtools/none-ls.nvim",
    },
    cmd = { "Sail", "Artisan", "Composer", "Npm", "Yarn", "Laravel" },
    keys = {
      { "la", ":Laravel artisan" },
      { "lr", ":Laravel routes" },
      { "lm", ":Laravel related" },
    },
    event = { "VeryLazy" },
    config = true,
    opts = {
      lsp_server = "intelephense",
      features = { null_ls = { enable = false } },
    },
  },
}

Ajoute la possibilité d’utiliser Goto File sur les vues Blade pour sauter aux composants et autres vues en utilisant gf.

return { 
  {
    ...
  },
  {
    -- Ajoute le plugin blade-nav.nvim qui fournit des capacités Goto File
    -- pour les fichiers Blade.
    "ricardoramirezr/blade-nav.nvim",
    dependencies = {
      "hrsh7th/nvim-cmp",
    },
    ft = { "blade", "php" },
  },
}

Un des grands avantages de LazyVim est la documentation. S’il y a quelque chose que vous avez l’habitude de faire dans VSCode et que vous voulez faire dans Neovim, il y a des chances que LazyVim l’ait déjà intégré. Je recommande de parcourir chaque section de LazyVim pour en savoir plus.

L’une des sections les plus importantes est probablement celle des cartes de touches. LazyVim utilise which-key.nvim pour vous aider à vous souvenir des keycaps configurés lorsque vous êtes dans l’éditeur, mais pour une liste complète, cliquez ici.

Vous voulez le support de Git ? LazyVim s’en occupe avec LazyGit qui est une interface de terminal très agréable pour Git. Utilisez <leader>gg pour l’ouvrir. Vous pouvez même installer LazyGit directement en utilisant quelque chose comme Homebrew pour l’exécuter directement sur la ligne de commande en utilisant lazygit.

Vous avez besoin d’outils supplémentaires comme PHPStan ou Psalm ? Utilisez <leader>cm ou :Mason pour afficher le menu Mason et rechercher ce dont vous avez besoin. De nombreux linters et formateurs populaires sont disponibles pour installation.

Comme je l’ai mentionné plus haut, LazyVim fournit une documentation incroyable qui vaut vraiment la peine d’être lue.

Jess Archer a un fantastique cours pour mettre en place Neovim sur Laracasts. Si vous n’êtes pas abonné à Laracasts, je ne saurais trop vous le recommander. Je suis un utilisateur à vie depuis 2017. Si c’est quelque chose qui vous intéresse, utilisez mon lien de référence.

DHH (le créateur de Ruby on Rails) a créé le paquet Omakub comme un moyen rapide de mettre en place un environnement de développement sur Ubuntu Linux. Même si vous n’utilisez pas Ubuntu, le repo d’Omakub vaut la peine d’être consulté car il contient de nombreuses configurations et outils intéressants, dont Neovim avec LazyVim.

Si vous voulez quelque chose d’un peu plus minimal que LazyVim, Kickstart.nvim est un bon point de départ. Vous pouvez regarder cette vidéo de TJ DeVries sur la façon de commencer. Même si vous voulez continuer à utiliser LazyVim, c’est toujours une excellente ressource pour en savoir plus sur la configuration de Neovim.

J’espère que cela vous aidera à commencer votre voyage dans Neovim. C’est un éditeur puissant et infiniment configurable. Bien qu’il ne soit pas aussi puissant que PhpStorm, il peut vous en rapprocher gratuitement et nécessite moins de ressources CPU.

Même si vous ne prévoyez pas d’utiliser Neovim comme éditeur principal, je pense qu’il peut toujours être bénéfique d’apprendre les raccourcis clavier. Je partage généralement mon temps entre Neovim et PhpStorm et j’essaie de garder mes raccourcis clavier aussi similaires que possible. Heureusement, le plugin IdeaVim pour JetBrains IDEs rend cela simple.

Pour votre référence, j’ai créé une repo avec tous les fichiers que nous avons créés dans ce post.

S’il vous plaît laissez-moi savoir si vous avez d’autres questions sur la configuration ou des fonctionnalités supplémentaires que j’aurais pu manquer.

Merci d’avoir lu !

Source:
https://seankegel.com/neovim-for-php-and-laravel