diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-01-03 04:30:40 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-01-06 21:20:33 +0900 |
| commit | 99cec584722619ccaba42737611a3a019644cdfc (patch) | |
| tree | 9f27d3d1469434994e158406ae970aff7e5813f5 | |
| parent | fe0fb3147b36cbe486e2fcb64a9861e4d8f92064 (diff) | |
| download | dotfiles-99cec584722619ccaba42737611a3a019644cdfc.tar.gz dotfiles-99cec584722619ccaba42737611a3a019644cdfc.tar.zst dotfiles-99cec584722619ccaba42737611a3a019644cdfc.zip | |
nvim: automatically insert namespace declaration into empty PHP file
| -rw-r--r-- | .config/nvim/after/ftplugin/php.lua | 92 |
1 files changed, 89 insertions, 3 deletions
diff --git a/.config/nvim/after/ftplugin/php.lua b/.config/nvim/after/ftplugin/php.lua index f6433f5..d6dbf6b 100644 --- a/.config/nvim/after/ftplugin/php.lua +++ b/.config/nvim/after/ftplugin/php.lua @@ -1,15 +1,101 @@ vimrc.after_ftplugin('php', function(conf) + -- Find "composer.json" file upward from the base directory. + local function find_composer_json(base_dir) + return vim.fs.find('composer.json', { + path = base_dir, + upward = true, + stop = vim.loop.os_homedir(), + type = 'file', + })[1] + end + + -- Read and decode JSON file. + local function load_json(file_path) + local ok_read, content = pcall(vim.fn.readblob, file_path) + if not ok_read then + return nil + end + local ok_decode, obj = pcall(vim.json.decode, content) + if not ok_decode then + return nil + end + return obj + end + + -- Generate namespace declaration based on the current file name and autoload settings. + local function generate_namespace_declaration() + local current_dir = vim.fs.dirname(vim.api.nvim_buf_get_name(0)) + local path_to_composer_json = find_composer_json(current_dir) + if not path_to_composer_json then + return nil -- failed to locate composer.json + end + local composer_json = load_json(path_to_composer_json) + if not composer_json then + return nil -- failed to load composer.json + end + local psr4 = vim.tbl_get(composer_json, 'autoload', 'psr-4') + if not psr4 then + return nil -- autoload.psr-4 section is absent + end + if vim.tbl_count(psr4) ~= 1 then + return nil -- psr-4 section is ambiguous + end + local psr4_namespace, psr4_dir + for k, v in pairs(psr4) do + psr4_namespace = k + psr4_dir = v + end + if psr4_namespace:sub(-1, -1) == '\\' then + psr4_namespace = psr4_namespace:sub(0, -2) + end + if psr4_dir:sub(-1, -1) == '/' then + psr4_dir = psr4_dir:sub(0, -2) + end + local namespace_root_dir = vim.fs.dirname(path_to_composer_json) .. '/' .. psr4_dir + if not vim.startswith(current_dir, namespace_root_dir) then + return nil + end + local current_path_suffix = current_dir:sub(#namespace_root_dir + 1) + local namespace = psr4_namespace .. current_path_suffix:gsub('/', '\\') + return ("namespace %s;"):format(namespace) + end + + local function generate_template() + local lines = { + '<?php', + '', + 'declare(strict_types=1);', + '', + } + local namespace_decl = generate_namespace_declaration() + if namespace_decl then + lines[#lines + 1] = namespace_decl + lines[#lines + 1] = '' + end + lines[#lines + 1] = '' + return lines + end + -- If a buffer is empty, insert a template and position the -- cursor at the end of the buffer. -- - -- Example: + -- Example 1: -- <?php -- -- declare(strict_types=1); -- -- [cursor] + -- + -- Example 2 with namespace declaration: + -- <?php + -- + -- declare(strict_types=1); + -- + -- namespace Foo\Bar\Baz; + -- + -- [cursor] if vim.fn.line('$') == 1 and vim.fn.getline(1) == '' then - vim.fn.setline(1, { '<?php', '', 'declare(strict_types=1);', '', '' }) - vim.fn.cursor(6, 0) + vim.fn.setline(1, generate_template()) + vim.fn.cursor('$', 0) end end) |
