LoginSignup
10
1

More than 1 year has passed since last update.

WinMergeにD言語シンタックスハイライト機能を追加しました

Posted at

はじめに

WinMergeのソースコードに手を加え、D言語のシンタックスハイライト機能を追加しました。
WinMergeのビルド方法や追加した機能ついて、書いてみたいと思います。

※v2.16.17以降に組み込まれる予定です。

WinMergeとは

詳細な説明は公式サイトを参照してください。私は普段からソースコードの修正時に愛用しています。

開発環境

WinMergeの実行モジュールであるWinMergeU.exeをビルドする際に必要なアプリケーションと、参考までに、私の開発環境のバージョンを紹介します。
インストーラを含む全体のビルドを行いたい方は、WinMerge GitHubのページを確認してください。

参考:Visual Studio Build Tools 2019 インストール対象
VC19.png

WinMergeのビルド

GitHubから WinMergeのソースコードを取得し、ビルドを行います。
WinMergeの実行モジュールであるWinMergeU.exeD:\Dev\winmerge\Build\x64\Releaseに作成されました。

コマンドプロンプト
D:\Dev> git clone https://github.com/winmerge/winmerge
Cloning into 'winmerge'...
remote: Enumerating objects: 124830, done.
remote: Counting objects: 100% (1119/1119), done.
remote: Compressing objects: 100% (484/484), done.
remote: Total 124830 (delta 729), reused 933 (delta 626), pack-reused 123711
Receiving objects: 100% (124830/124830), 442.15 MiB | 1.21 MiB/s, done.
Resolving deltas: 100% (54763/54763), done.
Updating files: 100% (6731/6731), done.

D:\Dev> cd winmerge

