2014年1月3日金曜日

Lazarus IDE の配色設定 (SynEditのSyntaxHighlighter) の移行

Lazarus のエディタの配色設定の移行について。

概要
1)旧環境から XML にエクスポート
2)新環境の userschemes ディレクトリに配置


詳細

配色設定は Lazarus IDE のツールのオプションから開く「IDEオプション」の表示-色から確認できます。

そこからディスクのアイコンをクリックすると、現在の配色設定をXML でエクスポートできます。
エクスポートしたXMLは、Lazarus の コンフィグディレクトリ内の userschemes ディレクトリに配置すると起動時にプリセットとして読み込んでくれます。

IDEオプションを開いて、配色設定のプリセットを選択すれば、以前の環境と同じ配色設定を利用できます。


一応 Lazarus wiki にも書いてあります。
http://wiki.freepascal.org/IDE_Window:_Editor_Options_HighlightColors

以上。

Lazarus IDE の 外部ツールの設定の移行 (Windows)

Lazarus IDE のメニューの「ツール」に定義できる外部ツールの移行の方法について。

古い環境ファイルが見つかった場合は、自動的に変換してくれますが、新規だったり古い環境ファイルを消してしまった場合などには、自分で移行作業をする必要があります。

外部ツールは  environmentoptions.xml の ExternalTools エレメントに定義してあります。

以前の環境の environmentoptions.xml から ExternalTools エレメントを新しい環境のenvironmentoptions.xml にコピーすれば新しい環境でも以前の外部ツールを利用できます。

environmentoptions.xml は、C:\Users\AppData\Local\Lazarus 等にあります。
config の場所を変えている場合は、そちらにあります。

以上です。

Object Pascal Style Guide

「Object Pascal Style Guide」

昔からあるものなのだけど。
Embacadero に移ってからも管理されており今でも入手可能です。
Style Guide といってもPascal は比較的お堅い言語なので仕様的に推奨されない書き方というのは、C等と比べると余り無く、あくまで見た目の問題の話です。

http://edn.embarcadero.com/article/10280

なので、人それぞれ好きなように書けばいいとは思うのだけど。
if ... then begin

end


という書き方が Lazarus の世界でも結構あるらしく、ソース読んでて気になってしまった。


このように書いてしまった人は、もともと Pascal を書く人間ではなかったのだろう・・・とは思う。
それでも初めて Pascal を書いた人がそれを見習ってしまってはいけないと思うので、そうではないのだという事も示さねばならないように思う。

Example:

  // INCORRECT
  if A < B then begin
    DoSomething;
    DoSomethingElse;
  end else begin
    DoThis;
    DoThat;
  end;

  // CORRECT
  if A < B then
  begin
    DoSomething;
    DoSomethingElse;
  end
  else
  begin
    DoThis;
    DoThat;
  end;                  


おそらく C や C++ の

if (...) {

}

https://github.com/NYTimes/objective-c-style-guide

の流れで横に begin が来てしまっているのだろうか。

今に始まったことではなく、25年前に既に多数みられ、実質的に問題はないので気にするほどの事ではないものの、あまりに多い場合や、すべてがそうである場合にはスタイルガイドを見てほしくなります。

if だけでなく while 等もそのように書く。
Pascal は、基本的にブロックの開始と終わりで列を合わせる。

つまり begin と end が縦に並ぶのがの望ましい。
私も本当の所の理由というのは知らないのだけど。
end に対応する begin を探す場合に上を辿るだけで分かるという利点はあります。

if ... then
begin

end

と書く。

  // INCORRECT
  if A < B then DoSomething;

  // CORRECT
  if A < B then
    DoSomething;
 
というのもあり、今どきの高解像度のディスプレイに対しては古さは感じます。

特にポインタを扱う場合など inc や dec は横に書きたくなる場合もあるし、IDE が進歩しているせいもあるので記号のようにコードを扱う事も多々あります。
特に Pascal は、いくらでも手の抜けるコードがかけるため、マクロやスクリプトのように使われることも多々あります。
なので、行単位での追加削除等がしやすいような書き方というのもあるので自由であってよいものの、指標となるようなコードの場合はスタイルガイドに沿ったほうが良いように思うわけです。

まあでも begin が横にくるのは、いかなる場合も推奨されないような気がする・・・。


次に、Delphi と FPC には完全論理評価というコンパイラオプションがあります。

if (length(s)>0) and (s[1]='a') then
begin

end

http://docwiki.embarcadero.com/RADStudio/XE5/ja/式(Delphi)

http://forum.lazarus.freepascal.org/index.php?topic=9202.0


常にそのことを気にかけられるのならが問題ありませんが、そうでないならブロックが1つ増えてしまおうと、元々の意図するところがこのような判定であったのなら、そう書いたほうがよろしいです。


if a then
begin
 if b then
 begin

 end
end



C# が Java のパクリだといわれる中、Javaが流行りだした時、Java は Object Pascal のパクリだろと思った人はあまり多くないらしく、故に C# と Object Pascal をつなげてみる人も少ないようです。

実際の所は、C# は Delphi の親戚のようなもので Pascal の伝統も受け継いでいる。

故になのかどうなのか C# も Object Pascal の Style Guide に似ている部分があります(?)。 (Java も縦に合わせる部分も多いが、for 等は横に書いたりしてもいいらしく、はっきりしなかった。)

http://msdn.microsoft.com/ja-jp/library/vstudio/ff926074.aspx http://www.cis.upenn.edu/~cis193/csstyle.html

namespace N
{
    class C
    {
        void f()
        {
            int x;
        }
    }
}

とはいえ、C系も使い込んできた人間としては、逆に { } が縦に並ぶのはちと気持ちが悪い。
これもいろいろと理由はあるのかもしれませんが。

