home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
word
/
text
/
019
/
ins.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
5KB
|
254 lines
/*
* Copyright (c) 1992 John E. Davis (davis@amy.tch.harvard.edu)
* All Rights Reserved.
*/
#include <stdio.h>
#include "buffer.h"
#include "ins.h"
#include "line.h"
#include "screen.h"
#include "window.h"
#include "misc.h"
#include "paste.h"
#include "vterm.h"
void update_generic_marks(Mark *m, int type, int n)
{
if (m == NULL) return;
/* called by line deletion routines */
if (type == LDELETE) while(m != NULL)
{
if (CLine == m->line)
{
if (CLine->prev != NULL)
m->line = CLine->prev;
else m->line = CBuf->beg;
m->point = 0;
}
m = m->next;
}
else if (type == CINSERT) while(m != NULL)
{
if ((m->line == CLine) && (m->point > Point))
{
m->point += n;
}
m = m->next;
}
else if (type == CDELETE) while(m != NULL)
{
if ((m->line == CLine) && (m->point > Point))
{
m->point -= n;
if (m->point < Point) m->point = Point;
}
m = m->next;
}
else if (type == NLINSERT) while(m != NULL)
{
/* This is a bit controversial if the mark corresponds to Window->beg.
In this case, Window beg gets shifted if Point = 0. */
if ((m->line == CLine) && (m->point >= Point))
{
m->line = CLine->next;
m->point -= Point;
if (m->point > m->line->len) m->point = m->line->len;
}
m = m->next;
}
else if (type == NLDELETE) while(m != NULL)
{
if (m->line == CLine)
{
m->line = CLine->prev;
m->point += Point;
}
m = m->next;
}
}
void update_marks(int type, int n)
{
Window_Type *w;
Cursor_Motion = 0;
mark_buffer_modified(&Number_One);
update_generic_marks(CBuf->spots, type, n);
update_generic_marks(CBuf->marks, type, n);
w = Window;
do
{
if (w->buffer == CBuf)
{
update_generic_marks(&(w->mark), type, n);
update_generic_marks(&(w->beg), type, n);
}
w = w->next;
}
while(w != Window);
register_change(type);
}
void ins(char c)
{
unsigned char *p, *p1;
if (CLine == NULL)
{
exit_error("ins: CLine is NULL\n");
}
if (CLine->space <= CLine->len + 1)
{
remake_line(CLine->space + 25);
}
p = CLine->data + Point;
if (Point < CLine->len)
{
p1 = CLine->data + (CLine->len - 1);
while(p1 >= p)
{
*(p1 + 1) = *p1;
p1--;
}
}
*p = c;
CLine->len += 1;
update_marks(CINSERT,1);
Point++;
}
void del()
{
unsigned char *p, *p1;
if (eobp())
{
msg_error("End of Buffer.");
return;
}
if (!eolp())
{
p = CLine->data + Point;
p1 = CLine->data + (CLine->len - 1);
while(p < p1)
{
*p = *(p + 1);
p++;
}
update_marks(CDELETE,1);
CLine->len -= 1;
}
else
{
if (CLine->len == 0)
{
exit_error("del(): empty line.");
}
CLine->len -= 1;
update_marks(CDELETE,1);
splice_line();
}
}
void ins_chars(unsigned char *s, int n)
{
unsigned char *p1, *p;
int n1, n2;
p1 = s;
n1 = 0;
/* count the number until a new line is reached */
while((n1 < n) && (*p1 != '\n'))
{
n1++;
p1++;
}
if (CLine->space <= CLine->len + n1 + 1)
{
remake_line(CLine->space + n1 + 25);
}
/* shove n1 chars over to make space */
p = CLine->data + Point;
if (Point < CLine->len) /* could be equal for last line of buffer */
{
p1 = CLine->data + CLine->len - 1;
while(p1 >= p)
{
*(p1 + n1) = *p1;
p1--;
}
}
CLine->len += n1;
n2 = n1;
while (n2--) *p++ = *s++;
update_marks(CINSERT, n1);
Point += n1;
if (n1 < n)
{
split_line();
ins('\n');
CLine = CLine->next;
Point = 0;
ins_chars(s + 1, n - n1 - 1);
}
}
void ins_char_n_times(char c, int n)
{
char b[100], *p;
int n1;
if (n == 0) return;
if (n > 100) n = 100;
p = b;
n1 = n;
while(n1--) *p++ = c;
ins_chars((unsigned char *) b, n);
}
void insert_buffer(Buffer *b)
{
Buffer *cb;
if ((cb = CBuf) == b) return;
switch_to_buffer(b);
push_spot();
bob(); push_mark();
eob();
copy_region_to_buffer(cb);
pop_spot();
switch_to_buffer(cb);
touch_window();
}
int No_Screen_Update;
void fast_ins(char ch)
{
No_Screen_Update = 1;
vins(ch);
ins(ch);
}
void fast_del()
{
No_Screen_Update = 1;
vdel();
del();
}