Пример #1
0
Файл: edit.c Проект: vigna/ne
static int save_space(line_desc * const ld, const int tab_size, const encoding_type encoding) {
	if (pa_space) free(pa_space);
	pa_space  = NULL;
	pa_space_len = 0;
	pa_space_pos = 0;

	if (!ld->line) return 0; /* No data on this line. */

	int64_t pos = 0;
	while(pos < ld->line_len && isasciispace(ld->line[pos])) pos = next_pos(ld->line, pos, encoding);

	if (pos == ld->line_len) return 0; /* Blank lines don't count. */

	pa_space_pos = pos;
	pa_space_len = calc_width(ld, pos, tab_size, encoding);

	if (pos == 0) {
		return 1;
	}

	if ((pa_space = malloc(pos))) {
		memcpy(pa_space, ld->line, pos);
		return 1;
	}

	return 0;
}
Пример #2
0
Text *
new_text(const char *string, Font *font, real height,
	 Point *pos, Color *color, Alignment align)
{
  Text *text;

  text = g_new(Text, 1);

  text->font = font;
  text->height = height;

  text->position = *pos;
  text->color = *color;
  text->alignment = align;

  text->cursor_pos = 0;
  text->cursor_row = 0;
  
  text->focus.obj = NULL;
  text->focus.has_focus = FALSE;
  text->focus.user_data = (void *)text;
  text->focus.key_event = text_key_event;
  
  set_string(text, string);

  calc_width(text);
  calc_ascent_descent(text);

  return text;
}
Пример #3
0
void
text_set_font(Text *text, Font *font)
{
  text->font = font;
  
  calc_width(text);
  calc_ascent_descent(text);
}
Пример #4
0
void
text_set_height(Text *text, real height)
{
  text->height = height;

  calc_width(text);
  calc_ascent_descent(text);
}
Пример #5
0
void
text_set_string(Text *text, const char *string)
{
  if (text->line != NULL)
    free_string(text);
  
  set_string(text, string);

  calc_width(text);
}
Пример #6
0
void
text_set_height(Text *text, real height)
{
  int i;
  text->height = height;
  for (i = 0; i < text->numlines; i++) {
    text_line_set_height(text->lines[i], height);
  }
  calc_width(text);
  calc_ascent_descent(text);
}
Пример #7
0
Файл: buffer.c Проект: dmt4/ne
int undelete_line(buffer * const b) {
	line_desc * const ld = b->cur_line_desc;
	if (!b->last_deleted) return ERROR;
	start_undo_chain(b);
	if (b->cur_pos > ld->line_len) 
		insert_spaces(b, ld, b->cur_line, ld->line_len, b->win_x + b->cur_x - calc_width(ld, ld->line_len, b->opt.tab_size, b->encoding));

	insert_one_line(b, ld, b->cur_line, b->cur_pos);
	insert_stream(b, ld, b->cur_line, b->cur_pos, b->last_deleted->stream, b->last_deleted->len);
	end_undo_chain(b);
	return OK;
}
Пример #8
0
Файл: edit.c Проект: vigna/ne
static int is_part_of_paragraph(const line_desc * const ld, const int tab_size, int64_t * const first_non_blank, const encoding_type encoding) {
	*first_non_blank = -1;
	if (!ld->line) return 0;

	int64_t pos = 0;
	while (pos < ld->line_len && isasciispace(ld->line[pos])) pos = next_pos(ld->line, pos, encoding);
	if (pos < ld->line_len && calc_width(ld, pos, tab_size, encoding) == pa_space_len) {
		*first_non_blank = pos;
		return 1;
	}
	return 0;
}
Пример #9
0
static void do_list(const char *heading, const char *path)
{
	int num;
	int prev;
	int width;
 	char buf[screen_cols];
	size_t i, len;
	glob_t gl;

	pushd(path);
	if (glob("*.conf", 0, NULL, &gl)) {
		chdir(cwd);
		return;
	}

	if (gl.gl_pathc <= 0)
		goto done;

	memset(buf, 0, sizeof(buf));
	snprintf(buf, sizeof(buf), "%s :: %s ", heading, path);
	len = strlen(buf);
	for (size_t i = len; i < (sizeof(buf) - 1); i++)
		buf[i] = '-';
	printf("\e[1m%s\e[0m\n", buf);

	width = calc_width(gl.gl_pathv, gl.gl_pathc);
	if (width <= 0)
		goto done;

	num = (screen_cols - 2) / width;
	if ((num - 1) * 2 + num * width > screen_cols)
		num--;

	prev = 0;
	for (i = 0; i < gl.gl_pathc; i++) {
		if (i > 0 && !(i % num)) {
			puts("");
			prev = 0;
		}

		if (prev)
			printf("  ");
		printf("%-*s", width, gl.gl_pathv[i]);
		prev++;
	}
	puts("\n");

done:
	globfree(&gl);
	popd();
}
Пример #10
0
/**
 * Fit a string of text into a pixel width
 * use_ellipsis determines how the returned string will appear
 * Example with "Hello World" (let's assume a monospace font and a width that can fit 6 characters):
 * use_ellipsis == true: "Hello ..."
 * use_ellipsis == false: " World"
 */