{}の場合は横につなげるのを推奨してよかったんじゃないのか・・・とも思うものの、これは伝統なのか?と感じられる部分があったのは、少しうれしくなりました。

とりあえず、他にも細かいことがスタイルガイドには書いてあるのだけど。
begin と end の扱いさえ合わせれば、他の所が違っていても、まあそれらしくなります。
なので、新しい言語を学ぶ場合は、言語ごとのスタイルガイドも一度読んでみる事をお勧めします。



FPC の 文字エンコード

Application.Exename が cp932(ansiやsjisの友達) を返していたので何故なのかと。

全部が 全部 UTF8 ではないようです。(FPC 2.6.2 + Windows 8)

フォーラムを見るとよくある話のようで、Wiki だのマニュアルだのよく読まないといけなさそうです。

LCL は UTF8 で統一されているそうですが、そうでないものに関しては、cp932 等、LConvEncoding.GetDefaultTextEncoding()と同じ charsetで文字が返ってきます。

UTF8対応のクラスや関数がある場合はそれを使い、そうでない場合は随時UTF8ToSys() を使って変換するという方針で書いていけば、とりあえずOKなようです。

UTF8非対応な環境で利用する場合も問題ないよう対策されているようです。

これらは FileUtil で宣言されているので、ファイル名関連に使ってやるとよさそうです。

FileExistsUTF8() などは UTF8文字列を渡してやります。
ソースコードが UTF8 で書かれているなら const 等の定義済み文字列もそのまま渡します。
UTF8対応クラスや関数が返す文字列もUTF8なのでそのまま渡せます。

とりあえず関数の対応状況が不明な場合はコードを辿るか {$OPT D+} や Assert() で観察したほうがよさそうです。

FileExists() を使う時は UTF8ToSys() で変換してやれば使えます。

TFileStream や TMemoryStream などは UTF8 非対応のようです。
継承してファイル名の入出力だけ SysToUTF8(), UTF8ToSys() すればいいように思います。

しかし、拡張された一部の文字が取り扱えないようです。
関連: http://forum.lazarus.freepascal.org/index.php?topic=17692.0

Application.Exename
Application.Exename はよく使われると思いますが cp932 を返してくるので  UTF8関数で利用する場合は SysToUTF8() cp932等に変換してやらねばなりません。

2回エンコードするとどうなるか
また、UTF8ToSys() や SysToUTF8()は二重にエンコードすると化けるようです。
現在の文字セットの判定はしてくれません。
コード辿れば分かる事なのですが、ansiフラグ(*1)が有効な場合と、ascii 文字列のエンコードは避けてくれるようです。

(*1):SetNeedRTLAnsi() で、ansi 固定に指定できそうに見えますが試していないので不明。

エンコードを判定するには LConvEncoding.GuessEncoding()  が利用できます。
この関数は文字セットを"cp932" や "UTF8" 等の文字列で返します。

また、LConvEncoding.GuessEncoding() は us_ascii や空文字列も utf8 と返してくるので注意が必要です。

ちなみに LConvEncoding の ConvertEncoding() 関数を使ってもエンコードできます。

2014年1月1日水曜日

Lazarus IDE v1.2RC1 FPC 2.6.2

あけおめことよろ。

Lazarus IDE v1.2RC1 FPC 2.6.2 がいつの間にかリリースされていた。(2013/11/6)
http://forum.lazarus.freepascal.org/index.php/topic,22558.msg133321/topicseen.html#new
http://wiki.lazarus.freepascal.org/Lazarus_1.2.0_release_notes

このインストーラーはインストール済みのLazarusの他のバージョンを残しつつ追加でv1.2RC1をインストールできます。
コンフィグの保存先などもインストール時に指定できるようになってます。



この v1.2RC1においても Windows 8 Pro,8.1 環境で Open/Save ダイアログでコンテキストメニューのサブメニューを開いたときにクラッシュするバグが修正されているのかクラッシュしなくなりました。

このバグはFPC 2.7.1 で修正されたという書き込みをバグトラッカーで見たと思ったのだけど。

FPC 2.6.2 のままで直ったという事は Lazarus 側に修正が入ったのだろうか・・・。


長らく Lazarus IDE v1.1 FPC 2.7.1 と svn で使っていましたが、コード補完でBSが効かなくなるバグがなかなか直らないようなので、これを機会にいったんFPCも 2.6.2 に戻すことに。


日本語に関しては一部の記号の幅の問題は直っていないようです。「」や▲●とか。

ただし、フォントがデフォルトの Courier New  のままの場合はコードやコメントを読むには問題無さそう。
Consolas も大丈夫でした。
なのでコードエディタとしては問題ないかと。


とはいえ、半角1文字相当の幅で小さく描画されるので等幅で日本語は半角2文字相当と思ってレイアウトすると今まで通りにはいかない。 Unicode を ブラウザで表示したようなイメージ。

コード読んでないので不明だけど、意図的というより標準の処理系に渡ってるだけのような感じなのかもしれない。


MS ゴシック等を選択した場合、半角2文字相当の幅になるために半分しか表示されなかったり、次に表示される文字で消えてしまう場合があるのは以前と同じ。
「」や▽●等の幅が適切でなくて重なって見えなくなってしまうバグも修正されている模様。

指定したフォントによっては 余分にマージンがついて全体が横長になってはしまうが潰れることは無くなるというものもある。

なかなか落ち着かないな・・・。
IE v1.0~v1.1 の synedit用であちこちで独自の修正方法に関する情報があるのだけど、▲や●が直っても「」が駄目だったりとか、全て直すのは難しそうです。
ということで当面は独自の修正を行うよりは Courier New のまま使ったほうが良さそうな予感。