D:\Dev\winmerge> git submodule init
Submodule 'Externals/freeimage' (https://github.com/WinMerge/freeimage.git) registered for path 'Externals/freeimage'
Submodule 'Externals/frhed' (https://github.com/WinMerge/frhed.git) registered for path 'Externals/frhed'
Submodule 'Externals/jq' (https://github.com/stedolan/jq) registered for path 'Externals/jq'
Submodule 'Externals/patch' (https://github.com/WinMerge/patch.git) registered for path 'Externals/patch'
Submodule 'Externals/sevenzip' (https://github.com/WinMerge/sevenzip.git) registered for path 'Externals/sevenzip'
Submodule 'Externals/tidy-html5' (https://github.com/htacg/tidy-html5) registered for path 'Externals/tidy-html5'
Submodule 'Externals/wil' (https://github.com/microsoft/wil) registered for path 'Externals/wil'
Submodule 'Externals/winimerge' (https://github.com/WinMerge/winimerge.git) registered for path 'Externals/winimerge'

D:\Dev\winmerge> git submodule update
Cloning into 'D:/Dev/winmerge/Externals/freeimage'...
Cloning into 'D:/Dev/winmerge/Externals/frhed'...
Cloning into 'D:/Dev/winmerge/Externals/jq'...
Cloning into 'D:/Dev/winmerge/Externals/patch'...
Cloning into 'D:/Dev/winmerge/Externals/sevenzip'...
Cloning into 'D:/Dev/winmerge/Externals/tidy-html5'...
Cloning into 'D:/Dev/winmerge/Externals/wil'...
Cloning into 'D:/Dev/winmerge/Externals/winimerge'...
Submodule path 'Externals/freeimage': checked out '111502a59d938d476ebb5a975ccf0cadd14e1cab'
Submodule path 'Externals/frhed': checked out '50590011df95cac36aa5fd800d3d2653fc16e410'
Submodule path 'Externals/jq': checked out 'e73951f3d1928591b3a9a60de11ae975a21e621f'
Submodule path 'Externals/patch': checked out 'a44c7a2921d52b274ab33900a3f49e6b02a5a95f'
Submodule path 'Externals/sevenzip': checked out 'cff58f15205a4e45343a5ed9214059162039e6c0'
Submodule path 'Externals/tidy-html5': checked out '0016e0083505ccee25a5c76dcf64cfe336765128'
Submodule path 'Externals/wil': checked out '209ff9c7e30e71bf6d1405557bf78544920f8157'
Submodule path 'Externals/winimerge': checked out '7b751b2342e2bb2924df53e13b93c92a21d35632'

D:\Dev\winmerge> path="C:\Program Files\7-Zip";%PATH%

D:\Dev\winmerge> DownloadDeps.cmd

・・・省略・・・

D:\Dev\winmerge> BuildBin.vs2019.cmd x64

・・・省略・・・

開発にチャレンジ

WinMergeを使っていて、D言語のシンタックスハイライト機能が欲しいと思い、開発にチャレンジしました。
D言語向け機能の実装を行った中で、以下がメインの作業となりました。
ソースコードでの実装方法に選択肢が多いのは、ソースコードを書く側としてありがたいのですが、今回ソースコードを解析する側に立つと、大変だなと思いました。:sweat_smile:

D言語の特徴1:コメントのネスト(入れ子)構造

D言語は、コメント行の書き方を3種類提供しています。

sample1.d
//  一行コメント
/+
    string s = "ここは、コメント行1";
    /+
        string s = "ここは、コメント行2";
    +/
    string s = "ここは、コメント行3";
+/
/*
    string s = "ここは、コメント行4";
/*
    string s = "ここは、コメント行5";
*/
    string s = "ここは、コメント行ではない";

D言語のブロックコメント/+ +/は、ネストに対応しています。
/* */は、C言語と言語仕様に合わせて、ネストに対応していません。

Rustはブロックコメント/* */がネストに対応しているそうで、実装での参考にしました。

D言語の特徴2:文字列の表現

D言語は、文字列リテラルの表現方法がたくさん用意されています。

sample2a.d
import std.stdio;

void main()
{
    string[] arr = [
        "string
            1\\\"",
        r"string
            2\"c,
        `"string
            3\"`,
        q"(string
            4a\")",
        q"[string
            4b\"]",
        q"{string
            4c\"}",
        q"<string
            4d\">",
        q"/string
            4e\"/"
    ];
    foreach( i, s; arr ){
        writefln("-----arr[%s]-----\n%s", i, s);
    }
}

arr[0]は C言語と同じ文字列表現です。
arr[1]以降はWysiwyg Stringsでエスケープシーケンスを使わずにダブルクォーテーション"やバックスラッシュ(円マーク)\を表現できます。ただし、arr[1]ではダブルクォーテーション"自体を文字列に含めることができません。
また、文字列中に改行があると、改行文字\nとして扱われます。

sample2a.dのコンパイル実行結果
-----arr[0]-----
string
            1\"
-----arr[1]-----
string
            2\
-----arr[2]-----
"string
            3\"
-----arr[3]-----
string
            4a\"
-----arr[4]-----
string
            4b\"
-----arr[5]-----
string
            4c\"
-----arr[6]-----
string
            4d\"
-----arr[7]-----
string
            4e\"

WinMergeでの実装が難しく、以下の文字列は未対応(断念)としました。
"EOSEOS"の間にあるのが文字列になります。
以下の例のEOSに限らず、D言語では任意の文字列を区切り文字(デリミタ)にできます。

sample2b.d
import std.stdio;

string s =
q"EOS
This
is a multi-line
heredoc string
EOS";

void main()
{
    writeln(s);
}
sample2b.dのコンパイル実行結果
This
is a multi-line
heredoc string

D言語の特徴3:文字列のネスト(入れ子)構造

D言語では、文字列の区切り文字(デリミタ)のネストを許容するパターンがあります。Token strings

sample3.d
import std.stdio;

void main()
{
    string s =
        q{string
            5 q{string 5+} };
    writeln(s);
}

QiitaのMarkdown カラー表示が、少しわかりにくいですが、
q{}の間が文字列になります。ネストが許容されるので、内側のq{}は文字列に含まれます。
以下にコンパイル実行結果を記載します。表示されている部分が文字列です。

sample3.dのコンパイル実行結果
string
            5 q{string 5+} 

WinMerge実装結果

完成したD言語シンタックスハイライト機能のイメージです。

image.png

おわりに

私なんかが、いきなりプルリクエストして採用されるのだろうか・・・
と、ちょっと心配でしたが、v2.16.17の追加機能として、無事マージされました。

WinMergeのマイルストーンを見ると、
v2.16.17(ベータ版)は2021/12/19リリース予定、v2.16.18(安定版)は2022/1/27リリース予定となっています。

みなさまのD言語開発に活用していただければと思います。

参考情報

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1