⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emacs.c

📁 一个开放源代码的 AT&T 的 Korn Shell 的复制品, 支持大多数 ksh89 的特性。
💻 C
📖 第 1 页 / 共 3 页
字号:
	int col = xcp - xbuf;	if (col == 0)  {		x_e_putc(BEL);		return KSTD;	}	if (x_arg > col)		x_arg = col;	x_goto(xcp - x_arg);	return KSTD;}static intx_mv_forw(c)	int c;{	int nleft = xep - xcp;	if (!nleft) {		x_e_putc(BEL);		return KSTD;	}	if (x_arg > nleft)		x_arg = nleft;	x_goto(xcp + x_arg);	return KSTD;}static intx_search_char_forw(c)	int c;{	char *cp = xcp;	*xep = '\0';	c = x_e_getc();	while (x_arg--) {	    if (c < 0	       || ((cp = (cp == xep) ? NULL : strchr(cp + 1, c)) == NULL		   && (cp = strchr(xbuf, c)) == NULL))	    {		    x_e_putc(BEL);		    return KSTD;	    }	}	x_goto(cp);	return KSTD;}static intx_search_char_back(c)	int c;{	char *cp = xcp, *p;	c = x_e_getc();	for (; x_arg--; cp = p)		for (p = cp; ; ) {			if (p-- == xbuf)				p = xep;			if (c < 0 || p == cp) {				x_e_putc(BEL);				return KSTD;			}			if (*p == c)				break;		}	x_goto(cp);	return KSTD;}static intx_newline(c)	int c;{	x_e_putc('\r');	x_e_putc('\n');	x_flush();	*xep++ = '\n';	return KEOL;}static intx_end_of_text(c)	int c;{	return KEOL;}static int x_beg_hist(c) int c; { x_load_hist(history); return KSTD;}static int x_end_hist(c) int c; { x_load_hist(histptr); return KSTD;}static int x_prev_com(c) int c; { x_load_hist(x_histp - x_arg); return KSTD;}static int x_next_com(c) int c; { x_load_hist(x_histp + x_arg); return KSTD;}  /* Goto a particular history number obtained from argument. * If no argument is given history 1 is probably not what you * want so we'll simply go to the oldest one. */static intx_goto_hist(c)	int c;{	if (x_arg_defaulted)		x_load_hist(history);	else		x_load_hist(histptr + x_arg - source->line);	return KSTD;}static voidx_load_hist(hp)	register char **hp;{	int	oldsize;	if (hp < history || hp > histptr) {		x_e_putc(BEL);		return;	}	x_histp = hp;	oldsize = x_size_str(xbuf);	(void)strcpy(xbuf, *hp);	xbp = xbuf;	xep = xcp = xbuf + strlen(*hp);	xlp_valid = FALSE;	if (xep > x_lastcp())	  x_goto(xep);	else	  x_redraw(oldsize);}static intx_nl_next_com(c)	int	c;{	x_nextcmd = source->line - (histptr - x_histp) + 1;	return (x_newline(c));}static intx_eot_del(c)	int	c;{	if (xep == xbuf && x_arg_defaulted)		return (x_end_of_text(c));	else		return (x_del_char(c));}/* reverse incremental history search */static intx_search_hist(c)	int c;{	int offset = -1;	/* offset of match in xbuf, else -1 */	char pat [256+1];	/* pattern buffer */	register char *p = pat;	Findex f;	*p = '\0';	while (1) {		if (offset < 0) {			x_e_puts("\nI-search: ");			x_e_puts(pat);		}		x_flush();		if ((c = x_e_getc()) < 0)			return KSTD;		f = x_tab[0][c&CHARMASK];		if (c == CTRL('['))			break;		else if (f == XFUNC_search_hist)			offset = x_search(pat, 0, offset);		else if (f == XFUNC_del_back) {			if (p == pat) {				offset = -1;				break;			}			if (p > pat)				*--p = '\0';			if (p == pat)				offset = -1;			else				offset = x_search(pat, 1, offset);			continue;		} else if (f == XFUNC_insert) {			/* add char to pattern */			/* overflow check... */			if (p >= &pat[sizeof(pat) - 1]) {				x_e_putc(BEL);				continue;			}			*p++ = c, *p = '\0';			if (offset >= 0) {				/* already have partial match */				offset = x_match(xbuf, pat);				if (offset >= 0) {					x_goto(xbuf + offset + (p - pat) - (*pat == '^'));					continue;				}			}			offset = x_search(pat, 0, offset);		} else { /* other command */			x_e_ungetc(c);			break;		}	}	if (offset < 0)		x_redraw(-1);	return KSTD;}/* search backward from current line */static intx_search(pat, sameline, offset)	char *pat;	int sameline;	int offset;{	register char **hp;	int i;	for (hp = x_histp - (sameline ? 0 : 1) ; hp >= history; --hp) {		i = x_match(*hp, pat);		if (i >= 0) {			if (offset < 0)				x_e_putc('\n');			x_load_hist(hp);			x_goto(xbuf + i + strlen(pat) - (*pat == '^'));			return i;		}	}	x_e_putc(BEL);	x_histp = histptr;	return -1;}/* return position of first match of pattern in string, else -1 */static intx_match(str, pat)	char *str, *pat;{	if (*pat == '^') {		return (strncmp(str, pat+1, strlen(pat+1)) == 0) ? 0 : -1;	} else {		char *q = strstr(str, pat);		return (q == NULL) ? -1 : q - str;	}}static intx_del_line(c)	int c;{	int	i, j;	*xep = 0;	i = xep- xbuf;	j = x_size_str(xbuf);	xcp = xbuf;	x_push(i);	xlp = xbp = xep = xbuf;	xlp_valid = TRUE;	*xcp = 0;	xmp = NULL;	x_redraw(j);	return KSTD;}static intx_mv_end(c)	int c;{	x_goto(xep);	return KSTD;}static intx_mv_begin(c)	int c;{	x_goto(xbuf);	return KSTD;}static intx_draw_line(c)	int c;{	x_redraw(-1);	return KSTD;}/* Redraw (part of) the line.  If limit is < 0, the everything is redrawn * on a NEW line, otherwise limit is the screen column up to which needs * redrawing. */static voidx_redraw(limit)  int limit;{	int	i, j;	char	*cp;		x_adj_ok = 0;	if (limit == -1)		x_e_putc('\n');	else 		x_e_putc('\r');	x_flush();	if (xbp == xbuf)	{	  pprompt(prompt + prompt_skip, 0);	  x_col = promptlen(prompt, (const char **) 0);	}	x_displen = xx_cols - 2 - x_col;	xlp_valid = FALSE;	cp = x_lastcp();	x_zots(xbp);	if (xbp != xbuf || xep > xlp)	  limit = xx_cols;	if (limit >= 0)	{	  if (xep > xlp)	    i = 0;			/* we fill the line */	  else	    i = limit - (xlp - xbp);	  for (j = 0; j < i && x_col < (xx_cols - 2); j++)	    x_e_putc(' ');	  i = ' ';	  if (xep > xlp)		/* more off screen */	  {	    if (xbp > xbuf)	      i = '*';	    else	      i = '>';	  }	  else	    if (xbp > xbuf)	      i = '<';	  x_e_putc(i);	  j++;	  while (j--)	    x_e_putc('\b');	}	for (cp = xlp; cp > xcp; )	  x_bs(*--cp);	x_adj_ok = 1;	D__(x_flush();)	return;}static intx_transpose(c)	int c;{	char	tmp;	/* What transpose is meant to do seems to be up for debate. This	 * is a general summary of the options; the text is abcd with the	 * upper case character or underscore indicating the cursor positiion:	 *     Who			Before	After  Before	After	 *     at&t ksh in emacs mode:	abCd	abdC   abcd_	(bell)	 *     at&t ksh in gmacs mode:	abCd	baCd   abcd_	abdc_	 *     gnu emacs:		abCd	acbD   abcd_	abdc_	 * Pdksh currently goes with GNU behavior since I believe this is the	 * most common version of emacs, unless in gmacs mode, in which case	 * it does the at&t ksh gmacs mdoe.	 * This should really be broken up into 3 functions so users can bind	 * to the one they want.	 */	if (xcp == xbuf) {		x_e_putc(BEL);		return KSTD;	} else if (xcp == xep || Flag(FGMACS)) {		if (xcp - xbuf == 1) {			x_e_putc(BEL);			return KSTD;		}		/* Gosling/Unipress emacs style: Swap two characters before the		 * cursor, do not change cursor position		 */		x_bs(xcp[-1]);		x_bs(xcp[-2]);		x_zotc(xcp[-1]);		x_zotc(xcp[-2]);		tmp = xcp[-1];		xcp[-1] = xcp[-2];		xcp[-2] = tmp;	} else {		/* GNU emacs style: Swap the characters before and under the		 * cursor, move cursor position along one.		 */		x_bs(xcp[-1]);		x_zotc(xcp[0]);		x_zotc(xcp[-1]);		tmp = xcp[-1];		xcp[-1] = xcp[0];		xcp[0] = tmp;		x_bs(xcp[0]);		x_goto(xcp + 1);	}	return KSTD;}static intx_literal(c)	int c;{	x_curprefix = -1;	return KSTD;}static intx_meta1(c)	int c;{	x_curprefix = 1;	return KSTD;}static intx_meta2(c)	int c;{	x_curprefix = 2;	return KSTD;}#ifdef OS2static intx_meta3(c)	int c;{	x_curprefix = 3;	return KSTD;}#endif /* OS2 */static intx_kill(c)	int c;{	int col = xcp - xbuf;	int lastcol = xep - xbuf;	int ndel;	if (x_arg_defaulted)		x_arg = lastcol;	else if (x_arg > lastcol)		x_arg = lastcol;	ndel = x_arg - col;	if (ndel < 0) {		x_goto(xbuf + x_arg);		ndel = -ndel;	}	x_delete(ndel, TRUE);	return KSTD;}static voidx_push(nchars)	int nchars;{	char	*cp = str_nsave(xcp, nchars, AEDIT);	if (killstack[killsp])		afree((void *)killstack[killsp], AEDIT);	killstack[killsp] = cp;	killsp = (killsp + 1) % KILLSIZE;}static intx_yank(c)	int c;{	if (killsp == 0)		killtp = KILLSIZE;	else		killtp = killsp;	killtp --;	if (killstack[killtp] == 0)  {		x_e_puts("\nnothing to yank");		x_redraw(-1);		return KSTD;	}	xmp = xcp;	x_ins(killstack[killtp]);	return KSTD;}static intx_meta_yank(c)	int c;{	int	len;	if (x_last_command != XFUNC_yank && x_last_command != XFUNC_meta_yank) {		x_e_puts("\nyank something first");		x_redraw(-1);		return KSTD;	}	len = strlen(killstack[killtp]);	x_goto(xcp - len);	x_delete(len, FALSE);	do {		if (killtp == 0)			killtp = KILLSIZE - 1;		else			killtp--;	} while (killstack[killtp] == 0);	x_ins(killstack[killtp]);	return KSTD;}static intx_abort(c)	int c;{	/* x_zotc(c); */	xlp = xep = xcp = xbp = xbuf;	xlp_valid = TRUE;	*xcp = 0;	return KINTR;}static intx_error(c)	int c;{	x_e_putc(BEL);	return KSTD;}static intx_stuffreset(c)	int c;{#ifdef TIOCSTI	(void)x_stuff(c);	return KINTR;#else	x_zotc(c);	xlp = xcp = xep = xbp = xbuf;	xlp_valid = TRUE;	*xcp = 0;	x_redraw(-1);	return KSTD;#endif}static intx_stuff(c)	int c;{#if 0 || defined TIOCSTI	char	ch = c;	bool_t	savmode = x_mode(FALSE);	(void)ioctl(TTY, TIOCSTI, &ch);	(void)x_mode(savmode);	x_redraw(-1);#endif	return KSTD;}static char *x_mapin(cp)	const char *cp;{	char *new, *op;	op = new = str_save(cp, ATEMP);	while (*cp)  {		/* XXX -- should handle \^ escape? */		if (*cp == '^')  {			cp++;#ifdef OS2			if (*cp == '0')	/* To define function keys */				*op++ = 0xE0;			else#endif /* OS2 */			if (*cp >= '?')	/* includes '?'; ASCII */				*op++ = CTRL(*cp);			else  {				*op++ = '^';				cp--;			}		} else			*op++ = *cp;		cp++;	}	*op = '\0';	return new;}static char *x_mapout(c)	int c;{	static char buf[8];	register char *p = buf;#ifdef OS2	if (c == 0xE0) {		*p++ = '^';		*p++ = '0';	} else#endif /* OS2 */	if (iscntrl(c))  {		*p++ = '^';		*p++ = UNCTRL(c);	} else		*p++ = c;	*p = 0;	return buf;}static voidx_print(prefix, key)	int prefix, key;{	if (prefix == 1)		shprintf("%s", x_mapout(x_prefix1));	if (prefix == 2)		shprintf("%s", x_mapout(x_prefix2));#ifdef OS2	if (prefix == 3)		shprintf("%s", x_mapout(x_prefix3));#endif /* OS2 */	shprintf("%s = ", x_mapout(key));	if (x_tab[prefix][key] != XFUNC_ins_string)		shprintf("%s\n", x_ftab[x_tab[prefix][key]].xf_name);	else		shprintf("'%s'\n", x_atab[prefix][key]);}intx_bind(a1, a2, macro, list)	const char *a1, *a2;	int macro;		/* bind -m */	int list;		/* bind -l */{	Findex f;	int prefix, key;	char *sp = NULL;	char *m1, *m2;	if (x_tab == NULL) {		bi_errorf("cannot bind, not a tty");		return 1;	}	/* List function names */	if (list) {		for (f = 0; f < NELEM(x_ftab); f++)			if (x_ftab[f].xf_name			    && !(x_ftab[f].xf_flags & XF_NOBIND))				shprintf("%s\n", x_ftab[f].xf_name);		return 0;	}	if (a1 == NULL) {		for (prefix = 0; prefix < X_NTABS; prefix++)			for (key = 0; key < X_TABSZ; key++) {				f = x_tab[prefix][key];				if (f == XFUNC_insert || f == XFUNC_error				    || (macro && f != XFUNC_ins_string))					continue;				x_print(prefix, key);			}		return 0;	}	m1 = x_mapin(a1);	prefix = key = 0;	for (;; m1++) {		key = *m1 & CHARMASK;		if (x_tab[prefix][key] == XFUNC_meta1)			prefix = 1;		else if (x_tab[prefix][key] == XFUNC_meta2)			prefix = 2;#ifdef OS2		else if (x_tab[prefix][key] == XFUNC_meta3)			prefix = 3;#endif /* OS2 */		else			break;	}	if (a2 == NULL) {		x_print(prefix, key);		return 0;	}	if (*a2 == 0)		f = XFUNC_insert;	else if (!macro) {		for (f = 0; f < NELEM(x_ftab); f++)			if (x_ftab[f].xf_name			    && strcmp(x_ftab[f].xf_name, a2) == 0)				break;		if (f == NELEM(x_ftab) || x_ftab[f].xf_flags & XF_NOBIND) {			bi_errorf("%s: no such function", a2);			return 1;		}#if 0		/* This breaks the bind commands that map arrow keys */		if (f == XFUNC_meta1)			x_prefix1 = key;		if (f == XFUNC_meta2)			x_prefix2 = key;#endif /* 0 */	} else {		f = XFUNC_ins_string;		m2 = x_mapin(a2);		sp = str_save(m2, AEDIT);	}	if (x_tab[prefix][key] == XFUNC_ins_string && x_atab[prefix][key])		afree((void *)x_atab[prefix][key], AEDIT);	x_tab[prefix][key] = f;	x_atab[prefix][key] = sp;	/* Track what the user has bound so x_emacs_keys() won't toast things */	if (f == XFUNC_insert)		x_bound[(prefix * X_TABSZ + key) / 8] &=			~(1 << ((prefix * X_TABSZ + key) % 8));	else		x_bound[(prefix * X_TABSZ + key) / 8] |=			(1 << ((prefix * X_TABSZ + key) % 8));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -