2016-06-02 17:19:08 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "elementary_config.h"
|
2015-01-28 16:36:28 -08:00
|
|
|
#endif
|
|
|
|
|
2016-06-02 17:19:08 -07:00
|
|
|
#include "Elementary.h"
|
2015-01-28 16:36:28 -08:00
|
|
|
|
2015-04-04 10:17:01 -07:00
|
|
|
#include "elm_code_widget_private.h"
|
2015-01-28 16:36:28 -08:00
|
|
|
|
2015-04-04 11:01:05 -07:00
|
|
|
static int
|
|
|
|
_elm_code_widget_text_line_number_width_get(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd)
|
2015-01-28 16:36:28 -08:00
|
|
|
{
|
|
|
|
int max;
|
|
|
|
|
|
|
|
max = elm_code_file_lines_get(pd->code->file);
|
|
|
|
if (max < 1)
|
|
|
|
max = 1;
|
|
|
|
|
2015-01-28 16:50:07 -08:00
|
|
|
return floor(log10(max)) + 1;
|
2015-01-28 16:36:28 -08:00
|
|
|
}
|
|
|
|
|
2015-04-04 11:01:05 -07:00
|
|
|
static int
|
|
|
|
_elm_code_widget_text_left_gutter_width_get(Eo *obj, Elm_Code_Widget_Data *pd)
|
2015-01-28 16:36:28 -08:00
|
|
|
{
|
2015-04-04 11:01:05 -07:00
|
|
|
Elm_Code_Widget *widget;
|
2015-01-28 16:36:28 -08:00
|
|
|
int width = 1; // the status icon, for now
|
|
|
|
|
2015-04-04 11:01:05 -07:00
|
|
|
widget = obj;
|
2015-02-03 05:55:20 -08:00
|
|
|
if (!widget)
|
|
|
|
return width;
|
|
|
|
|
2015-01-28 16:36:28 -08:00
|
|
|
if (pd->show_line_numbers)
|
2015-04-04 11:01:05 -07:00
|
|
|
width += _elm_code_widget_text_line_number_width_get(widget, pd);
|
2015-01-28 16:36:28 -08:00
|
|
|
|
|
|
|
return width;
|
|
|
|
}
|
2015-06-03 13:29:31 -07:00
|
|
|
|
2016-02-21 15:46:10 -08:00
|
|
|
static char *
|
|
|
|
_elm_code_widget_text_multi_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd,
|
|
|
|
unsigned int start_col, unsigned int start_line,
|
|
|
|
unsigned int end_col, unsigned int end_line)
|
|
|
|
{
|
|
|
|
Elm_Code_Line *line;
|
|
|
|
char *first, *last, *ret, *ptr;
|
|
|
|
const char *newline;
|
|
|
|
short newline_len;
|
|
|
|
int ret_len;
|
|
|
|
unsigned int row, start, end;
|
|
|
|
|
|
|
|
newline = elm_code_file_line_ending_chars_get(pd->code->file, &newline_len);
|
|
|
|
|
|
|
|
line = elm_code_file_line_get(pd->code->file, start_line);
|
|
|
|
start = elm_code_widget_line_text_position_for_column_get(widget, line, start_col);
|
2016-09-01 13:41:57 -07:00
|
|
|
first = elm_code_line_text_substr(line, start, line->length - start);
|
2016-02-21 15:46:10 -08:00
|
|
|
|
|
|
|
line = elm_code_file_line_get(pd->code->file, end_line);
|
|
|
|
end = elm_code_widget_line_text_position_for_column_get(widget, line, end_col + 1);
|
|
|
|
last = elm_code_line_text_substr(line, 0, end);
|
|
|
|
|
|
|
|
ret_len = strlen(first) + strlen(last) + newline_len;
|
|
|
|
|
2016-09-01 13:41:57 -07:00
|
|
|
for (row = start_line + 1; row < end_line; row++)
|
2016-02-21 15:46:10 -08:00
|
|
|
{
|
|
|
|
line = elm_code_file_line_get(pd->code->file, row);
|
|
|
|
ret_len += line->length + newline_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = malloc(sizeof(char) * (ret_len + 1));
|
|
|
|
|
|
|
|
snprintf(ret, strlen(first) + newline_len + 1, "%s%s", first, newline);
|
|
|
|
|
|
|
|
ptr = ret;
|
|
|
|
ptr += strlen(first) + newline_len;
|
|
|
|
|
|
|
|
for (row = start_line + 1; row < end_line; row++)
|
|
|
|
{
|
|
|
|
line = elm_code_file_line_get(pd->code->file, row);
|
2016-09-01 13:41:57 -07:00
|
|
|
snprintf(ptr, line->length + 1, "%s",
|
|
|
|
elm_code_line_text_get(line, NULL));
|
2016-02-21 15:46:10 -08:00
|
|
|
|
|
|
|
snprintf(ptr + line->length, newline_len + 1, "%s", newline);
|
|
|
|
ptr += line->length + newline_len;
|
|
|
|
}
|
|
|
|
snprintf(ptr, strlen(last) + 1, "%s", last);
|
|
|
|
|
|
|
|
free(first);
|
|
|
|
free(last);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
_elm_code_widget_text_single_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd,
|
|
|
|
unsigned int start_col, unsigned int start_line,
|
|
|
|
unsigned int end_col)
|
|
|
|
{
|
|
|
|
Elm_Code_Line *line;
|
|
|
|
unsigned int start, end;
|
|
|
|
|
|
|
|
line = elm_code_file_line_get(pd->code->file, start_line);
|
|
|
|
start = elm_code_widget_line_text_position_for_column_get(widget, line, start_col);
|
|
|
|
end = elm_code_widget_line_text_position_for_column_get(widget, line, end_col + 1);
|
|
|
|
|
|
|
|
return elm_code_line_text_substr(line, start, end - start);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
_elm_code_widget_text_between_positions_get(Eo *widget, Elm_Code_Widget_Data *pd,
|
|
|
|
unsigned int start_col, unsigned int start_line,
|
|
|
|
unsigned int end_col, unsigned int end_line)
|
|
|
|
{
|
|
|
|
if (start_line == end_line)
|
|
|
|
return _elm_code_widget_text_single_get(widget, pd, start_col, start_line, end_col);
|
|
|
|
else
|
|
|
|
return _elm_code_widget_text_multi_get(widget, pd, start_col, start_line, end_col, end_line);
|
|
|
|
}
|
|
|
|
|
2015-06-03 13:29:31 -07:00
|
|
|
static unsigned int
|
2015-06-08 15:13:03 -07:00
|
|
|
_elm_code_widget_line_text_column_width_to_position(Eo *obj, Elm_Code_Widget_Data *pd EINA_UNUSED, Elm_Code_Line *line, unsigned int position)
|
2015-06-03 13:29:31 -07:00
|
|
|
{
|
|
|
|
Eina_Unicode unicode;
|
|
|
|
unsigned int count = 1;
|
|
|
|
int index = 0;
|
|
|
|
const char *chars;
|
|
|
|
|
|
|
|
if (line->length == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (line->modified)
|
|
|
|
chars = line->modified;
|
|
|
|
else
|
|
|
|
chars = line->content;
|
|
|
|
if (position > line->length)
|
|
|
|
position = line->length;
|
|
|
|
|
|
|
|
while ((unsigned int) index < position)
|
|
|
|
{
|
|
|
|
unicode = eina_unicode_utf8_next_get(chars, &index);
|
|
|
|
if (unicode == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (unicode == '\t')
|
2015-06-08 15:13:03 -07:00
|
|
|
count += elm_code_widget_text_tabwidth_at_column_get(obj, count);
|
2015-06-03 13:29:31 -07:00
|
|
|
else
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
_elm_code_widget_line_text_column_width_get(Eo *obj, Elm_Code_Widget_Data *pd, Elm_Code_Line *line)
|
|
|
|
{
|
2015-06-10 15:32:15 -07:00
|
|
|
if (!line)
|
|
|
|
return 0;
|
|
|
|
|
2015-06-03 13:29:31 -07:00
|
|
|
return _elm_code_widget_line_text_column_width_to_position(obj, pd, line, line->length) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
2015-06-08 15:13:03 -07:00
|
|
|
_elm_code_widget_line_text_position_for_column_get(Eo *obj, Elm_Code_Widget_Data *pd EINA_UNUSED, Elm_Code_Line *line, unsigned int column)
|
2015-06-03 13:29:31 -07:00
|
|
|
{
|
|
|
|
Eina_Unicode unicode;
|
2015-06-08 15:13:03 -07:00
|
|
|
unsigned int count = 1, position = 0;
|
2015-06-03 13:29:31 -07:00
|
|
|
int index = 0;
|
|
|
|
const char *chars;
|
|
|
|
|
2016-09-01 13:41:57 -07:00
|
|
|
if (!line || line->length == 0 || column == 1)
|
2015-06-03 13:29:31 -07:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (line->modified)
|
|
|
|
chars = line->modified;
|
|
|
|
else
|
|
|
|
chars = line->content;
|
|
|
|
|
2015-06-08 15:13:03 -07:00
|
|
|
while ((unsigned int) count <= column && index <= (int) line->length)
|
2015-06-03 13:29:31 -07:00
|
|
|
{
|
2015-06-08 15:13:03 -07:00
|
|
|
position = (unsigned int) index;
|
2015-06-03 13:29:31 -07:00
|
|
|
unicode = eina_unicode_utf8_next_get(chars, &index);
|
|
|
|
|
|
|
|
if (unicode == 0)
|
|
|
|
return line->length;
|
|
|
|
else if (unicode == '\t')
|
2015-06-08 15:13:03 -07:00
|
|
|
count += elm_code_widget_text_tabwidth_at_column_get(obj, count);
|
2015-06-03 13:29:31 -07:00
|
|
|
else
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2015-06-08 15:13:03 -07:00
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
_elm_code_widget_text_tabwidth_at_column_get(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd, unsigned int column)
|
|
|
|
{
|
|
|
|
return pd->tabstop - ((column - 1) % pd->tabstop);
|
2015-06-03 13:29:31 -07:00
|
|
|
}
|
2015-06-08 15:13:03 -07:00
|
|
|
|