[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00020] Re: file name completion problems



 しらいです。

 技術的に込入った話題が多いようですけど、もっと初心者的な質
問なんかも受付けますので、余り技術知識の無い方でも萎縮しない
で下さいね :-)

In Message-Id <86r8hpujzi.wl@archon.local.idaemons.org>
        "Akinori MUSHA" <knu@iDaemons.org>さんwrites:
>  ファイル名補完に関わる問題を二つ見つけたので報告します。

 「問題」と呼べるほどのものでも無いと思いますが。確かにより
使い易くはなるでしょうけど、bug だとは思いませんし。


> $ cp a\ [tab]
> $ cp a\ a
> 
> →次のようになってほしい。
> 
> $ cp a\ b 

 「"a 」と入力した時点で補完すると「"a b"」となると思います。
空文字は IFS (Input Field Separator) なので普通に処理しよう
とすると TAB 押下時点でのカーソル位置を filename の先頭と見
なして補完してしまうんでしょう。
 この操作例で補完結果が「a\ a」になっているのは、directory
内に含まれる全 filename が「a」から始まっているために、その
共通部分「a」を補完した結果ですね。「ab」が存在しなければ、
多分「a\ "a b"」と補完された筈です。

 FDclone の仕様では、meta characher を含む filename を補完
する際には「\」で prefix するのではなく「"」で括るようになっ
ていますので、ここでは補完結果が「"a b"」になるように改めた
いと思います。入力部分の「\」は補完の結果削除されます。
 以下補完例を幾つか示します。
	「a\ 」->「"a b" 」
	「\a\ 」->「"a b" 」
	「a 」->「a a」(「a b」と「ab」の共通部分)
	「"a\ 」->失敗
	「'a\ 」->失敗

 主には bash の挙動に合わせたつもりですが、後ろ二つは bash
では何故かそれぞれ「"a b"」「'a b'」に補完されてしまいますね。
これは bash の側の問題点だと思います。
 「"」や「'」で括られた中の「\」はそのまま「\」の意味で評価
されるというのは FDclone にも bash にも共通した仕様です。
 もし仮に「a\ a」という filename があったとすると、「"a\ 」
や「'a\ 」は「"a\ a"」や「'a\ a'」に補完されるべきではないで
しょうか。
 bash ではそうなっていませんが、FDclone ではそういう仕様に
しました。


> $ vi ~/tmp/a[tab]
> $ vi "~/tmp/a b" 
> 
> →次のいずれかになってほしい。
> 
> $ vi ~/tmp/a\ b 
> $ vi ~/tmp/"a b" 
> $ vi "/home/knu/tmp/a b" 

 bash に合わせて三番目の仕様にしてみました。補完される対象
の filename が meta character を含み「"」で括ってやる必要が
ある時のみ、「~」を展開します。
 bash の仕様ですと、path 中に存在した「$」まで展開してしま
うのですが、FDclone や bash のルールでは「"」の中の「$」は環
境変数として評価されるので、FDclone の仕様では「$」の展開は
していません。
 以下補完例を幾つか示します。
	「~/tmp/a」->「"/home/knu/tmp/a b" 」
	「~/tmp/x」->「~/tmp/xyz 」
	「~/$TMP/a」->「"/home/knu/$TMP/a b" 」


 上記の修正を施した patch を添付しますが、bug では無いとい
う判断で、時期 release 時に自然切替えという扱いで宜しいでし
ょうか?
 bug fix 扱いであれば、各 distributor の方には patch を含め
た形で配布 package を作り直して貰うよう要請するところですが、
今回はその必要はないと判断します。

---- Cut Here ----
diff -u ../old/FD-2.01b/input.c ./input.c
--- ../old/FD-2.01b/input.c	Wed Jul 10 00:00:00 2002
+++ ./input.c	Mon Jul 29 14:54:00 2002
@@ -1052,7 +1052,7 @@
 int cx, len, plen, max, linemax, comline, cont;
 {
 # if	!MSDOS || !defined (_NOORIGSHELL)
-	int bq;
+	int bq, hadmeta;
 # endif
 	char *cp1, *cp2, **argv;
 	int i, l, ins, top, fix, argc, quote, quoted, hasmeta;
@@ -1064,7 +1064,7 @@
 	}
 
 # if	!MSDOS || !defined (_NOORIGSHELL)
