home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / movement.c < prev    next >
C/C++ Source or Header  |  1994-09-09  |  25KB  |  932 lines

  1. /* movement.c -- Positioning the cursor
  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 <ctype.h>
  24.  
  25. static long move_down_screens(long);
  26. static long move_up_screens(long);
  27. static bool prev_char(long, POS *, TX *);
  28. static bool next_char(long, POS *, TX *);
  29. static int find_matching_bracket(POS *, TX *, u_char esc);
  30. _PR void movement_init(void);
  31.  
  32. _PR VALUE cmd_screen_top_line(void);
  33. DEFUN("screen-top-line", cmd_screen_top_line, subr_screen_top_line, (void), V_Subr0, DOC_screen_top_line) /*
  34. ::doc:screen_top_line::
  35. screen-top-line
  36.  
  37. Returns the line number of the first line being shown in the current window.
  38. ::end:: */
  39. {
  40.     return(make_number(curr_vw->vw_StartLine));
  41. }
  42.  
  43. _PR VALUE cmd_screen_bottom_line(void);
  44. DEFUN("screen-bottom-line", cmd_screen_bottom_line, subr_screen_bottom_line, (void), V_Subr0, DOC_screen_bottom_line) /*
  45. ::doc:screen_bottom_line::
  46. screen-bottom-line
  47.  
  48. Returns the line number of the last line being shown in the current window.
  49. ::end:: */
  50. {
  51.     return(make_number(curr_vw->vw_StartLine + curr_vw->vw_MaxY - 1));
  52. }
  53.  
  54. _PR VALUE cmd_screen_first_column(void);
  55. DEFUN("screen-first-column", cmd_screen_first_column, subr_screen_first_column, (void), V_Subr0, DOC_screen_first_column) /*
  56. ::doc:screen_first_column::
  57. screen-first-column
  58.  
  59. Returns the line number of the first column being shown in the current window.
  60. ::end:: */
  61. {
  62.     return(make_number(curr_vw->vw_StartCol));
  63. }
  64.  
  65. _PR VALUE cmd_screen_last_column(void);
  66. DEFUN("screen-last-column", cmd_screen_last_column, subr_screen_last_column, (void), V_Subr0, DOC_screen_last_column) /*
  67. ::doc:screen_last_column::
  68. screen-last-column
  69.  
  70. Returns the line number of the last column being shown in the current window.
  71. ::end:: */
  72. {
  73.     return(make_number(curr_vw->vw_StartCol + curr_vw->vw_MaxX - 1));
  74. }
  75.  
  76. _PR VALUE cmd_goto_char(VALUE pos);
  77. DEFUN("goto-char", cmd_goto_char, subr_goto_char, (VALUE pos), V_Subr1, DOC_goto_char) /*
  78. ::doc:goto_char::
  79. goto-char POS
  80.  
  81. Set the cursor position in the current window to the character position POS.
  82. ::end:: */
  83. {
  84.     VW *vw = curr_vw;
  85.     DECLARE1(pos, POSP);
  86.     if(check_line(vw->vw_Tx, &VPOS(pos)))
  87.     {
  88.     vw->vw_CursorPos = VPOS(pos);
  89.     return(pos);
  90.     }
  91.     return(sym_nil);
  92. }
  93.  
  94. _PR VALUE cmd_goto_glyph(VALUE pos);
  95. DEFUN("goto-glyph", cmd_goto_glyph, subr_goto_glyph, (VALUE pos), V_Subr1, DOC_goto_glyph) /*
  96. ::doc:goto_glyph::
  97. goto-glyph POS
  98.  
  99. Set the cursor position in the current window to the glyph position POS.
  100. ::end:: */
  101. {
  102.     VW *vw = curr_vw;
  103.     DECLARE1(pos, POSP);
  104.     if(check_line(vw->vw_Tx, &VPOS(pos)))
  105.     {
  106.     vw->vw_CursorPos.pos_Col = char_col(vw->vw_Tx, VPOS(pos).pos_Col,
  107.                         VPOS(pos).pos_Line);
  108.     vw->vw_CursorPos.pos_Line = VPOS(pos).pos_Line;
  109.     return(pos);
  110.     }
  111.     return(sym_nil);
  112. }
  113.  
  114. _PR VALUE cmd_centre_display(VALUE vw);
  115. DEFUN_INT("centre-display", cmd_centre_display, subr_centre_display, (VALUE vw), V_Subr1, DOC_centre_display, "") /*
  116. ::doc:centre_display::
  117. centre-display [WINDOW]
  118.  
  119. Arrange it so that the line that the cursor is on is displayed in the
  120. middle of the window (if possible).
  121. ::end:: */
  122. {
  123.     long start_line;
  124.     if(!WINDOWP(vw))
  125.     vw = VAL(curr_vw);
  126.     start_line = VWIN(vw)->vw_CursorPos.pos_Line - (VWIN(vw)->vw_MaxY / 2);
  127.     if(start_line < 0)
  128.     start_line = 0;
  129.     if(start_line >= VWIN(vw)->vw_Tx->tx_NumLines)
  130.     start_line = VWIN(vw)->vw_Tx->tx_NumLines - 1;
  131.     VWIN(vw)->vw_StartLine = start_line;
  132.     return(vw);
  133. }
  134.  
  135. _PR VALUE cmd_next_screen(VALUE number);
  136. DEFUN_INT("next-screen", cmd_next_screen, subr_next_screen, (VALUE number), V_Subr1, DOC_next_screen, "p") /*
  137. ::doc:next_screen::
  138. next-screen [NUMBER]
  139.  
  140. Move NUMBER (default: 1) screens forwards in the current window.
  141. ::end:: */
  142. {
  143.     if(move_down_screens(NUMBERP(number) ? VNUM(number) : 1))
  144.     return(sym_t);
  145.     return(sym_nil);
  146. }
  147.  
  148. _PR VALUE cmd_prev_screen(VALUE number);
  149. DEFUN_INT("prev-screen", cmd_prev_screen, subr_prev_screen, (VALUE number), V_Subr1, DOC_prev_screen, "p") /*
  150. ::doc:prev_screen::
  151. prev-screen [NUMBER]
  152.  
  153. Move NUMBER (default: 1) screens backwards in the current window.
  154. ::end:: */
  155. {
  156.     if(move_up_screens(NUMBERP(number) ? VNUM(number) : 1))
  157.     return(sym_t);
  158.     return(sym_nil);
  159. }
  160.  
  161. _PR VALUE cmd_buffer_end(VALUE tx);
  162. DEFUN("buffer-end", cmd_buffer_end, subr_buffer_end, (VALUE tx), V_Subr1, DOC_buffer_end) /*
  163. ::doc:buffer_end::
  164. buffer-end [BUFFER]
  165.  
  166. Return the position of the last character in BUFFER.
  167. ::end:: */
  168. {
  169.     long x, y;
  170.     if(!BUFFERP(tx))
  171.     tx = VAL(curr_vw->vw_Tx);
  172.     y = VTX(tx)->tx_NumLines - 1;
  173.     x = VTX(tx)->tx_Lines[y].ln_Strlen - 1;
  174.     return(make_lpos2(x, y));
  175. }
  176.  
  177. _PR VALUE cmd_goto_buffer_end(void);
  178. DEFUN_INT("goto-buffer-end", cmd_goto_buffer_end, subr_goto_buffer_end, (void), V_Subr0, DOC_goto_buffer_end, "") /*
  179. ::doc:goto_buffer_end::
  180. goto-buffer-end
  181.  
  182. Move to the last character in the current window.
  183. ::end:: */
  184. {
  185.     VW *vw = curr_vw;
  186.     vw->vw_CursorPos.pos_Line = vw->vw_Tx->tx_NumLines - 1;
  187.     vw->vw_CursorPos.pos_Col = vw->vw_Tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
  188.     return(sym_t);
  189. }
  190.  
  191. _PR VALUE cmd_buffer_start(void);
  192. DEFUN("buffer-start", cmd_buffer_start, subr_buffer_start, (void), V_Subr0, DOC_buffer_start) /*
  193. ::doc:buffer_start::
  194. buffer-start
  195.  
  196. Return the position of the start of the buffer.
  197. ::end:: */
  198. {
  199.     return(make_lpos2(0, 0));
  200. }
  201.  
  202. _PR VALUE cmd_goto_buffer_start(void);
  203. DEFUN_INT("goto-buffer-start", cmd_goto_buffer_start, subr_goto_buffer_start, (void), V_Subr0, DOC_goto_buffer_start, "") /*
  204. ::doc:goto_buffer_start::
  205. goto-buffer-start
  206.  
  207. Move to the first character in the buffer displayed in the current window.
  208. ::end:: */
  209. {
  210.     curr_vw->vw_CursorPos.pos_Col = 0;
  211.     curr_vw->vw_CursorPos.pos_Line = 0;
  212.     return(sym_t);
  213. }
  214.  
  215. _PR VALUE cmd_line_end(VALUE pos, VALUE tx);
  216. DEFUN("line-end", cmd_line_end, subr_line_end, (VALUE pos, VALUE tx), V_Subr2, DOC_line_end) /*
  217. ::doc:line_end::
  218. line-end [POS] [BUFFER]
  219.  
  220. Return the position of the last character in the line pointed to by POS (or
  221. the cursor).
  222. ::end:: */
  223. {
  224.     POS res;
  225.     if(!BUFFERP(tx))
  226.     tx = VAL(curr_vw->vw_Tx);
  227.     if(POSP(pos))
  228.     res.pos_Line = VPOS(pos).pos_Line;
  229.     else
  230.     res.pos_Line = get_tx_cursor(VTX(tx))->pos_Line;
  231.     if(res.pos_Line < VTX(tx)->tx_NumLines)
  232.     {
  233.     res.pos_Col = VTX(tx)->tx_Lines[res.pos_Line].ln_Strlen - 1;
  234.     return(make_lpos(&res));
  235.     }
  236.     return(sym_nil);
  237. }
  238.  
  239. _PR VALUE cmd_goto_line_end(void);
  240. DEFUN_INT("goto-line-end", cmd_goto_line_end, subr_goto_line_end, (void), V_Subr0, DOC_goto_line_end, "") /*
  241. ::doc:goto_line_end::
  242. goto-line-end
  243.  
  244. Move to the last character in the line.
  245. ::end:: */
  246. {
  247.     VW *vw = curr_vw;
  248.     vw->vw_CursorPos.pos_Col = vw->vw_Tx->tx_Lines[vw->vw_CursorPos.pos_Line].ln_Strlen - 1;
  249.     return(sym_t);
  250. }
  251.  
  252. _PR VALUE cmd_line_start(VALUE pos);
  253. DEFUN("line-start", cmd_line_start, subr_line_start, (VALUE pos), V_Subr1, DOC_line_start) /*
  254. ::doc:line_start::
  255. line-start [POS]
  256.  
  257. Return the position of the first character in the line pointed to by POS
  258. (or the cursor).
  259. ::end:: */
  260. {
  261.     POS res;
  262.     if(POSP(pos))
  263.     res.pos_Line = VPOS(pos).pos_Line;
  264.     else
  265.     res.pos_Line = curr_vw->vw_CursorPos.pos_Line;
  266.     res.pos_Col = 0;
  267.     return(make_lpos(&res));
  268. }
  269.  
  270. _PR VALUE cmd_goto_line_start(void);
  271. DEFUN_INT("goto-line-start", cmd_goto_line_start, subr_goto_line_start, (void), V_Subr0, DOC_goto_line_start, "") /*
  272. ::doc:goto_line_start::
  273. goto-line-start
  274.  
  275. Move to the start of the current line.
  276. ::end:: */
  277. {
  278.     VW *vw = curr_vw;
  279.     vw->vw_CursorPos.pos_Col = 0;
  280.     return(sym_t)