static char rcsid[] = "$Id: lmacs.c,v 1.1 1992/09/14 13:02:14 mike Exp $";

/* $Log: lmacs.c,v $
 * Revision 1.1  1992/09/14  13:02:14  mike
 * Initial revision
 *
 */

/* tmacs.c : the Emacs extensions to LED
 * C Durland
 */

/* Copyright 1990, 1991 Craig Durland
 *   Distributed under the terms of the GNU General Public License.
 *   Distributed "as is", without warranties of any kind, but comments,
 *     suggestions and bug reports are welcome.
 */

#include <char.h>
#include <const.h>
#include "ed.h"
#include "led.h"

extern char *Ltext, *Hsearch(),	*Hcurrent(), *str_in_str();
extern int Lerrorno, Lflags, Hadd(), Hprev(), Hnext();
extern void Lrepeat_fcn();

extern int Ldot(), Lline_length(), Lmacs();


#define LM_HIST_PREV	0
#define LM_HIST_NEXT	1
#define LM_HIST_SEARCH	2
#define LM_HIST_FIRST	3
#define LM_HIST_LAST	4
#define LM_FOREWORD	5
#define LM_BACKWORD	6
#define LM_DELWORD	7
#define LM_VERSION	8
#define LM_ABORT	9

void Lmacskeys()
{
  Lregister_callback(0, Lmacs);

  Ldo_fcn(
    LF_BINDKEY,
      LF_ABORT,		CTRL|'G',	/* abort */
      LF_RIGHT,		CTRL|'F',	/* next-character */
      LF_LEFT,		CTRL|'B',	/* previous-character */
      LF_BoL,		CTRL|'A',	/* beginning-of-line */
      LF_DEL_CHAR,	CTRL|'D',	/* delete-character */
      LF_EEoL,		CTRL|'K',	/* kill-line */
      LF_EoL,		CTRL|'E',	/* end-of-line */
      LF_QUOTE,		CTRL|'^',	/* quote */
      LF_QUOTE,		CTRL|'Q',	/* quote - Often unreachable */

#if 0
      LF_EXTEND, LM_ABORT,	CTRL|'C',
      LF_EXTEND, LM_ABORT,	CTRL|'G',
#endif

      LF_EXTEND, LM_FOREWORD,	META|'F',
      LF_EXTEND, LM_BACKWORD,	META|'B',
      LF_EXTEND, LM_DELWORD,	META|'D',
      LF_EXTEND, LM_VERSION,	CTRL|'V',
      LF_EXTEND, LM_HIST_NEXT,	CTRL|'N',
      LF_EXTEND, LM_HIST_PREV,	CTRL|'P',
      LF_EXTEND, LM_HIST_SEARCH, CTRL|'R',
      LF_EXTEND, LM_HIST_FIRST, META|'<',
      LF_EXTEND, LM_HIST_LAST,	META|'>',

      LF_EXTEND, LM_HIST_PREV,	SOFKEY|'C',	/* up arrow */
      LF_EXTEND, LM_HIST_NEXT,	SOFKEY|'D',	/* down arrow */

      LF_STOP,

    LF_PKEY,
      0,CTRL | '[', LF_STOP,
    LF_STOP);
}

static char *search_pattern;
static int matcher(ptr) char *ptr;
	{ return (NULL != str_in_str(ptr, search_pattern)); }

Lmacs(kc,fcn, op) KeyCode kc; int fcn, *op;
{
  extern char *Hsearch();
  extern int Lflags;

  char *ptr;
  int n, dot = Ldot(), linelength = Lline_length();

  switch (fcn)
  {
    default: return FALSE;		/* nothing I know about */
    case LM_FOREWORD:
      while (dot < linelength &&  isspace(Ltext[dot])) dot++;
      while (dot < linelength && !isspace(Ltext[dot])) dot++;
      Lrepeat_fcn(LF_RIGHT,dot -Ldot());
      break;
    case LM_BACKWORD:
      if (0 < dot) dot--;
      while (0 < dot &&  isspace(Ltext[dot])) dot--;
      while (0 < dot && !isspace(Ltext[dot])) dot--;
      if (dot) dot++;	/* move back to start of word */
      Lrepeat_fcn(LF_LEFT,Ldot() -dot);
      break;
    case LM_DELWORD:
	break;
    case LM_HIST_PREV:		  /* move to previous history entry */
      if (Hprev())
	Ldo_fcn(LF_CLEAR_LINE,LF_INSERT_STRING,Hcurrent(),LF_STOP);
      break;
    case LM_HIST_NEXT:		      /* move to next history entry */
      if (Hnext())
	Ldo_fcn(LF_CLEAR_LINE,LF_INSERT_STRING,Hcurrent(),LF_STOP);
      break;
    case LM_HIST_SEARCH:
      n = Lflags; Lflags |= (LFnohist | LFrecdraw);
      Led("Search for: ","",(pfi)NULL);
      search_pattern = Ltext;
      if (ptr = Hsearch(FALSE,matcher))
	Ldo_fcn(LF_CLEAR_LINE,LF_INSERT_STRING,ptr,LF_STOP);
      Lflags = n;
      break;
    case LM_HIST_FIRST:
      Hbottom();
      Ldo_fcn(LF_CLEAR_LINE,LF_INSERT_STRING,Hcurrent(),LF_STOP);
      break;
    case LM_HIST_LAST:
      Htop(); Hprev();
      Ldo_fcn(LF_CLEAR_LINE,LF_INSERT_STRING,Hcurrent(),LF_STOP);
      break;
    case LM_VERSION:
      t_clearline(); printf(">LED version<"); t_flush();
      Ldo_fcn(LF_REDRAW,LF_STOP);
      break;
/*    case LM_ABORT: Texit(); */
  }
  *op = LF_NOOP;

  return TRUE;
}

void Lrepeat_fcn(fcn,n) { while (n--) Ldo_fcn(fcn,LF_STOP); }