std::string SDLFontEngine::trimTextToWidth(const std::string& text, const int width, const bool use_ellipsis) {
	if (width >= calc_width(text))
		return text;

	size_t text_length = text.length();
	size_t ret_length = text_length;
	int total_width = (use_ellipsis ? width - calc_width("...") : width);

	for (size_t i=text_length; i>0; i--) {
		if (use_ellipsis) {
			if (total_width < calc_width(text.substr(0,ret_length)))
				ret_length = i;
			else
				break;
		}
		else {
			if (total_width < calc_width(text.substr(text_length-ret_length)))
				ret_length = i;
			else
				break;
		}
	}

	if (!use_ellipsis) {
		return text.substr(text_length-ret_length);
	}
	else {
		if (text_length <= 3)
			return std::string("...");

		if (text_length-ret_length < 3)
			ret_length = text_length-3;

		std::string ret_str = text.substr(0,ret_length);
		ret_str = ret_str + '.' + '.' + '.';
		return ret_str;
	}
}
Пример #11
0
void measure_slide(slide *sl)
{
	if(sl->image_file != NULL)
	{
		sl->des_w = sl->render->w;
		sl->des_h = sl->render->h;
	}
	else
	{
		sl->des_w = calc_width(sl);
		sl->des_h = calc_height(sl);
	}
	sl->scr_w = to_screen_coords(sl->des_w);
	sl->scr_h = to_screen_coords(sl->des_h);
}
Пример #12
0
void
text_set_font(Text *text, DiaFont *font)
{
  DiaFont *old_font = text->font;
  int i;

  text->font = dia_font_ref(font);
  dia_font_unref(old_font);

  for (i = 0; i < text->numlines; i++) {
    text_line_set_font(text->lines[i], font);
  }
  
  calc_width(text);
  calc_ascent_descent(text);
}
Пример #13
0
void
text_calc_boundingbox(Text *text, Rectangle *box)
{
  calc_width(text);
  calc_ascent_descent(text);

  if (box == NULL) return; /* For those who just want the text info
			      updated */
  box->left = text->position.x;
  switch (text->alignment) {
  case ALIGN_LEFT:
    break;
  case ALIGN_CENTER:
    box->left -= text->max_width / 2.0;
    break;
  case ALIGN_RIGHT:
    box->left -= text->max_width;
    break;
  }

  box->right = box->left + text->max_width;
  
  box->top = text->position.y - text->ascent;
#if 0
  box->bottom = box->top + text->height*text->numlines + text->descent;
#else
  /* why should we add one descent? isn't ascent+descent~=height? */
  box->bottom = box->top + (text->ascent+text->descent+text->height*(text->numlines-1));
#endif
  if (text->focus.has_focus) {
    real height = text->ascent + text->descent;
    if (text->cursor_pos == 0) {
      /* Half the cursor width */
      box->left -= height/(CURSOR_HEIGHT_RATIO*2);
    } else {
      /* Half the cursor width. Assume that
	 if it isn't at position zero, it might be 
	 at the last position possible. */
      box->right += height/(CURSOR_HEIGHT_RATIO*2);
    }
   
    /* Account for the size of the cursor top and bottom */
    box->top -= height/(CURSOR_HEIGHT_RATIO*2);
    box->bottom += height/CURSOR_HEIGHT_RATIO;
  }
}
Пример #14
0
void LFont::text_out( int x, int y, SDL_Surface *thisSurface, string text, unsigned long int flags )
//////////////////////////////////////////////////////////////////////////////////////////////////////
{
	//get the new x and y coordinates
	this->y = y;
	this->x = x; 

	//the part of the text image going to be used
	SDL_Rect textImage;

    //align x offset
	if( bool( flags & LFONT_HCENTER ) )
	{
		x = ( thisSurface->w - calc_width( text, thisSurface ) ) / 2;
	}
	else if( bool( flags & LFONT_LEFT ) )
	{
        x = 0;    
    }
    else if( bool( flags & LFONT_RIGHT ) )
	{
        x = ( thisSurface->w - calc_width( text, thisSurface ) );
    }

    //align the y off set
	if( bool( flags & LFONT_VCENTER ) )
	{
		y = ( thisSurface->h - calc_max( text, thisSurface ).h ) / 2;
	}
	else if( bool( flags & LFONT_TOP ) )
	{
        y = 0;
    }
    else if( bool( flags & LFONT_BOTTOM ) )
	{
        y = ( thisSurface->h - calc_max( text, thisSurface ).h );
    }

	//go through the string
	for( int stringPosition = 0; text[ stringPosition ] != '\0'; stringPosition++ )//while the current postion in the string is not a null character, keep going through the string
	{
		switch( text[ stringPosition ] )//the current postion in the string
		{
			//assign the proper surface
			case 'A': textImage = textSurfaces[ LFONT_A ]; break;
			case 'B': textImage = textSurfaces[ LFONT_B ]; break;
			case 'C': textImage = textSurfaces[ LFONT_C ]; break;
			case 'D': textImage = textSurfaces[ LFONT_D ]; break;
			case 'E': textImage = textSurfaces[ LFONT_E ]; break;
			case 'F': textImage = textSurfaces[ LFONT_F ]; break;
			case 'G': textImage = textSurfaces[ LFONT_G ]; break;
			case 'H': textImage = textSurfaces[ LFONT_H ]; break;
			case 'I': textImage = textSurfaces[ LFONT_I ]; break;
			case 'J': textImage = textSurfaces[ LFONT_J ]; break;
			case 'K': textImage = textSurfaces[ LFONT_K ]; break;
			case 'L': textImage = textSurfaces[ LFONT_L ]; break;
			case 'M': textImage = textSurfaces[ LFONT_M ]; break;
			case 'N': textImage = textSurfaces[ LFONT_N ]; break;
			case 'O': textImage = textSurfaces[ LFONT_O ]; break;
			case 'P': textImage = textSurfaces[ LFONT_P ]; break;
			case 'Q': textImage = textSurfaces[ LFONT_Q ]; break;
			case 'R': textImage = textSurfaces[ LFONT_R ]; break;
			case 'S': textImage = textSurfaces[ LFONT_S ]; break;
			case 'T': textImage = textSurfaces[ LFONT_T ]; break;
			case 'U': textImage = textSurfaces[ LFONT_U ]; break;
			case 'V': textImage = textSurfaces[ LFONT_V ]; break;
			case 'W': textImage = textSurfaces[ LFONT_W ]; break;
			case 'X': textImage = textSurfaces[ LFONT_X ]; break;
			case 'Y': textImage = textSurfaces[ LFONT_Y ]; break;
			case 'Z': textImage = textSurfaces[ LFONT_Z ]; break;

			case 'a': textImage = textSurfaces[ LFONT_a ]; break;
			case 'b': textImage = textSurfaces[ LFONT_b ]; break;
			case 'c': textImage = textSurfaces[ LFONT_c ]; break;
			case 'd': textImage = textSurfaces[ LFONT_d ]; break;
			case 'e': textImage = textSurfaces[ LFONT_e ]; break;
			case 'f': textImage = textSurfaces[ LFONT_f ]; break;
			case 'g': textImage = textSurfaces[ LFONT_g ]; break;
			case 'h': textImage = textSurfaces[ LFONT_h ]; break;
			case 'i': textImage = textSurfaces[ LFONT_i ]; break;
			case 'j': textImage = textSurfaces[ LFONT_j ]; break;
			case 'k': textImage = textSurfaces[ LFONT_k ]; break;
			case 'l': textImage = textSurfaces[ LFONT_l ]; break;
			case 'm': textImage = textSurfaces[ LFONT_m ]; break;
			case 'n': textImage = textSurfaces[ LFONT_n ]; break;
			case 'o': textImage = textSurfaces[ LFONT_o ]; break;
			case 'p': textImage = textSurfaces[ LFONT_p ]; break;
			case 'q': textImage = textSurfaces[ LFONT_q ]; break;
			case 'r': textImage = textSurfaces[ LFONT_r ]; break;
			case 's': textImage = textSurfaces[ LFONT_s ]; break;
			case 't': textImage = textSurfaces[ LFONT_t ]; break;
			case 'u': textImage = textSurfaces[ LFONT_u ]; break;
			case 'v': textImage = textSurfaces[ LFONT_v ]; break;
			case 'w': textImage = textSurfaces[ LFONT_w ]; break;
			case 'x': textImage = textSurfaces[ LFONT_x ]; break;
			case 'y': textImage = textSurfaces[ LFONT_y ]; break;
			case 'z': textImage = textSurfaces[ LFONT_z ]; break;

			case '0': textImage = textSurfaces[ LFONT_0 ]; break;
			case '1': textImage = textSurfaces[ LFONT_1 ]; break;
			case '2': textImage = textSurfaces[ LFONT_2 ]; break;
			case '3': textImage = textSurfaces[ LFONT_3 ]; break;
			case '4': textImage = textSurfaces[ LFONT_4 ]; break;
			case '5': textImage = textSurfaces[ LFONT_5 ]; break;
			case '6': textImage = textSurfaces[ LFONT_6 ]; break;
			case '7': textImage = textSurfaces[ LFONT_7 ]; break;
			case '8': textImage = textSurfaces[ LFONT_8 ]; break;
			case '9': textImage = textSurfaces[ LFONT_9 ]; break;

			case '!': textImage = textSurfaces[ LFONT_EXCLAIM ]; break;
			case '@': textImage = textSurfaces[ LFONT_AT ]; break;
			case '#': textImage = textSurfaces[ LFONT_HASH ]; break;
			case '$': textImage = textSurfaces[ LFONT_DOLLAR ]; break;
			case '%': textImage = textSurfaces[ LFONT_PERCENT ]; break;
			case '^': textImage = textSurfaces[ LFONT_CARET ]; break;
			case '&': textImage = textSurfaces[ LFONT_AMPERSAND ]; break;
			case '*': textImage = textSurfaces[ LFONT_ASTERISK ]; break;
			case '(': textImage = textSurfaces[ LFONT_LEFTPAREN ]; break;
			case ')': textImage = textSurfaces[ LFONT_RIGHTPAREN ]; break;
			case '-': textImage = textSurfaces[ LFONT_MINUS ]; break;
			case '_': textImage = textSurfaces[ LFONT_UNDERSCORE ]; break;
			case '=': textImage = textSurfaces[ LFONT_EQUALS ]; break;
			case '+': textImage = textSurfaces[ LFONT_PLUS ]; break;
			case '[': textImage = textSurfaces[ LFONT_LEFTBRACKET ]; break;
			case ']': textImage = textSurfaces[ LFONT_RIGHTBRACKET ]; break;
			case '{': textImage = textSurfaces[ LFONT_LEFTBRACE ]; break;
			case '}': textImage = textSurfaces[ LFONT_RIGHTBRACE ]; break;
			case ';': textImage = textSurfaces[ LFONT_SEMICOLON ]; break;
			case ':': textImage = textSurfaces[ LFONT_COLON ]; break;
			case '\'': textImage = textSurfaces[ LFONT_QUOTE ]; break;
			case '\"': textImage = textSurfaces[ LFONT_DBLQUOTE ]; break;
			case ',': textImage = textSurfaces[ LFONT_COMMA ]; break;
			case '.': textImage = textSurfaces[ LFONT_PERIOD ]; break;
			case '<': textImage = textSurfaces[ LFONT_LESS ]; break;
			case '>': textImage = textSurfaces[ LFONT_GREATER ]; break;
			case '?': textImage = textSurfaces[ LFONT_QUESTION ]; break;
			case '/': textImage = textSurfaces[ LFONT_SLASH ]; break;
			case '|': textImage = textSurfaces[ LFONT_LINE ]; break;
			case '\\': textImage = textSurfaces[ LFONT_BACKSLASH ]; break;
			case '`': textImage = textSurfaces[ LFONT_BACKQUOTE ]; break;
			case '~': textImage = textSurfaces[ LFONT_TILDE ]; break;

			case ' ': x += w; break;//if there's a space move overthe space width

			case '\n': x = 0; y += h; break;//if there's newline, move down the text height
		}
	
	    // if the current character is not null, a newline or a space
		if( ( text[ stringPosition ] != '\0' ) && ( text[ stringPosition ] != '\n' ) && ( text[ stringPosition ] != ' ' ) )
		{
            //if the text surface will go off the screen
			if( x + textImage.w > thisSurface->w )
			{
                //if wrap is enabled
				if( bool( flags & LFONT_WRAP ) )
				{
                    //move down
					x = 0;
					y += h;

                    //and align the x offset
					if( bool( flags & LFONT_HCENTER ) )
					{
						x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ) / 2;
					}
					else if( bool( flags & LFONT_LEFT ) )
	                {
                        x = 0;    
                    }
                    else if( bool( flags & LFONT_RIGHT ) )
	                {
                        x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) );
                    }
				}
			}
			
			//stick the text surface onto the surface
			apply_surface( x, y, font, thisSurface, &textImage );
			
			//and move over the x offset the width of the surface 
			x += textImage.w;
		}
		else
		{	
            //if there's a new line
			if( text[ stringPosition ] == '\n' )
			{
                //align the x offset
				if( bool( flags & LFONT_HCENTER ) )
				{
					x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) ) / 2;
				}
				else if( bool( flags & LFONT_LEFT ) )
	            {
                    x = 0;    
                }
                else if( bool( flags & LFONT_RIGHT ) )
	            {
                    x = ( thisSurface->w - calc_width( &text[ stringPosition + 1 ], thisSurface ) );
                }
			}
		}	
    
	}
}
Пример #15
0
Файл: edit.c Проект: vigna/ne
int shift(buffer * const b, char *p, char *msg, int msg_size) {
	const bool use_tabs = b->opt.tabs && b->opt.shift_tabs;
	const int64_t init_line = b->cur_line, init_pos = b->cur_pos, init_y = b->cur_y;

	line_desc *ld = NULL, *start_line_desc = NULL;
	int64_t shift_size = 1;
	char dir = '>';
	int shift_mag = b->opt.tab_size, rc = 0;

	/* Parse parm p; looks like [<|>] ### [s|t], but we allow them
	   in any order, once, with optional white space. */
	if (p) {
		int dir_b = 0, size_b = 0, st_b = 0;
		while (*p) {
			if (isasciispace(*p)) p++;
			else if (!dir_b && (dir_b = (*p == '<' || *p == '>'))) dir = *p++;
			else if (!size_b && (size_b = isdigit((unsigned char)*p))) {
				errno = 0;
				shift_size = strtoll(p, &p, 10);
				if (errno) return INVALID_SHIFT_SPECIFIED;
			} else if (!st_b && (st_b = (*p == 's' || *p == 'S'))) {
				shift_mag = 1;
				p++;
			} else if (!st_b && (st_b = (*p == 't' || *p == 'T'))) p++;
			else return INVALID_SHIFT_SPECIFIED;
		}
	}
	shift_size *= max(1, shift_mag);
	if (shift_size == 0) return INVALID_SHIFT_SPECIFIED;

	int64_t first_line = b->cur_line, last_line = b->cur_line, left_col = 0;

	if (b->marking) {
		if (b->mark_is_vertical) left_col = min(calc_width(b->cur_line_desc, b->block_start_pos, b->opt.tab_size, b->encoding),
		                                        calc_width(b->cur_line_desc, b->cur_pos,         b->opt.tab_size, b->encoding));
		first_line = min(b->block_start_line, b->cur_line);
		last_line  = max(b->block_start_line, b->cur_line);
	}

	/* If we're shifting left (dir=='<'), verify that we have sufficient white space
	   to remove on all the relevant lines before making any changes, i. */

	if (dir == '<') {
		shift_size = -shift_size; /* signed shift_size now also indicates direction. */
		for (int64_t line = first_line; !rc && line <= last_line; line++) {
			int64_t pos;
			goto_line(b, line);
			pos = calc_pos(b->cur_line_desc, left_col, b->opt.tab_size, b->encoding);
			while (pos < b->cur_line_desc->line_len &&
			       left_col - calc_width(b->cur_line_desc, pos, b->opt.tab_size, b->encoding) > shift_size) {
				if (isasciispace(b->cur_line_desc->line[pos]))
					pos = next_pos(b->cur_line_desc->line, pos, b->encoding);
				else {
					rc = INSUFFICIENT_WHITESPACE;
					break;
				}
			}
		}
	}


	if (!rc) {
		start_undo_chain(b);
		for (int64_t line = first_line; line <= last_line; line++) {
			int64_t pos, c_pos, c_col_orig, offset;
			b->attr_len = -1;
			goto_line(b, line);
			b->cur_pos = -1;
			ld = b->cur_line_desc;
			if (line == first_line) start_line_desc = ld;
			pos = calc_pos(ld, left_col, b->opt.tab_size, b->encoding);
			/* If left_col is in the middle of a tab, pos will be on that tab. */
			/* whitespace adjustment strategy:
			   1. Starting from left_col, advance to the right to the first non-blank character C.
			   2. Note C's col. The desired new column is this value +/- shift_size.
			   3. Move left looking for the first tab or non-whitespace or the left_col, whichever comes first.
			      Whitespace changes all take place at that transition point.
			   4. While C's col is wrong
			        if C's col is too far to the right,
			          if we're on a space, delete it;
			          else if there's a tab to our left, delete it;
			          else we should not have started, because it's not possible!
			        if C's col is too far to the left,
			           if its needs to be beyond the next tab stop,
			             insert a tab and move right;
			           else insert a space. */
			/* 1. */
			while (pos < ld->line_len && isasciispace(ld->line[pos]))
				pos = next_pos(ld->line, pos, b->encoding);
			if (pos >= ld->line_len) continue; /* We ran off the end of the line. */
			/* line[pos] should be the first non-blank character. */
			/* 2. */
			c_pos = pos;
			c_col_orig = calc_width(ld, c_pos, b->opt.tab_size, b->encoding);
			/* 3. */
			while (pos && ld->line[pos-1] == ' ')
				pos = prev_pos(ld->line, pos, b->encoding);
			/* If pos is non-zero, it should be on a blank, with only blanks between here and c_pos. */
			/* 4. */
			/* offset = how_far_we_have_moved - how_far_we_want_to_move. */
			while (!stop && (offset = calc_width(ld, c_pos, b->opt.tab_size, b->encoding)-c_col_orig - shift_size)) {
				if (offset > 0) { /* still too far right; remove whitespace */
					if (ld->line[pos] == ' ') {
						delete_stream(b, ld, b->cur_line, pos, 1);
						c_pos--;
					}
					else if (pos) { /* should be a tab just to our left */
						pos = prev_pos(ld->line, pos, b->encoding); /* now we're on the tab */
						if (ld->line[pos] == '\t') {
							delete_stream(b, ld, b->cur_line, pos, 1);
							c_pos--;
						}
						else break; /* Should have been a tab. This should never happen! Give up on this line and go mangle the next one. */
					}
					else break; /* This should never happen; give up on this line and go mangle the next one. */
				}
				else if (offset < 0) { /* too far left; insert whitespace */
					char c = ' ';
					if (use_tabs && (b->opt.tab_size - calc_width(ld, pos, b->opt.tab_size, b->encoding) % b->opt.tab_size) <= -offset )
						c = '\t';
					if (insert_one_char(b, ld, b->cur_line, pos, c)) {
						break;
					}
					pos++;
					c_pos++;
				}
			}
		}
		end_undo_chain(b);
		if (b->syn) {
			b->attr_len = -1;
			need_attr_update = true;
			update_syntax_states(b, -1, start_line_desc, (line_desc *)ld->ld_node.next);
		}
		update_window_lines(b, b->top_line_desc, 0, ne_lines - 2, false);
	}

	/* put the screen back where way we found it. */
	goto_line_pos(b, init_line, init_pos);
	delay_update();
	const int64_t avshift = b->cur_y - init_y;
	if (avshift) {
		snprintf(msg, msg_size, "%c%" PRId64, avshift > 0 ? 'T' :'B', avshift > 0 ? avshift : -avshift);
		adjust_view(b, msg);
	}

	return rc;
}
Пример #16
0
Файл: edit.c Проект: vigna/ne
int paragraph(buffer * const b) {
	line_desc *ld = b->cur_line_desc, *start_line_desc = ld;

	if (!ld->line) return line_down(b);

	/* Establish appropriate leading space. This will be taken from the line
      following the current line if it is non-blank. Otherwise it will be
      taken from the current line. Save a copy of it for later as space[]. **/

	if ( !(    (ld->ld_node.next->next && save_space((line_desc *)ld->ld_node.next, b->opt.tab_size, b->encoding))
	        || save_space(ld, b->opt.tab_size, b->encoding) )
	   ) return line_down(b);

	int64_t pos = b->cur_pos;
	b->cur_pos = -1;

	start_undo_chain(b);

	/* This insertion and deletion of a single character ensures
	   that the cursor ends up here after an undo. */
	int64_t line = b->cur_line;
	insert_one_char(b, ld, line, 0, ' ');
	delete_stream(b, ld, line, 0, 1);

	const int right_margin = b->opt.right_margin ? b->opt.right_margin : ne_columns;
	bool done;

	do {
		done = true; /* set this to false if we do any work in the loop. */

		trim_trailing_space(b, ld, line, b->encoding);

		/* Suck up subsequent lines until this one is long enough to need splitting */
		while ((calc_width(ld, ld->line_len, b->opt.tab_size, b->encoding) <= right_margin) &&
		       ld->ld_node.next->next && is_part_of_paragraph((line_desc *)ld->ld_node.next, b->opt.tab_size, &pos, b->encoding)) {
			line_desc *ld_next = (line_desc *)ld->ld_node.next;
			insert_one_char(b, ld, line, ld->line_len, ' ');
			if (pos) delete_stream(b, ld_next, line + 1, 0, pos); /* pos was set by is_part_of_paragraph() above. */
			delete_stream(b, ld, line, ld->line_len, 1);          /* joins next line to this one */
			trim_trailing_space(b, ld, line, b->encoding);
			done = false;
		}

		if (calc_width(ld, ld->line_len, b->opt.tab_size, b->encoding) > right_margin) {
			int64_t spaces;
			int64_t split_pos;
			/* Skip past leading spaces... */
			pos = 0;
			while(pos < ld->line_len && isasciispace(ld->line[pos]))
				pos = next_pos(ld->line, pos, b->encoding);

			/* Find the split point */
			split_pos = spaces = 0;
			while (pos < ld->line_len && (calc_width(ld, pos, b->opt.tab_size, b->encoding) < right_margin || ! split_pos)) {
				if (isasciispace(ld->line[pos])) {
					split_pos = pos;
					spaces = 0;
					while (pos < ld->line_len && isasciispace(ld->line[pos])) {
						pos = next_pos(ld->line, pos, b->encoding);
						spaces++;
					}
				}
				else pos = next_pos(ld->line, pos, b->encoding);
			}
			if (split_pos) {
				done = false;
				/* Remove any space at the split point. */
				if (spaces) delete_stream(b, ld, line, split_pos, spaces);

				/* Split the line at the split point.  (We are done with this line) */
				insert_one_line(b, ld, line, split_pos);

				/* Make the new next line the current line **/
				if (ld->ld_node.next->next) {
					ld = (line_desc *)ld->ld_node.next;
					line++;
					if (pa_space && pa_space_len && pa_space_pos)
						insert_stream(b, ld, line, 0, pa_space, pa_space_pos);
					trim_trailing_space(b, ld, line, b->encoding);
				}
			} else { /* Line not split; is there a next one in the paragraph? */
				if ( ld->ld_node.next->next && is_part_of_paragraph((line_desc *)ld->ld_node.next, b->opt.tab_size, &pos, b->encoding) ) {
					ld = (line_desc *)ld->ld_node.next;
					line++;
					done = false;
				}
			}
		}
	} while (!stop && !done);

	end_undo_chain(b);

	if (pa_space) {
		free(pa_space);
		pa_space = NULL;
	}

	if (b->syn) {
		b->attr_len = -1;
		need_attr_update = true;
		update_syntax_states(b, -1, start_line_desc, (line_desc *)ld->ld_node.next);
	}
	update_window_lines(b, b->cur_line_desc, b->cur_y, ne_lines - 2, false);

	goto_line_pos(b, line, pos);
	if (stop || line_down(b) == ERROR) return stop ? STOPPED : ERROR;

	/* Try to find the first non-blank starting with this line. */
	ld = b->cur_line_desc;
	line = b->cur_line;

	do {
		if (ld->line) {
			for (pos = 0; pos < ld->line_len; pos = next_pos(ld->line, pos, b->encoding)) {
				if (!isasciispace(ld->line[pos])) {
					goto_line_pos(b, line, pos);
					return ld->ld_node.next ? OK : ERROR;
				}
			}
		}
		ld = (line_desc *)ld->ld_node.next;
		line++;
	} while (ld->ld_node.next);

	return b->cur_line_desc->ld_node.next ? OK : ERROR;
}