1/*
2 * deltochar.c - ZLE module implementing Emacs' zap-to-char
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1996-1997 Peter Stephenson
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Peter Stephenson or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Peter Stephenson and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Peter Stephenson and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Peter Stephenson and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "deltochar.mdh"
31#include "deltochar.pro"
32
33static Widget w_deletetochar;
34static Widget w_zaptochar;
35
36/**/
37static int
38deltochar(UNUSED(char **args))
39{
40    ZLE_INT_T c = getfullchar(0);
41    int dest = zlecs, ok = 0, n = zmult;
42    int zap = (bindk->widget == w_zaptochar);
43
44    if (n > 0) {
45	while (n-- && dest != zlell) {
46	    while (dest != zlell && (ZLE_INT_T)zleline[dest] != c)
47		INCPOS(dest);
48	    if (dest != zlell) {
49		if (!zap || n > 0)
50		    INCPOS(dest);
51		if (!n) {
52		    forekill(dest - zlecs, CUT_RAW);
53		    ok++;
54		}
55	    }
56	}
57    } else {
58	/* ignore character cursor is on when scanning backwards */
59	if (dest)
60	    DECPOS(dest);
61	while (n++ && dest != 0) {
62	    while (dest != 0 && (ZLE_INT_T)zleline[dest] != c)
63		DECPOS(dest);
64	    if ((ZLE_INT_T)zleline[dest] == c) {
65		if (!n) {
66		    /* HERE adjust zap for trailing combining chars */
67		    backkill(zlecs - dest - zap, CUT_RAW|CUT_FRONT);
68		    ok++;
69		}
70		if (dest)
71		    DECPOS(dest);
72	    }
73	}
74    }
75    return !ok;
76}
77
78
79static struct features module_features = {
80    NULL, 0,
81    NULL, 0,
82    NULL, 0,
83    NULL, 0,
84    0
85};
86
87
88/**/
89int
90setup_(UNUSED(Module m))
91{
92    return 0;
93}
94
95/**/
96int
97features_(Module m, char ***features)
98{
99    *features = featuresarray(m, &module_features);
100    return 0;
101}
102
103/**/
104int
105enables_(Module m, int **enables)
106{
107    return handlefeatures(m, &module_features, enables);
108}
109
110/**/
111int
112boot_(Module m)
113{
114    w_deletetochar = addzlefunction("delete-to-char", deltochar,
115                                    ZLE_KILL | ZLE_KEEPSUFFIX);
116    if (w_deletetochar) {
117	w_zaptochar = addzlefunction("zap-to-char", deltochar,
118				     ZLE_KILL | ZLE_KEEPSUFFIX);
119	if (w_zaptochar)
120	    return 0;
121	deletezlefunction(w_deletetochar);
122    }
123    zwarnnam(m->node.nam, "deltochar: name clash when adding ZLE functions");
124    return -1;
125}
126
127/**/
128int
129cleanup_(Module m)
130{
131    deletezlefunction(w_deletetochar);
132    deletezlefunction(w_zaptochar);
133    return setfeatureenables(m, &module_features, NULL);
134}
135
136/**/
137int
138finish_(UNUSED(Module m))
139{
140    return 0;
141}
142