ウィンドウ番号入れ替え2

ウィンドウ番号入れ替え - vimとかでやり方は分ったけど、
bindする方法が分らない。

bind N number

とした場合、今のウィンドウ番号とタイトルが表示されるだけだし、

bind N number 1

としたら使い勝手が悪すぎる><


というわけで、ソース(4.0.2 + screen install memo (UNIX)のパッチあてたバージョン)をいじってしまいました。
numberコマンドの動作はそのままで、引数で"-i"が指定されるとウィンドウ番号の入力を求めるようにしてみました。
C-a Nでウィンドウ番号表示とかしないので、

bind N number -i

として使っています。
ソースいじらないでも出来るwwwって人はぜひ教えてください><


ついでにソース晒し。
process.cのDoAction関数の上に以下の関数3つを書く。

static void
WindowNumberChange(n)
int n;
{
  struct display *odisplay = display;
  int old = fore->w_number;
  struct win *p = wtab[n];

  wtab[n] = fore;
  fore->w_number = n;
  wtab[old] = p;
  if (p)
    p->w_number = old;
#ifdef MULTIUSER
  /* exchange the acls for these windows. */
  AclWinSwap(old, n);
#endif
#ifdef UTMPOK
  /* exchange the utmp-slots for these windows */
  if ((fore->w_slot != (slot_t) -1) && (fore->w_slot != (slot_t) 0))
    {
      RemoveUtmp(fore);
      SetUtmp(fore);
    }
  if (p && (p->w_slot != (slot_t) -1) && (p->w_slot != (slot_t) 0))
    {
      /* XXX: first display wins? */
      display = fore->w_layer.l_cvlist ? fore->w_layer.l_cvlist->c_display : 0;
      RemoveUtmp(p);
      SetUtmp(p);
    }
#endif

  WindowChanged(fore, 'n');
  WindowChanged((struct win *)0, 'w');
  WindowChanged((struct win *)0, 'W');
  WindowChanged((struct win *)0, 0);

  if (display != odisplay)
    {
      for (display = displays; display; display = display->d_next)
        if (display == odisplay)
          break;
    }
}

static void
SelectWindowNumberFin(buf, len, data)
char *buf;
int len;
char *data; /* dummy */
{
  int i;
  char* p;

  if (!len || !display)
    return;

  p = buf;
  i = 0;

  while (*p)
    {
      if (*p >= '0' && *p <= '9')
        i = 10 * i + (*p - '0');
      else
        {
          Msg(0, "%s: invalid argument. Give numeric argument.",
              rc_name);
          return;
        }
      p++;
    }

  if (i < 0 || i >= maxwin)
    return;

  WindowNumberChange(i);
}

static void
InputSetWindowNumber()
{
  Input("Set window's number to: ", 20, INP_COOKED, SelectWindowNumberFin, NULL);
}

あと、これも同じくprocess.cのDoAction関数内にある巨大なswitch分の case RC_NUMBER: を以下のように書き換える。

    case RC_NUMBER:
      if (*args == 0)
        {
          Msg(0, "This is window %d (%s).\n", fore->w_number, fore->w_title);
          break;
        }
      if (!strcmp(*args, "-i") && !args[1])
        {
          InputSetWindowNumber();
        }
      else
        {
          if (ParseNum(act, &n) || n >= maxwin)
            break;
          WindowNumberChange(n);
        }
      break;

以上です。