diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-04-09 22:24:50 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-04-09 22:24:50 +0900 |
| commit | d1b4bc44170196a4dcef5254d092fc387e73792e (patch) | |
| tree | a6bbe0e61b73c99a815d730ae7956a5124200066 /vhosts/blog/public/posts/2021-10-02 | |
| parent | bba1212ab46ed85c2ed3b646f2362bdbb1f45b63 (diff) | |
| parent | 4f46d262e6967c9c638b40f3b0246d21b7a9b9dc (diff) | |
| download | nsfisis.dev-d1b4bc44170196a4dcef5254d092fc387e73792e.tar.gz nsfisis.dev-d1b4bc44170196a4dcef5254d092fc387e73792e.tar.zst nsfisis.dev-d1b4bc44170196a4dcef5254d092fc387e73792e.zip | |
Merge branch 'nuldoc-djot'
Diffstat (limited to 'vhosts/blog/public/posts/2021-10-02')
7 files changed, 227 insertions, 427 deletions
diff --git a/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html b/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html index d99fc02c..fee0e109 100644 --- a/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html +++ b/vhosts/blog/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html @@ -65,14 +65,14 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/94090937bcf860cfa93b" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/94090937bcf860cfa93b</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/94090937bcf860cfa93b" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/94090937bcf860cfa93b</a> + </p> </div> </div> - <p> - タイトル落ち。まずはこのコードを見て欲しい。 + タイトル落ち。まずはこのコードを見て欲しい。 </p> - <div class="codeblock" language="cpp"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">#include</span><span style="color:#032F62"> <iostream></span></span> <span class="line"></span> @@ -94,109 +94,96 @@ <span class="line"><span style="color:#6F42C1"> std</span><span style="color:#24292E">::cout </span><span style="color:#D73A49"><<</span><span style="color:#032F62"> "Hello, World!"</span><span style="color:#D73A49"> <<</span><span style="color:#6F42C1"> std</span><span style="color:#24292E">::endl;</span></span> <span class="line"><span style="color:#24292E">}</span></span></code></pre> </div> - - <blockquote> - <p> - コンパイラのバージョン $ clang++ –version Apple clang version 11.0.0 (clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin - </p> - - <p> - コンパイルコマンド (C17指定) $ clang –std=c++17 hoge.cpp - </p> - </blockquote> - <p> - この記事から得られるものはこれ以上ないので以下は蛇足になる。 + コンパイラのバージョン + </p> + <div class="codeblock"> + <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ clang++ –version Apple clang version 11.0.0</span></span> +<span class="line"><span>(clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model:</span></span> +<span class="line"><span>posix InstalledDir:</span></span> +<span class="line"><span>/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin</span></span></code></pre> + </div> + <p> + コンパイルコマンド (C17指定) + </p> + <div class="codeblock"> + <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ clang –std=c++17 hoge.cpp</span></span></code></pre> + </div> + <p> + この記事から得られるものはこれ以上ないので以下は蛇足になる。 </p> - <p> - 別件で cppreference.com の <a href="https://en.cppreference.com/w/cpp/language/identifiers" rel="noreferrer" target="_blank">identifier のページ</a> を読んでいた時、次の文が目に止まった。 + 別件で <a href="https://en.cppreference.com/w/cpp/language/identifiers" rel="noreferrer" target="_blank">cppreference.com の identifier のページ</a>を読んでいた時、次の文が目に止まった。 </p> - <blockquote> <ul> <li> - the identifiers that are keywords cannot be used for other purposes; + <p> + the identifiers that are keywords cannot be used for other purposes; + </p> <ul> <li> - The only place they can be used as non-keywords is in an attribute-token. (e.g. [[private]] is a valid attribute) (since C++11) + The only place they can be used as non-keywords is in an attribute-token. (e.g. [[private]] is a valid attribute) (since C++11) </li> </ul> </li> </ul> </blockquote> - <p> - キーワードでも属性として指定する場合は非キーワードとして使えるらしい。実際にやってみる。 + キーワードでも属性として指定する場合は非キーワードとして使えるらしい。 実際にやってみる。 </p> - <p> - 同サイトの <a href="https://en.cppreference.com/w/cpp/keyword" rel="noreferrer" target="_blank">keywords のページ</a> から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇' ignored) がコンパイラから出力されるが、コンパイルできる。 + 同サイトの <a href="https://en.cppreference.com/w/cpp/keyword" rel="noreferrer" target="_blank">keywords のページ</a> から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇’ ignored) がコンパイラから出力されるが、コンパイルできる。 </p> - <p> - 上のコードでは <code>[[using]]</code> をコメントアウトしているが、これは <code>using</code> キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。 + 上のコードでは <code>[[using]]</code> をコメントアウトしているが、これは <code>using</code> キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。 </p> - <div class="codeblock" language="cpp"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">// using の例</span></span> <span class="line"><span style="color:#005CC5">[[</span><span style="color:#D73A49">using</span><span style="color:#6F42C1"> foo</span><span style="color:#005CC5">: </span><span style="color:#6F42C1">attr1</span><span style="color:#005CC5">, </span><span style="color:#6F42C1">attr2</span><span style="color:#005CC5">]]</span><span style="color:#D73A49"> int</span><span style="color:#24292E"> x;</span><span style="color:#6A737D"> // [[foo::attr1, foo::attr2]] の糖衣構文</span></span></code></pre> </div> - <p> - C++17 の仕様も見てみる (正確には標準化前のドラフト)。 + C++17 の仕様も見てみる (正確には標準化前のドラフト)。 </p> - <p> - 引用元: <a href="https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4" rel="noreferrer" target="_blank">https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4</a> + 引用元: <a href="https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4" rel="noreferrer" target="_blank">https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4</a> </p> - <blockquote> <p> - If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier. + If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier. </p> </blockquote> - <p> - 「<code>identifier</code> の構文上の要件を満たすキーワードまたは代替トークンが <code>attribute-token</code> に含まれている場合、<code>identifier</code> とみなされる」とある。どうやら間違いないようだ。 + 「<code>identifier</code> の構文上の要件を満たすキーワードまたは代替トークンが <code>attribute-token</code> に含まれている場合、<code>identifier</code> とみなされる」とある。どうやら間違いないようだ。 </p> - <p> - ところで、代替トークン (alternative token) とは <code>and</code> (<code>&</code>) や <code>bitor</code> (<code>|</code>) などのことだが、<code>identifier</code> の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考: <a href="https://timsong-cpp.github.io/cppwp/n4659/lex.digraph" rel="noreferrer" target="_blank">同ドラフト</a>) + ところで、代替トークン (alternative token) とは <code>and</code> (<code>&</code>) や <code>bitor</code> (<code>|</code>) などのことだが、<code>identifier</code> の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考: <a href="https://timsong-cpp.github.io/cppwp/n4659/lex.digraph" rel="noreferrer" target="_blank">同ドラフト</a> ) </p> - <ul> <li> <code><%</code> → <code>{</code> </li> - <li> <code>%></code> → <code>}</code> </li> - <li> <code><:</code> → <code>[</code> </li> - <li> <code>:></code> → <code>]</code> </li> - <li> <code>%:</code> → <code>#</code> </li> - <li> <code>%:%:</code> → <code>##</code> </li> </ul> - <p> - 「<code>identifier</code> の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。 + 「<code>identifier</code> の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。 </p> - <p> - 調べた感想: 字句解析器か構文解析器が辛そう + 調べた感想: 字句解析器か構文解析器が辛そう </p> </div> </article> diff --git a/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html b/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html index f3a11356..d3db5da6 100644 --- a/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html +++ b/vhosts/blog/public/posts/2021-10-02/python-unbound-local-error/index.html @@ -65,18 +65,17 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/5d733703afcb35bbf399" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/5d733703afcb35bbf399</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/5d733703afcb35bbf399" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/5d733703afcb35bbf399</a> + </p> </div> </div> - <p> - 本記事は Python 3.7.6 の動作結果を元にして書かれている。 + 本記事は Python 3.7.6 の動作結果を元にして書かれている。 </p> - <p> - Python でクロージャを作ろうと、次のようなコードを書いた。 + Python でクロージャを作ろうと、次のようなコードを書いた。 </p> - <div class="codeblock" language="python"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span> <span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span></span> @@ -86,21 +85,17 @@ <span class="line"></span> <span class="line"><span style="color:#24292E">f()</span></span></code></pre> </div> - <p> - 関数 <code>g</code> から 関数 <code>f</code> のスコープ内で定義された変数 <code>x</code> を参照し、それに 1 を足そうとしている。 これを実行すると <code>x += 1</code> の箇所でエラーが発生する。 + 関数 <code>g</code> から 関数 <code>f</code> のスコープ内で定義された変数 <code>x</code> を参照し、それに 1 を足そうとしている。 これを実行すると <code>x += 1</code> の箇所でエラーが発生する。 </p> - <blockquote> <p> - UnboundLocalError: local variable `x' referenced before assignment + UnboundLocalError: local variable `x’ referenced before assignment </p> </blockquote> - <p> - local変数 <code>x</code> が代入前に参照された、とある。これは、<code>f</code> の <code>x</code> を参照するのではなく、新しく別の変数を <code>g</code> 内に作ってしまっているため。前述のコードを宣言と代入を便宜上分けて書き直すと次のようになる。<code>var</code> を変数宣言のための構文として擬似的に利用している。 + local変数 <code>x</code> が代入前に参照された、とある。これは、<code>f</code> の <code>x</code> を参照するのではなく、新しく別の変数を <code>g</code> 内に作ってしまっているため。 前述のコードを宣言と代入を便宜上分けて書き直すと次のようになる。<code>var</code> を変数宣言のための構文として擬似的に利用している。 </p> - <div class="codeblock" language="python"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># 注: var は正しい Python の文法ではない。上記参照のこと</span></span> <span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span> @@ -113,11 +108,9 @@ <span class="line"><span style="color:#6A737D"> # 加算する前の値を参照しようとするが、まだ代入されていないためエラー</span></span> <span class="line"><span style="color:#24292E"> g()</span></span></code></pre> </div> - <p> - 当初の意図を表現するには、次のように書けばよい。 + 当初の意図を表現するには、次のように書けばよい。 </p> - <div class="codeblock" language="python"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">def</span><span style="color:#6F42C1"> f</span><span style="color:#24292E">():</span></span> <span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span></span> @@ -126,7 +119,6 @@ <span class="line"><span style="color:#24292E"> x </span><span style="color:#D73A49">+=</span><span style="color:#005CC5"> 1</span></span> <span class="line"><span style="color:#24292E"> g()</span></span></code></pre> </div> - <p> <code>(*)</code> のように、<code>nonlocal</code> を追加する。これにより一つ外側のスコープ (<code>g</code> の一つ外側 = <code>f</code>) で定義されている <code>x</code> を探しに行くようになる。 </p> diff --git a/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html b/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html index cf2eb729..d022bf8d 100644 --- a/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html +++ b/vhosts/blog/public/posts/2021-10-02/ruby-detect-running-implementation/index.html @@ -62,26 +62,23 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/74d7ffeeebc51b20d791</a> + </p> </div> </div> - <p> - Ruby という言語には複数の実装があるが、それらをスクリプト上からどのようにして programmatically に見分ければよいだろうか。 + Ruby という言語には複数の実装があるが、それらをスクリプト上からどのようにして programmatically に見分ければよいだろうか。 </p> - <p> <code>Object</code> クラスに定義されている <code>RUBY_ENGINE</code> という定数がこの用途に使える。 </p> - <p> - 参考: <a href="https://docs.ruby-lang.org/ja/latest/method/Object/c/RUBY_ENGINE.html" rel="noreferrer" target="_blank">Object::RUBY_ENGINE</a> + 参考: <a href="https://docs.ruby-lang.org/ja/latest/method/Object/c/RUBY_ENGINE.html" rel="noreferrer" target="_blank">Object::RUBY_ENGINE</a> </p> - <p> - 上記ページの例から引用する: + 上記ページの例から引用する: </p> - <div class="codeblock" language="shell-session"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ ruby-1.9.1 -ve 'p RUBY_ENGINE'</span></span> <span class="line"><span>ruby 1.9.1p0 (2009-03-04 revision 22762) [x86_64-linux]</span></span> @@ -90,129 +87,39 @@ <span class="line"><span>jruby 1.2.0 (ruby 1.8.6 patchlevel 287) (2009-03-16 rev 9419) [i386-java]</span></span> <span class="line"><span>"jruby"</span></span></code></pre> </div> - <p> - それぞれの処理系がどのような値を返すかだが、stack overflow に良い質問と回答があった。 + それぞれの処理系がどのような値を返すかだが、stack overflow に良い質問と回答があった。 </p> - <p> - <a href="https://stackoverflow.com/a/9894232" rel="noreferrer" target="_blank">What values for RUBY_ENGINE correspond to which Ruby implementations?</a> より引用: + <a href="https://stackoverflow.com/a/9894232" rel="noreferrer" target="_blank">What values for RUBY_ENGINE correspond to which Ruby implementations?</a> より引用: </p> - <blockquote> - <table> - <thead> - <tr> - <td> - RUBY_ENGINE - </td> - - <td> - Implementation - </td> - </tr> - </thead> - - <tbody> - <tr> - <td> - <undefined> - </td> - - <td> - MRI < 1.9 - </td> - </tr> - - <tr> - <td> - `ruby' - </td> - - <td> - MRI >= 1.9 or REE - </td> - </tr> - - <tr> - <td> - `jruby' - </td> - - <td> - JRuby - </td> - </tr> - - <tr> - <td> - `macruby' - </td> - - <td> - MacRuby - </td> - </tr> - - <tr> - <td> - `rbx' - </td> - - <td> - Rubinius - </td> - </tr> - - <tr> - <td> - `maglev' - </td> - - <td> - MagLev - </td> - </tr> - - <tr> - <td> - `ironruby' - </td> - - <td> - IronRuby - </td> - </tr> - - <tr> - <td> - `cardinal' - </td> - - <td> - Cardinal - </td> - </tr> - </tbody> - </table> + <div class="codeblock"> + <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>| RUBY_ENGINE | Implementation |</span></span> +<span class="line"><span>|:-----------:|:------------------|</span></span> +<span class="line"><span>| <undefined> | MRI < 1.9 |</span></span> +<span class="line"><span>| 'ruby' | MRI >= 1.9 or REE |</span></span> +<span class="line"><span>| 'jruby' | JRuby |</span></span> +<span class="line"><span>| 'macruby' | MacRuby |</span></span> +<span class="line"><span>| 'rbx' | Rubinius |</span></span> +<span class="line"><span>| 'maglev' | MagLev |</span></span> +<span class="line"><span>| 'ironruby' | IronRuby |</span></span> +<span class="line"><span>| 'cardinal' | Cardinal |</span></span></code></pre> + </div> </blockquote> - <p> - なお、この質問・回答は 2014年になされたものであり、値は変わっている可能性がある。MRI (aka CRuby) については執筆時現在 (2020/12/8) も <code>'ruby'</code> が返ってくることを確認済み。 + なお、この質問・回答は 2014年になされたものであり、値は変わっている可能性がある。MRI (aka CRuby) については執筆時現在 (2020/12/8) も <code>'ruby'</code> が返ってくることを確認済み。 </p> - <p> - この表にない主要な処理系として、<a href="https://mruby.org" rel="noreferrer" target="_blank">mruby</a> は <code>'mruby'</code> を返す。 + この表にない主要な処理系として、 <a href="https://mruby.org" rel="noreferrer" target="_blank">mruby</a> は <code>'mruby'</code> を返す。 </p> - <p> - <a href="https://github.com/mruby/mruby/blob/ed29d74bfd95362eaeb946fcf7e865d80346b62b/include/mruby/version.h#L32-L35" rel="noreferrer" target="_blank">mruby 該当部分のソース</a> より引用: + <a href="https://github.com/mruby/mruby/blob/ed29d74bfd95362eaeb946fcf7e865d80346b62b/include/mruby/version.h#L32-L35" rel="noreferrer" target="_blank">mruby 該当部分のソース</a> より引用: </p> - <div class="codeblock" language="c"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/*</span></span> -<span class="line"><span style="color:#6A737D">* Ruby engine.</span></span> -<span class="line"><span style="color:#6A737D">*/</span></span> +<span class="line"><span style="color:#6A737D"> * Ruby engine.</span></span> +<span class="line"><span style="color:#6A737D"> */</span></span> <span class="line"><span style="color:#D73A49">#define</span><span style="color:#6F42C1"> MRUBY_RUBY_ENGINE</span><span style="color:#032F62"> "mruby"</span></span></code></pre> </div> </div> diff --git a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html b/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html index 76f7058c..cf80ece0 100644 --- a/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html +++ b/vhosts/blog/public/posts/2021-10-02/ruby-then-keyword-and-case-in/index.html @@ -65,23 +65,22 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/787a8cf888a304497223" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/787a8cf888a304497223</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/787a8cf888a304497223" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/787a8cf888a304497223</a> + </p> </div> </div> - <section id="section--tl-dr"> - <h2><a href="#section--tl-dr">TL; DR</a></h2> + <h2><a href="#section--tl-dr">TL; DR</a></h2> <p> <code>case</code> - <code>in</code> によるパターンマッチング構文でも、<code>case</code> - <code>when</code> と同じように <code>then</code> が使える (場合によっては使う必要がある)。 </p> </section> - <section id="section--what-is-then-keyword"> - <h2><a href="#section--what-is-then-keyword"><code>then</code> とは</a></h2> + <h2><a href="#section--what-is-then-keyword"><code>then</code> とは</a></h2> <p> - 使われることは稀だが、Ruby では <code>then</code> がキーワードになっている。次のように使う: + 使われることは稀だが、Ruby では <code>then</code> がキーワードになっている。次のように使う: </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> cond </span><span style="color:#D73A49">then</span></span> <span class="line"><span style="color:#005CC5"> puts</span><span style="color:#032F62"> "Y"</span></span> @@ -89,11 +88,9 @@ <span class="line"><span style="color:#005CC5"> puts</span><span style="color:#032F62"> "N"</span></span> <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> - <p> - このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code> 構文がそれに当たる。 上記のように、何か条件を書いた後 <code>then</code> を置き、式がそこで終了していることを示すマーカーとして機能する。 + このキーワードが現れうる場所はいくつかあり、<code>if</code>、<code>unless</code>、<code>rescue</code>、<code>case</code> 構文がそれに当たる。 上記のように、何か条件を書いた後 <code>then</code> を置き、式がそこで終了していることを示すマーカーとして機能する。 </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># Example:</span></span> <span class="line"></span> @@ -117,21 +114,17 @@ <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> </section> - <section id="section--why-then-is-usually-unnecessary"> - <h2><a href="#section--why-then-is-usually-unnecessary">なぜ普段は書かなくてもよいのか</a></h2> + <h2><a href="#section--why-then-is-usually-unnecessary">なぜ普段は書かなくてもよいのか</a></h2> <p> - 普通 Ruby のコードで <code>then</code> を書くことはない。なぜか。次のコードを実行してみるとわかる。 + 普通 Ruby のコードで <code>then</code> を書くことはない。なぜか。次のコードを実行してみるとわかる。 </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#005CC5"> true</span><span style="color:#005CC5"> puts</span><span style="color:#032F62"> 'Hello, World!'</span><span style="color:#D73A49"> end</span></span></code></pre> </div> - <p> - 次のような構文エラーが出力される。 + 次のような構文エラーが出力される。 </p> - <div class="codeblock"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>20:1: syntax error, unexpected local variable or method, expecting `then' or ';' or '\n'</span></span> <span class="line"><span>if true puts 'Hello, World!' end</span></span> @@ -139,72 +132,58 @@ <span class="line"><span>20:1: syntax error, unexpected `end', expecting end-of-input</span></span> <span class="line"><span>...f true puts 'Hello, World!' end</span></span></code></pre> </div> - <p> - 二つ目のメッセージは無視して一つ目を読むと、<code>then</code> か <code>;</code> か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。 + 二つ目のメッセージは無視して一つ目を読むと、<code>then</code> か <code>;</code> か改行が来るはずのところ変数だかメソッドだかが現れたことによりエラーとなっているようだ。 </p> - <p> - ポイントは改行が <code>then</code> (や <code>;</code>) の代わりとなることである。<code>true</code> の後に改行を入れてみる。 + ポイントは改行が <code>then</code> (や <code>;</code>) の代わりとなることである。<code>true</code> の後に改行を入れてみる。 </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#005CC5"> true</span></span> <span class="line"><span style="color:#005CC5">puts</span><span style="color:#032F62"> 'Hello, World!'</span><span style="color:#D73A49"> end</span></span></code></pre> </div> - <p> - 無事 Hello, World! と出力されるようになった。 + 無事 Hello, World! と出力されるようになった。 </p> </section> - <section id="section--why-then-or-linebreak-is-needed"> - <h2><a href="#section--why-then-or-linebreak-is-needed">なぜ <code>then</code> や <code>;</code> や改行が必要か</a></h2> + <h2><a href="#section--why-then-or-linebreak-is-needed">なぜ <code>then</code> や <code>;</code> や改行が必要か</a></h2> <p> - なぜ <code>then</code> や <code>;</code> や改行 (以下 「<code>then</code> 等」) が必要なのだろうか。次の例を見てほしい: + なぜ <code>then</code> や <code>;</code> や改行 (以下 「<code>then</code> 等」) が必要なのだろうか。次の例を見てほしい: </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> a b </span><span style="color:#D73A49">end</span></span></code></pre> </div> - <p> - <code>then</code> も <code>;</code> も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。この例は二通りに解釈できる。 + <code>then</code> も <code>;</code> も改行もないのでエラーになるが、これは条件式がどこまで続いているのかわからないためだ。 この例は二通りに解釈できる。 </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># a という変数かメソッドの評価結果が truthy なら b という変数かメソッドを評価</span></span> <span class="line"><span style="color:#D73A49">if</span><span style="color:#24292E"> a </span><span style="color:#D73A49">then</span></span> <span class="line"><span style="color:#24292E">b</span></span> <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D"># a というメソッドに b という変数かメソッドの評価結果を渡して呼び出し、</span></span> <span class="line"><span style="color:#6A737D"># その結果が truthy なら何もしない</span></span> <span class="line"><span style="color:#D73A49">if</span><span style="color:#6F42C1"> a</span><span style="color:#24292E">(b) </span><span style="color:#D73A49">then</span></span> <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> - <p> <code>then</code> 等はこの曖昧性を排除するためにあり、条件式は <code>if</code> から <code>then</code> 等までの間にある、ということを明確にする。 C系の <code>if</code> 後に来る <code>(</code>/<code>)</code> や、Python の <code>:</code>、Rust/Go/Swift などの <code>{</code> も同じ役割を持つ。 </p> - <p> - Ruby の場合、プログラマーが書きやすいよう改行でもって <code>then</code> が代用できるので、ほとんどの場合 <code>then</code> は必要ない。 + Ruby の場合、プログラマーが書きやすいよう改行でもって <code>then</code> が代用できるので、ほとんどの場合 <code>then</code> は必要ない。 </p> </section> - <section id="section--then-in-case-in"> - <h2><a href="#section--then-in-case-in"><code>case</code> - <code>in</code> における <code>then</code></a></h2> + <h2><a href="#section--then-in-case-in"><code>case</code> - <code>in</code> における <code>then</code></a></h2> <p> - ようやく本題にたどり着いた。来る Ruby 3.0 では <code>case</code> と <code>in</code> キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして <code>then</code> 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。 + ようやく本題にたどり着いた。来る Ruby 3.0 では <code>case</code> と <code>in</code> キーワードを使ったパターンマッチングの構文が入る予定である。この構文でもパターン部との区切りとして <code>then</code> 等が必要になる。 (現在の) Ruby には formal な形式での文法仕様は存在しないので、yacc の定義ファイルを参照した (yacc の説明は省略)。 </p> - <p> - <a href="https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986" rel="noreferrer" target="_blank">https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986</a> + <a href="https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986" rel="noreferrer" target="_blank">https://github.com/ruby/ruby/blob/221ca0f8281d39f0dfdfe13b2448875384bbf735/parse.y#L3961-L3986</a> </p> - <div class="codeblock" language="yacc"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>p_case_body : keyword_in</span></span> <span class="line"><span>{</span></span> @@ -233,24 +212,19 @@ <span class="line"><span>}</span></span> <span class="line"><span>;</span></span></code></pre> </div> - <p> - 簡略版: + 簡略版: </p> - <div class="codeblock" language="yacc"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>p_case_body : keyword_in p_top_expr then compstmt p_cases</span></span> <span class="line"><span>;</span></span></code></pre> </div> - <p> - ここで、<code>keyword_in</code> は文字通り <code>in</code>、<code>p_top_expr</code> はいわゆるパターン、<code>then</code> は <code>then</code> キーワードのことではなく、この記事で <code>then</code> 等と呼んでいるもの、つまり <code>then</code> キーワード、<code>;</code>、改行のいずれかである。 + ここで、<code>keyword_in</code> は文字通り <code>in</code>、<code>p_top_expr</code> はいわゆるパターン、<code>then</code> は <code>then</code> キーワードのことではなく、この記事で <code>then</code> 等と呼んでいるもの、つまり <code>then</code> キーワード、<code>;</code>、改行のいずれかである。 </p> - <p> - これにより、<code>case</code> - <code>when</code> による従来の構文と同じように、<code>then</code> 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる: + これにより、<code>case</code> - <code>when</code> による従来の構文と同じように、<code>then</code> 等をパターンの後ろに挿入すればよいことがわかった。つまり次の3通りのいずれかになる: </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span> <span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 1</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> a</span></span> @@ -273,11 +247,9 @@ <span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 3</span><span style="color:#24292E">; c</span></span> <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> - <p> - ところで、<code>p_top_expr</code> には <code>if</code> による guard clause が書けるので、その場合は <code>if</code> - <code>then</code> と似たような見た目になる。 + ところで、<code>p_top_expr</code> には <code>if</code> による guard clause が書けるので、その場合は <code>if</code> - <code>then</code> と似たような見た目になる。 </p> - <div class="codeblock" language="ruby"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">case</span><span style="color:#24292E"> x</span></span> <span class="line"><span style="color:#D73A49">in</span><span style="color:#005CC5"> 0</span><span style="color:#D73A49"> then</span><span style="color:#24292E"> a</span></span> @@ -286,23 +258,22 @@ <span class="line"><span style="color:#D73A49">end</span></span></code></pre> </div> </section> - <section id="section--outro"> - <h2><a href="#section--outro">まとめ</a></h2> + <h2><a href="#section--outro">まとめ</a></h2> <ul> <li> - <code>if</code> や <code>case</code> の条件の後ろには <code>then</code>、<code>;</code>、改行のいずれかが必要 + <p> + <code>if</code> や <code>case</code> の条件の後ろには <code>then</code>、<code>;</code>、改行のいずれかが必要 + </p> <ul> <li> 通常は改行しておけばよい </li> </ul> </li> - <li> 3.0 で入る予定の <code>case</code> - <code>in</code> でも <code>then</code> 等が必要になる </li> - <li> Ruby の構文を正確に知るには (現状) <code>parse.y</code> を直接読めばよい </li> diff --git a/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html b/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html index 4ae7f235..052f674a 100644 --- a/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html +++ b/vhosts/blog/public/posts/2021-10-02/rust-where-are-primitive-types-from/index.html @@ -62,16 +62,16 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/9a429432258bbcd6c565" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/9a429432258bbcd6c565</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/9a429432258bbcd6c565" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/9a429432258bbcd6c565</a> + </p> </div> </div> - <section id="section--intro"> - <h2><a href="#section--intro">前置き</a></h2> + <h2><a href="#section--intro">前置き</a></h2> <p> - Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。 + Rust において、プリミティブ型の名前は予約語でない。したがって、次のコードは合法である。 </p> - <div class="codeblock" language="rust"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">#![allow(non_camel_case_types)]</span></span> <span class="line"><span style="color:#24292E">#![allow(dead_code)]</span></span> @@ -94,40 +94,30 @@ <span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> f64</span><span style="color:#24292E">;</span></span> <span class="line"><span style="color:#D73A49">struct</span><span style="color:#6F42C1"> str</span><span style="color:#24292E">;</span></span></code></pre> </div> - <p> - では、普段単に <code>bool</code> と書いたとき、この <code>bool</code> は一体どこから来ているのか。rustc のソースを追ってみた。 + では、普段単に <code>bool</code> と書いたとき、この <code>bool</code> は一体どこから来ているのか。rustc のソースを追ってみた。 + </p> + <p> + 前提知識: 一般的なコンパイラの構造、用語。<code>rustc</code> そのものの知識は不要 (というよりも筆者自身がよく知らない) </p> - - <blockquote> - <p> - 前提知識: 一般的なコンパイラの構造、用語。<code>rustc</code> そのものの知識は不要 (というよりも筆者自身がよく知らない) - </p> - </blockquote> </section> - <section id="section--code-reading"> - <h2><a href="#section--code-reading">調査</a></h2> + <h2><a href="#section--code-reading">調査</a></h2> <p> - 調査に使用したソース (調査時点での最新 master) + 調査に使用したソース (調査時点での最新 master) </p> - <p> - <a href="https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98" rel="noreferrer" target="_blank">https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98</a> + <a href="https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98" rel="noreferrer" target="_blank">https://github.com/rust-lang/rust/tree/511ed9f2356af365ad8affe046b3dd33f7ac3c98</a> </p> - <p> - どのようにして調べるか。rustc の構造には詳しくないため、すぐに当たりをつけるのは難しい。 + どのようにして調べるか。rustc の構造には詳しくないため、すぐに当たりをつけるのは難しい。 </p> - <p> - 大雑把な構造としては、<code>compiler</code> フォルダ以下に <code>rustc_*</code> という名前のクレートが数十個入っている。これがどうやら <code>rustc</code> コマンドの実装部のようだ。 + 大雑把な構造としては、<code>compiler</code> フォルダ以下に <code>rustc_*</code> という名前のクレートが数十個入っている。これがどうやら <code>rustc</code> コマンドの実装部のようだ。 </p> - <p> - <code>rustc</code> はセルフホストされている (= <code>rustc</code> 自身が Rust で書かれている) ので、<code>bool</code> や <code>char</code> などで適当に検索をかけてもノイズが多すぎて話にならない。しかし、お誂え向きなことに <code>i128</code>/<code>u128</code> というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って <code>git grep</code> してみる。 + <code>rustc</code> はセルフホストされている (= <code>rustc</code> 自身が Rust で書かれている) ので、<code>bool</code> や <code>char</code> などで適当に検索をかけてもノイズが多すぎて話にならない。 しかし、お誂え向きなことに <code>i128</code>/<code>u128</code> というコンパイラ自身が使うことがなさそうな型が存在するのでこれを使って <code>git grep</code> してみる。 </p> - <div class="codeblock"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ git grep "\bi128\b" | wc # i128</span></span> <span class="line"><span>165 1069 15790</span></span> @@ -138,22 +128,18 @@ <span class="line"><span>$ git grep "\bbool\b" | wc # cf. bool の結果</span></span> <span class="line"><span>3563 23577 294659</span></span></code></pre> </div> - <p> - 165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。 + 165 程度であれば探すことができそうだ。今回は、クレート名を見ておおよその当たりをつけた。 </p> - <div class="codeblock"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ git grep "\bi128\b"</span></span> <span class="line"><span>...</span></span> <span class="line"><span>rustc_resolve/src/lib.rs: table.insert(sym::i128, Int(IntTy::I128));</span></span> <span class="line"><span>...</span></span></code></pre> </div> - <p> <code>rustc_resolve</code> というのはいかにも名前解決を担いそうなクレート名である。該当箇所を見てみる。 </p> - <div class="codeblock" language="rust"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/// Interns the names of the primitive types.</span></span> <span class="line"><span style="color:#6A737D">///</span></span> @@ -188,21 +174,17 @@ <span class="line"><span style="color:#24292E"> }</span></span> <span class="line"><span style="color:#24292E">}</span></span></code></pre> </div> - <p> - これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、 + これは初めに列挙したプリミティブ型の一覧と一致している。doc comment にも、 </p> - - <blockquote> - <p> - All other types are defined somewhere and possibly imported, but the primitive ones need special handling, since they have no place of origin. - </p> - </blockquote> - + <div class="codeblock"> + <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>All other types are defined somewhere and possibly imported, but the</span></span> +<span class="line"><span>primitive ones need special handling, since they have no place of</span></span> +<span class="line"><span>origin.</span></span></code></pre> + </div> <p> - とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。 + とある。次はこの struct の使用箇所を追う。追うと言っても使われている箇所は次の一箇所しかない。なお説明に不要な箇所は大きく削っている。 </p> - <div class="codeblock" language="rust"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">/// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.</span></span> <span class="line"><span style="color:#6A737D">/// (略)</span></span> @@ -226,23 +208,18 @@ <span class="line"><span style="color:#6F42C1"> None</span></span> <span class="line"><span style="color:#24292E">}</span></span></code></pre> </div> - <p> - 関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。<code>if ns == TypeNS</code> のブロック内では、<code>primitive_type_table</code> (上記の <code>PrimitiveTypeTable::new()</code> で作られた変数) に含まれている識別子 (<code>bool</code>、<code>i32</code> など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。 + 関数名や doc comment が示している通り、この関数は識別子 (identifier, ident) を現在のレキシカルスコープ内で解決 (resolve) する。 <code>if ns == TypeNS</code> のブロック内では、<code>primitive_type_table</code> (上記の <code>PrimitiveTypeTable::new()</code> で作られた変数) に含まれている識別子 (<code>bool</code>、<code>i32</code> など) かどうか判定し、そうであればそれに紐づけられたプリミティブ型を返している。 </p> - <p> - なお、<code>ns</code> は「名前空間」を示す変数である。Rust における名前空間はC言語におけるそれとほとんど同じで、今探している名前が関数名/変数名なのか型なのかマクロなのかを区別している。この <code>if</code> は、プリミティブ型に解決されるのは型を探しているときだけだ、と言っている。 + なお、<code>ns</code> は「名前空間」を示す変数である。Rust における名前空間はC言語におけるそれとほとんど同じで、今探している名前が関数名/変数名なのか型なのかマクロなのかを区別している。この <code>if</code> は、プリミティブ型に解決されるのは型を探しているときだけだ、と言っている。 </p> - <p> - 重要なのは、これが <code>resolve_ident_in_lexical_scope()</code> の最後に書かれている点である。つまり、最初に挙げたプリミティブ型の識別子は、「名前解決の最終段階で」、「他に同名の型が見つかっていなければ」プリミティブ型として解決される。 + 重要なのは、これが <code>resolve_ident_in_lexical_scope()</code> の最後に書かれている点である。つまり、最初に挙げたプリミティブ型の識別子は、「名前解決の最終段階で」、「他に同名の型が見つかっていなければ」プリミティブ型として解決される。 </p> - <p> - 動作がわかったところで、例として次のコードを考える。 + 動作がわかったところで、例として次のコードを考える。 </p> - <div class="codeblock" language="rust"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">#![allow(non_camel_case_types)]</span></span> <span class="line"></span> @@ -252,16 +229,14 @@ <span class="line"><span style="color:#D73A49"> let</span><span style="color:#24292E"> _</span><span style="color:#D73A49">:</span><span style="color:#6F42C1"> bool</span><span style="color:#D73A49"> =</span><span style="color:#6F42C1"> bool</span><span style="color:#24292E">;</span></span> <span class="line"><span style="color:#24292E">}</span></span></code></pre> </div> - <p> - ここで <code>main()</code> の <code>bool</code> は <code>struct bool</code> として解決される。なぜなら、プリミティブ型の判定をする前に <code>bool</code> という名前の別の型が見つかるからだ。 + ここで <code>main()</code> の <code>bool</code> は <code>struct bool</code> として解決される。なぜなら、プリミティブ型の判定をする前に <code>bool</code> という名前の別の型が見つかるからだ。 </p> </section> - <section id="section--outro"> - <h2><a href="#section--outro">まとめ</a></h2> + <h2><a href="#section--outro">まとめ</a></h2> <p> - Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。 + Rust のプリミティブ型は予約語ではない。名前解決の最終段階で特別扱いされ、他に同名の型が見つかっていなければ対応するプリミティブ型に解決される。 </p> </section> </div> diff --git a/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html b/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html index ddf70cae..fa0553d5 100644 --- a/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html +++ b/vhosts/blog/public/posts/2021-10-02/vim-difference-between-autocmd-bufwrite-and-bufwritepre/index.html @@ -62,103 +62,92 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/79ab4db8564032de0b25" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/79ab4db8564032de0b25</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/79ab4db8564032de0b25" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/79ab4db8564032de0b25</a> + </p> </div> </div> - <section id="section--tl-dr"> - <h2><a href="#section--tl-dr">TL; DR</a></h2> + <h2><a href="#section--tl-dr">TL; DR</a></h2> <p> - 違いはない。ただのエイリアス。 + 違いはない。ただのエイリアス。 </p> </section> - <section id="section--code-reading"> - <h2><a href="#section--code-reading">調査記録</a></h2> + <h2><a href="#section--code-reading">調査記録</a></h2> <p> - Vim の autocmd events には似通った名前のものがいくつかある。大抵は <code>:help</code> に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。 + Vim の autocmd events には似通った名前のものがいくつかある。大抵は <code>:help</code> に説明があるが、この記事のタイトルにある2つを含めた以下のイベントには、その違いについて説明がない。 </p> - <ul> <li> <code>BufRead</code>/<code>BufReadPost</code> </li> - <li> <code>BufWrite</code>/<code>BufWritePre</code> </li> - <li> <code>BufAdd</code>/<code>BufCreate</code> </li> </ul> - <p> - このうち、<code>BufAdd</code>/<code>BufCreate</code> に関しては、<code>:help BufCreate</code> に + このうち、<code>BufAdd</code>/<code>BufCreate</code> に関しては、<code>:help BufCreate</code> に </p> - <blockquote> <p> - The BufCreate event is for historic reasons. + The BufCreate event is for historic reasons. </p> </blockquote> - <p> - とあり、おそらくは <code>BufAdd</code> のエイリアスであろうということがわかる。他の2組も同様ではないかと予想されるが、確認のため vim と neovim のソースコードを調査した。 + とあり、おそらくは <code>BufAdd</code> のエイリアスであろうということがわかる。他の2組も同様ではないかと予想されるが、確認のため vim と neovim のソースコードを調査した。 </p> - - <blockquote> - <p> - ソースコードへのリンク <a href="https://github.com/vim/vim/tree/8e6be34338f13a6a625f19bcef82019c9adc65f2" rel="noreferrer" target="_blank">vim (調査時点での master branch)</a> <a href="https://github.com/neovim/neovim/tree/71d4f5851f068eeb432af34850dddda8cc1c71e3" rel="noreferrer" target="_blank">neovim (上に同じ)</a> - </p> - </blockquote> - + <p> + ソースコードへのリンク + </p> + <ul> + <li> + <a href="https://github.com/vim/vim/tree/8e6be34338f13a6a625f19bcef82019c9adc65f2" rel="noreferrer" target="_blank">vim (調査時点での master branch)</a> + </li> + <li> + <a href="https://github.com/neovim/neovim/tree/71d4f5851f068eeb432af34850dddda8cc1c71e3" rel="noreferrer" target="_blank">neovim (上に同じ)</a> + </li> + </ul> <section id="section--code-reading--vim"> - <h3><a href="#section--code-reading--vim">vim のソースコード</a></h3> + <h3><a href="#section--code-reading--vim">vim のソースコード</a></h3> <p> - 以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。 + 以下は、autocmd events の名前と内部で使われている整数値とのマッピングを定義している箇所である。見ての通り、上でエイリアスではないかと述べた3組には、それぞれ同じ内部値が使われている。 </p> - <p> - <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86</a> + <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L85-L86</a> </p> - <div class="codeblock" language="c"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufAdd"</span><span style="color:#24292E">, EVENT_BUFADD},</span></span> <span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufCreate"</span><span style="color:#24292E">, EVENT_BUFADD},</span></span></code></pre> </div> - <p> - <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97</a> + <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L95-L97</a> </p> - <div class="codeblock" language="c"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufRead"</span><span style="color:#24292E">, EVENT_BUFREADPOST},</span></span> <span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufReadCmd"</span><span style="color:#24292E">, EVENT_BUFREADCMD},</span></span> <span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufReadPost"</span><span style="color:#24292E">, EVENT_BUFREADPOST},</span></span></code></pre> </div> - <p> - <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105</a> + <a href="https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105" rel="noreferrer" target="_blank">https://github.com/vim/vim/blob/8e6be34338f13a6a625f19bcef82019c9adc65f2/src/autocmd.c#L103-L105</a> </p> - <div class="codeblock" language="c"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWrite"</span><span style="color:#24292E">, EVENT_BUFWRITEPRE},</span></span> <span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWritePost"</span><span style="color:#24292E">, EVENT_BUFWRITEPOST},</span></span> <span class="line"><span style="color:#24292E">{</span><span style="color:#032F62">"BufWritePre"</span><span style="color:#24292E">, EVENT_BUFWRITEPRE},</span></span></code></pre> </div> </section> - <section id="section--code-reading--neovim"> - <h3><a href="#section--code-reading--neovim">neovim のソースコード</a></h3> + <h3><a href="#section--code-reading--neovim">neovim のソースコード</a></h3> <p> - neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり <code>aliases</code> と書かれている。 + neovim の場合でも同様のマッピングが定義されているが、こちらの場合は Lua で書かれている。以下にある通り、はっきり <code>aliases</code> と書かれている。 </p> - <p> - <a href="https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124" rel="noreferrer" target="_blank">https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124</a> + <a href="https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124" rel="noreferrer" target="_blank">https://github.com/neovim/neovim/blob/71d4f5851f068eeb432af34850dddda8cc1c71e3/src/nvim/auevents.lua#L119-L124</a> </p> - <div class="codeblock" language="lua"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">aliases </span><span style="color:#D73A49">=</span><span style="color:#24292E"> {</span></span> <span class="line"><span style="color:#24292E"> BufCreate </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'BufAdd'</span><span style="color:#24292E">,</span></span> @@ -167,11 +156,9 @@ <span class="line"><span style="color:#24292E"> FileEncoding </span><span style="color:#D73A49">=</span><span style="color:#032F62"> 'EncodingChanged'</span><span style="color:#24292E">,</span></span> <span class="line"><span style="color:#24292E">},</span></span></code></pre> </div> - <p> - ところで、上では取り上げなかった <code>FileEncoding</code> だが、これは <code>:help FileEncoding</code> にしっかりと書いてある。 + ところで、上では取り上げなかった <code>FileEncoding</code> だが、これは <code>:help FileEncoding</code> にしっかりと書いてある。 </p> - <div class="codeblock"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span> *FileEncoding*</span></span> <span class="line"><span>FileEncoding Obsolete. It still works and is equivalent</span></span> @@ -179,53 +166,55 @@ </div> </section> </section> - <section id="section--outro"> - <h2><a href="#section--outro">まとめ</a></h2> + <h2><a href="#section--outro">まとめ</a></h2> <p> - 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。 + 記事タイトルについて言えば、どちらも変わらないので好きな方を使えばよい。あえて言えば、次のようになるだろう。 </p> - <ul> <li> - <code>BufAdd</code>/<code>BufCreate</code> + <p> + <code>BufAdd</code>/<code>BufCreate</code> + </p> <ul> <li> - → <code>BufCreate</code> は歴史的な理由により ("for historic reasons") 存在しているため、新しい方 (<code>BufAdd</code>) を使う + → <code>BufCreate</code> は歴史的な理由により (“for historic reasons”) 存在しているため、新しい方 (<code>BufAdd</code>) を使う </li> </ul> </li> - <li> - <code>BufRead</code>/<code>BufReadPost</code> + <p> + <code>BufRead</code>/<code>BufReadPost</code> + </p> <ul> <li> → <code>BufReadPre</code> との対称性のため、あるいは <code>BufWritePost</code> との対称性のため <code>BufReadPost</code> を使う </li> </ul> </li> - <li> - <code>BufWrite</code>/<code>BufWritePre</code> + <p> + <code>BufWrite</code>/<code>BufWritePre</code> + </p> <ul> <li> → <code>BufWritePost</code> との対称性のため、あるいは <code>BufReadPre</code> との対称性のため <code>BufWritePre</code> を使う </li> </ul> </li> - <li> - <code>FileEncoding</code>/<code>EncodingChanged</code> + <p> + <code>FileEncoding</code>/<code>EncodingChanged</code> + </p> <ul> <li> - → <code>FileEncoding</code> は <code>`Obsolete'' と明言されているので、`EncodingChanged</code> を使う + → <code>FileEncoding</code> は “Obsolete” と明言されているので、<code>EncodingChanged</code> を使う </li> </ul> </li> </ul> - <p> - ところでこの調査で知ったのだが、<code>BufRead</code> と <code>BufWrite</code> は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら <code>Pre</code>/<code>Post</code> 付きのものを使った方が分かりやすいだろう。 + ところでこの調査で知ったのだが、<code>BufRead</code> と <code>BufWrite</code> は上にある通り発火するタイミングが「後」と「前」で対称性がない。可能なら <code>Pre</code>/<code>Post</code> 付きのものを使った方が分かりやすいだろう。 </p> </section> </div> diff --git a/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html b/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html index afee803f..ec7e5591 100644 --- a/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html +++ b/vhosts/blog/public/posts/2021-10-02/vim-swap-order-of-selected-lines/index.html @@ -62,12 +62,13 @@ NOTE </div> <div class="admonition-content"> - この記事は Qiita から移植してきたものです。元 URL: <a href="https://qiita.com/nsfisis/items/4fefb361d9a693803520" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/4fefb361d9a693803520</a> + <p> + この記事は Qiita から移植してきたものです。 元 URL: <a href="https://qiita.com/nsfisis/items/4fefb361d9a693803520" rel="noreferrer" target="_blank">https://qiita.com/nsfisis/items/4fefb361d9a693803520</a> + </p> </div> </div> - <section id="section--tl-dr"> - <h2><a href="#section--tl-dr">TL; DR</a></h2> + <h2><a href="#section--tl-dr">TL; DR</a></h2> <div class="codeblock" language="vim"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6A737D">" License: Public Domain</span></span> <span class="line"></span> @@ -76,110 +77,96 @@ <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> keeppatterns <line1>,<line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m<line1>-</span><span style="color:#005CC5">1</span></span></code></pre> </div> </section> - <section id="section--version"> - <h2><a href="#section--version">バージョン情報</a></h2> + <h2><a href="#section--version">バージョン情報</a></h2> <p> - <code>:version</code> の一部 + <code>:version</code> の一部 </p> - <blockquote> <p> - VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 26 2020 11:30:30) macOS version Included patches: 1-148 Huge version without GUI. + VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jan 26 2020 11:30:30) macOS version Included patches: 1-148 Huge version without GUI. </p> </blockquote> </section> - <section id="section--existing-solution"> - <h2><a href="#section--existing-solution">よく紹介されている手法</a></h2> + <h2><a href="#section--existing-solution">よく紹介されている手法</a></h2> <section id="section--existing-solution--external-commands"> - <h3><a href="#section--existing-solution--external-commands"><code>tac</code> / <code>tail</code></a></h3> + <h3><a href="#section--existing-solution--external-commands"><code>tac</code> / <code>tail</code></a></h3> <p> <code>tac</code> や <code>tail -r</code> などの外部コマンドを <code>!</code> を使って呼び出し、置き換える。 </p> - <blockquote> <p> - :h v_! + :h v_! </p> </blockquote> - <p> - <code>tac</code> コマンドや <code>tail</code> の <code>-r</code> オプションは環境によって利用できないことがあり、複数の環境を行き来する場合に採用しづらい + <code>tac</code> コマンドや <code>tail</code> の <code>-r</code> オプションは環境によって利用できないことがあり、複数の環境を行き来する場合に採用しづらい </p> </section> - <section id="section--existing-solution--global-command"> - <h3><a href="#section--existing-solution--global-command"><code>:g/^/m0</code></a></h3> + <h3><a href="#section--existing-solution--global-command"><code>:g/^/m0</code></a></h3> <p> - こちらは外部コマンドに頼らず、Vim の機能のみを使う。<code>g</code> は <code>:global</code> コマンドの、<code>m</code> は <code>:move</code> コマンドの略 + こちらは外部コマンドに頼らず、Vim の機能のみを使う。<code>g</code> は <code>:global</code> コマンドの、<code>m</code> は <code>:move</code> コマンドの略 </p> - <p> <code>:global</code> コマンドは <code>:[range]global/{pattern}/[command]</code> のように使い、<code>[range]</code> で指定された範囲の行のうち、<code>{pattern}</code> で指定された検索パターンにマッチする行に対して、順番に <code>[command]</code> で指定された Ex コマンドを呼び出す。 </p> - <blockquote> <p> - :h :global + :h :global </p> </blockquote> - <p> <code>:move</code> コマンドは <code>[range]:move {address}</code> のように使い、<code>[range]</code> で指定された範囲の行を <code>{address}</code> で指定された位置に移動させる。 </p> - <blockquote> <p> - :h :move + :h :move </p> </blockquote> - <p> <code>:g/^/m0</code> のように組み合わせると、「すべての行を1行ずつ 0行目(1行目の上)に動かす」という動きをする。これは確かに行の入れ替えになっている。 </p> - <p> - なお、<code>:g/^/m0</code> は全ての行を入れ替えるが、<code>:N,Mg/^/mN-1</code> とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。 + なお、<code>:g/^/m0</code> は全ての行を入れ替えるが、<code>:N,Mg/^/mN-1</code> とすることで N行目から M行目を処理範囲とするよう拡張できる。手でこれを入力するわけにはいかないので、次のようなコマンドを用意する。 </p> - <div class="codeblock" language="vim"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span> <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span> <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> <line1>,<line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m<line1>-</span><span style="color:#005CC5">1</span></span></code></pre> </div> - <p> - これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。 + これは望みの動作をするが、実際に実行してみると全行がハイライトされてしまう。次節で詳細を述べる。 </p> </section> </section> - <section id="section--problem-of-global-command"> - <h2><a href="#section--problem-of-global-command"><code>:g/^/m0</code> の問題点</a></h2> + <h2><a href="#section--problem-of-global-command"><code>:g/^/m0</code> の問題点</a></h2> <p> <code>:global</code> コマンドは各行に対してマッチングを行う際、現在の検索パターンを上書きしてしまう。<code>^</code> は行の先頭にマッチするため、結果として全ての行がハイライトされてしまう。<code>'hlsearch'</code> オプションを無効にしている場合その限りではないが、その場合でも直前の検索パターンが失われてしまうと <code>n</code> コマンドなどの際に不便である。 </p> - <blockquote> <p> - :h @/ + :h @/ </p> </blockquote> </section> - <section id="section--solution"> - <h2><a href="#section--solution">解決策</a></h2> - <blockquote> - <p> - [2020/9/28追記] より簡潔な方法を見つけたので次節に追記した - </p> - </blockquote> - + <h2><a href="#section--solution">解決策</a></h2> + <div class="admonition"> + <div class="admonition-label"> + NOTE + </div> + <div class="admonition-content"> + <p> + [2020/9/28追記] より簡潔な方法を見つけたので次節に追記した + </p> + </div> + </div> <p> - 前述した <code>:Reverse</code> コマンドの定義を少し変えて、次のようにする: + 前述した <code>:Reverse</code> コマンドの定義を少し変えて、次のようにする: </p> - <div class="codeblock" language="vim"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">function!</span><span style="color:#6F42C1"> s:reverse_lines</span><span style="color:#24292E">(from, </span><span style="color:#005CC5">to</span><span style="color:#24292E">) </span><span style="color:#D73A49">abort</span></span> <span class="line"><span style="color:#005CC5"> execute</span><span style="color:#6F42C1"> printf</span><span style="color:#24292E">(</span><span style="color:#032F62">"%d,%dg/^/m%d"</span><span style="color:#24292E">, a:from, a:to, a:from</span><span style="color:#D73A49"> - </span><span style="color:#005CC5">1</span><span style="color:#24292E">)</span></span> @@ -189,69 +176,61 @@ <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span> <span class="line"><span style="color:#D73A49"> \</span><span style="color:#D73A49"> call</span><span style="color:#24292E"> <</span><span style="color:#005CC5">SID</span><span style="color:#24292E">></span><span style="color:#6F42C1">reverse_lines</span><span style="color:#24292E">(<line1>, <line2>)</span></span></code></pre> </div> - <p> - 実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。 + 実行しているコマンドが変わったわけではないが、関数呼び出しを経由するようにした。これだけで前述の問題が解決する。 </p> - <p> - この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが <code>^</code> で上書きされることがなくなる。 + この理由は、ユーザー定義関数を実行する際は検索パターンが一度保存され、実行が終了したあと復元されるため。結果として検索パターンが <code>^</code> で上書きされることがなくなる。 </p> - <p> - Vim のヘルプから該当箇所を引用する (強調は筆者による)。 + Vim のヘルプから該当箇所を引用する (強調は筆者による)。 </p> - <blockquote> <p> - :h autocmd-searchpat + :h autocmd-searchpat </p> - <p> - <strong>Autocommands do not change the current search patterns.</strong> Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the `hlsearch' option. + <strong>Autocommands do not change the current search patterns.</strong> Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the ‘hlsearch’ option. </p> </blockquote> - <p> - これは autocommand の実行に関しての記述だが、これと同じことがユーザー定義関数の実行時にも適用される。このことは <code>:nohlsearch</code> のヘルプにある。同じく該当箇所を引用する (強調は筆者による)。 + これは autocommand の実行に関しての記述だが、これと同じことがユーザー定義関数の実行時にも適用される。このことは <code>:nohlsearch</code> のヘルプにある。同じく該当箇所を引用する (強調は筆者による)。 </p> - <blockquote> <p> - :h :nohlsearch + :h :nohlsearch </p> - <p> - (略) This command doesn’t work in an autocommand, because the highlighting state is saved and restored when executing autocommands |autocmd-searchpat|. <strong>Same thing for when invoking a user function.</strong> + (略) This command doesn’t work in an autocommand, because the highlighting state is saved and restored when executing autocommands |autocmd-searchpat|. <strong>Same thing for when invoking a user function.</strong> </p> </blockquote> - <p> - この仕様により、<code>:g/^/m0</code> の呼び出しをユーザー定義関数に切り出すことで上述の問題を解決できる。 + この仕様により、<code>:g/^/m0</code> の呼び出しをユーザー定義関数に切り出すことで上述の問題を解決できる。 </p> </section> - <section id="section--solution-revised"> - <h2><a href="#section--solution-revised">解決策 (改訂版)</a></h2> - <blockquote> - <p> - [2020/9/28追記] より簡潔な方法を見つけたため追記する - </p> - </blockquote> - + <h2><a href="#section--solution-revised">解決策 (改訂版)</a></h2> + <div class="admonition"> + <div class="admonition-label"> + NOTE + </div> + <div class="admonition-content"> + <p> + [2020/9/28追記] より簡潔な方法を見つけたため追記する + </p> + </div> + </div> <div class="codeblock" language="vim"> <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">command!</span><span style="color:#24292E"> -bar -</span><span style="color:#D73A49">range=</span><span style="color:#24292E">%</span></span> <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> Reverse</span></span> <span class="line"><span style="color:#D73A49"> \</span><span style="color:#24292E"> keeppatterns <line1>,<line2>g</span><span style="color:#032F62">/^/</span><span style="color:#24292E">m<line1>-</span><span style="color:#005CC5">1</span></span></code></pre> </div> - <p> - まさにこのための Exコマンド、<code>:keeppatterns</code> が存在する。<code>:keeppatterns {command}</code> のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。 + まさにこのための Exコマンド、<code>:keeppatterns</code> が存在する。<code>:keeppatterns {command}</code> のように使い、読んで字の如く、後ろに続く Exコマンドを「現在の検索パターンを保ったまま」実行する。はるかに分かりやすく意図を表現できる。 </p> - <blockquote> <p> - :h :keeppatterns + :h :keeppatterns </p> </blockquote> </section> |
