This is ins.c in view mode; [Download] [Up]
/* * Copyright (c) 1992, 1995 John E. Davis (davis@space.mit.edu) * All Rights Reserved. */ #include <config.h> #include <stdio.h> #include <string.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" #include "ledit.h" #include "undo.h" int Suspend_Screen_Update = 0; static void update_generic_marks(register Mark *m, register int type, int n) { int tmp; if (m == NULL) return; 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)) { /* BCC generates wrong code here with optimization */ tmp = m->point; tmp -= n; if (tmp < Point) tmp = Point; m->point = tmp; /* BAD CODE: m->point -= n; if (m->point < Point) m->point = Point; */ } m = m->next; } /* called by line deletion routines */ else 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; } if (LineNum + CBuf->nup <= m->n) m->n -= 1; m = m->next; } /* newline added-- affects only marks onward from insertion point */ else if (type == NLINSERT) while(m != NULL) { /* This is a bit controversial if the mark corresponds to JWindow->beg. In this case, JWindow beg gets shifted if Point = 0. */ if ((LineNum + CBuf->nup < m->n) || ((LineNum + CBuf->nup == m->n) && (m->point > Point))) m->n += 1; 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; } /* deletion performed at end of a line (CLine->prev) */ else if (type == NLDELETE) while(m != NULL) { if (m->line == CLine) { m->line = CLine->prev; m->point += Point; } if (LineNum + CBuf->nup <= m->n) m->n -= 1; m = m->next; } } void update_marks(int type, int n) { register Window_Type *w; register Buffer *b = CBuf; Mark *m; if (!n) return; Cursor_Motion = 0; if (b->flags & UNDO_ENABLED) { if (b->undo == NULL) create_undo_ring(); Undo_Buf_Unch_Flag = !(b->flags & BUFFER_TRASHED); } mark_buffer_modified(&Number_One); if ((m = b->spots) != NULL) update_generic_marks(m, type, n); if ((m = b->marks) != NULL) update_generic_marks(m, type, n); if ((m = b->user_marks) != NULL) update_generic_marks(m, type, n); w = JWindow; do { if (w->buffer == b) { update_generic_marks(&w->mark, type, n); update_generic_marks(&w->beg, type, n); } w = w->next; } while(w != JWindow); if (!Suspend_Screen_Update) register_change(type); } void ins(char c) { register unsigned char *p, *p1, *p2; if (CLine == NULL) { exit_error("ins: CLine is NULL", 1); } #ifdef KEEP_SPACE_INFO if (CLine->space <= CLine->len + 1) remake_line(CLine->space + 15); #else remake_line (CLine->len + 1); #endif p = CLine->data + Point; if (Point < CLine->len) { p1 = CLine->data + (CLine->len - 1); p2 = p1 + 1; while(p1 >= p) { *p2 = *p1; p2 = p1; p1--; /* *(p1 + 1) = *p1; p1--; */ } } *p = c; CLine->len += 1; update_marks(CINSERT,1); if ((c != '\n') || (CBuf == MiniBuffer)) record_insertion(1); Point++; } void del_newline(void) { CHECK_READ_ONLY_VOID #ifdef JED_LINE_ATTRIBUTES if ((CLine->next != NULL) && (CLine->next->flags & JED_LINE_READONLY)) { msg_error (Line_Read_Only_Error); return; } #endif if (!eol() || eobp()) return; #ifdef DEBUG_JED if (CLine->len == 0) { exit_error("del(): empty line", 1); } #endif CLine->len -= 1; update_marks(CDELETE,1); record_deletion((unsigned char *) "\n", 1); splice_line(); } /* del *np chars up until newline. Return actual number deleted */ int deln(int *np) { int n = *np; register int nn; register unsigned char *p, *pmax; if ((n == 0) || !CLine->len) return(0); nn = CLine->len - 1; p = CLine->data + nn; if ((*p == '\n') && (CBuf != MiniBuffer)) nn = nn - Point; else nn = nn - Point + 1; p = CLine->data + Point; nn = nn > n ? n : nn; if (!nn) return (0); update_marks(CDELETE, nn); record_deletion(p, nn); CLine->len -= nn; pmax = CLine->data + CLine->len; while (p < pmax) { *p = *(p + nn); p++; } return(nn); } /* delete n characters, crossing nl if necessary */ void generic_deln(int *np) { int n = *np; CHECK_READ_ONLY_VOID while ((n > 0) && (SLang_Error == 0)) { if (eobp()) { msg_error("End of Buffer."); return; } n -= deln(&n); if (n) del_newline(); n--; } } void del() { generic_deln(&Number_One); } void quick_insert(register unsigned char *s, int n) { register unsigned char *p, *p1; int nl = 0; if (n == 0) return; if ((*(s + (n - 1)) == '\n') && (CBuf != MiniBuffer)) { n--; nl = 1; } #ifdef KEEP_SPACE_INFO if (CLine->space <= CLine->len + n + 1) remake_line(CLine->space + n + 8); #else if (n) remake_line (CLine->len + n); #endif /* shove n 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 + n) = *p1; p1--; } } CLine->len += n; MEMCPY((char *) p, (char *) s, n); update_marks(CINSERT, n); record_insertion(n); Point += n; if (nl) { split_line(); ins('\n'); CLine = CLine->next; LineNum++; Point = 0; } } void ins_chars(unsigned char *ss, int n) { register unsigned char nl, *pmax; register unsigned char *p, *p1, *s = ss; int n1; if (CBuf == MiniBuffer) nl = 0; else nl = '\n'; p1 = s; while (1) { p = p1; /* count the number until a new line is reached */ pmax = p1 + n; while((p1 < pmax) && (*p1 != nl)) p1++; n1 = (int) (p1 - p); if (p1 != pmax) n1++; quick_insert(p, n1); if (p1++ == pmax) return; n -= n1; } } /* This needs fixed to handle large n */ void ins_char_n_times(char c, int n) { char b[256], *p; int n1; if (n == 0) return; if (n > 255) n = 255; 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) { if (JWindow == JWindow->next) No_Screen_Update = 1; vins(ch); ins(ch); } void fast_del() { if (JWindow == JWindow->next) No_Screen_Update = 1; vdel(); del(); } void replace_char(unsigned char ch) { if (ch == '\n') return; if (*(CLine->data + Point) == ch) return; ins(ch); del(); Point--; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.