-	bq = 0;
+	bq = hadmeta = 0;
 # endif
 	quote = '\0';
 	quoted = 0;
@@ -1077,6 +1077,13 @@
 			quote = '\0';
 		}
 		else if (iskanji1(s, i)) i++;
+# if	!MSDOS || !defined (_NOORIGSHELL)
+		else if (quote == '\'');
+		else if (isnmeta(s, i, quote, cx)) {
+			i++;
+			hadmeta++;
+		}
+# endif
 		else if (quote);
 		else if (s[i] == '"') quote = s[i];
 # if	!MSDOS || !defined (_NOORIGSHELL)
@@ -1182,8 +1189,23 @@
 	}
 
 	if (hasmeta) {
+		char *tmp, *home;
+		int hlen;
+
+		if (quote || quoted > top || s[top] != '~') {
+			home = NULL;
+			i = hlen = 0;
+		}
+		else {
+			tmp = &(s[top]);
+			s[len] = '\0';
+			home = malloc2(len - top + 1);
+			hlen = evalhome(&home, 0, &tmp);
+			i = ++tmp - &(s[top]);
+		}
+
 		if (quote);
-		else if (quoted) {
+		else if (quoted > top) {
 			quote = s[quoted];
 			setcursor(vlen(s, quoted), plen, max, linemax);
 			deletechar(s, quoted, len, plen, max, linemax, 1);
@@ -1191,7 +1213,35 @@
 			l--;
 			setcursor(vlen(s, --cx), plen, max, linemax);
 		}
-		else if (len < max) {
+		else if (len + hlen - i < max) {
+			if (home) {
+				setcursor(vlen(s, top), plen, max, linemax);
+				deletechar(s, top, len, plen, max, linemax, i);
+				delshift(s, top, len, i);
+				len -= i;
+				l -= i;
+				cx -= i;
+				i = insertstr(s, top, len, plen, max, linemax,
+					home, hlen, '\0');
+				len += i;
+				l += i;
+				cx += i;
+				free(home);
+			}
+# if	!MSDOS || !defined (_NOORIGSHELL)
+			if (hadmeta) for (i = top; i < cx; i++) {
+				if (iskanji1(s, i)) {
+					i++;
+					continue;
+				}
+				if (!isnmeta(s, i, '\0', cx)) continue;
+				setcursor(vlen(s, i), plen, max, linemax);
+				deletechar(s, i, len, plen, max, linemax, 1);
+				delshift(s, i, len--, 1);
+				l--;
+				cx--;
+			}
+# endif	/* !MSDOS || !_NOORIGSHELL */
 			setcursor(vlen(s, top), plen, max, linemax);
 			insertchar(s, top, len, plen, max, linemax, 1);
 			insshift(s, top, len++, 1);
diff -u ../old/FD-2.01b/pathname.c ./pathname.c
--- ../old/FD-2.01b/pathname.c	Wed Jul 10 00:00:00 2002
+++ ./pathname.c	Mon Jul 29 13:40:14 2002
@@ -178,7 +178,6 @@
 static int NEAR replacevar __P_((char *, char **, int, int, int, int));
 static char *NEAR insertarg __P_((char *, int, char *, int, int));
 static int NEAR evalvar __P_((char **, int, char **, int));
-static int NEAR evalhome __P_((char **, int, char **));
 
 #ifdef	LSI_C
 #include <jctype.h>
@@ -2480,7 +2479,7 @@
 	return(NULL);
 }
 
-static int NEAR evalhome(bufp, ptr, argp)
+int evalhome(bufp, ptr, argp)
 char **bufp;
 int ptr;
 char **argp;
diff -u ../old/FD-2.01b/pathname.h ./pathname.h
--- ../old/FD-2.01b/pathname.h	Wed Jul 10 00:00:00 2002
+++ ./pathname.h	Mon Jul 29 13:39:48 2002
@@ -161,6 +161,7 @@
 # endif
 #endif
 extern char *gethomedir __P_((VOID_A));
+extern int evalhome __P_((char **, int, char **));
 extern char *evalarg __P_((char *, int, int));
 extern int evalifs __P_((int, char ***, char *));
 extern int evalglob __P_((int, char ***, int));
---- Cut Here ----

                                               しらい たかし