w3mのNEXT_DOWNをいじってみた
w3mのNEXT_DOWNは、OperaのNavigate downに似ているんだけど、ちょっとだけ違う。w3mは真下にしか移動しないけど、Operaは多少横にずれていても移動してくれる。
というわけで、適当にいじくってみたら、わりと簡単にできた。w3mすごい。
変更したあとのコードはGitHub - mzp/w3m: w3mにおいてあります。そのうち他の変更も加えるかも。
設定項目の追加
fm.hにグローバル変数を追加する。
global int use_lessopen init(FALSE); global char *keymap_file init(KEYMAP_FILE); /* 許容する幅を設定する変数 */ global int next_down_width init(10);
rc.cに項目を追加する。これでoをおしたときの設定パネルに項目が追加される。
#define CMT_NEXT_DOWN_WIDTH N_("NEXT_DOWN width") ... ... struct param_ptr params3[] = { .... {"next_down_width", P_INT, PI_TEXT, (void *)&next_down_width, CMT_NEXT_DOWN_WIDTH, NULL}, {NULL, 0, 0, NULL, NULL, NULL}, };
NEXT_DOWNを変更
main.cのnextYをちょっと変更する。多少のx方向を許容するようにする。
static int max(int x,int y){ return x > y ? x : y; } /* go to the next downward/upward anchor */ static void nextY(int d) { HmarkerList *hl = Currentbuf->hmarklist; Anchor *an, *pan; int i, j, x, y, n = searchKeyNum(); int hseq; if (Currentbuf->firstLine == NULL) return; if (!hl || hl->nmark == 0) return; an = retrieveCurrentAnchor(Currentbuf); if (an == NULL) an = retrieveCurrentForm(Currentbuf); x = Currentbuf->pos; y = Currentbuf->currentLine->linenumber + d; pan = NULL; hseq = -1; for (i = 0; i < n; i++) { if (an) hseq = abs(an->hseq); an = NULL; for (; y >= 0 && y <= Currentbuf->lastLine->linenumber; y += d) { for(j = 0; j < max(next_down_width,1); j++){ an = retrieveAnchor(Currentbuf->href, y, x+j); if( !an){ an = retrieveAnchor(Currentbuf->formitem, y, x+j); } if(x-j >= 0){ if (!an){ an = retrieveAnchor(Currentbuf->formitem, y, x-j); } if (!an){ an = retrieveAnchor(Currentbuf->href, y, x-j); } } if (an && hseq != abs(an->hseq)) { pan = an; break; } } if(an){ break; } } if (!an) break; } if (pan == NULL) return; gotoLine(Currentbuf, y); Currentbuf->pos = pan->start.pos; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); }
まとめ
これまでの変更をdiffにまとめるとこうなる。
diff --git a/fm.h b/fm.h index 7ac6b30..057fc7e 100644 --- a/fm.h +++ b/fm.h @@ -1143,6 +1143,7 @@ global double image_scale init(100); global int use_lessopen init(FALSE); global char *keymap_file init(KEYMAP_FILE); +global int next_down_width init(10); #ifdef USE_M17N #define get_mctype(c) ((Lineprop)wtf_type((wc_uchar *)(c)) << 8) diff --git a/main.c b/main.c index 17047cf..a24cce8 100644 --- a/main.c +++ b/main.c @@ -3776,6 +3776,11 @@ nextX(int d, int dy) } +static int +max(int x,int y){ + return x > y ? x : y; +} + /* go to the next downward/upward anchor */ static void nextY(int d) @@ -3803,17 +3808,25 @@ nextY(int d) hseq = abs(an->hseq); an = NULL; for (; y >= 0 && y <= Currentbuf->lastLine->linenumber; y += d) { - for(j = -10; j < 10; ++j){ - if(x+j >= 0) { - an = retrieveAnchor(Currentbuf->href, y, x+j); + for(j = 0; j < max(next_down_width,1); j++){ + an = retrieveAnchor(Currentbuf->href, y, x+j); + if( !an){ + an = retrieveAnchor(Currentbuf->formitem, y, x+j); + } + + if(x-j >= 0){ if (!an){ - an = retrieveAnchor(Currentbuf->formitem, y, x+j); + an = retrieveAnchor(Currentbuf->formitem, y, x-j); } - if (an && hseq != abs(an->hseq)) { - pan = an; - break; + if (!an){ + an = retrieveAnchor(Currentbuf->href, y, x-j); } } + + if (an && hseq != abs(an->hseq)) { + pan = an; + break; + } } if(an){ break; diff --git a/rc.c b/rc.c index abb2e31..cceb8e1 100644 --- a/rc.c +++ b/rc.c @@ -233,6 +233,8 @@ static int OptionEncode = FALSE; #define CMT_KEYMAP_FILE N_("keymap file") +#define CMT_NEXT_DOWN_WIDTH N_("NEXT_DOWN width") + #define PI_TEXT 0 #define PI_ONOFF 1 #define PI_SEL_C 2 @@ -483,6 +485,8 @@ struct param_ptr params3[] = { CMT_PRESERVE_TIMESTAMP, NULL}, {"keymap_file", P_STRING, PI_TEXT, (void *)&keymap_file, CMT_KEYMAP_FILE, NULL}, + {"next_down_width", P_INT, PI_TEXT, (void *)&next_down_width, CMT_NEXT_DOWN_WIDTH, + NULL}, {NULL, 0, 0, NULL, NULL, NULL}, }; -- 1.5.5.3