From b94e7267ce1a836024333759f157c716ee5df4bf Mon Sep 17 00:00:00 2001
From: Oliver Davies <oliver@oliverdavies.uk>
Date: Thu, 2 Jun 2022 22:32:43 +0100
Subject: [PATCH] feat(nvim): add drupalclass snippet

Add a new `drupalclass` snippet for Luasnip that scaffolds a new PHP
class that's opinionated for Drupal applications.

The class name is based on the filename (minus the file extension) and
the namespace is generated automatically from the directory structure
based on the location of the `src` directory.

It also includes the `Tests` entry within the namespace if the file is
witin a `tests` directory.
---
 .../files/lua/opdavies/snippets/ft/php.lua    | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/roles/neovim/files/lua/opdavies/snippets/ft/php.lua b/roles/neovim/files/lua/opdavies/snippets/ft/php.lua
index af8311df..7475ed2e 100644
--- a/roles/neovim/files/lua/opdavies/snippets/ft/php.lua
+++ b/roles/neovim/files/lua/opdavies/snippets/ft/php.lua
@@ -2,10 +2,63 @@ local fmta = require("luasnip.extras.fmt").fmta
 local ls = require "luasnip"
 
 local c = ls.choice_node
+local f = ls.function_node
 local i = ls.insert_node
 local t = ls.text_node
 
 local M = {
+
+  drupalclass = fmta([[
+    <<?php
+
+    declare(strict_types=1);
+
+    namespace <>;
+
+    final class <> {
+
+      <>
+
+    }]],
+    {
+      f(function()
+        local filepath = vim.fn.expand('%:h')
+        local filepath_parts = vim.fn.split(filepath, "/")
+
+        if not vim.tbl_contains(filepath_parts, "src") then
+          return ""
+        end
+
+        local namespace_parts = { "Drupal" }
+
+        local is_test_file = vim.tbl_contains(filepath_parts, "tests")
+        if is_test_file then
+          table.insert(namespace_parts, "Tests")
+        end
+
+        -- Find and add the module name.
+        for k, v in ipairs(filepath_parts) do
+          if v == "src" then
+            if is_test_file then
+              table.insert(namespace_parts, filepath_parts[k - 2])
+            else
+              table.insert(namespace_parts, filepath_parts[k - 1])
+            end
+          end
+        end
+
+        -- Add the rest of the namespace.
+        local namespace = vim.split(filepath, "src/")
+        local final_part = (namespace[2] or ""):gsub("/", "\\")
+        table.insert(namespace_parts, final_part)
+
+        return table.concat(namespace_parts, "\\")
+      end),
+      f(function() return vim.fn.expand("%:t:r"); end),
+      i(0),
+    }
+  ),
+
   func = fmta("function <>(<>)<> {\n  <>\n}<>", { i(1), i(2), i(3), i(4), i(0) }),
 
   met = fmta(