home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / src / editcommands.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  22KB  |  790 lines

  1. /* editcommands.c -- Lisp functions for editing
  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 <ctype.h>
  25.  
  26. _PR void edit_init(void);
  27.  
  28. static VALUE sym_upcase_table, sym_downcase_table;
  29. /* These are actually 256-byte-long Lisp strings, they're initialised in
  30.    edit_init().     If struct String changes these will have to as well.  */
  31. static u_char UpCaseTable[257], DownCaseTable[257];
  32.  
  33. _PR VALUE cmd_split_line(void);
  34. DEFUN("split-line", cmd_split_line, subr_split_line, (void), V_Subr0, DOC_split_line) /*
  35. ::doc:split_line::
  36. (split-line)
  37. Splits the line into two at the cursor position, if the auto-indent option
  38. is enabled the cursor will be placed at the same level of indentation as
  39. the previous line.
  40. ::end:: */
  41. {
  42.     VW *vw = CurrVW;
  43.     TX *tx = vw->vw_Tx;
  44.     if(!readonly(tx))
  45.     {
  46.     POS old = vw->vw_CursorPos;
  47.     if(padcursor(vw))
  48.     {
  49.         if(splitline(tx, &vw->vw_CursorPos))
  50.         {
  51.         flaginsertion(tx, &old, &vw->vw_CursorPos);
  52.         return(sym_t);
  53.         }
  54.     }
  55.     }
  56.     return(sym_nil);
  57. }
  58.  
  59. _PR VALUE cmd_insert(VALUE string, VALUE pos, VALUE buff);
  60. DEFUN("insert", cmd_insert, subr_insert, (VALUE string, VALUE lpos, VALUE buff), V_Subr3, DOC_insert) /*
  61. ::doc:insert::
  62. (insert STRING [POS] [BUFFER])
  63. Inserts STRING into BUFFER at POS.
  64. ::end:: */
  65. {
  66.     POS pos;
  67.     DECLARE1(string, STRINGP);
  68.     if(POSP(lpos))
  69.     pos = VPOS(lpos);
  70.     else
  71.     pos = CurrVW->vw_CursorPos;
  72.     if(!BUFFERP(buff))
  73.     buff = CurrVW->vw_Tx;
  74.     if(!readonly(VTX(buff)) && padpos(VTX(buff), &pos))
  75.     {
  76.     if(insertstring(VTX(buff), VSTR(string), VTX(buff)->tx_TabSize, &pos))
  77.         return(sym_t);
  78.     else
  79.         settitle(NoMemMsg);
  80.     }
  81.     return(sym_nil);
  82. }
  83.  
  84. _PR VALUE cmd_insert_rect(VALUE str, VALUE pos, VALUE buff);
  85. DEFUN("insert-rect", cmd_insert_rect, subr_insert_rect, (VALUE str, VALUE lpos, VALUE buff), V_Subr3, DOC_insert_rect) /*
  86. ::doc:insert_rect::
  87. (insert-rect STRING [POS] [BUFFER])
  88. Inserts STRING into BUFFER at POS treating it as a ``rectangle'' of
  89. text -- that is, each separate line in STRING (separated by newlines) is
  90. inserted at the *same* column in successive lines.
  91. ::end:: */
  92. {
  93.     POS pos;
  94.     DECLARE1(str, STRINGP);
  95.     if(POSP(lpos))
  96.     pos = VPOS(lpos);
  97.     else
  98.     pos = CurrVW->vw_CursorPos;
  99.     if(!BUFFERP(buff))
  100.     buff = CurrVW->vw_Tx;
  101.     if(!readonly(VTX(buff)) && padpos(VTX(buff), &pos))
  102.     {
  103.     if(rectinsertstring(VTX(buff), VSTR(str), &pos))
  104.         return(sym_t);
  105.     else
  106.         settitle(NoMemMsg);
  107.     }
  108.     return(sym_nil);
  109. }
  110.  
  111. _PR VALUE cmd_delete_area(VALUE start, VALUE end, VALUE buff);
  112. DEFUN("delete-area", cmd_delete_area, subr_delete_area, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_delete_area) /*
  113. ::doc:delete_area::
  114. (delete-area START-POS END-POS [BUFFER])
  115. Deletes from START-POS up to (but not including) END-POS.
  116. ::end:: */
  117. {
  118.     POS start, end;
  119.     DECLARE1(lstart, POSP);
  120.     DECLARE2(lend, POSP);
  121.     start = VPOS(lstart);
  122.     end = VPOS(lend);
  123.     if(!BUFFERP(buff))
  124.     buff = CurrVW->vw_Tx;
  125.     if(!readonly(VTX(buff)) && checksect(VTX(buff), &start, &end))
  126.     {
  127.     deletesection(VTX(buff), &start, &end);
  128.     return(sym_t);
  129.     }
  130.     return(sym_nil);
  131. }
  132.  
  133. _PR VALUE cmd_delete_rect(VALUE lstart, VALUE lend, VALUE buff);
  134. DEFUN("delete-rect", cmd_delete_rect, subr_delete_rect, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_delete_rect) /*
  135. ::doc:delete_rect::
  136. (delete-rect START-POS END-POS [BUFFER])
  137. Deletes the rectangle of text from one corner, START-POS, to the opposite
  138. corner, END-POS.
  139. ::end:: */
  140. {
  141.     POS start, end;
  142.     DECLARE1(lstart, POSP);
  143.     DECLARE2(lend, POSP);
  144.     if(!BUFFERP(buff))
  145.     buff = CurrVW->vw_Tx;
  146.     orderrect(&start, &end, &VPOS(lstart), &VPOS(lend));
  147.     if(!readonly(VTX(buff)) && checkline(VTX(buff), &end))
  148.     {
  149.     rectdeletesection(VTX(buff), &start, &end);
  150.     return(sym_t);
  151.     }
  152.     return(sym_nil);
  153. }
  154.  
  155. _PR VALUE cmd_copy_area(VALUE lstart, VALUE lend, VALUE buff);
  156. DEFUN("copy-area", cmd_copy_area, subr_copy_area, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_copy_area) /*
  157. ::doc:copy_area::
  158. (copy-area START-POS END-POS [BUFFER])
  159. Returns the string from START-POS up to END-POS.
  160. ::end:: */
  161. {
  162.     POS start, end;
  163.     DECLARE1(lstart, POSP);
  164.     DECLARE2(lend, POSP);
  165.     start = VPOS(lstart);
  166.     end = VPOS(lend);
  167.     if(!BUFFERP(buff))
  168.     buff = CurrVW->vw_Tx;
  169.     if(checksect(VTX(buff), &start, &end))
  170.     {
  171.     long tlen = sectionlength(VTX(buff), &start, &end) + 1;
  172.     VALUE str = valstralloc(tlen);
  173.     if(str)
  174.     {
  175.         copysection(VTX(buff), &start, &end, VSTR(str));
  176.         VSTR(str)[tlen - 1] = 0;
  177.         return(str);
  178.     }
  179.     }
  180.     return(sym_nil);
  181. }
  182.  
  183. _PR VALUE cmd_copy_rect(VALUE lstart, VALUE lend, VALUE buff);
  184. DEFUN("copy-rect", cmd_copy_rect, subr_copy_rect, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_copy_rect) /*
  185. ::doc:copy_rect::
  186. (copy-rect START-POS END-POS [BUFFER])
  187. Returns the rectangle of text marked out by START-POS and END-POS.
  188. ::end:: */
  189. {
  190.     POS start, end;
  191.     DECLARE1(lstart, POSP);
  192.     DECLARE2(lend, POSP);
  193.     if(!BUFFERP(buff))
  194.     buff = CurrVW->vw_Tx;
  195.     orderrect(&start, &end, &VPOS(lstart), &VPOS(lend));
  196.     if(checkline(VTX(buff), &end))
  197.     {
  198.     long tlen = rectsectionlength(VTX(buff), &start, &end) + 1;
  199.     VALUE str = valstralloc(tlen);
  200.     if(str)
  201.     {
  202.         rectcopysection(VTX(buff), &start, &end, VSTR(str));
  203.         VSTR(str)[tlen - 1] = 0;
  204.         return(str);
  205.     }
  206.     }
  207.     return(sym_nil);
  208. }
  209.  
  210. _PR VALUE cmd_cut_area(VALUE lstart, VALUE lend, VALUE buff);
  211. DEFUN("cut-area", cmd_cut_area, subr_cut_area, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_cut_area) /*
  212. ::doc:cut_area::
  213. (cut-area START-POS END-POS [BUFFER])
  214. The same as `copy-area' except that the section of text copied (START-POS to
  215. END-POS) is deleted from the file after being duplicated.
  216. ::end:: */
  217. {
  218.     POS start, end;
  219.     DECLARE1(lstart, POSP);
  220.     DECLARE2(lend, POSP);
  221.     start = VPOS(lstart);
  222.     end = VPOS(lend);
  223.     if(!BUFFERP(buff))
  224.     buff = CurrVW->vw_Tx;
  225.     if(!readonly(VTX(buff)) && checksect(VTX(buff), &start, &end))
  226.     {
  227.     long tlen = sectionlength(VTX(buff), &start, &end) + 1;
  228.     VALUE str = valstralloc(tlen);
  229.     if(str)
  230.     {
  231.         copysection(VTX(buff), &start, &end, VSTR(str));
  232.         VSTR(str)[tlen - 1] = 0;
  233.         deletesection(VTX(buff), &start, &end);
  234.         return(str);
  235.     }
  236.     }
  237.     return(sym_nil);
  238. }
  239.  
  240. _PR VALUE cmd_cut_rect(VALUE lstart, VALUE lend, VALUE buff);
  241. DEFUN("cut-rect", cmd_cut_rect, subr_cut_rect, (VALUE lstart, VALUE lend, VALUE buff), V_Subr3, DOC_cut_rect) /*
  242. ::doc:cut_rect::
  243. (cut-rect START-POS END-POS [BUFFER])
  244. The same as `copy-rect' except that the section of text copied (START-POS
  245. to END-POS) is deleted from the file after being duplicated.
  246. ::end:: */
  247. {
  248.     POS start, end;
  249.     DECLARE1(lstart, POSP);
  250.     DECLARE2(lend, POSP);
  251.     if(!BUFFERP(buff))
  252.     buff = CurrVW->vw_Tx;
  253.     orderrect(&start, &end, &VPOS(lstart), &VPOS(lend));
  254.     if(!readonly(VTX(buff)) && checkline(VTX(buff), &end))
  255.     {
  256.     long tlen = rectsectionlength(VTX(buff), &start, &end) + 1;
  257.     VALUE str = valstralloc(tlen);
  258.     if(str)
  259.     {
  260.         rectcopysection(VTX(buff), &start, &end, VSTR(str));
  261.         VSTR(str)[tlen - 1] = 0;
  262.         rectdeletesection(VTX(buff), &start, &end);
  263.         return(str);
  264.     }
  265.     }
  266.     return(sym_nil);
  267. }
  268.  
  269. _PR VALUE cmd_block_toggle(void);
  270. DEFUN("block-toggle", cmd_block_toggle, subr_block_toggle, (void), V_Subr0, DOC_block_toggle) /*
  271. ::doc:block_toggle::
  272. (block-toggle)
  273. ::end:: */
  274. {
  275.     VW *vw = CurrVW;
  276.     switch(vw->vw_BlockStatus)
  277.     {
  278.     case 0:
  279.         vw->vw_BlockStatus = -1;
  280.         setblockrefresh(vw);
  281.         break;
  282.     case 1:
  283.