home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / text.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  7.7 KB  |  420 lines

  1. /*
  2.  *  Copyright (c) 1992, 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "config.h"
  9. #include "buffer.h"
  10. #include "ins.h"
  11. #include "ledit.h"
  12. #include "text.h"
  13. #include "screen.h"
  14. #include "cmds.h"
  15. #include "paste.h"
  16. #include "misc.h"
  17. #include "slang.h"
  18.  
  19. /* This routine deletes multiple spaces except those following a period, '?'
  20.    or a '!'.
  21.  
  22.    Returns the address of beginning of non whitespace */
  23. unsigned char *text_format_line(void)
  24. {
  25.     unsigned char *p, *p1;
  26.     int min;
  27.  
  28.     p = CLine->data;
  29.     Point = 0;
  30.  
  31.     while(((*p == '\t') || (*p == ' ')) && (Point < CLine->len)) p++, Point++;
  32.     min = Point;
  33.  
  34.     Point = CLine->len - 1;
  35.     if (Point < 0) Point = 0;
  36.     p = CLine->data + Point;
  37.  
  38.     while (Point > min)
  39.       {
  40.           if ((*p == ' ') || (*p == '\t'))
  41.             {
  42.            Point--; p--;
  43.            p1 = p - 1;
  44.            if (((*p == ' ') || (*p == '\t')) && (Point > min)
  45.            && (*p1 != '.') && (*p1 != '?') && (*p1 != '!'))
  46.          {
  47.             del();
  48.             if (*p == '\t') *p = ' ';
  49.          }
  50.         }
  51.           else
  52.             {
  53.                 Point--; p--;
  54.             }
  55.       }
  56.    return(CLine->data + min);
  57. }
  58.  
  59. int wrap_line1(int format)
  60. {
  61.    unsigned char *p, *pmin;
  62.    int col;
  63.  
  64.    if (format) pmin = text_format_line(); else pmin = CLine->data;
  65.    eol();
  66.    col = calculate_column();
  67.    if (col < User_Vars.wrap_column)
  68.      {
  69.     return(0);
  70.      }
  71.  
  72.    point_column(User_Vars.wrap_column - 1);
  73.    p = CLine->data + Point;
  74.  
  75.    while(p > pmin)
  76.      {
  77.     if ((*p == ' ') || (*p == '\t')) break;
  78.     p--;
  79.      }
  80.  
  81.    if (p == pmin)
  82.      {
  83.     /* that failed, so go the other way */
  84.     p = CLine->data + CLine->len;
  85.     while(pmin < p)
  86.       {
  87.          if ((*pmin == ' ') || (*pmin == '\t')) break;
  88.          pmin++;
  89.       }
  90.     if (p == pmin) return(0);
  91.     p = pmin;
  92.      }
  93.  
  94.    Point = (int) (p - CLine->data);
  95.    trim_whitespace();
  96.    newline();
  97.    CLine = CLine->prev; LineNum--;
  98.    return(1);
  99. }
  100.  
  101. void wrap_line(int format)
  102. {
  103.     push_spot();
  104.     wrap_line1(format);
  105.     pop_spot();
  106. }
  107.  
  108. /* Here a paragraph follows either an indentation, a '\\' char or two
  109.    '\n' chars.  or a '%' char since tex uses this */
  110.  
  111.  
  112. int is_paragraph_sep(void)
  113. {
  114.    unsigned char *p;
  115.    int ret;
  116.    p = CLine->data;
  117.    
  118.    if (CBuf->par_sep != NULL)
  119.      {
  120.     SLexecute_function(CBuf->par_sep);
  121.     (void) SLang_pop_integer(&ret);
  122.     if (SLang_Error) 
  123.       {
  124.          CBuf->par_sep = NULL;
  125.          ret = 1;
  126.       }
  127.     return ret;
  128.      }
  129.    if ((*p == '\n') || (*p == '\\') || (*p == '%')) return(1);
  130.    return(0);
  131. }
  132.  
  133. int backward_paragraph(void)
  134. {
  135.    Line *prev = CLine->prev;
  136.    int ro = CBuf->flags & READ_ONLY;
  137.    
  138.    if (NULL == CBuf->par_sep)
  139.      {
  140.     CBuf->par_sep = SLang_get_function("is_paragraph_separator");
  141.      }
  142.  
  143.    Point = 0;
  144.    if (prev == NULL) return(0);
  145.    CLine = prev; LineNum--;
  146.    
  147.    while(1)
  148.      {
  149.     eol();
  150.     if (!ro) trim_whitespace();
  151.     if (is_paragraph_sep() || (CLine->prev == NULL)) break;
  152.     CLine = CLine->prev; LineNum--;
  153.      }
  154.    Point = 0;
  155.    return(1);
  156. }
  157.  
  158. int forward_paragraph(void)
  159. {
  160.    int ro = CBuf->flags & READ_ONLY;   
  161.    
  162.    if (NULL == CBuf->par_sep)
  163.      {
  164.     CBuf->par_sep = SLang_get_function("is_paragraph_separator");
  165.      }
  166.  
  167.    while(1)
  168.      {
  169.     if (CLine->next == NULL) break;
  170.     CLine = CLine->next;  LineNum++;
  171.     eol();
  172.     if (!ro) trim_whitespace();
  173.     if (is_paragraph_sep()) break;
  174.      }
  175.  
  176.    eol();
  177.    return(1);
  178. }
  179.  
  180. /* format paragraph and if Prefix argument justify_hook is called. */
  181. int text_format_paragraph()
  182. {
  183.    unsigned char *p;
  184.    int n, col;
  185.    Line *end, *beg, *next;
  186.    
  187.    CHECK_READ_ONLY
  188.    push_spot();
  189.    if (is_paragraph_sep())
  190.      {
  191.     pop_spot();
  192.     return(0);
  193.      }
  194.    
  195.    /* if (CBuf->modes != WRAP_MODE) return(0); */
  196.  
  197.    get_current_indent(&n);
  198.  
  199.    /* find end */
  200.    forward_paragraph();
  201.    if (CLine->next == NULL) end = NULL; 
  202.    else
  203.      {
  204.     end = CLine;
  205.      }
  206.  
  207.    /* find paragraph start */
  208.    backward_paragraph();
  209.    if (is_paragraph_sep() && (CLine->next != NULL))
  210.      {
  211.     CLine = CLine->next; LineNum++;
  212.      }
  213.    beg = CLine;
  214.    Point = 0;
  215.    
  216.    /* Now loop formatting as we go until the end is reached */
  217.    while(CLine != end)
  218.      {
  219.     eol();
  220.     if (CLine != beg) indent_to(n);
  221.     if (wrap_line1(1))
  222.       {
  223.          CLine = CLine->next;
  224.          LineNum++;
  225.          indent_to(n);
  226.          continue;
  227.       }
  228.     else if (CLine->next == end) break;
  229.  
  230.     next = CLine->next;
  231.     if (next != end)
  232.       {
  233.          /* Now count the length of the word on the next line. */
  234.          CLine = next;  LineNum++;
  235.          Point = 0;
  236.          trim_whitespace();
  237.          p = CLine->data;
  238.          while((*p > ' ') && (p - CLine->data < CLine->len)) p++;
  239.  
  240.          CLine = CLine->prev; LineNum--;
  241.          eol();
  242.  
  243.          col = calculate_column();
  244.          if ((p - next->data) + col < User_Vars.wrap_column - 1)
  245.            {
  246.           del();
  247.           ins(' ');
  248.            }
  249.          else 
  250.            {
  251.           CLine = CLine->next;
  252.           LineNum++;
  253.            }
  254.       }
  255.      }
  256.    if (Repeat_Factor != NULL) 
  257.      {
  258.     SLang_run_hooks("format_paragraph_hook", NULL, NULL);
  259.     Repeat_Factor = NULL;
  260.      }
  261.    pop_spot();
  262.    return(1);
  263. }
  264.  
  265. int narrow_paragraph(void)
  266. {
  267.    int wrap, n;
  268.    
  269.    CHECK_READ_ONLY
  270.    /* if (CBuf->modes != WRAP_MODE) return(0); */
  271.    get_current_indent(&n);
  272.    wrap = User_Vars.wrap_column;
  273.    if (wrap - n <= wrap/2) return(0);
  274.    User_Vars.wrap_column -= n;
  275.    text_format_paragraph();
  276.    User_Vars.wrap_column = wrap;
  277.    return(1);
  278. }
  279.  
  280. int center_line(void)
  281. {
  282.    unsigned char *p, *pmax;
  283.    int len;
  284.  
  285.    CHECK_READ_ONLY
  286.    push_spot();
  287.    (void) eol_cmd();
  288.    p = CLine->data;
  289.    pmax = p + CLine->len;
  290.  
  291.    while(p < pmax)
  292.      {
  293.     if (*p > ' ') break;
  294.     p++;
  295.      }
  296.    if ((len = (int)(pmax - p)) < 0) len = 0;
  297.    if ((len = (User_Vars.wrap_column - len) / 2) < 0) len = 0;
  298.    indent_to(len);
  299.    pop_spot();
  300.    return(1);
  301. }
  302.  
  303. int text_smart_quote(void)
  304. {
  305.    char c, last;
  306.    int upd;
  307.  
  308.    /* Force a screen update.  This help syntax highlighting */
  309.    JWindow->trashed = 1;
  310.    
  311.    if (Point) c = (char ) *(CLine->data + (Point - 1)); else c = 0;
  312.    if (!(CBuf->modes & WRAP_MODE) || (c == '\\')) return ins_char_cmd();
  313.  
  314.    last = SLang_Last_Key_Char;
  315.    if ((c == '(') || (c == '[') || (c == '{') || (c <= ' ') || !Point)
  316.      SLang_Last_Key_Char = '`';
  317.    else
  318.      SLang_Last_Key_Char = '\'';
  319.  
  320.    upd = ins_char_cmd();
  321.    if (last == '"') upd = ins_char_cmd();
  322.    SLang_Last_Key_Char = last;
  323.    return upd;
  324. }
  325.  
  326. char Jed_Word_Range[256];
  327.  
  328.  
  329. void define_word(char *w)
  330. {
  331.   strcpy(Jed_Word_Range, w);
  332. }
  333.  
  334. /* capitalize region does not really work since it involves words, etc... */
  335. void transform_region(int *what)
  336. {
  337.    int pnt, n;
  338.    Line *line;
  339.    unsigned char *p;
  340.  
  341.    CHECK_READ_ONLY_VOID
  342.    if (!check_region(&Number_One)) return;    /* spot pushed */
  343.  
  344.    pnt = Point;
  345.    line = CLine;
  346.    pop_mark(&Number_One);
  347.  
  348.    for (p = CLine->data + Point; 1; p = CLine->data)
  349.      {
  350.     if (line == CLine) n = pnt; else n = CLine->len;
  351.     
  352.     switch (*what)
  353.       {
  354.        case 'u': 
  355.          while (Point < n)
  356.            {
  357.           p = CLine->data + Point;
  358.           replace_char(UPPER_CASE(*p));
  359.           Point++;
  360.            }
  361.          break;
  362.          
  363.        case 'c':
  364.          p = CLine->data + Point;
  365.          replace_char(UPPER_CASE(*p));
  366.          Point++;
  367.          p = CLine->data + Point;
  368.          /* drop through */
  369.          
  370.        case 'd': 
  371.          while (Point < n) 
  372.            {
  373.           p = CLine->data + Point;
  374.           replace_char(LOWER_CASE(*p));
  375.           Point++;
  376.            }
  377.          break;
  378.          
  379.        default: 
  380.          while (Point < n) 
  381.            {
  382.           p = CLine->data + Point;
  383.           replace_char(CHANGE_CASE(*p));
  384.           Point++;
  385.            }
  386.          break;
  387.       }
  388.     
  389.     
  390.     if (line == CLine) break;
  391.     CLine = CLine->next;
  392.     LineNum++;
  393.     Point = 0;
  394.      }
  395.    pop_spot();
  396.    /* mark_buffer_modified(&Number_One); */
  397. }
  398.  
  399.  
  400. void skip_word_chars(void)
  401. {
  402.    skip_chars1(Jed_Word_Range, 0);
  403. }
  404.  
  405. void skip_non_word_chars(void)
  406. {
  407.    skip_chars1(Jed_Word_Range, 1);
  408. }
  409.  
  410. void bskip_word_chars(void)
  411. {
  412.    bskip_chars1(Jed_Word_Range, 0);
  413. }
  414.  
  415. void bskip_non_word_chars(void)
  416. {
  417.    bskip_chars1(Jed_Word_Range, 1);
  418. }
  419.  
  420.