home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / buffers.c < prev    next >
C/C++ Source or Header  |  1994-10-03  |  30KB  |  1,147 lines

  1. /* buffers.c -- Buffer handling
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <string.h>
  24. #include <stdlib.h>
  25.  
  26. _PR void buffer_sweep(void);
  27. _PR void buffer_prin(VALUE, VALUE);
  28. _PR TX *first_buffer(void);
  29. _PR void swap_buffers(VW *, TX *);
  30. _PR TX *swap_buffers_tmp(VW *, TX *);
  31. _PR POS *get_tx_cursor(TX *);
  32. _PR int auto_save_buffers(void);
  33. _PR void make_marks_resident(TX *);
  34. _PR void make_marks_non_resident(TX *);
  35. _PR void mark_sweep(void);
  36. _PR int mark_cmp(VALUE, VALUE);
  37. _PR void mark_prin(VALUE, VALUE);
  38. _PR void buffers_init(void);
  39. _PR void buffers_kill(void);
  40.  
  41. /*
  42.  * Chain of all allocated TXs.
  43.  */
  44. _PR TX *buffer_chain;
  45. TX *buffer_chain;
  46.  
  47. VALUE sym_auto_save_function, sym_leading, sym_all;
  48.  
  49. _PR VALUE cmd_make_buffer_name(VALUE);
  50. DEFUN("make-buffer-name", cmd_make_buffer_name, subr_make_buffer_name, (VALUE rawName), V_Subr1, DOC_make_buffer_name) /*
  51. ::doc:make_buffer_name::
  52. make-buffer-name NAME
  53.  
  54. Construct a unique buffer-name from NAME.
  55. ::end:: */
  56. {
  57.     int suffix = 1;
  58.     DECLARE1(rawName, STRINGP);
  59.     while(TRUE)
  60.     {
  61.     u_char buf[256];
  62.     u_char *thistry;
  63.     TX *tx = buffer_chain;
  64.     if(suffix != 1)
  65.     {
  66.         sprintf(buf, "%s<%d>", VSTR(rawName), suffix);
  67.         thistry = buf;
  68.     }
  69.     else
  70.         thistry = VSTR(rawName);
  71.     while(tx)
  72.     {
  73.         if(tx->tx_BufferName && !strcmp(thistry, VSTR(tx->tx_BufferName)))
  74.         break;
  75.         tx = tx->tx_Next;
  76.     }
  77.     if(!tx)
  78.     {
  79.         if(suffix == 1)
  80.         return(rawName);
  81.         return(string_dup(buf));
  82.     }
  83.     suffix++;
  84.     }
  85. }
  86.  
  87. _PR VALUE cmd_make_buffer(VALUE, VALUE, VALUE);
  88. DEFUN("make-buffer", cmd_make_buffer, subr_make_buffer, (VALUE name, VALUE oldTx, VALUE litName), V_Subr3, DOC_make_buffer) /*
  89. ::doc:make_buffer::
  90. make-buffer NAME
  91.  
  92. Return a new buffer, it's name is the result of (make-buffer-name NAME).
  93. ::end:: */
  94. {
  95.     TX *tx;
  96.     DECLARE1(name, STRINGP);
  97.     if(!BUFFERP(oldTx))
  98.     {
  99.     if(curr_vw)
  100.         oldTx = VAL(curr_vw->vw_Tx);
  101.     else
  102.         oldTx = NULL;
  103.     }
  104.     if((tx = mycalloc(sizeof(TX))) && clear_line_list(tx))
  105.     {
  106.     tx->tx_Type = V_Buffer;
  107.     tx->tx_Next = buffer_chain;
  108.     buffer_chain = tx;
  109.     data_after_gc += sizeof(TX);
  110.     tx->tx_BufferName = NILP(litName) ? cmd_make_buffer_name(name) : name;
  111.     if(tx->tx_BufferName)
  112.     {
  113.         tx->tx_FileName = null_string;
  114.         tx->tx_MinorModeNameList = sym_nil;
  115.         tx->tx_MinorModeNameString = null_string;
  116.         tx->tx_SavedBlockStatus = -1;
  117.         tx->tx_TabSize = 8;
  118.         tx->tx_LocalVariables = sym_nil;
  119.         tx->tx_GlyphTable = oldTx ? VTX(oldTx)->tx_GlyphTable
  120.                               : cmd_default_glyph_table();
  121.         tx->tx_LastSaveTime = sys_time();
  122.         tx->tx_UndoList = sym_nil;
  123.         tx->tx_ToUndoList = NULL;
  124.         tx->tx_UndoneList = sym_nil;
  125.         return(VAL(tx));
  126.     }
  127.     }
  128.     return(NULL);
  129. }
  130.  
  131. _PR VALUE cmd_destroy_buffer(VALUE);
  132. DEFUN("destroy-buffer", cmd_destroy_buffer, subr_destroy_buffer, (VALUE tx), V_Subr1, DOC_destroy_buffer) /*
  133. ::doc:destroy_buffer::
  134. destory-buffer BUFFER
  135.  
  136. Throw away everything associated with buffer. All resident marks are made
  137. non-resident.
  138. ::end:: */
  139. {
  140.     DECLARE1(tx, BUFFERP);
  141.     make_marks_non_resident(VTX(tx));
  142.     clear_line_list(VTX(tx));
  143.     VTX(tx)->tx_FileName = null_string;
  144.     VTX(tx)->tx_BufferName = null_string;
  145.     VTX(tx)->tx_ModeName = NULL;
  146.     VTX(tx)->tx_MinorModeNameList = sym_nil;
  147.     VTX(tx)->tx_MinorModeNameString = null_string;
  148.     VTX(tx)->tx_Changes = 0;
  149.     VTX(tx)->tx_LocalVariables = sym_nil;
  150.     VTX(tx)->tx_GlyphTable = cmd_default_glyph_table();
  151.     VTX(tx)->tx_Flags |= TXFF_RDONLY | TXFF_REFRESH_ALL | TXFF_NO_UNDO;
  152.     VTX(tx)->tx_UndoList = sym_nil;
  153.     VTX(tx)->tx_ToUndoList = NULL;
  154.     VTX(tx)->tx_UndoneList = sym_nil;
  155. #if 0
  156.     sm_flush(&main_strmem);
  157. #endif
  158.     return(sym_t);
  159. }
  160.  
  161. void
  162. buffer_sweep(void)
  163. {
  164.     TX *tx = buffer_chain;
  165.     buffer_chain = NULL;
  166.     while(tx)
  167.     {
  168.     TX *nxt = tx->tx_Next;
  169.     if(!GC_MARKEDP(VAL(tx)))
  170.     {
  171.         make_marks_non_resident(tx);
  172.         kill_line_list(tx);
  173.         myfree(tx);
  174.     }
  175.     else
  176.     {
  177.         GC_CLR(VAL(tx));
  178.         tx->tx_Next = buffer_chain;
  179.         buffer_chain = tx;
  180.     }
  181.     tx = nxt;
  182.     }
  183. }
  184. void
  185. buffer_prin(VALUE strm, VALUE obj)
  186. {
  187.     stream_puts(strm, "#<buffer ", -1, FALSE);
  188.     stream_puts(strm, VSTR(VTX(obj)->tx_BufferName), -1, TRUE);
  189.     stream_putc(strm, '>');
  190. }
  191.  
  192. TX *
  193. first_buffer(void)
  194. {
  195.     TX *tx;
  196.     if(!curr_vw)
  197.     {
  198.     curr_vw = VWIN(cmd_make_window(sym_nil, sym_nil, sym_nil, sym_nil));
  199.     if(!curr_vw)
  200.         return(NULL);
  201.     }
  202.     tx = VTX(cmd_make_buffer(MKSTR("*jade*"), sym_nil, sym_t));
  203.     if(tx)
  204.     {
  205.     swap_buffers(curr_vw, tx);
  206. #ifndef NOSCRLBAR
  207.     sys_update_scroller(curr_vw);
  208. #endif
  209.     return(tx);
  210.     }
  211.     return(NULL);
  212. }
  213.  
  214. /*
  215.  * Makes `new' the file being shown in window `vw'
  216.  */
  217. void
  218. swap_buffers(VW *vw, TX *new)
  219. {
  220.     TX *old = vw->vw_Tx;
  221.     if(old != new)
  222.     {
  223.     if(old)
  224.     {
  225.         old->tx_SavedCPos = vw->vw_CursorPos;
  226.         old->tx_SavedWPos = vw->vw_DisplayOrigin;
  227.         old->tx_SavedBlockPos[0] = vw->vw_BlockS;
  228.         old->tx_SavedBlockPos[1] = vw->vw_BlockE;
  229.         old->tx_SavedBlockStatus = vw->vw_BlockStatus;
  230.     }
  231.     vw->vw_Tx = new;
  232.     vw->vw_CursorPos = new->tx_SavedCPos;
  233.     vw->vw_DisplayOrigin = new->tx_SavedWPos;
  234.     vw->vw_BlockS = new->tx_SavedBlockPos[0];
  235.     vw->vw_BlockE = new->tx_SavedBlockPos[1];
  236.     vw->vw_BlockStatus = new->tx_SavedBlockStatus;
  237.     vw->vw_LastRefTx = NULL;
  238.     }
  239. }
  240. /*
  241.  * "nd" means non-destructive. refcount's of buffers are not changed and
  242.  * previous buffer shown is returned.
  243.  * This is intended to allow *temporary* switching of buffers before
  244.  * reinstalling the original.
  245.  * ** this is kind of obsolete but never mind **
  246.  */
  247. TX *
  248. swap_buffers_tmp(VW *vw, TX *new)
  249. {
  250.     TX *old = vw->vw_Tx;
  251.     if(old != new)
  252.     {
  253.     if(old)
  254.     {
  255.         old->tx_SavedCPos = vw->vw_CursorPos;
  256.         old->tx_SavedWPos = vw->vw_DisplayOrigin;
  257.         old->tx_SavedBlockPos[0] = vw->vw_BlockS;
  258.         old->tx_SavedBlockPos[1] = vw->vw_BlockE;
  259.         old->tx_SavedBlockStatus = vw->vw_BlockStatus;
  260.     }
  261.     vw->vw_Tx = new;
  262.     vw->vw_CursorPos = new->tx_SavedCPos;
  263.     vw->vw_DisplayOrigin = new->tx_SavedWPos;
  264.     vw->vw_BlockS = new->tx_SavedBlockPos[0];
  265.     vw->vw_BlockE = new->tx_SavedBlockPos[1];
  266.     vw->vw_BlockStatus = new->tx_SavedBlockStatus;
  267.     }
  268.     return(old);
  269. }
  270.  
  271. _PR VALUE cmd_get_file_buffer(VALUE);
  272. DEFUN("get-file-buffer", cmd_get_file_buffer, subr_get_file_buffer, (VALUE name), V_Subr1, DOC_get_file_buffer) /*
  273. ::doc:get_file_buffer::
  274. get-file-buffer NAME
  275.  
  276. Scan all buffers for one containing the file NAME.
  277. ::end:: */
  278. {
  279.     TX *tx = buffer_chain;
  280.     DECLARE1(name, STRINGP);
  281.     while(tx)
  282.     {
  283.     if(same_files(VSTR(name), VSTR(tx->tx_FileName)))
  284.         return(VAL(tx));
  285.     tx = tx->tx_Next;
  286.     }
  287.     return(sym_nil);
  288. }
  289.  
  290. _PR VALUE cmd_get_buffer(VALUE);
  291. DEFUN("get-buffer", cmd_get_buffer, subr_get_buffer, (VALUE name), V_Subr1, DOC_get_buffer) /*
  292. ::doc:get_buffer::
  293. get-buffer NAME
  294.  
  295. Scan all buffers for one whose name is NAME.
  296. ::end:: */
  297. {
  298.     TX *tx = buffer_chain;
  299.     if(BUFFERP(name))
  300.     return(name);
  301.     DECLARE1(name, STRINGP);
  302.     while(tx)
  303.     {
  304.     if(!strcmp(VSTR(name), VSTR(tx->tx_BufferName)))
  305.         return(VAL(tx));
  306.     tx = tx->tx_Next;
  307.     }
  308.     return(sym_nil);
  309. }
  310.  
  311. POS *
  312. get_tx_cursor(TX *tx)
  313. {
  314.     VW *vw = view_chain;
  315.     /* Check active window first */
  316.     if(curr_vw->vw_Tx == tx)
  317.     return(&curr_vw->vw_CursorPos);
  318.     while(vw)
  319.     {
  320.     if(vw->vw_Window && (vw->vw_Tx == tx))
  321.         return(&vw->vw_CursorPos);
  322.     vw = vw->vw_Next;
  323.     }
  324.     return(&tx->tx_SavedCPos);
  325. }
  326.  
  327. /*
  328.  * returns the number of buffers saved.
  329.  * (maybe should only save one buffer at a time, then wait to be c