Пример #1
0
/* replace a range of lines with the joined text of those lines */
bool join_lines( const int from, const int to, const bool isglobal )
  {
  static char * buf = 0;
  static int bufsz = 0;
  int size = 0;
  line_t * const ep = search_line_node( inc_addr( to ) );
  line_t * bp = search_line_node( from );

  while( bp != ep )
    {
    const char * const s = get_sbuf_line( bp );
    if( !s || !resize_buffer( &buf, &bufsz, size + bp->len ) ) return false;
    memcpy( buf + size, s, bp->len );
    size += bp->len;
    bp = bp->q_forw;
    }
  if( !resize_buffer( &buf, &bufsz, size + 2 ) ) return false;
  memcpy( buf + size, "\n", 2 );
  size += 2;
  if( !delete_lines( from, to, isglobal ) ) return false;
  current_addr_ = from - 1;
  disable_interrupts();
  if( !put_sbuf_line( buf, size, current_addr_ ) ||
      !push_undo_atom( UADD, current_addr_, current_addr_ ) )
    { enable_interrupts(); return false; }
  modified_ = true;
  enable_interrupts();
  return true;
  }
Пример #2
0
/* append lines from the yank buffer */
bool put_lines( const int addr )
  {
  undo_t * up = 0;
  line_t *p, *lp = yank_buffer_head.q_forw;

  if( lp == &yank_buffer_head )
    { set_error_msg( "Nothing to put" ); return false; }
  current_addr_ = addr;
  while( lp != &yank_buffer_head )
    {
    disable_interrupts();
    p = dup_line_node( lp );
    if( !p ) { enable_interrupts(); return false; }
    add_line_node( p, current_addr_++ );
    if( up ) up->tail = p;
    else
      {
      up = push_undo_atom( UADD, current_addr_, current_addr_ );
      if( !up ) { enable_interrupts(); return false; }
      }
    modified_ = true;
    lp = lp->q_forw;
    enable_interrupts();
    }
  return true;
  }
Пример #3
0
/* copy a range of lines; return false if error */
bool copy_lines( const int first_addr, const int second_addr, const int addr )
  {
  line_t *lp, *np = search_line_node( first_addr );
  undo_t * up = 0;
  int n = second_addr - first_addr + 1;
  int m = 0;

  current_addr_ = addr;
  if( addr >= first_addr && addr < second_addr )
    {
    n = addr - first_addr + 1;
    m = second_addr - addr;
    }
  for( ; n > 0; n = m, m = 0, np = search_line_node( current_addr_ + 1 ) )
    for( ; n-- > 0; np = np->q_forw )
      {
      disable_interrupts();
      lp = dup_line_node( np );
      if( !lp ) { enable_interrupts(); return false; }
      add_line_node( lp, current_addr_++ );
      if( up ) up->tail = lp;
      else
        {
        up = push_undo_atom( UADD, current_addr_, current_addr_ );
        if( !up ) { enable_interrupts(); return false; }
        }
      modified_ = true;
      enable_interrupts();
      }
  return true;
  }
Пример #4
0
/* for each line in a range, change text matching a pattern according to
   a substitution template; return false if error */
char search_and_replace( const int first_addr, const int second_addr,
                         const int gflags, const int snum, const char isglobal )
  {
  int lc;
  char match_found = 0;

  set_current_addr( first_addr - 1 );
  for( lc = 0; lc <= second_addr - first_addr; ++lc )
    {
    line_t *lp = search_line_node( inc_current_addr() );
    int len = replace_matching_text( lp, gflags, snum );
    if( len < 0 ) return 0;
    if( len )
      {
      const char *txt = rbuf;
      const char *eot = rbuf + len;
      undo_t *up = 0;
      disable_interrupts();
      if( !delete_lines( current_addr(), current_addr(), isglobal ) ) return 0;
      do {
        txt = put_sbuf_line( txt, current_addr() );
        if( !txt ) { enable_interrupts(); return 0; }
        if( up ) up->tail = search_line_node( current_addr() );
        else if( !( up = push_undo_atom( UADD, -1, -1 ) ) )
          { enable_interrupts(); return 0; }
        }
      while( txt != eot );
      enable_interrupts();
      match_found = 1;
      }
    }
  if( !match_found && !( gflags & GLB ) )
    { set_error_msg( "No match" ); return 0; }
  return 1;
  }
