web404

引用符内を順次選択するマクロ

カーソル位置を含む引用符の間を選択します。
ただし、同じ論理行にある引用符のみが対象です。

カーソル位置が引用符内にない場合は、ファイルの末尾に向かって同じ論理行に複数存在する引用符を探索し、それらの間を選択します。
連続して実行すると、次の引用符の間を選択します。

連続実行時は、選択範囲に隣接する引用符との間は選択しないようにしています。
たとえば、1つの論理行に同じ引用符が4つあり、このマクロで1つ目と2つ目の間を選択している場合、次に選択するのは3つ目と4つ目の間です。
なお、2つ目と3つ目の引用符の間を個別に選択することは可能です。

対応する引用符は「"」「'」です。
引用符の直前に「\」があれば、エスケープされているとみなします。


ダウンロード

quotation.zip


更新履歴

Version 1.10 (2025/2/10)
マクロ名の変更
連続実行時の処理の修正
サブルーチンの修正
探索を左方向と右方向で分けた
論理行頭の処理の修正
ソースコードの整理
過去の履歴
Version 1.00 (2025/1/28)
公開

ソースコード

#x = x; #y = y;
disabledraw;

if (selecting) {
	escape;
	if (code == '"' || code == '\'') {	//連続実行時の処理
		call CheckEscape;
		if (##return) right;
		else call SeekLeft;
	} else call SeekLeft;
} else call SeekLeft;

while (1) {
	if (code == 13) moveto2 0, lineno + 1;
	else if (code == -1) {
		if (x != #x || y != #y) moveto #x, #y;
		beep;
		goto End;
	}
	call SeekRight;
}

SeekLeft:	//左方向に引用符を探索
	#col = column;
	
	while (column) {	//左方向に開始引用符を探索
		left;
		if (code == '"' || code == '\'') {
			call CheckEscape;
			if (##return) {
				$q = gettext2(column, lineno, column + 1, lineno);
				#ct = column + 1;
				moveto2 #col, lineno;
				call SeekEnd;
				break;
			}
		}
	}
	
	moveto2 #col, lineno;
	return;

SeekRight:	//右方向に引用符を探索
	#col = column;
	
	while (code != 13 && code != -1) {	//右方向に開始引用符を探索
		if (code == '"' || code == '\'') {
			call CheckEscape;
			if (##return) {
				$q = gettext2(column, lineno, column + 1, lineno);
				right;
				#ct = column;
				call SeekEnd;
				break;
			}
		}
		right;
	}
	
	moveto2 #col, lineno;
	if ($q == "\"") $q = "'";	//探索対象の変更
	else $q = "\"";
	while (code != 13 && code != -1) {	//右方向に開始引用符を探索
		if (code == ascii($q)) {
			call CheckEscape;
			if (##return) {
				right;
				#ct = column;
				call SeekEnd;
				break;
			}
		}
		right;
	}
	
	return;

SeekEnd:	//右方向に終了引用符を探索
	while (code != 13 && code != -1) {
		if (code == ascii($q)) {
			call CheckEscape;
			if (##return) {
				#ce = column;
				moveto2 #ct, lineno;
				beginsel;
				moveto2 #ce, lineno;
				endsel;
				goto End;
			}
		}
		right;
	}
	return;

CheckEscape:	//エスケープされていないかを調べる
	##col = column;
	##i = 1;
	if (column) {
		left;
		while (code == '\\') {
			##i = ##i + 1;
			if (!column) break;
			left;
		}
		moveto2 ##col, lineno;
	}
	return ##i % 2;

End:	//終了処理
	enabledraw;
	endmacro;

できるだけ無意味な範囲は選択しないようにしています。
複数の論理行にわたる範囲が対象外なのも、このためです。