aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-07 23:06:23 +0900
committernsfisis <nsfisis@gmail.com>2026-02-07 23:06:23 +0900
commit9d5ec5e3bc01c6174dea048e118edee579c36565 (patch)
tree8bdb98836728e14f61bad56043f67bb352590963 /services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
parent479747454273abdbe9b5cc3f5c3dd18bbda7741a (diff)
downloadnsfisis.dev-9d5ec5e3bc01c6174dea048e118edee579c36565.tar.gz
nsfisis.dev-9d5ec5e3bc01c6174dea048e118edee579c36565.tar.zst
nsfisis.dev-9d5ec5e3bc01c6174dea048e118edee579c36565.zip
fix(style): fix codeblock style for rouge
Diffstat (limited to 'services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html')
-rw-r--r--services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html260
1 files changed, 128 insertions, 132 deletions
diff --git a/services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html b/services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
index 46780269..8e538579 100644
--- a/services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
+++ b/services/nuldoc/public/blog/posts/2024-01-10/neovim-insert-namespace-declaration-to-empty-php-file/index.html
@@ -15,7 +15,7 @@
<meta name="Hatena::Bookmark" content="nocomment">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<title>【Neovim】 空の PHP ファイルに namespace 宣言を挿入する|REPL: Rest-Eat-Program Loop</title>
- <link rel="stylesheet" href="/style.css?h=81dfc0b483beda175e3e17562faac7c9">
+ <link rel="stylesheet" href="/style.css?h=c3724e2d900f13528c82005e79a8ec23">
</head>
<body class="single">
<header class="header">
@@ -100,20 +100,18 @@
Neovim で空の PHP ファイルを開いたとき、そのファイルが置かれているディレクトリの構造に基づいて、自動的に <code>namespace</code> 宣言を挿入したい。具体的には、トップレベルの名前空間が <code>MyNamespace</code> であり、ファイル <code>src/Foo/Bar/Baz.php</code> を開いたときに、そのファイルが空であるなら、次のようなテンプレートが自動的に挿入されてほしい。
</p>
<div class="codeblock">
- <pre class="highlight" style="background-color:#f5f5f5"><code><span style="color: #6e7781">&lt;?php</span>
-
-<span style="color: #cf222e">namespace</span> <span style="color: #953800">MyNamespace\Foo\Bar</span><span style="color: #24292f;background-color: #f6f8fa">;</span>
-</code></pre>
+ <pre class="highlight" style="background-color:#f5f5f5"><code><div class="codeblock-line"><span style="color: #6e7781">&lt;?php</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #cf222e">namespace</span> <span style="color: #953800">MyNamespace\Foo\Bar</span><span style="color: #24292f;background-color: #f6f8fa">;</span></div></code></pre>
</div>
</section>
<section id="section--version">
<h2><a href="#section--version">バージョン情報</a></h2>
<div class="codeblock">
- <pre class="highlight" style="background-color:#f5f5f5"><code>$ nvim --version
-NVIM v0.9.2
-Build type: Release
-LuaJIT 2.1.1693350652
-</code></pre>
+ <pre class="highlight" style="background-color:#f5f5f5"><code><div class="codeblock-line">$ nvim --version
+</div><div class="codeblock-line">NVIM v0.9.2
+</div><div class="codeblock-line">Build type: Release
+</div><div class="codeblock-line">LuaJIT 2.1.1693350652</div></code></pre>
</div>
<p>
今回は Lua で処理を記述したため、Vim では動作しない。以下の説明でも Neovim に絞って述べる。また、パス区切りがスラッシュである前提で記述したため、Windows には対応していない。
@@ -137,14 +135,13 @@ LuaJIT 2.1.1693350652
ファイルタイプは読み込んだあとに変更されることもあるので、ftplugin は複数回実行されうる。二重読み込みを防ぐために、<code>did_ftplugin_&lt;FILE_TYPE&gt;_after</code> というバッファローカル変数を定義しておくのが慣習となっている。
</p>
<div class="codeblock">
- <pre class="highlight" style="background-color:#f5f5f5"><code><span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #6e7781">-- ここに実際の処理を書く</span>
-
-<span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span>
-</code></pre>
+ <pre class="highlight" style="background-color:#f5f5f5"><code><div class="codeblock-line"><span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #6e7781">-- ここに実際の処理を書く</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span></div></code></pre>
</div>
</section>
<section id="section--implement">
@@ -176,120 +173,119 @@ LuaJIT 2.1.1693350652
実装を簡単にするため、Composer を用いない場合や PSR 4 以外のオートロード規則を使う場合には対応しない。少々長くなるが、以下にスクリプト全文を載せる。
</p>
<div class="codeblock">
- <pre class="highlight" style="background-color:#f5f5f5"><code><span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #6e7781">-- base_dir を起点としてディレクトリを上向きに辿っていき、composer.json を探す</span>
-<span style="color: #6e7781">-- :help vim.fs.find()</span>
-<span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">find_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">base_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">find</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'composer.json'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">{</span>
- <span style="color: #24292f;background-color: #f6f8fa">path</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">base_dir</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #24292f;background-color: #f6f8fa">upward</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #6e7781">-- ホームディレクトリまで到達したら探索を打ち切る</span>
- <span style="color: #24292f;background-color: #f6f8fa">stop</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">loop</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">os_homedir</span><span style="color: #24292f;background-color: #f6f8fa">(),</span>
- <span style="color: #953800">type</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">'file'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #24292f;background-color: #f6f8fa">})[</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #6e7781">-- JSON ファイルを読み込み、デコードして返す</span>
-<span style="color: #6e7781">-- :help readblob()</span>
-<span style="color: #6e7781">-- :help vim.json.decode</span>
-<span style="color: #6e7781">-- :help luaref-pcall()</span>
-<span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">load_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">file_path</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #6e7781">-- readblob() は Vim script では Blob オブジェクトを返すが、Lua から呼ぶと string に変換される</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">ok_read</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">content</span> <span style="color: #0550ae">=</span> <span style="color: #953800">pcall</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">readblob</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">file_path</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">ok_read</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">ok_decode</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">obj</span> <span style="color: #0550ae">=</span> <span style="color: #953800">pcall</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">json</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">decode</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">content</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">ok_decode</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">obj</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #6e7781">-- 対象ファイルの置かれたディレクトリを基に namespace 宣言を生成する</span>
-<span style="color: #6e7781">-- :help nvim_buf_get_name()</span>
-<span style="color: #6e7781">-- :help vim.fs.dirname()</span>
-<span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">generate_namespace_declaration</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
- <span style="color: #6e7781">-- composer.json を探し、トップレベルの名前空間とディレクトリを特定する</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">current_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">dirname</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">api</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">nvim_buf_get_name</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">))</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">find_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- failed to locate composer.json</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">composer_json</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">load_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">composer_json</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- failed to load composer.json</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #6e7781">-- autoload.psr-4 を探し、型が期待される型と一致するかどうか調べる</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">psr4</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">tbl_get</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">composer_json</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0a3069">'autoload'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0a3069">'psr-4'</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">psr4</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- autoload.psr-4 section is absent</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">tbl_count</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0550ae">1</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is ambiguous</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span>
- <span style="color: #cf222e">for</span> <span style="color: #24292f;background-color: #f6f8fa">k</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">v</span> <span style="color: #cf222e">in</span> <span style="color: #953800">pairs</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #cf222e">do</span>
- <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">k</span>
- <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">v</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">if</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'table'</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">==</span> <span style="color: #0550ae">1</span> <span style="color: #cf222e">then</span>
- <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span>
- <span style="color: #cf222e">else</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is ambiguous</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">if</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0a3069">'string'</span> <span style="color: #0550ae">or</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0a3069">'string'</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is invalid</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #6e7781">-- 末尾のスラッシュとバックスラッシュを取り除いておく</span>
- <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'</span><span style="color: #0a3069">\\</span><span style="color: #0a3069">'</span> <span style="color: #cf222e">then</span>
- <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">2</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'/'</span> <span style="color: #cf222e">then</span>
- <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">2</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">end</span>
-
- <span style="color: #6e7781">-- 対象ファイルが置かれたディレクトリとトップレベルのディレクトリを比較し、その差分を名前空間とする</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">dirname</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">..</span> <span style="color: #0a3069">'/'</span> <span style="color: #0550ae">..</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span>
- <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">startswith</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #cf222e">then</span>
- <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">current_path_suffix</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">..</span> <span style="color: #24292f;background-color: #f6f8fa">current_path_suffix</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #953800">gsub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #116329">'/'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #116329">'</span><span style="color: #0a3069">\\</span><span style="color: #116329">'</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
- <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">"namespace %s;"</span><span style="color: #24292f;background-color: #f6f8fa">):</span><span style="color: #24292f;background-color: #f6f8fa">format</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">namespace</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">generate_template</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">{</span>
- <span style="color: #0a3069">'&lt;?php'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #0a3069">''</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #0a3069">'declare(strict_types=1);'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #0a3069">''</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
- <span style="color: #24292f;background-color: #f6f8fa">}</span>
- <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">generate_namespace_declaration</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
- <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span> <span style="color: #cf222e">then</span>
- <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span>
- <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">''</span>
- <span style="color: #cf222e">end</span>
- <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">''</span>
- <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">lines</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">line</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'$'</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0550ae">1</span> <span style="color: #0550ae">and</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">getline</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">''</span> <span style="color: #cf222e">then</span>
- <span style="color: #6e7781">-- 対象ファイルが空なら、テンプレートを挿入してカーソルを末尾に移動させる</span>
- <span style="color: #6e7781">-- :help setline()</span>
- <span style="color: #6e7781">-- :help cursor()</span>
- <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">setline</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">generate_template</span><span style="color: #24292f;background-color: #f6f8fa">())</span>
- <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">cursor</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'$'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
-<span style="color: #cf222e">end</span>
-
-<span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span>
-</code></pre>
+ <pre class="highlight" style="background-color:#f5f5f5"><code><div class="codeblock-line"><span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #6e7781">-- base_dir を起点としてディレクトリを上向きに辿っていき、composer.json を探す</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help vim.fs.find()</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">find_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">base_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">find</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'composer.json'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">{</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">path</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">base_dir</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">upward</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- ホームディレクトリまで到達したら探索を打ち切る</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">stop</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">loop</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">os_homedir</span><span style="color: #24292f;background-color: #f6f8fa">(),</span>
+</div><div class="codeblock-line"> <span style="color: #953800">type</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">'file'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">})[</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #6e7781">-- JSON ファイルを読み込み、デコードして返す</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help readblob()</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help vim.json.decode</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help luaref-pcall()</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">load_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">file_path</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- readblob() は Vim script では Blob オブジェクトを返すが、Lua から呼ぶと string に変換される</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">ok_read</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">content</span> <span style="color: #0550ae">=</span> <span style="color: #953800">pcall</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">readblob</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">file_path</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">ok_read</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">ok_decode</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">obj</span> <span style="color: #0550ae">=</span> <span style="color: #953800">pcall</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">json</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">decode</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">content</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">ok_decode</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">obj</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #6e7781">-- 対象ファイルの置かれたディレクトリを基に namespace 宣言を生成する</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help nvim_buf_get_name()</span>
+</div><div class="codeblock-line"><span style="color: #6e7781">-- :help vim.fs.dirname()</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">generate_namespace_declaration</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- composer.json を探し、トップレベルの名前空間とディレクトリを特定する</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">current_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">dirname</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">api</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">nvim_buf_get_name</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">))</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">find_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- failed to locate composer.json</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">composer_json</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">load_json</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">composer_json</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- failed to load composer.json</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- autoload.psr-4 を探し、型が期待される型と一致するかどうか調べる</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">psr4</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">tbl_get</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">composer_json</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0a3069">'autoload'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0a3069">'psr-4'</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">psr4</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- autoload.psr-4 section is absent</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">tbl_count</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0550ae">1</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is ambiguous</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">for</span> <span style="color: #24292f;background-color: #f6f8fa">k</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">v</span> <span style="color: #cf222e">in</span> <span style="color: #953800">pairs</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #cf222e">do</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">k</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">v</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'table'</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">==</span> <span style="color: #0550ae">1</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">else</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is ambiguous</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0a3069">'string'</span> <span style="color: #0550ae">or</span> <span style="color: #953800">type</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">~=</span> <span style="color: #0a3069">'string'</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span> <span style="color: #6e7781">-- psr-4 section is invalid</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- 末尾のスラッシュとバックスラッシュを取り除いておく</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'</span><span style="color: #0a3069">\\</span><span style="color: #0a3069">'</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">2</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">'/'</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">-</span><span style="color: #0550ae">2</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- 対象ファイルが置かれたディレクトリとトップレベルのディレクトリを比較し、その差分を名前空間とする</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fs</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">dirname</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">path_to_composer_json</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">..</span> <span style="color: #0a3069">'/'</span> <span style="color: #0550ae">..</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_dir</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #0550ae">not</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">startswith</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #0550ae">nil</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">current_path_suffix</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">current_dir</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #24292f;background-color: #f6f8fa">sub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">namespace_root_dir</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">psr4_namespace</span> <span style="color: #0550ae">..</span> <span style="color: #24292f;background-color: #f6f8fa">current_path_suffix</span><span style="color: #24292f;background-color: #f6f8fa">:</span><span style="color: #953800">gsub</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #116329">'/'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #116329">'</span><span style="color: #0a3069">\\</span><span style="color: #116329">'</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">"namespace %s;"</span><span style="color: #24292f;background-color: #f6f8fa">):</span><span style="color: #24292f;background-color: #f6f8fa">format</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #24292f;background-color: #f6f8fa">namespace</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #cf222e">local</span> <span style="color: #cf222e">function</span> <span style="color: #8250df">generate_template</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">{</span>
+</div><div class="codeblock-line"> <span style="color: #0a3069">'&lt;?php'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #0a3069">''</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #0a3069">'declare(strict_types=1);'</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #0a3069">''</span><span style="color: #24292f;background-color: #f6f8fa">,</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">}</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">local</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">generate_namespace_declaration</span><span style="color: #24292f;background-color: #f6f8fa">()</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #24292f;background-color: #f6f8fa">namespace_decl</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">''</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">end</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">lines</span><span style="color: #24292f;background-color: #f6f8fa">[</span><span style="color: #0550ae">#</span><span style="color: #24292f;background-color: #f6f8fa">lines</span> <span style="color: #0550ae">+</span> <span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">]</span> <span style="color: #0550ae">=</span> <span style="color: #0a3069">''</span>
+</div><div class="codeblock-line"> <span style="color: #cf222e">return</span> <span style="color: #24292f;background-color: #f6f8fa">lines</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #cf222e">if</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">line</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'$'</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0550ae">1</span> <span style="color: #0550ae">and</span> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">getline</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">)</span> <span style="color: #0550ae">==</span> <span style="color: #0a3069">''</span> <span style="color: #cf222e">then</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- 対象ファイルが空なら、テンプレートを挿入してカーソルを末尾に移動させる</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- :help setline()</span>
+</div><div class="codeblock-line"> <span style="color: #6e7781">-- :help cursor()</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">setline</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0550ae">1</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #24292f;background-color: #f6f8fa">generate_template</span><span style="color: #24292f;background-color: #f6f8fa">())</span>
+</div><div class="codeblock-line"> <span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">fn</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">cursor</span><span style="color: #24292f;background-color: #f6f8fa">(</span><span style="color: #0a3069">'$'</span><span style="color: #24292f;background-color: #f6f8fa">,</span> <span style="color: #0550ae">0</span><span style="color: #24292f;background-color: #f6f8fa">)</span>
+</div><div class="codeblock-line"><span style="color: #cf222e">end</span>
+</div><div class="codeblock-line">
+</div><div class="codeblock-line"><span style="color: #24292f;background-color: #f6f8fa">vim</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">b</span><span style="color: #24292f;background-color: #f6f8fa">.</span><span style="color: #24292f;background-color: #f6f8fa">did_ftplugin_php_after</span> <span style="color: #0550ae">=</span> <span style="color: #0550ae">true</span></div></code></pre>
</div>
</section>
<section id="section--outro">