*usr_50.txt*	For Vim バージョン 9.1.  Last change: 2025 Nov 09


		     VIM ユーザーマニュアル	by Bram Moolenaar


			 高度な Vim script の書き方


|50.1|	例外
|50.2|	可変長引数の関数
|50.3|	ビューの復元

次章: |usr_51.txt|  プラグインを作る
前章: |usr_45.txt|  言語を選択する (ロケール)
目次: |usr_toc.txt|

==============================================================================
*50.1*	例外

まずは例から始めましょう: >

	try
	   read ~/templates/pascal.tmpl
	catch /E484:/
	   echo "パスカル用のテンプレートファイルは見つかりませんでした。"
	endtry

`read` コマンドはファイルがなければ失敗します。そのエラーをキャッチして、エラー
メッセージの代わりにより詳細な情報のメッセージを表示しています。

`try` と `endtry` の間で起きたエラーは例外に変換されます。例外は文字列です。エ
ラーの場合、文字列はエラーメッセージを含んでいます。そして、全てのエラーメッ
セージは番号を持っています。この場合、キャッチしたエラーには "E484:" が含まれ
ています。この番号は変わらないことが保証されています (テキストは翻訳されるなど
して変わる可能性があります)。

素敵なエラーメッセージを出力し、Vim は `:endtry` 以降のコマンドの実行も続けま
す。それ以外のキャッチされないエラーに遭遇した場合、スクリプト/関数/マッピング
の実行は中断されます。

`read` コマンドが他のエラーを起こした場合、"E484:" というパターンはマッチしな
いでしょう。したがって、その例外はキャッチされず、通常のエラーメッセージの表示
とともに実行が中断されます。

あなたはこれをしたくなるかもしれません: >

	try
	   read ~/templates/pascal.tmpl
	catch
	   echo "パスカル用のテンプレートファイルは見つかりませんでした。"
	endtry

全ての例外がキャッチされます。しかし "E21: Cannot make changes, 'modifiable'
is off" のようなまったく異なる問題を示す有効なエラーに気づくことができません。
エラーをキャッチする前によく考えてください!

もう1つの便利なメカニズムは `finally` コマンドです: >

 	var tmp = tempname()
	try
	   exe ":.,$write " .. tmp
	   exe "!filter " .. tmp
	   :.,$delete
	   exe ":$read " .. tmp
	finally
	   delete(tmp)
	endtry

これは、ファイル名の引数をとる "filter" コマンドを使用して、カーソルからファイ
ルの終わりまでの行をフィルタリングします。フィルタリングが動作しても、`try` と
`finally` の間で何か問題が発生した場合や、ユーザーが CTRL-C を押してフィルタリ
ングをキャンセルした場合は、常に `delete(tmp)` 呼び出しが実行されます。これに
より、一時ファイルを残さないようにすることができます。

`finally` は例外をキャッチせず、エラーはそれ以降の実行を中断します。

例外についてさらに詳しい情報はリファレンスマニュアルの|exception-handling|を
参照してください。

==============================================================================
*50.2*	可変長引数の関数

Vim では、可変数の引数を持つ関数を定義できます。例えば、次のコマンドは、1つの
引数(start)を持つ必要があり、最大20個の追加の引数を持つことができる関数を定義
します: >

	def Show(start: string, ...items: list<string>)

変数 "items" は、追加の引数を含む関数内のリストになります。any型のリストと同じ
ように使用できます。例: >

	def Show(start: string, ...items: list<string>)
	  echohl Title
	  echo "start is " .. start
	  echohl None
	  for index in range(len(items))
	    echon $"  Arg {index} is {items[index]}"
	  endfor
	  echo
	enddef

このように呼び出しできます: >

	Show('Title', 'one', 'two', 'three')
<	start is Title  Arg 0 is one  Arg 1 is two  Arg 2 is three ~

これは `echohl` コマンドを使用して以降の `echo` コマンドをハイライトするように
指定しています。`echohl None` で再度停止します。`echon` コマンドは `echo` と同
様に動作しますが、改行を出力しません。

引数を1つで呼び出したときは "items" リストは空になります。`range(len(items))`
はインデックス付きのリストを返します。`for` がループするものについては、さらに
詳しく説明します。

==============================================================================
*50.3*	ビューの復元

場合によっては、ジャンプして変更を加えてから、同じ位置とビューに戻りたいことが
あります。例えば、ファイルヘッダーの何かを変更します。これは、次の 2 つの関数
で実行できます: >

	var view = winsaveview()
	# 移動して、変更を行う
	winrestview(view)

==============================================================================

Next chapter: |usr_51.txt|  プラグインを作る

Copyright: see |manual-copyright|  vim:tw=78:ts=8:noet:ft=help:norl:
