home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- /* Routines to perform all kinds of deletion. */
-
- #include "jove.h"
-
- /* Assumes that either line1 or line2 is actual the current line, so it can
- put its result into linebuf. */
-
- void
- patchup(line1, char1, line2, char2)
- Line *line1,
- *line2;
- register int char1,
- char2;
- {
- if (line1 != line2)
- ChkWindows(line1, line2);
- DotTo(line1, char1);
- modify();
- linecopy(linebuf, curchar, lcontents(line2) + char2);
-
- /* The following is a redisplay optimization. */
- if (line1 != line2 && (char1 == 0 && char2 == 0))
- line1->l_dline = line2->l_dline;
-
- DFixMarks(line1, char1, line2, char2);
- makedirty(curline);
- }
-
- /* Deletes the region by unlinking the lines in the middle,
- and patching things up. The unlinked lines are still in
- order. */
-
- Line *
- reg_delete(line1, char1, line2, char2)
- Line *line1,
- *line2;
- {
- register Line *retline;
-
- if ((line1 == line2 && char1 == char2) || line2 == 0)
- complain((char *) 0);
- (void) fixorder(&line1, &char1, &line2, &char2);
-
- retline = nbufline(); /* New buffer line */
-
- (void) ltobuf(line1, genbuf);
- if (line1 == line2)
- genbuf[char2] = '\0';
-
- retline->l_prev = 0;
- retline->l_dline = putline(&genbuf[char1]);
- patchup(line1, char1, line2, char2);
-
- if (line1 == line2)
- retline->l_next = 0;
- else {
- retline->l_next = line1->l_next;
- (void) ltobuf(line2, genbuf);
- genbuf[char2] = '\0';
- line2->l_dline = putline(genbuf);
- /* Shorten this line */
- }
-
- if (line1 != line2) {
- line1->l_next = line2->l_next;
- if (line1->l_next)
- line1->l_next->l_prev = line1;
- else
- curbuf->b_last = line1;
- line2->l_next = 0;
- }
-
- return retline;
- }
-
- void
- lremove(line1, line2)
- register Line *line1,
- *line2;
- {
- Line *next = line1->l_next;
-
- if (line1 == line2)
- return;
- line1->l_next = line2->l_next;
- if (line1->l_next)
- line1->l_next->l_prev = line1;
- else
- curbuf->b_last = line1;
- lfreereg(next, line2); /* Put region at end of free line list. */
- }
-
- /* Delete character forward */
-
- void
- DelNChar()
- {
- del_char(FORWARD, arg_value());
- }
-
- /* Delete character backward */
-
- void
- DelPChar()
- {
- if (MinorMode(OverWrite)) {
- int count = min(arg_value(), curchar);
-
- b_char(count);
-
- /* overwrite with spaces */
- set_arg_value(count);
- LastKeyStruck = ' ';
- SelfInsert();
-
- b_char(count);
- } else
- del_char(BACKWARD, arg_value());
- }
-
- /* Delete some characters. If deleting forward then call for_char
- to the final position otherwise call back_char. Then delete the
- region between the two with patchup(). */
-
- void
- del_char(dir, num)
- {
- Bufpos before,
- after;
- int killp = (abs(num) > 1);
-
- DOTsave(&before);
- if (dir == FORWARD) f_char(num);
- else b_char(num);
- if (before.p_line == curline && before.p_char == curchar)
- complain((char *) 0);
- if (killp)
- reg_kill(before.p_line, before.p_char, 1);
- else {
- DOTsave(&after);
- (void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char);
- patchup(before.p_line, before.p_char, after.p_line, after.p_char);
- lremove(before.p_line, after.p_line);
- }
- }
-
- /* This kills a region between point, and line1/char1 and puts it on
- the kill-ring. If the last command was one of the kill commands,
- the region is appended (prepended if backwards) to the last entry. */
-
- int killptr = 0;
- Line *killbuf[NUMKILLS];
-
- void
- reg_kill(line2, char2, dot_moved)
- Line *line2;
- {
- Line *nl,
- *line1 = curline;
- int char1 = curchar;
- int backwards;
-
- backwards = !fixorder(&line1, &char1, &line2, &char2);
- /* This is a kludge! But it possible for commands that don't
- know which direction they are deleting in (e.g., delete
- previous word could have been called with a negative argument
- in which case, it wouldn't know that it really deleted
- forward. */
-
- if (!dot_moved)
- backwards = !backwards;
-
- DotTo(line1, char1);
-
- nl = reg_delete(line1, char1, line2, char2);
-
- if (last_cmd != KILLCMD) {
- killptr = ((killptr + 1) % NUMKILLS);
- lfreelist(killbuf[killptr]);
- killbuf[killptr] = nl;
- } else {
- Line *lastln = lastline(nl);
-
- if (backwards)
- (void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0);
- else {
- Line *olastln = lastline(killbuf[killptr]);
-
- (void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0);
- }
- }
- this_cmd = KILLCMD;
- }
-
- void
- DelReg()
- {
- register Mark *mp = CurMark();
-
- reg_kill(mp->m_line, mp->m_char, 0);
- }
-
- /* Save a region. A pretend kill. */
-
- void
- CopyRegion()
- {
- register Line *nl;
- register Mark *mp;
- register int status;
-
- mp = CurMark();
- if (mp->m_line == curline && mp->m_char == curchar)
- complain((char *) 0);
-
- killptr = ((killptr + 1) % NUMKILLS);
- if (killbuf[killptr])
- lfreelist(killbuf[killptr]);
- nl = killbuf[killptr] = nbufline();
- SavLine(nl, NullStr);
- nl->l_next = nl->l_prev = 0;
-
- status = inorder(mp->m_line, mp->m_char, curline, curchar);
- if (status == -1)
- return;
-
- if (status)
- (void) DoYank(mp->m_line, mp->m_char, curline, curchar,
- nl, 0, (Buffer *) 0);
- else
- (void) DoYank(curline, curchar, mp->m_line, mp->m_char,
- nl, 0, (Buffer *) 0);
- }
-
- void
- DelWtSpace()
- {
- register char *ep = &linebuf[curchar],
- *sp = &linebuf[curchar];
-
- while (*ep == ' ' || *ep == '\t')
- ep += 1;
- while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
- sp -= 1;
- if (sp != ep) {
- curchar = sp - linebuf;
- DFixMarks(curline, curchar, curline, curchar + (ep - sp));
- strcpy(sp, ep);
- makedirty(curline);
- modify();
- }
- }
-
- void
- DelBlnkLines()
- {
- register Mark *dot;
- int all;
-
- if (!blnkp(&linebuf[curchar]))
- return;
- dot = MakeMark(curline, curchar, M_FLOATER);
- all = !blnkp(linebuf);
- while (blnkp(linebuf) && curline->l_prev)
- SetLine(curline->l_prev);
- all |= (firstp(curline));
- Eol();
- DelWtSpace();
- line_move(FORWARD, 1, NO);
- while (blnkp(linebuf) && !eobp()) {
- DelWtSpace();
- del_char(FORWARD, 1);
- }
- if (!all && !eobp())
- open_lines(1);
- ToMark(dot);
- DelMark(dot);
- }
-
- void
- DelNWord()
- {
- dword(1);
- }
-
- void
- DelPWord()
- {
- dword(0);
- }
-
- void
- dword(forward)
- {
- Bufpos savedot;
-
- DOTsave(&savedot);
- if(forward) ForWord();
- else BackWord();
- reg_kill(savedot.p_line, savedot.p_char, 1);
- }
-