Пример #5
0
/* move a range of lines */
bool move_lines( const int first_addr, const int second_addr, const int addr,
                 const bool isglobal )
  {
  line_t *b1, *a1, *b2, *a2;
  int n = inc_addr( second_addr );
  int p = first_addr - 1;

  disable_interrupts();
  if( addr == first_addr - 1 || addr == second_addr )
    {
    a2 = search_line_node( n );
    b2 = search_line_node( p );
    current_addr_ = second_addr;
    }
  else if( !push_undo_atom( UMOV, p, n ) ||
           !push_undo_atom( UMOV, addr, inc_addr( addr ) ) )
    { enable_interrupts(); return false; }
  else
    {
    a1 = search_line_node( n );
    if( addr < first_addr )
      {
      b1 = search_line_node( p );
      b2 = search_line_node( addr );	/* this search_line_node last! */
      }
    else
      {
      b2 = search_line_node( addr );
      b1 = search_line_node( p );	/* this search_line_node last! */
      }
    a2 = b2->q_forw;
    link_nodes( b2, b1->q_forw );
    link_nodes( a1->q_back, a2 );
    link_nodes( b1, a1 );
    current_addr_ = addr + ( ( addr < first_addr ) ?
                           second_addr - first_addr + 1 : 0 );
    }
  if( isglobal ) unset_active_nodes( b2->q_forw, a2 );
  modified_ = true;
  enable_interrupts();
  return true;
  }
Пример #6
0
/* delete a range of lines */
bool delete_lines( const int from, const int to, const bool isglobal )
  {
  line_t *n, *p;

  if( !yank_lines( from, to ) ) return false;
  disable_interrupts();
  if( !push_undo_atom( UDEL, from, to ) )
    { enable_interrupts(); return false; }
  n = search_line_node( inc_addr( to ) );
  p = search_line_node( from - 1 );	/* this search_line_node last! */
  if( isglobal ) unset_active_nodes( p->q_forw, n );
  link_nodes( p, n );
  last_addr_ -= to - from + 1;
  current_addr_ = from - 1;
  modified_ = true;
  enable_interrupts();
  return true;
  }
Пример #7
0
/* Insert text from stdin (or from command buffer if global) to after
   line n; stop when either a single period is read or EOF.
   Return false if insertion fails. */
bool append_lines( const char ** const ibufpp, const int addr,
                   const bool isglobal )
  {
  int size = 0;
  undo_t * up = 0;
  current_addr_ = addr;

  while( true )
    {
    if( !isglobal )
      {
      *ibufpp = get_tty_line( &size );
      if( !*ibufpp ) return false;
      if( size == 0 || (*ibufpp)[size-1] != '\n' )
        { clearerr( stdin ); return ( size == 0 ); }
      }
    else
      {
      if( !**ibufpp ) return true;
      for( size = 0; (*ibufpp)[size++] != '\n'; ) ;
      }
    if( size == 2 && **ibufpp == '.' ) { *ibufpp += size; return true; }
    disable_interrupts();
    if( !put_sbuf_line( *ibufpp, size, current_addr_ ) )
      { enable_interrupts(); return false; }
    if( up ) up->tail = search_line_node( current_addr_ );
    else
      {
      up = push_undo_atom( UADD, current_addr_, current_addr_ );
      if( !up ) { enable_interrupts(); return false; }
      }
    *ibufpp += size;
    modified_ = true;
    enable_interrupts();
    }
  }