Ticket #1447: 0001-Implementation-of-soft-wraps-screen-only-division-of.patch

File 0001-Implementation-of-soft-wraps-screen-only-division-of.patch, 112.2 KB (added by psprint, 9 months ago)

Add soft wraps to MCEdit

  • lib/keybind.h

    From 25445612b3fe895cb5b64a3d45ebce415d1b3128 Mon Sep 17 00:00:00 2001
    From: Sebastian Gniazdowski <sgniazdowski@gmail.com>
    Date: Thu, 17 Aug 2023 11:14:33 -0500
    Subject: [PATCH] =?UTF-8?q?Implementation=20of=20soft=20wraps=20=E2=80=93?=
     =?UTF-8?q?=C2=A0screen=20only=20division=20of=20too=20long=20lines?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     lib/keybind.h            |   1 +
     lib/util.h               |   7 +
     src/editor/edit-impl.h   |  13 +-
     src/editor/edit.c        | 501 ++++++++++++++++++++++++++-------
     src/editor/edit.h        |   5 +
     src/editor/editbuffer.c  | 151 ++++++++--
     src/editor/editbuffer.h  |  22 +-
     src/editor/editcmd.c     |  42 +--
     src/editor/editdraw.c    | 579 ++++++++++++++++++++++++++-------------
     src/editor/editoptions.c |  16 +-
     src/editor/editsearch.c  |   2 +-
     src/editor/editwidget.c  |  32 ++-
     src/editor/editwidget.h  |  11 +-
     src/editor/format.c      |  12 +-
     src/setup.c              |   1 +
     15 files changed, 1020 insertions(+), 375 deletions(-)
    
    diff --git a/lib/keybind.h b/lib/keybind.h
    index 9c0fe98a1..8ec763523 100644
    a b enum 
    3939 
    4040    /* common */ 
    4141    CK_Enter = 1L, 
     42    CK_SoftFolds, 
    4243    CK_ChangePanel, 
    4344    CK_Up, 
    4445    CK_Down, 
  • lib/util.h

    diff --git a/lib/util.h b/lib/util.h
    index ec8b25ec5..d72d252a4 100644
    a b  
    3838#define MC_PIPE_ERROR_CREATE_PIPE_STREAM -4 
    3939#define MC_PIPE_ERROR_READ -5 
    4040 
     41#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME 
     42#define WMSG2(x,y) send_message(WIDGET(x), NULL, y, -1, NULL) 
     43#define WMSG3(x,y,p) send_message(WIDGET(x), NULL, y, p, NULL) 
     44#define WMSG4(x,y,p,q) send_message(WIDGET(x), NULL, y, p, q) 
     45#define WMSG(...) GET_MACRO(__VA_ARGS__, WMSG4, WMSG3, WMSG2)(__VA_ARGS__) 
     46 
     47 
    4148/* gnulib efa15594e17fc20827dba66414fb391e99905394 
    4249 
    4350 *_GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2. 
  • src/editor/edit-impl.h

    diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h
    index 3d0054537..4beab55df 100644
    a b extern edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO]; 
    128128 
    129129extern int max_undo; 
    130130extern gboolean auto_syntax; 
    131  
    132131extern gboolean search_create_bookmark; 
    133132 
    134133extern char *edit_window_state_char; 
    135134extern char *edit_window_close_char; 
    136135 
    137136/*** declarations of public functions ************************************************************/ 
     137#define sum_plines_to_row(x,y) sum_plines_to_row_full(x,y,1) 
     138int sum_plines_to_row_full(GPtrArray *page_line_data, int row, gboolean count_only_second_etc_lines); 
    138139 
    139140gboolean edit_add_window (WDialog * h, const WRect * r, const vfs_path_t * f, long fline); 
    140141WEdit *edit_find_editor (const WDialog * h); 
    void edit_menu_cmd (WDialog * h); 
    144145void user_menu (WEdit * edit, const char *menu_file, int selected_entry); 
    145146void edit_init_menu (WMenuBar * menubar); 
    146147void edit_save_mode_cmd (void); 
    147 off_t edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto); 
     148off_t edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto, gboolean as_btes, off_t len_limit); 
    148149void edit_scroll_screen_over_cursor (WEdit * edit); 
    149150void edit_render_keypress (WEdit * edit); 
    150151void edit_scroll_upward (WEdit * edit, long i); 
    151152void edit_scroll_downward (WEdit * edit, long i); 
    152153void edit_scroll_right (WEdit * edit, long i); 
    153154void edit_scroll_left (WEdit * edit, long i); 
    154 void edit_move_up (WEdit * edit, long i, gboolean do_scroll); 
    155 void edit_move_down (WEdit * edit, long i, gboolean do_scroll); 
     155void edit_move_up (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines); 
     156void edit_move_down (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines); 
    156157void edit_move_to_prev_col (WEdit * edit, off_t p); 
    157158long edit_get_col (const WEdit * edit); 
    158159void edit_update_curs_row (WEdit * edit); 
    void edit_delete_line (WEdit * edit); 
    168169 
    169170int edit_delete (WEdit * edit, gboolean byte_delete); 
    170171int edit_backspace (WEdit * edit, gboolean byte_delete); 
     172void edit_move_to_top (WEdit * edit); 
     173void edit_move_to_bottom (WEdit * edit); 
     174void edit_cursor_to_bol (WEdit * edit, gboolean screen_lines); 
     175void edit_cursor_to_eol (WEdit * edit, gboolean screen_lines); 
    171176void edit_insert (WEdit * edit, int c); 
    172177void edit_insert_over (WEdit * edit); 
    173178void edit_cursor_move (WEdit * edit, off_t increment); 
  • src/editor/edit.c

    diff --git a/src/editor/edit.c b/src/editor/edit.c
    index dc3b3228b..0e3ef47c2 100644
    a b edit_options_t edit_options = { 
    107107}; 
    108108 
    109109int max_undo = 32768; 
     110int soft_last_row; 
    110111 
    111112gboolean enable_show_tabs_tws = TRUE; 
    112113 
    edit_find_filter (const vfs_path_t * filename_vpath) 
    256257    return -1; 
    257258} 
    258259 
     260/* --------------------------------------------------------------------------------------------- */ 
     261gboolean edit_set_end_column(WEdit *edit) 
     262{ 
     263    gboolean ret = FALSE; 
     264    Widget *w = WIDGET(edit); 
     265    Widget *wh = WIDGET(WIDGET(edit)->owner); 
     266    int x1, x2, last_column, start_column = 0, end_column; 
     267 
     268    int wh_cols = wh ? wh->rect.cols : COLS; 
     269    int wh_x = 0; 
     270 
     271    x1 = w->rect.x; 
     272    x2 = w->rect.x + w->rect.cols - 1; 
     273    if (x2 < x1 || x2 < wh_x) 
     274    { 
     275        /* Still, set a good, not overcomplicated, value */ 
     276        edit->end_col = edit->buffer.end_col = w->rect.cols-1; 
     277        return ret; /* false */ 
     278    } 
     279 
     280    last_column = wh_x + wh_cols-1; 
     281    if (x2 <= last_column) 
     282        end_column = w->rect.cols-1; 
     283    else if (x1 >= wh_x) 
     284        end_column = wh_cols-1-x1; 
     285    else 
     286        end_column = start_column+wh_cols-1; 
     287 
     288    ret = (end_column<=COLS-1) && (end_column>0); 
     289    if (!ret) 
     290        end_column = 80; 
     291 
     292    edit->end_col = end_column; 
     293    edit->buffer.end_col = end_column; 
     294 
     295    return ret; 
     296} 
     297 
    259298/* --------------------------------------------------------------------------------------------- */ 
    260299 
    261300static char * 
    edit_load_file (WEdit * edit) 
    437476 
    438477    if (fast_load) 
    439478    { 
    440         edit_buffer_init (&edit->buffer, edit->stat1.st_size); 
     479        edit_buffer_init (edit, &edit->buffer, edit->stat1.st_size); 
    441480 
    442481        if (!edit_load_file_fast (&edit->buffer, edit->filename_vpath)) 
    443482        { 
    edit_load_file (WEdit * edit) 
    447486    } 
    448487    else 
    449488    { 
    450         edit_buffer_init (&edit->buffer, 0); 
     489        edit_buffer_init (edit, &edit->buffer, 0); 
    451490 
    452491        if (edit->filename_vpath != NULL 
    453492            && *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) != '\0') 
    is_blank (const edit_buffer_t * buf, off_t offset) 
    678717{ 
    679718    off_t s, f; 
    680719 
    681     s = edit_buffer_get_bol (buf, offset); 
    682     f = edit_buffer_get_eol (buf, offset) - 1; 
     720    s = edit_buffer_get_bol (buf, offset, FALSE); 
     721    f = edit_buffer_get_eol (buf, offset, FALSE) - 1; 
    683722    while (s <= f) 
    684723    { 
    685724        int c; 
    edit_find_line (WEdit * edit, long line) 
    708747        edit->line_numbers[1] = edit->buffer.curs_line; 
    709748        edit->line_offsets[1] = edit_buffer_get_current_bol (&edit->buffer); 
    710749        edit->line_numbers[2] = edit->buffer.lines; 
    711         edit->line_offsets[2] = edit_buffer_get_bol (&edit->buffer, edit->buffer.size); 
     750        edit->line_offsets[2] = edit_buffer_get_bol (&edit->buffer, edit->buffer.size, FALSE); 
    712751        edit->caches_valid = TRUE; 
    713752    } 
    714753    if (line >= edit->buffer.lines) 
    edit_find_line (WEdit * edit, long line) 
    736775    if (line > edit->line_numbers[j]) 
    737776        edit->line_offsets[i] = 
    738777            edit_buffer_get_forward_offset (&edit->buffer, edit->line_offsets[j], 
    739                                             line - edit->line_numbers[j], 0); 
     778                                            line - edit->line_numbers[j], 0, FALSE); 
    740779    else 
    741780        edit->line_offsets[i] = 
    742781            edit_buffer_get_backward_offset (&edit->buffer, edit->line_offsets[j], 
    743                                              edit->line_numbers[j] - line); 
     782                                             edit->line_numbers[j] - line, FALSE); 
    744783    edit->line_numbers[i] = line; 
    745784    return edit->line_offsets[i]; 
    746785} 
    edit_move_up_paragraph (WEdit * edit, gboolean do_scroll) 
    779818        } 
    780819    } 
    781820 
    782     edit_move_up (edit, edit->buffer.curs_line - i, do_scroll); 
     821    edit_move_up (edit, edit->buffer.curs_line - i, do_scroll, FALSE); 
    783822} 
    784823 
    785824/* --------------------------------------------------------------------------------------------- */ 
    edit_move_down_paragraph (WEdit * edit, gboolean do_scroll) 
    814853            if (edit_line_is_blank (edit, i) || i >= edit->buffer.lines) 
    815854                break; 
    816855    } 
    817     edit_move_down (edit, i - edit->buffer.curs_line, do_scroll); 
     856    edit_move_down (edit, i - edit->buffer.curs_line, do_scroll, FALSE); 
    818857} 
    819858 
    820859/* --------------------------------------------------------------------------------------------- */ 
    static void 
    823862edit_begin_page (WEdit * edit) 
    824863{ 
    825864    edit_update_curs_row (edit); 
    826     edit_move_up (edit, edit->curs_row, FALSE); 
     865    edit_move_up (edit, edit->curs_row, FALSE, FALSE); 
    827866} 
    828867 
    829868/* --------------------------------------------------------------------------------------------- */ 
    static void 
    832871edit_end_page (WEdit * edit) 
    833872{ 
    834873    edit_update_curs_row (edit); 
    835     edit_move_down (edit, WIDGET (edit)->rect.lines - edit->curs_row - 1, FALSE); 
     874    edit_move_down (edit, WIDGET (edit)->rect.lines - edit->curs_row - 1, FALSE, FALSE); 
    836875} 
    837876 
    838877 
    839878/* --------------------------------------------------------------------------------------------- */ 
    840879/** goto beginning of text */ 
    841880 
    842 static void 
     881void 
    843882edit_move_to_top (WEdit * edit) 
    844883{ 
    845884    if (edit->buffer.curs_line != 0) 
    edit_move_to_top (WEdit * edit) 
    855894/* --------------------------------------------------------------------------------------------- */ 
    856895/** goto end of text */ 
    857896 
    858 static void 
     897void 
    859898edit_move_to_bottom (WEdit * edit) 
    860899{ 
    861900    if (edit->buffer.curs_line < edit->buffer.lines) 
    862901    { 
    863         edit_move_down (edit, edit->buffer.lines - edit->curs_row, FALSE); 
     902        edit_move_down (edit, edit->buffer.lines - edit->curs_row, FALSE, FALSE); 
    864903        edit->start_display = edit->buffer.size; 
    865904        edit->start_line = edit->buffer.lines; 
    866905        edit_scroll_upward (edit, WIDGET (edit)->rect.lines - 1); 
    edit_move_to_bottom (WEdit * edit) 
    871910/* --------------------------------------------------------------------------------------------- */ 
    872911/** goto beginning of line */ 
    873912 
    874 static void 
    875 edit_cursor_to_bol (WEdit * edit) 
     913void 
     914edit_cursor_to_bol (WEdit * edit, gboolean screen_lines) 
    876915{ 
    877     edit_cursor_move (edit, edit_buffer_get_current_bol (&edit->buffer) - edit->buffer.curs1); 
     916    off_t bol = edit_buffer_get_bol(&edit->buffer, edit->buffer.curs1 - edit->flag, screen_lines); 
     917    screen_lines &= edit_options.soft_wrap; 
     918    edit->flag2 = TRUE; 
     919    edit->flag = FALSE; 
     920    edit_cursor_move (edit, bol - edit->buffer.curs1); 
    878921    edit->search_start = edit->buffer.curs1; 
    879922    edit->prev_col = edit_get_col (edit); 
    880923    edit->over_col = 0; 
    edit_cursor_to_bol (WEdit * edit) 
    883926/* --------------------------------------------------------------------------------------------- */ 
    884927/** goto end of line */ 
    885928 
    886 static void 
    887 edit_cursor_to_eol (WEdit * edit) 
     929void 
     930edit_cursor_to_eol (WEdit * edit, gboolean screen_lines) 
    888931{ 
    889     edit_cursor_move (edit, edit_buffer_get_current_eol (&edit->buffer) - edit->buffer.curs1); 
     932    screen_lines &= edit_options.soft_wrap; 
     933    if (edit->flag) 
     934        return; 
     935    edit->flag2 = 0; 
     936    off_t eol = edit_buffer_get_eol(&edit->buffer, edit->buffer.curs1, screen_lines); 
     937 
     938    edit_cursor_move (edit, eol - edit->buffer.curs1); 
    890939    edit->search_start = edit->buffer.curs1; 
    891940    edit->prev_col = edit_get_col (edit); 
    892941    edit->over_col = 0; 
    edit_left_char_move_cmd (WEdit * edit) 
    10681117*/ 
    10691118 
    10701119static void 
    1071 edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction) 
     1120edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction, gboolean screen_lines) 
    10721121{ 
    10731122    long p; 
    1074     long l = direction ? edit->buffer.curs_line : edit->buffer.lines - edit->buffer.curs_line; 
     1123    long l, cnt_; 
     1124    off_t curs1 = edit->buffer.curs1; 
     1125    off_t boln = edit_buffer_get_bol (&edit->buffer, curs1, FALSE); 
     1126    int col, real_col, end_col; 
    10751127 
     1128    screen_lines &= edit_options.soft_wrap; 
     1129    if (do_scroll) 
     1130        screen_lines = FALSE; 
     1131    if (direction) 
     1132    { 
     1133        l = edit_buffer_count_lines(&edit->buffer, 0, curs1, screen_lines); 
     1134        if (l==0) 
     1135            l++; 
     1136        p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1137        /* Count possible only "touched"/started screen line */ 
     1138        cnt_ = (p%edit->end_col==0) ? 1:0; 
     1139        l+=cnt_-1; 
     1140    } 
     1141    else 
     1142    { 
     1143        l = edit->buffer.lines - edit->buffer.curs_line; 
     1144        if (screen_lines && l < lines) 
     1145        { 
     1146            GPtrArray *page_line_data = edit->page_line_data; 
     1147            if (edit->page_line_data == NULL) 
     1148                page_line_data = edit->page_line_data = g_ptr_array_new_full(LINES, g_free); 
     1149            g_ptr_array_set_size(edit->page_line_data, LINES); 
     1150            cnt_ = sum_plines_to_row_full(page_line_data, soft_last_row+1, FALSE); 
     1151            l += cnt_; 
     1152            cnt_ = sum_plines_to_row_full(page_line_data, edit->array_row, FALSE); 
     1153            l -= 1 + cnt_; 
     1154            p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1155            cnt_ = p/edit->end_col - ((p%edit->end_col==0)?1:0); 
     1156            l -= cnt_; 
     1157        } 
     1158    } 
    10761159    if (lines > l) 
    10771160        lines = l; 
    10781161 
    edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean directi 
    10881171        else 
    10891172            edit_scroll_downward (edit, lines); 
    10901173    } 
    1091     p = edit_buffer_get_current_bol (&edit->buffer); 
    1092     p = direction ? edit_buffer_get_backward_offset (&edit->buffer, p, lines) : 
    1093         edit_buffer_get_forward_offset (&edit->buffer, p, lines, 0); 
    1094     edit_cursor_move (edit, p - edit->buffer.curs1); 
    1095     edit_move_to_prev_col (edit, p); 
     1174    p = edit_get_cursor_offset (edit); 
     1175    edit_update_curs_col(edit); 
     1176    col=edit->curs_col;  
     1177    end_col=edit->end_col; 
     1178 
     1179    if (/*m.right*/curs1==edit->prev_curs1+1 && col == 0 && curs1 != boln && 
     1180      /*not flagged */ !edit->flag) 
     1181        real_col=end_col; 
     1182    else if (/*m.left*/curs1==edit->prev_curs1-1 &&  
     1183           col == end_col-1 &&  
     1184           !edit->flag) 
     1185        real_col=end_col; 
     1186    else if (ABS(curs1-edit->prev_curs1) != 1 && col == 0 && curs1 != boln && !edit->flag2)      
     1187        real_col=end_col; 
     1188    else 
     1189        real_col=col; 
     1190 
     1191    if (direction) 
     1192        p=edit_buffer_get_backward_offset (&edit->buffer, p, lines, screen_lines); 
     1193    else 
     1194        p=edit_buffer_get_forward_offset (&edit->buffer, p, lines, 0, screen_lines); 
     1195 
     1196    int offset=edit_move_forward3(edit, p, col, 0, FALSE, 0); 
     1197    int offset2=edit_move_forward3(edit, p, real_col % end_col, 0, FALSE, 0); 
     1198    if (real_col == end_col && offset-1 > 0 && edit_buffer_get_byte_ex(&edit->buffer, offset-1) == '\n' && edit_buffer_get_byte_ex(&edit->buffer, offset) != '\n') 
     1199        offset2=offset-1; 
     1200    edit_cursor_move(edit, offset2 - curs1); 
    10961201 
    10971202#ifdef HAVE_CHARSET 
    10981203    /* search start of current multibyte char (like CJK) */ 
    1099     if (edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
     1204    if (0 && edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
    11001205        && edit_buffer_get_current_byte (&edit->buffer) >= 256) 
    11011206    { 
    11021207        edit_right_char_move_cmd (edit); 
    static void 
    11581263edit_do_undo (WEdit * edit) 
    11591264{ 
    11601265    long ac; 
    1161     long count = 0; 
    11621266 
    11631267    edit->undo_stack_disable = 1;       /* don't record undo's onto undo stack! */ 
    11641268    edit->over_col = 0; 
    edit_do_undo (WEdit * edit) 
    12001304        { 
    12011305            edit->mark1 = ac - MARK_1; 
    12021306            edit->column1 = 
    1203                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1204                                            0, edit->mark1); 
     1307                (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1308                                           0, edit->mark1, FALSE, 0); 
    12051309        } 
    12061310        if (ac >= MARK_2 - 2 && ac < MARK_CURS - 2) 
    12071311        { 
    12081312            edit->mark2 = ac - MARK_2; 
    12091313            edit->column2 = 
    1210                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1211                                            0, edit->mark2); 
     1314                (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1315                                           0, edit->mark2, FALSE, 0); 
    12121316        } 
    12131317        else if (ac >= MARK_CURS - 2 && ac < KEY_PRESS) 
    12141318        { 
    12151319            edit->end_mark_curs = ac - MARK_CURS; 
    12161320        } 
    1217         if (count++) 
    1218             edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ 
     1321        edit->force |= REDRAW_PAGE; 
    12191322    } 
    12201323 
    12211324    if (edit->start_display > ac - KEY_PRESS) 
    12221325    { 
    1223         edit->start_line -= 
    1224             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1326        edit->start_line -=  
     1327            edit_buffer_count_lines(&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) - 1; 
    12251328        edit->force |= REDRAW_PAGE; 
    12261329    } 
    12271330    else if (edit->start_display < ac - KEY_PRESS) 
    12281331    { 
    12291332        edit->start_line += 
    1230             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1333            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) - 1; 
    12311334        edit->force |= REDRAW_PAGE; 
    12321335    } 
    12331336    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    static void 
    12431346edit_do_redo (WEdit * edit) 
    12441347{ 
    12451348    long ac; 
    1246     long count = 0; 
    12471349 
    12481350    if (edit->redo_stack_reset) 
    12491351        return; 
    edit_do_redo (WEdit * edit) 
    12851387        { 
    12861388            edit->mark1 = ac - MARK_1; 
    12871389            edit->column1 = 
    1288                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1289                                            0, edit->mark1); 
     1390                (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1391                                           0, edit->mark1, FALSE, 0); 
    12901392        } 
    12911393        else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) 
    12921394        { 
    12931395            edit->mark2 = ac - MARK_2; 
    12941396            edit->column2 = 
    1295                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1296                                            0, edit->mark2); 
     1397                (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1398                                           0, edit->mark2, FALSE, 0); 
    12971399        } 
    1298         /* more than one pop usually means something big */ 
    1299         if (count++) 
    1300             edit->force |= REDRAW_PAGE; 
     1400        edit->force |= REDRAW_PAGE; 
    13011401    } 
    13021402 
    13031403    if (edit->start_display > ac - KEY_PRESS) 
    13041404    { 
    13051405        edit->start_line -= 
    1306             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1406            edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) -1; 
    13071407        edit->force |= REDRAW_PAGE; 
    13081408    } 
    13091409    else if (edit->start_display < ac - KEY_PRESS) 
    13101410    { 
    13111411        edit->start_line += 
    1312             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1412            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) -1; 
    13131413        edit->force |= REDRAW_PAGE; 
    13141414    } 
    13151415    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    edit_auto_indent (WEdit * edit) 
    14041504 
    14051505    p = edit->buffer.curs1; 
    14061506    /* use the previous line as a template */ 
    1407     p = edit_buffer_get_backward_offset (&edit->buffer, p, 1); 
     1507    p = edit_buffer_get_backward_offset (&edit->buffer, p, 1, FALSE); 
    14081508    /* copy the leading whitespace of the line */ 
    14091509    while (TRUE) 
    14101510    {                           /* no range check - the line _is_ \n-terminated */ 
    edit_move_block_to_right (WEdit * edit) 
    16041704    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16051705        return; 
    16061706 
    1607     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1608     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1707    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1708    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16091709 
    16101710    do 
    16111711    { 
    edit_move_block_to_right (WEdit * edit) 
    16171717            else 
    16181718                edit_insert (edit, '\t'); 
    16191719            edit_cursor_move (edit, 
    1620                               edit_buffer_get_bol (&edit->buffer, cur_bol) - edit->buffer.curs1); 
     1720                              edit_buffer_get_bol (&edit->buffer, cur_bol, FALSE) - edit->buffer.curs1); 
    16211721        } 
    16221722 
    16231723        if (cur_bol == 0) 
    16241724            break; 
    16251725 
    1626         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1726        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16271727    } 
    16281728    while (cur_bol >= start_bol); 
    16291729 
    edit_move_block_to_left (WEdit * edit) 
    16411741    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16421742        return; 
    16431743 
    1644     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1645     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1744    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1745    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16461746 
    16471747    do 
    16481748    { 
    edit_move_block_to_left (WEdit * edit) 
    16711771        if (cur_bol == 0) 
    16721772            break; 
    16731773 
    1674         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1774        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16751775    } 
    16761776    while (cur_bol >= start_bol); 
    16771777 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17481848                    } 
    17491849                } 
    17501850 
    1751                 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1); 
     1851                edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0, FALSE, 0) - edit->buffer.curs1); 
    17521852 
    17531853                for (l = col - edit_get_col (edit); l >= space_width; l -= space_width) 
    17541854                    edit_insert (edit, ' '); 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17691869/*** public functions ****************************************************************************/ 
    17701870/* --------------------------------------------------------------------------------------------- */ 
    17711871 
     1872 
     1873void  
     1874edit_apply_curs_exceptions(WEdit *e) 
     1875{ 
     1876    off_t bol_m2 = edit_buffer_get_bol (&e->buffer, e->buffer.curs1 +(e->buffer.curs1-2>=0 ? -2:0), TRUE); 
     1877    off_t bol = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, TRUE); 
     1878    off_t boln = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, FALSE); 
     1879    off_t eol = edit_buffer_get_eol(&e->buffer, e->buffer.curs1, TRUE); 
     1880    off_t curs1 = e->buffer.curs1, prev_curs1 = e->prev_curs1; 
     1881    long size=e->buffer.size, psize=e->prev_size; 
     1882    long cnt_m2=edit_move_forward3(e, bol_m2, 0, eol, FALSE, 0); 
     1883    long col=edit_move_forward3(e, bol, 0, curs1, FALSE, 0); 
     1884    long end_col=e->end_col; 
     1885    edit_update_curs_row(e); 
     1886 
     1887    /* First one exception is turned on – the one 
     1888     * that increases cursor y position when at 
     1889     * first column and not at bol */ 
     1890    if (curs1 != boln && curs1 == bol && col == 0) 
     1891    { 
     1892        e->curs_row ++; 
     1893        if (cnt_m2 <= end_col-2) 
     1894            e->flag2=1; 
     1895    } 
     1896 
     1897    if (curs1 == bol && /*m.left*/curs1<prev_curs1) 
     1898        e->flag2 = TRUE; 
     1899 
     1900    /* Remaining apply only for screen-long lines */ 
     1901    if (cnt_m2 <= end_col-2) 
     1902        return; 
     1903 
     1904    /* The second exception – when moving at 
     1905     * col == 0 from a lower curs1 position (right), 
     1906     * meaning that it should be an end_col position 
     1907     */ 
     1908    if (/*m.right*/curs1==prev_curs1+1 && col == 0 && curs1 != boln &&  /*not flagged */ !e->flag) 
     1909    { 
     1910        if (psize + 1 != size) 
     1911        { 
     1912            e->flag=TRUE; 
     1913            e->curs_col=e->end_col; 
     1914            e->curs_row --; 
     1915        } 
     1916        e->flag2=0; 
     1917    } 
     1918    else if (/*m.right*/curs1==prev_curs1+1 && col == 1 && curs1 >= boln+1 && 
     1919      /* flagged */ e->flag) 
     1920    { 
     1921        if (psize + 1 != size) 
     1922        { 
     1923            edit_cursor_move(e, -1); 
     1924            e->flag=FALSE; 
     1925            e->curs_col=0; 
     1926        } 
     1927        e->flag2=1; 
     1928    } 
     1929    else if (/*m.left*/curs1==prev_curs1-1 &&  
     1930           col == end_col-1 &&  
     1931           !e->flag) 
     1932    { 
     1933        if (psize != size + 1) 
     1934        { 
     1935            edit_cursor_move (e, 1); 
     1936            e->flag=TRUE; 
     1937            e->curs_col=end_col; 
     1938        } 
     1939        e->flag2=0; 
     1940    } 
     1941    else if (ABS(curs1-prev_curs1) != 1 && col == 0 && curs1 != boln && !e->flag2) 
     1942    { 
     1943        e->curs_col=end_col; 
     1944        e->curs_row --; 
     1945        e->flag=TRUE; 
     1946    } 
     1947    else  
     1948    { 
     1949        e->flag=0; 
     1950    } 
     1951} 
     1952 
    17721953/** User edit menu, like user menu (F2) but only in editor. */ 
    17731954 
    17741955void 
    edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath) 
    20852266 * cursor on that line and show it in the middle of the screen. 
    20862267 */ 
    20872268 
    2088 WEdit * 
    2089 edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, long line) 
     2269WEdit *edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, long line) 
    20902270{ 
    20912271    gboolean to_free = FALSE; 
    20922272 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21242304        edit_save_size (edit); 
    21252305    } 
    21262306 
     2307    if (edit->page_line_data == NULL) 
     2308            edit->page_line_data = g_ptr_array_new_full(LINES, g_free); 
     2309    g_ptr_array_set_size(edit->page_line_data, LINES); 
     2310 
    21272311    edit->drag_state = MCEDIT_DRAG_NONE; 
    21282312 
    21292313    edit->stat1.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21532337    edit_set_codeset (edit); 
    21542338#endif 
    21552339 
     2340    edit_set_end_column (edit); 
    21562341    if (!edit_load_file (edit)) 
    21572342    { 
    21582343        /* edit_load_file already gives an error message */ 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21792364        edit_move_to_line (edit, line - 1); 
    21802365    } 
    21812366 
     2367 
    21822368    edit_load_macro_cmd (edit); 
    21832369 
    21842370    return edit; 
    edit_push_redo_action (WEdit * edit, long c) 
    25082694        edit->redo_stack_bottom = edit->redo_stack_pointer = 0; 
    25092695} 
    25102696 
     2697 
     2698/* --------------------------------------------------------------------------------------------- */ 
     2699 
    25112700/* --------------------------------------------------------------------------------------------- */ 
    25122701/** 
    25132702   Basic low level single character buffer alterations and movements at the cursor. 
    edit_insert (WEdit * edit, int c) 
    25312720    /* now we must update some info on the file and check if a redraw is required */ 
    25322721    if (c == '\n') 
    25332722    { 
     2723        edit->buffer.line_begin_offset = edit->buffer.curs1; 
    25342724        book_mark_inc (edit, edit->buffer.curs_line); 
    25352725        edit->buffer.curs_line++; 
    25362726        edit->buffer.lines++; 
    edit_backspace (WEdit * edit, gboolean byte_delete) 
    27242914void 
    27252915edit_cursor_move (WEdit * edit, off_t increment) 
    27262916{ 
     2917    gboolean scroll = FALSE; 
     2918    off_t idx; 
    27272919    if (increment < 0) 
    27282920    { 
    2729         for (; increment < 0 && edit->buffer.curs1 != 0; increment++) 
     2921        for (idx = 0; idx > increment && edit->buffer.curs1 != 0; idx--) 
    27302922        { 
    27312923            int c; 
    27322924 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27372929            c = edit_buffer_backspace (&edit->buffer); 
    27382930            if (c == '\n') 
    27392931            { 
     2932                edit->buffer.line_begin_offset = 0; 
     2933                for (int i=edit->buffer.curs1-1; i>0; i --) 
     2934                { 
     2935                    unsigned char ch = edit_buffer_get_byte(&edit->buffer, i); 
     2936                    if (ch == '\n') 
     2937                    { 
     2938                        edit->buffer.line_begin_offset = i + 1; 
     2939                        break; 
     2940                    } 
     2941                } 
    27402942                edit->buffer.curs_line--; 
    27412943                edit->force |= REDRAW_LINE_BELOW; 
     2944                if (edit->buffer.curs_line < edit->start_line) 
     2945                    scroll = TRUE; 
    27422946            } 
    27432947        } 
     2948        if (scroll) 
     2949        { 
     2950            edit_scroll_upward (edit, edit->start_line - edit->buffer.curs_line); 
     2951        } 
    27442952    } 
    27452953    else 
    27462954    { 
    2747         for (; increment > 0 && edit->buffer.curs2 != 0; increment--) 
     2955        for (idx = 0; idx < increment && edit->buffer.curs2 != 0; idx ++) 
    27482956        { 
    27492957            int c; 
    27502958 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27552963            c = edit_buffer_delete (&edit->buffer); 
    27562964            if (c == '\n') 
    27572965            { 
     2966                edit->buffer.line_begin_offset = edit->buffer.curs1; 
    27582967                edit->buffer.curs_line++; 
     2968                if (edit->buffer.curs_line - edit->start_line >= soft_last_row) 
     2969                    scroll = TRUE; 
    27592970                edit->force |= REDRAW_LINE_ABOVE; 
    27602971            } 
    27612972        } 
     2973        if (scroll) 
     2974        { 
     2975            edit_scroll_downward(edit, (edit->buffer.curs_line - edit->start_line) - soft_last_row); 
     2976            edit->force |= REDRAW_PAGE; 
     2977        } 
    27622978    } 
    27632979} 
    27642980 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27672983/* If upto is zero returns index of cols across from current. */ 
    27682984 
    27692985off_t 
    2770 edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
     2986edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto, gboolean as_bytes, off_t col_limit) 
    27712987{ 
    27722988    off_t p, q; 
    2773     long col; 
     2989    long col, col_acc = 0, btes = 0, prev_len = 0; 
     2990    int char_length = 1; 
     2991    int utf_ch; 
    27742992 
    27752993    if (upto != 0) 
    27762994    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27782996        cols = -10; 
    27792997    } 
    27802998    else 
    2781         q = edit->buffer.size + 2; 
     2999        q = edit->buffer.size + 1; 
    27823000 
    27833001    for (col = 0, p = current; p < q; p++) 
    27843002    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27973015#ifdef HAVE_CHARSET 
    27983016        if (edit->utf8) 
    27993017        { 
    2800             int utf_ch; 
    2801             int char_length = 1; 
    2802  
     3018            char_length = 1; 
    28033019            utf_ch = edit_buffer_get_utf (&edit->buffer, p, &char_length); 
     3020 
    28043021            if (mc_global.utf8_display) 
    28053022            { 
    28063023                if (char_length > 1) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28143031 
    28153032        c = convert_to_display_c (c); 
    28163033#endif 
     3034         
     3035        if (c == '\n') { 
     3036            return (upto != 0 ? (off_t) (as_bytes ? btes : col-col_acc) : p); 
     3037        } 
    28173038 
    2818         if (c == '\n') 
    2819             return (upto != 0 ? (off_t) col : p); 
    2820         if (c == '\t') 
    2821             col += TAB_SIZE - col % TAB_SIZE; 
     3039#ifdef HAVE_CHARSET 
     3040        if (edit->utf8) 
     3041        { 
     3042            btes += prev_len <= 1 ? char_length : 0; 
     3043            prev_len = prev_len <= 1 ? char_length : prev_len - 1; 
     3044        } else 
     3045            btes += 1; 
     3046#else 
     3047        btes += 1; 
     3048#endif 
     3049 
     3050        /* Treat tab specially, as it needs to use 
     3051         * whole line, not only screen line */ 
     3052        if (c == '\t' || utf_ch == '\t') { 
     3053            off_t boln = edit_buffer_get_bol(&edit->buffer, p, FALSE); 
     3054            off_t qq = boln, ncols = 0, acc = 0; 
     3055            int len = -1, ch; 
     3056            for(; len && qq <= p; 
     3057        (ch=edit_buffer_get_utf(&edit->buffer,qq,&len)),  
     3058          qq+=len, ncols+=(g_unichar_iswide (ch)>0)+(ch=='\t'?(TAB_SIZE-(ncols%TAB_SIZE)):len>0)) 
     3059            { 
     3060                /* Still modulo the line length */ 
     3061                if ((ncols-acc) >= edit->end_col) 
     3062                    acc += edit->end_col; 
     3063            } 
     3064            /* Apply precisely calculated cols */ 
     3065            col = ncols; 
     3066            if (boln != current) 
     3067                col -= acc; 
     3068        } 
    28223069        else if ((c < 32 || c == 127) && (orig_c == c 
    28233070#ifdef HAVE_CHARSET 
    28243071                                          || (!mc_global.utf8_display && !edit->utf8) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28293076            col += 2; 
    28303077        else 
    28313078            col++; 
     3079 
     3080        if (col_limit > 0) 
     3081        { 
     3082            btes = ((col - col_acc) >= col_limit) ? 0 : btes; 
     3083            col_acc += ((col - col_acc) >= col_limit) ? col_limit : 0; 
     3084        } 
    28323085    } 
    2833     return (off_t) col; 
     3086     
     3087    return (off_t) (as_bytes ? btes : col-col_acc); 
    28343088} 
    28353089 
    28363090/* --------------------------------------------------------------------------------------------- */ 
    edit_get_cursor_offset (const WEdit * edit) 
    28433097} 
    28443098 
    28453099/* --------------------------------------------------------------------------------------------- */ 
     3100 
    28463101/** returns the current column position of the cursor */ 
    28473102 
    28483103long 
    28493104edit_get_col (const WEdit * edit) 
    28503105{ 
    2851     return (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2852                                       edit->buffer.curs1); 
     3106    gboolean screen = edit_options.soft_wrap?1:0; 
     3107    off_t bol = edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, screen); 
     3108 
     3109    off_t col = (long) edit_move_forward3 (edit, bol, 0, edit->buffer.curs1, FALSE, 0); 
     3110    col -= -2*edit->start_col; 
     3111    return col; 
    28533112} 
    28543113 
    28553114/* --------------------------------------------------------------------------------------------- */ 
    edit_get_col (const WEdit * edit) 
    28573116/* --------------------------------------------------------------------------------------------- */ 
    28583117 
    28593118void 
    2860 edit_update_curs_row (WEdit * edit) 
     3119edit_update_curs_row (WEdit * e) 
    28613120{ 
    2862     edit->curs_row = edit->buffer.curs_line - edit->start_line; 
     3121    /* Helper variables */ 
     3122    edit_buffer_t *buf = &e->buffer; 
     3123    off_t curs1 = edit_get_cursor_offset(e); 
     3124 
     3125    /* The screen-line count ↔ the cursor row */ 
     3126    int lines = edit_buffer_count_lines(buf, e->start_display, curs1, TRUE); 
     3127    /* Screen-line count should be 0-based */ 
     3128    e->curs_row = lines > 0 ? lines-1 : 0; 
     3129    /* Non screen-lines line count */ 
     3130    e->array_row = edit_buffer_count_lines (buf, e->start_display, curs1, FALSE); 
     3131    /* Make the line count 0-based */ 
     3132    e->array_row>0 ? e->array_row-- : 0; 
    28633133} 
    28643134 
    28653135/* --------------------------------------------------------------------------------------------- */ 
    edit_update_curs_row (WEdit * edit) 
    28673137void 
    28683138edit_update_curs_col (WEdit * edit) 
    28693139{ 
    2870     edit->curs_col = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 
    2871                                                 0, edit->buffer.curs1); 
     3140    edit->curs_col = edit_get_col(edit); 
    28723141} 
    28733142 
    28743143/* --------------------------------------------------------------------------------------------- */ 
    edit_scroll_upward (WEdit * edit, long i) 
    28933162    { 
    28943163        edit->start_line -= i; 
    28953164        edit->start_display = 
    2896             edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i); 
     3165            edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i, FALSE); 
    28973166        edit->force |= REDRAW_PAGE; 
    28983167        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    28993168    } 
    edit_scroll_downward (WEdit * edit, long i) 
    29083177{ 
    29093178    long lines_below; 
    29103179 
    2911     lines_below = edit->buffer.lines - edit->start_line - (WIDGET (edit)->rect.lines - 1); 
     3180    lines_below = edit->buffer.lines - edit->start_line - (soft_last_row - 1); 
    29123181    if (lines_below > 0) 
    29133182    { 
    29143183        if (i > lines_below) 
    29153184            i = lines_below; 
    29163185        edit->start_line += i; 
    29173186        edit->start_display = 
    2918             edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0); 
     3187            edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0, FALSE); 
    29193188        edit->force |= REDRAW_PAGE; 
    29203189        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    29213190    } 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29583227    long over = edit->over_col; 
    29593228 
    29603229    edit_cursor_move (edit, 
    2961                       edit_move_forward3 (edit, p, prev + edit->over_col, 0) - edit->buffer.curs1); 
     3230                      edit_move_forward3 (edit, p, prev + edit->over_col, 0, FALSE, 0) - edit->buffer.curs1); 
    29623231 
    29633232    if (edit_options.cursor_beyond_eol) 
    29643233    { 
    29653234        long line_len; 
    29663235 
    29673236        line_len = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2968                                               edit_buffer_get_current_eol (&edit->buffer)); 
     3237                                              edit_buffer_get_current_eol (&edit->buffer), FALSE, FALSE); 
    29693238        if (line_len < prev + edit->over_col) 
    29703239        { 
    29713240            edit->over_col = prev + over - line_len; 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29983267                p = edit_buffer_get_current_bol (&edit->buffer); 
    29993268                edit_cursor_move (edit, 
    30003269                                  edit_move_forward3 (edit, p, edit->curs_col, 
    3001                                                       0) - edit->buffer.curs1); 
     3270                                                      0, FALSE, FALSE) - edit->buffer.curs1); 
    30023271                if (!left_of_four_spaces (edit)) 
    30033272                    edit_cursor_move (edit, 
    3004                                       edit_move_forward3 (edit, p, q, 0) - edit->buffer.curs1); 
     3273                                      edit_move_forward3 (edit, p, q, 0, FALSE, FALSE) - edit->buffer.curs1); 
    30053274            } 
    30063275        } 
    30073276    } 
    void 
    30293298edit_move_to_line (WEdit * e, long line) 
    30303299{ 
    30313300    if (line < e->buffer.curs_line) 
    3032         edit_move_up (e, e->buffer.curs_line - line, FALSE); 
     3301        edit_move_up (e, e->buffer.curs_line - line, FALSE, FALSE); 
    30333302    else 
    3034         edit_move_down (e, line - e->buffer.curs_line, FALSE); 
     3303        edit_move_down (e, line - e->buffer.curs_line, FALSE, FALSE); 
    30353304    edit_scroll_screen_over_cursor (e); 
    30363305} 
    30373306 
    edit_execute_key_command (WEdit * edit, long command, int char_for_insertion) 
    32603529void 
    32613530edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    32623531{ 
    3263     WRect *w = &WIDGET (edit)->rect; 
    3264  
    32653532    if (command == CK_WindowFullscreen) 
    32663533    { 
    32673534        edit_toggle_fullscreen (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    33533620    /* An ordinary key press */ 
    33543621    if (char_for_insertion >= 0) 
    33553622    { 
     3623        off_t prev_curs_col, col; 
     3624 
     3625        if (edit->curs_col == 0) 
     3626            edit->force |= REDRAW_AFTER_CURSOR; 
     3627        prev_curs_col = edit->curs_col; 
     3628 
    33563629        /* if non persistent selection and text selected */ 
    33573630        if (!edit_options.persistent_selections && edit->mark1 != edit->mark2) 
    33583631            edit_block_delete_cmd (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34083681            edit->force |= REDRAW_PAGE; 
    34093682        } 
    34103683        else 
     3684        { 
    34113685            check_and_wrap_line (edit); 
     3686            edit->force |= REDRAW_AFTER_CURSOR; 
     3687        } 
     3688        col = edit_get_col(edit); 
     3689        if (prev_curs_col == edit->buffer.end_col - 1 && col == 0) 
     3690            edit->force |= REDRAW_AFTER_CURSOR; 
    34123691        edit->found_len = 0; 
    34133692        edit->prev_col = edit_get_col (edit); 
    34143693        edit->search_start = edit->buffer.curs1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34673746    case CK_Right: 
    34683747    case CK_MarkLeft: 
    34693748    case CK_MarkRight: 
    3470         edit->force |= REDRAW_CHAR_ONLY; 
     3749        edit->force |= REDRAW_LINE; 
    34713750        break; 
    34723751    default: 
    34733752        break; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34973776        } 
    34983777        else 
    34993778            edit_backspace (edit, FALSE); 
     3779         
     3780        edit->force |= REDRAW_AFTER_CURSOR; 
    35003781        break; 
    35013782    case CK_Delete: 
    35023783        /* if non persistent selection and text selected */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    35633844        MC_FALLTHROUGH; 
    35643845    case CK_PageUp: 
    35653846    case CK_MarkPageUp: 
    3566         edit_move_up (edit, w->lines - 1, TRUE); 
     3847        edit_move_up (edit, soft_last_row, TRUE, FALSE); 
    35673848        break; 
    35683849    case CK_MarkColumnPageDown: 
    35693850        edit->column_highlight = 1; 
    35703851        MC_FALLTHROUGH; 
    35713852    case CK_PageDown: 
    35723853    case CK_MarkPageDown: 
    3573         edit_move_down (edit, w->lines - 1, TRUE); 
     3854        edit_move_down (edit, soft_last_row, TRUE, FALSE); 
    35743855        break; 
    35753856    case CK_MarkColumnLeft: 
    35763857        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36263907        MC_FALLTHROUGH; 
    36273908    case CK_Up: 
    36283909    case CK_MarkUp: 
    3629         edit_move_up (edit, 1, FALSE); 
     3910        edit_move_up (edit, 1, FALSE, TRUE); 
    36303911        break; 
    36313912    case CK_MarkColumnDown: 
    36323913        edit->column_highlight = 1; 
    36333914        MC_FALLTHROUGH; 
    36343915    case CK_Down: 
    36353916    case CK_MarkDown: 
    3636         edit_move_down (edit, 1, FALSE); 
     3917        edit_move_down (edit, 1, FALSE, TRUE); 
    36373918        break; 
    36383919    case CK_MarkColumnParagraphUp: 
    36393920        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36543935        MC_FALLTHROUGH; 
    36553936    case CK_ScrollUp: 
    36563937    case CK_MarkScrollUp: 
    3657         edit_move_up (edit, 1, TRUE); 
     3938        edit_move_up (edit, 1, TRUE, TRUE); 
    36583939        break; 
    36593940    case CK_MarkColumnScrollDown: 
    36603941        edit->column_highlight = 1; 
    36613942        MC_FALLTHROUGH; 
    36623943    case CK_ScrollDown: 
    36633944    case CK_MarkScrollDown: 
    3664         edit_move_down (edit, 1, TRUE); 
     3945        edit_move_down (edit, 1, TRUE, TRUE); 
    36653946        break; 
    36663947    case CK_Home: 
    36673948    case CK_MarkToHome: 
    3668         edit_cursor_to_bol (edit); 
     3949        edit_cursor_to_bol (edit, TRUE); 
    36693950        break; 
    36703951    case CK_End: 
    36713952    case CK_MarkToEnd: 
    3672         edit_cursor_to_eol (edit); 
     3953        edit_cursor_to_eol (edit, TRUE); 
    36733954        break; 
    36743955    case CK_Tab: 
    36753956        /* if text marked shift block */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37574038            if (p->next != NULL) 
    37584039            { 
    37594040                p = p->next; 
    3760                 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) 
    3761                     edit_move_display (edit, p->line - w->lines / 2); 
     4041                if (p->line >= edit->start_line + soft_last_row+1 || p->line < edit->start_line) 
     4042                    edit_move_display (edit, p->line - (soft_last_row+1) / 2); 
    37624043                edit_move_to_line (edit, p->line); 
    37634044            } 
    37644045        } 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37744055                    p = p->prev; 
    37754056            if (p->line >= 0) 
    37764057            { 
    3777                 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) 
    3778                     edit_move_display (edit, p->line - w->lines / 2); 
     4058                if (p->line >= edit->start_line + soft_last_row+1 || p->line < edit->start_line) 
     4059                    edit_move_display (edit, p->line - (soft_last_row+1) / 2); 
    37794060                edit_move_to_line (edit, p->line); 
    37804061            } 
    37814062        } 
    37824063        break; 
    37834064 
     4065    case CK_SoftFolds: 
     4066        edit_options.soft_wrap = !edit_options.soft_wrap; 
     4067        edit->start_col *= !edit_options.soft_wrap; 
     4068        edit->force |= REDRAW_COMPLETELY; 
     4069        break; 
     4070 
    37844071    case CK_Top: 
    37854072    case CK_MarkToFileBegin: 
    37864073        edit_move_to_top (edit); 
    edit_stack_free (void) 
    40504337/** move i lines */ 
    40514338 
    40524339void 
    4053 edit_move_up (WEdit * edit, long i, gboolean do_scroll) 
     4340edit_move_up (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40544341{ 
    4055     edit_move_updown (edit, i, do_scroll, TRUE); 
     4342    screen_lines &= edit_options.soft_wrap; 
     4343    edit_move_updown (edit, i, do_scroll, TRUE, screen_lines); 
    40564344} 
    40574345 
    40584346/* --------------------------------------------------------------------------------------------- */ 
    40594347/** move i lines */ 
    40604348 
    40614349void 
    4062 edit_move_down (WEdit * edit, long i, gboolean do_scroll) 
     4350edit_move_down (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40634351{ 
    4064     edit_move_updown (edit, i, do_scroll, FALSE); 
     4352    screen_lines &= edit_options.soft_wrap; 
     4353    edit_move_updown (edit, i, do_scroll, FALSE, screen_lines); 
    40654354} 
    40664355 
    40674356/* --------------------------------------------------------------------------------------------- */ 
  • src/editor/edit.h

    diff --git a/src/editor/edit.h b/src/editor/edit.h
    index 358aa3f14..ffdc0af97 100644
    a b typedef struct 
    6060    gboolean show_right_margin; 
    6161    gboolean simple_statusbar;  /* statusbar draw style */ 
    6262    gboolean check_nl_at_eof; 
     63    gboolean soft_wrap; 
    6364} edit_options_t; 
    6465 
    6566/*** global variables defined in .c file *********************************************************/ 
    6667 
    6768extern edit_options_t edit_options; 
     69extern int soft_last_row; 
    6870 
    6971/*** declarations of public functions ************************************************************/ 
     72void edit_apply_curs_exceptions(WEdit *edit); 
     73long edit_count_returns(WEdit *edit, off_t from, off_t to, gboolean screen_lines); 
     74gboolean edit_set_end_column(WEdit *edit); 
    7075 
    7176/* used in main() */ 
    7277void edit_stack_init (void); 
  • src/editor/editbuffer.c

    diff --git a/src/editor/editbuffer.c b/src/editor/editbuffer.c
    index 24bc7eeab..3da13b6e6 100644
    a b  
    4040 
    4141#include "lib/vfs/vfs.h" 
    4242 
     43#include "editwidget.h" 
    4344#include "edit-impl.h" 
    4445#include "editbuffer.h" 
    4546 
    edit_buffer_get_byte_ptr (const edit_buffer_t * buf, off_t byte_index) 
    136137 
    137138/* --------------------------------------------------------------------------------------------- */ 
    138139/*** public functions ****************************************************************************/ 
     140/* Todo: query unicode chars (not bytes) */ 
     141int edit_buffer_count_tabs(edit_buffer_t *buf, off_t first, off_t last, gboolean all_kinds) 
     142{ 
     143    int cnt = 0; 
     144    last = last > buf->size ? buf->size : last; 
     145    while (first <= last) 
     146    { 
     147        int byte = edit_buffer_get_byte(buf, first); 
     148        if (byte == '\t' || (all_kinds && byte == '\v')) 
     149            cnt ++; 
     150        ++ first; 
     151    } 
     152    return cnt; 
     153} 
     154 
    139155/* --------------------------------------------------------------------------------------------- */ 
    140156/** 
    141157 * Initialize editor buffers. 
    edit_buffer_get_byte_ptr (const edit_buffer_t * buf, off_t byte_index) 
    144160 */ 
    145161 
    146162void 
    147 edit_buffer_init (edit_buffer_t * buf, off_t size) 
     163edit_buffer_init (WEdit *e, edit_buffer_t * buf, off_t size) 
    148164{ 
    149165    buf->b1 = g_ptr_array_new_full (32, g_free); 
    150166    buf->b2 = g_ptr_array_new_full (32, g_free); 
     167    buf->edit_widget = e; 
     168    buf->end_col = 73; 
    151169 
    152170    buf->curs1 = 0; 
    153171    buf->curs2 = 0; 
    void 
    167185edit_buffer_clean (edit_buffer_t * buf) 
    168186{ 
    169187    if (buf->b1 != NULL) 
     188    { 
    170189        g_ptr_array_free (buf->b1, TRUE); 
     190    } 
    171191 
    172192    if (buf->b2 != NULL) 
     193    { 
    173194        g_ptr_array_free (buf->b2, TRUE); 
     195    } 
    174196} 
    175197 
    176198/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_clean (edit_buffer_t * buf) 
    182204  * 
    183205  * @return '\n' if byte_index is negative or larger than file size; byte at byte_index otherwise. 
    184206  */ 
     207int 
     208edit_buffer_get_byte_ex (const edit_buffer_t * buf, off_t byte_index) 
     209{ 
     210    char *p; 
     211 
     212    p = edit_buffer_get_byte_ptr (buf, byte_index); 
     213 
     214    return (p != NULL) ? *(unsigned char *) p : -1; 
     215} 
    185216 
    186217int 
    187218edit_buffer_get_byte (const edit_buffer_t * buf, off_t byte_index) 
    edit_buffer_get_prev_utf (const edit_buffer_t * buf, off_t byte_index, int *char 
    323354 */ 
    324355 
    325356long 
    326 edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
     357edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last, gboolean screen_lines) 
    327358{ 
    328     long lines = 0; 
     359    long lines = 0, prev_eol = 0, eol; 
     360    screen_lines &= edit_options.soft_wrap; 
    329361 
    330362    first = MAX (first, 0); 
    331363    last = MIN (last, buf->size); 
    332364 
    333     while (first < last) 
    334         if (edit_buffer_get_byte (buf, first++) == '\n') 
    335             lines++; 
     365    if (first == last) 
     366        return 0; 
    336367 
     368    while (first <= last) 
     369    { 
     370        eol = edit_buffer_get_eol(buf, first, screen_lines); 
     371        /* Advance in buffer */ 
     372        if (edit_buffer_get_byte_ex(buf, eol) == '\n' || ~screen_lines || eol == prev_eol) 
     373            first = eol+1; 
     374        else 
     375            first = eol; 
     376        prev_eol = eol; 
     377        /* Count line */ 
     378        lines++; 
     379    } 
    337380    return lines; 
    338381} 
    339382 
    edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
    348391 */ 
    349392 
    350393off_t 
    351 edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
     394edit_buffer_get_bol (const edit_buffer_t * buf, off_t current_bol, gboolean screen_lines) 
    352395{ 
    353     if (current <= 0) 
     396    off_t current_save = current_bol; 
     397    off_t current_eol = current_bol; 
     398    screen_lines &= edit_options.soft_wrap; 
     399    if (current_bol <= 0) 
     400    { 
    354401        return 0; 
    355  
    356     for (; edit_buffer_get_byte (buf, current - 1) != '\n'; current--) 
     402    } 
     403    for (; current_bol>0 && edit_buffer_get_byte (buf, current_bol-1)!='\n'; current_bol-=1) 
    357404        ; 
    358405 
    359     return current; 
     406    for (; (edit_buffer_get_byte (buf, current_eol)!='\n' || current_save == current_eol) && current_eol < buf->size 
     407                            ; current_eol+=1); 
     408 
     409 
     410    if (screen_lines) 
     411    { 
     412        off_t pos = current_save -  
     413    edit_move_forward3(buf->edit_widget, current_bol, 0, current_save, TRUE, buf->end_col); 
     414        return pos; 
     415    } 
     416    return current_bol; 
    360417} 
    361418 
    362419/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
    370427 */ 
    371428 
    372429off_t 
    373 edit_buffer_get_eol (const edit_buffer_t * buf, off_t current) 
     430edit_buffer_get_eol (const edit_buffer_t * buf, off_t current_eol, gboolean screen_lines) 
    374431{ 
    375     if (current >= buf->size) 
     432    off_t current_save = current_eol; 
     433    off_t current_bol = current_eol; 
     434    off_t q; 
     435    screen_lines &= edit_options.soft_wrap; 
     436    if (current_eol >= buf->size) 
    376437        return buf->size; 
    377438 
    378     for (; edit_buffer_get_byte (buf, current) != '\n'; current++) 
     439    for (; current_bol > 0 && edit_buffer_get_byte (buf, current_bol - 1) != '\n'; 
     440        current_bol--) 
    379441        ; 
    380442 
    381     return current; 
     443    if (screen_lines) 
     444    { 
     445        off_t prev_eol=0; 
     446        for (;  
     447           (edit_buffer_get_byte_ex (buf, current_eol) != '\n') &&  
     448            current_eol <= buf->size && 
     449    (current_eol==current_save || ((q=edit_move_forward3(buf->edit_widget, current_bol, 0, current_eol, FALSE, 0)%buf->end_col) != 0) 
     450                ) ; 
     451                current_eol=edit_move_forward3(buf->edit_widget,current_eol,1,0,FALSE,0), 
     452                current_eol+=prev_eol==current_eol?1:0,prev_eol=current_eol) 
     453            ; 
     454        if (current_eol > buf->size && edit_buffer_get_byte_ex(buf, current_eol) != '\n') 
     455            current_eol=buf->size; 
     456    } 
     457    else 
     458        for (; (edit_buffer_get_byte (buf, current_eol) != '\n') && current_eol < buf->size; current_eol++) 
     459        ; 
     460 
     461     
     462    return current_eol; 
    382463} 
    383464 
    384465/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_backspace (edit_buffer_t * buf) 
    638719 */ 
    639720 
    640721off_t 
    641 edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto) 
     722edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto, gboolean screen_lines) 
    642723{ 
     724    screen_lines &= edit_options.soft_wrap; 
    643725    if (upto != 0) 
    644         return (off_t) edit_buffer_count_lines (buf, current, upto); 
     726        return (off_t) edit_buffer_count_lines (buf, current, upto, screen_lines); 
    645727 
    646728    lines = MAX (lines, 0); 
    647729 
     730    if (lines > 0) 
     731    { 
     732        edit_update_curs_col(buf->edit_widget); 
     733        if (buf->edit_widget->curs_col == buf->end_col) 
     734            lines--; 
     735    } 
     736 
    648737    while (lines-- != 0) 
    649738    { 
    650         long next; 
     739        off_t next; 
     740        int byte; 
    651741 
    652         next = edit_buffer_get_eol (buf, current) + 1; 
    653         if (next > buf->size) 
     742        next = edit_buffer_get_eol (buf, current, screen_lines); 
     743        byte = edit_buffer_get_byte_ex(buf, next); 
     744 
     745        if (byte == '\n' || !screen_lines) 
     746            next++; 
     747        if (next > buf->size+1) 
    654748            break; 
    655749        current = next; 
    656750    } 
    657  
    658751    return current; 
    659752} 
    660753 
    edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long l 
    670763 */ 
    671764 
    672765off_t 
    673 edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines) 
     766edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines, gboolean screen_lines) 
    674767{ 
     768    screen_lines &= edit_options.soft_wrap; 
    675769    lines = MAX (lines, 0); 
    676     current = edit_buffer_get_bol (buf, current); 
     770    current = edit_buffer_get_bol (buf, current, screen_lines); 
    677771 
    678772    while (lines-- != 0 && current != 0) 
    679         current = edit_buffer_get_bol (buf, current - 1); 
     773    { 
     774        current = edit_buffer_get_bol (buf, current - 1, screen_lines); 
     775        if (screen_lines && current > 0 && 
     776    edit_buffer_get_byte_ex(buf,current) == '\n' &&  
     777    edit_buffer_get_byte_ex(buf,current-1) != '\n') 
     778            lines++; 
     779    } 
    680780 
     781    if (current > 0 && screen_lines && edit_buffer_get_byte_ex(buf,current-1) != '\n') 
     782        current = edit_buffer_get_eol (buf, current - 1, screen_lines); 
     783     
    681784    return current; 
    682785} 
    683786 
  • src/editor/editbuffer.h

    diff --git a/src/editor/editbuffer.h b/src/editor/editbuffer.h
    index def17eec5..eb4486f42 100644
    a b  
    1313 
    1414typedef struct edit_buffer_struct 
    1515{ 
     16    WEdit *edit_widget; 
    1617    off_t curs1;                /* position of the cursor from the beginning of the file. */ 
    1718    off_t curs2;                /* position from the end of the file */ 
    1819    GPtrArray *b1;              /* all data up to curs1 */ 
    typedef struct edit_buffer_struct 
    2021    off_t size;                 /* file size */ 
    2122    long lines;                 /* total lines in the file */ 
    2223    long curs_line;             /* line number of the cursor. */ 
     24    long line_begin_offset;     /* offset of first char after last \n */ 
     25    long end_col;               /* Maximum column in current view */ 
    2326} edit_buffer_t; 
    2427 
    2528typedef struct edit_buffer_read_file_status_msg_struct 
    typedef struct edit_buffer_read_file_status_msg_struct 
    3437/*** global variables defined in .c file *********************************************************/ 
    3538 
    3639/*** declarations of public functions ************************************************************/ 
     40int edit_buffer_get_byte_ex (const edit_buffer_t * buf, off_t byte_index); 
    3741 
    38 void edit_buffer_init (edit_buffer_t * buf, off_t size); 
     42int edit_buffer_count_tabs(edit_buffer_t *buf, off_t first, off_t last, gboolean all_kinds); 
     43void edit_buffer_init (WEdit *e, edit_buffer_t * buf, off_t size); 
    3944void edit_buffer_clean (edit_buffer_t * buf); 
    4045 
    4146int edit_buffer_get_byte (const edit_buffer_t * buf, off_t byte_index); 
    int edit_buffer_get_byte (const edit_buffer_t * buf, off_t byte_index); 
    4348int edit_buffer_get_utf (const edit_buffer_t * buf, off_t byte_index, int *char_length); 
    4449int edit_buffer_get_prev_utf (const edit_buffer_t * buf, off_t byte_index, int *char_length); 
    4550#endif 
    46 long edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last); 
    47 off_t edit_buffer_get_bol (const edit_buffer_t * buf, off_t current); 
    48 off_t edit_buffer_get_eol (const edit_buffer_t * buf, off_t current); 
     51long edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last, gboolean screen_lines); 
     52off_t edit_buffer_get_bol (const edit_buffer_t * buf, off_t current, gboolean screen_lines); 
     53off_t edit_buffer_get_eol (const edit_buffer_t * buf, off_t current, gboolean screen_lines); 
    4954GString *edit_buffer_get_word_from_pos (const edit_buffer_t * buf, off_t start_pos, off_t * start, 
    5055                                        gsize * cut); 
    5156gboolean edit_buffer_find_word_start (const edit_buffer_t * buf, off_t * word_start, 
    int edit_buffer_delete (edit_buffer_t * buf); 
    5762int edit_buffer_backspace (edit_buffer_t * buf); 
    5863 
    5964off_t edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, 
    60                                       off_t upto); 
    61 off_t edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines); 
     65                                      off_t upto, gboolean screen_lines); 
     66off_t edit_buffer_get_backward_offset (const edit_buffer_t *buf, off_t current, long lines, 
     67                                     gboolean screen_lines); 
    6268 
    6369off_t edit_buffer_read_file (edit_buffer_t * buf, int fd, off_t size, 
    6470                             edit_buffer_read_file_status_msg_t * sm, gboolean * aborted); 
    edit_buffer_get_previous_byte (const edit_buffer_t * buf) 
    94100static inline off_t 
    95101edit_buffer_get_current_bol (const edit_buffer_t * buf) 
    96102{ 
    97     return edit_buffer_get_bol (buf, buf->curs1); 
     103    return edit_buffer_get_bol (buf, buf->curs1, FALSE); 
    98104} 
    99105 
    100106/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_get_current_bol (const edit_buffer_t * buf) 
    109115static inline off_t 
    110116edit_buffer_get_current_eol (const edit_buffer_t * buf) 
    111117{ 
    112     return edit_buffer_get_eol (buf, buf->curs1); 
     118    return edit_buffer_get_eol (buf, buf->curs1, FALSE); 
    113119} 
    114120 
    115121/* --------------------------------------------------------------------------------------------- */ 
  • src/editor/editcmd.c

    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index de624f249..a550b52da 100644
    a b edit_delete_column_of_text (WEdit * edit) 
    467467    long b, c, d; 
    468468 
    469469    eval_marks (edit, &m1, &m2); 
    470     n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2) + 1; 
    471     c = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m1), 0, m1); 
    472     d = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m2), 0, m2); 
     470    n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2, FALSE) + 1; 
     471    c = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m1, TRUE), 0, m1, FALSE, 0); 
     472    d = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m2, TRUE), 0, m2, FALSE, 0); 
    473473    b = MAX (MIN (c, d), MIN (edit->column1, edit->column2)); 
    474474    c = MAX (c, MAX (edit->column1, edit->column2)); 
    475475 
    edit_delete_column_of_text (WEdit * edit) 
    478478        off_t r, p, q; 
    479479 
    480480        r = edit_buffer_get_current_bol (&edit->buffer); 
    481         p = edit_move_forward3 (edit, r, b, 0); 
    482         q = edit_move_forward3 (edit, r, c, 0); 
     481        p = edit_move_forward3 (edit, r, b, 0, FALSE, 0); 
     482        q = edit_move_forward3 (edit, r, c, 0, FALSE, 0); 
    483483        p = MAX (p, m1); 
    484484        q = MIN (q, m2); 
    485485        edit_cursor_move (edit, p - edit->buffer.curs1); 
    edit_delete_column_of_text (WEdit * edit) 
    492492        if (n != 0) 
    493493            edit_cursor_move (edit, 
    494494                              edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1, 
    495                                                               0) - edit->buffer.curs1); 
     495                                                              0, FALSE) - edit->buffer.curs1); 
    496496    } 
    497497} 
    498498 
    edit_block_delete (WEdit * edit) 
    547547            edit_move_to_line (edit, curs_line); 
    548548            /* calculate line width and cursor position before cut */ 
    549549            line_width = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    550                                              edit_buffer_get_current_eol (&edit->buffer)); 
     550                                             edit_buffer_get_current_eol (&edit->buffer), FALSE, FALSE); 
    551551            if (edit_options.cursor_beyond_eol && curs_pos > line_width) 
    552552                edit->over_col = curs_pos - line_width; 
    553553        } 
    edit_get_block (WEdit * edit, off_t start, off_t finish, off_t * l) 
    586586            int c; 
    587587            off_t x; 
    588588 
    589             x = edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, start), 0, start); 
     589            x = edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, start, TRUE), 0, start, FALSE, 0); 
    590590            c = edit_buffer_get_byte (&edit->buffer, start); 
    591591            if ((x >= edit->column1 && x < edit->column2) 
    592592                || (x >= edit->column2 && x < edit->column1) || c == '\n') 
    edit_insert_column_of_text (WEdit * edit, unsigned char *data, off_t size, long 
    699699                    break; 
    700700                } 
    701701            } 
    702             edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1); 
     702            edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0, FALSE, FALSE) - edit->buffer.curs1); 
    703703 
    704704            for (l = col - edit_get_col (edit); l >= space_width; l -= space_width) 
    705705                edit_insert (edit, ' '); 
    eval_marks (WEdit * edit, off_t * start_mark, off_t * end_mark) 
    13001300        long col1, col2; 
    13011301        off_t diff1, diff2; 
    13021302 
    1303         start_bol = edit_buffer_get_bol (&edit->buffer, *start_mark); 
    1304         start_eol = edit_buffer_get_eol (&edit->buffer, start_bol - 1) + 1; 
    1305         end_bol = edit_buffer_get_bol (&edit->buffer, *end_mark); 
    1306         end_eol = edit_buffer_get_eol (&edit->buffer, *end_mark); 
     1303        start_bol = edit_buffer_get_bol (&edit->buffer, *start_mark, FALSE); 
     1304        start_eol = edit_buffer_get_eol (&edit->buffer, start_bol - 1, FALSE) + 1; 
     1305        end_bol = edit_buffer_get_bol (&edit->buffer, *end_mark, FALSE); 
     1306        end_eol = edit_buffer_get_eol (&edit->buffer, *end_mark, FALSE); 
    13071307        col1 = MIN (edit->column1, edit->column2); 
    13081308        col2 = MAX (edit->column1, edit->column2); 
    13091309 
    1310         diff1 = edit_move_forward3 (edit, start_bol, col2, 0) - 
    1311             edit_move_forward3 (edit, start_bol, col1, 0); 
    1312         diff2 = edit_move_forward3 (edit, end_bol, col2, 0) - 
    1313             edit_move_forward3 (edit, end_bol, col1, 0); 
     1310        diff1 = edit_move_forward3 (edit, start_bol, col2, 0, FALSE, 0) - 
     1311            edit_move_forward3 (edit, start_bol, col1, 0, FALSE, 0); 
     1312        diff2 = edit_move_forward3 (edit, end_bol, col2, 0, FALSE, 0) - 
     1313            edit_move_forward3 (edit, end_bol, col1, 0, FALSE, 0); 
    13141314 
    13151315        *start_mark -= diff1; 
    13161316        *end_mark += diff2; 
    edit_block_move_cmd (WEdit * edit) 
    14091409        x2 = x + edit->over_col; 
    14101410 
    14111411        /* do nothing when cursor inside first line of selected area */ 
    1412         if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1) == 
    1413              edit_buffer_get_eol (&edit->buffer, start_mark)) && x2 > c1 && x2 <= c2) 
     1412        if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1, FALSE) == 
     1413             edit_buffer_get_eol (&edit->buffer, start_mark, FALSE)) && x2 > c1 && x2 <= c2) 
    14141414            return; 
    14151415 
    14161416        if (edit->buffer.curs1 > start_mark 
    1417             && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark)) 
     1417            && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark, FALSE)) 
    14181418        { 
    14191419            if (x > c2) 
    14201420                x -= b_width; 
    edit_block_move_cmd (WEdit * edit) 
    14291429 
    14301430        edit->over_col = MAX (0, edit->over_col - b_width); 
    14311431        /* calculate the cursor pos after delete block */ 
    1432         current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0); 
     1432        current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0, FALSE, 0); 
    14331433        edit_cursor_move (edit, current - edit->buffer.curs1); 
    14341434        edit_scroll_screen_over_cursor (edit); 
    14351435 
  • src/editor/editdraw.c

    diff --git a/src/editor/editdraw.c b/src/editor/editdraw.c
    index fbd1e095f..d61347c96 100644
    a b  
    7676 
    7777/*** file scope type declarations ****************************************************************/ 
    7878 
    79 typedef struct 
     79typedef struct line 
    8080{ 
    8181    unsigned int ch; 
    8282    unsigned int style; 
    83 } line_s; 
     83} line; 
    8484 
    8585/*** forward declarations (file scope functions) *************************************************/ 
     86typedef struct 
     87{ 
     88    long soft_last_row; 
     89    long row;           /* Normal (not soft-wrapped) line number to print to */ 
     90    int plines_count;   /* Will occupy that much screen lines */ 
     91    int index;          /* Line number in doc (normal, no wraps, whole) */ 
     92    int scr_index;      /* Line number (logical) on screen, i.e.: from 0 */ 
     93    int size;           /* Length of line ↔ # elements in ldata[] */ 
     94    long order_idx;     /* Should be same as row above */ 
     95 
     96    /* In future versions it'll be possible to draw only part of 
     97     * the line – currently *_col fields are unused. */ 
     98    int q, start_col_real; 
     99    long ec; 
     100    char status[LINE_STATE_WIDTH + 1]; 
     101    int bookmarked; 
     102    gboolean visible; 
     103 
     104    line ldata[];     /* Flexible array for a single malloc */ 
     105} MCELineData; 
    86106 
    87107/*** file scope variables ************************************************************************/ 
    88108 
    89109/*** file scope functions ************************************************************************/ 
    90110 
     111static MCELineData * 
     112edit_prepare_this_line (WEdit * edit, off_t b, long order_idx, long row, long start_col, long end_col, long soft_last_row, gboolean draw, long base_line); 
     113 
     114gboolean refresh_line_data(WEdit *edit, GPtrArray *page_line_data, long start_column, long end_column, long end_row); 
     115 
     116gboolean refresh_line_data(WEdit *edit, GPtrArray *page_line_data, long start_column, long end_column, long end_row) 
     117{ 
     118    MCELineData *prev_ldata, *line_data; 
     119    gboolean ret = FALSE; 
     120    long base_line,row,start_row = 0; 
     121    int prev_plines = 0; 
     122 
     123    base_line=edit_buffer_count_lines(&edit->buffer,0,edit->start_display,FALSE); 
     124    off_t b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, FALSE); 
     125    for (row = start_row; row < end_row; row++) 
     126    { 
     127        int pplines_add = 0; 
     128        if (!edit_options.soft_wrap) 
     129            pplines_add = -prev_plines; 
     130        line_data = edit_prepare_this_line (edit, b, row, row+prev_plines+pplines_add, 
     131            start_column, end_column, -1, FALSE,base_line); 
     132        line_data->plines_count += pplines_add; 
     133        prev_ldata = (MCELineData*)page_line_data->pdata[row]; 
     134        if (prev_ldata == NULL || prev_ldata->plines_count != line_data->plines_count) 
     135            /* Return true if any plines changed */ 
     136            ret = TRUE; 
     137        page_line_data->pdata[row] = line_data; 
     138        prev_plines += (line_data->plines_count > 0) ? line_data->plines_count-1 : 0; 
     139        b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     140    } 
     141    return ret; 
     142} 
     143 
     144int  
     145sum_plines_to_row_full(GPtrArray *page_line_data, int row, gboolean count_only_second_etc_lines) 
     146{ 
     147    int prev_plines = 0; 
     148 
     149    if (!edit_options.soft_wrap) 
     150        return prev_plines; 
     151 
     152    for (int idx = 0; idx < row && idx < (long)page_line_data->len; idx ++) 
     153    { 
     154        MCELineData *line_data = page_line_data->pdata[idx]; 
     155        if(line_data != NULL) 
     156            prev_plines += (line_data->plines_count>0) ? line_data->plines_count-(count_only_second_etc_lines?1:0) : 0; 
     157        else 
     158            prev_plines += count_only_second_etc_lines?0:1; 
     159    } 
     160    return prev_plines; 
     161} 
     162 
    91163static inline void 
    92164printwstr (const char *s, int len) 
    93165{ 
    status_string (WEdit * edit, char *s, int w) 
    136208    } 
    137209 
    138210    /* The field lengths just prevent the status line from shortening too much */ 
     211    off_t bol = edit_buffer_get_current_bol(&edit->buffer); 
     212    off_t col = edit_move_forward3(edit,bol,0, 
     213                    edit->buffer.curs1,FALSE,0); 
    139214    if (edit_options.simple_statusbar) 
    140215        g_snprintf (s, w, 
    141216                    "%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s", 
    142217                    edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-', 
    143218                    edit->modified ? 'M' : '-', 
    144219                    macro_index < 0 ? '-' : 'R', 
    145                     edit->overwrite == 0 ? '-' : 'O', 
    146                     edit->curs_col + edit->over_col, 
     220                    edit->overwrite == 0 ? '-':'O', 
     221                    col, 
    147222                    edit->buffer.curs_line + 1, 
    148223                    edit->buffer.lines + 1, (long) edit->buffer.curs1, (long) edit->buffer.size, 
    149224                    byte_str, 
    status_string (WEdit * edit, char *s, int w) 
    157232                    edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-', 
    158233                    edit->modified ? 'M' : '-', 
    159234                    macro_index < 0 ? '-' : 'R', 
    160                     edit->overwrite == 0 ? '-' : 'O', 
    161                     edit->curs_col + edit->over_col, 
     235                    edit->overwrite == 0 ? '-':'O', 
     236                    col, 
    162237                    edit->start_line + 1, 
    163238                    edit->curs_row, 
    164239                    edit->buffer.curs_line + 1, 
    edit_status_fullscreen (WEdit * edit, int color) 
    185260    const int w = h->rect.cols; 
    186261    const int gap = 3;          /* between the filename and the status */ 
    187262    const int right_gap = 5;    /* at the right end of the screen */ 
    188     const int preferred_fname_len = 16; 
     263    const int preferred_fname_len = 14; 
    189264    char *status; 
    190265    size_t status_size; 
    191266    int status_len; 
    edit_draw_window_icons (const WEdit * edit, int color) 
    377452/* --------------------------------------------------------------------------------------------- */ 
    378453 
    379454static inline void 
    380 print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    381                  long end_col, line_s line[], char *status, int bookmarked) 
     455print_to_widget (WEdit * edit, MCELineData *line_data) 
     456 
    382457{ 
     458    int linesize = line_data->size; 
     459    long row = edit_options.soft_wrap ? line_data->row : line_data->scr_index; 
     460    int q = line_data->q; 
     461    int start_col_real = line_data->start_col_real; 
     462    long ec = line_data->ec, idx; 
     463    line *line_ = line_data->ldata; 
     464    char *status = line_data->status; 
     465    int bookmarked = line_data->bookmarked; 
     466 
    383467    Widget *w = WIDGET (edit); 
    384     line_s *p; 
     468    line *p; 
    385469    int x, x1, y, cols_to_skip; 
    386     int i; 
    387     int wrap_start; 
     470    int i, yp; 
     471    int f_start; 
    388472    int len; 
    389473 
     474    if (row<line_data->row) 
     475    { 
     476        row = line_data->row; 
     477    } 
    390478    x = start_col_real; 
    391     x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     479    x1 = q + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    392480    y = row + EDIT_TEXT_VERTICAL_OFFSET; 
    393     cols_to_skip = abs (x); 
     481    cols_to_skip = abs(x); 
    394482 
    395483    if (!edit->fullscreen) 
    396484    { 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    398486        y++; 
    399487    } 
    400488 
    401     tty_setcolor (EDITOR_NORMAL_COLOR); 
    402     if (bookmarked != 0) 
    403         tty_setcolor (bookmarked); 
     489    len = ec + 1 - q; 
     490    f_start = edit_options.word_wrap_line_length + edit->start_col; 
    404491 
    405     len = end_col + 1 - start_col; 
    406     wrap_start = edit_options.word_wrap_line_length + edit->start_col; 
    407  
    408     if (len > 0 && w->rect.y + y >= 0) 
     492    for (idx=0; idx < line_data->plines_count || idx == 0; idx++) 
    409493    { 
    410         if (!edit_options.show_right_margin || wrap_start > end_col) 
    411             tty_draw_hline (w->rect.y + y, w->rect.x + x1, ' ', len); 
    412         else if (wrap_start < 0) 
     494        if (len > 0 && w->rect.y + y >= 0) 
    413495        { 
    414             tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    415             tty_draw_hline (w->rect.y + y, w->rect.x + x1, ' ', len); 
    416         } 
    417         else 
    418         { 
    419             if (wrap_start > 0) 
    420                 tty_draw_hline (w->rect.y + y, w->rect.x + x1, ' ', wrap_start); 
     496            if (!edit_options.show_right_margin || f_start > ec) 
     497            { 
     498                tty_setcolor (EDITOR_NORMAL_COLOR); 
     499                if (bookmarked != 0) 
     500                    tty_setcolor (bookmarked); 
    421501 
    422             len -= wrap_start; 
    423             if (len > 0) 
     502                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     503            } 
     504            else if (f_start < 0) 
    424505            { 
    425506                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    426                 tty_draw_hline (w->rect.y + y, w->rect.x + x1 + wrap_start, ' ', len); 
     507                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     508            } 
     509            else 
     510            { 
     511                if (f_start > 0) 
     512                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', f_start); 
     513 
     514                len -= f_start; 
     515                if (len > 0) 
     516                { 
     517                    tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
     518                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1 + f_start, ' ', len); 
     519                } 
     520            } 
     521        } 
     522    } 
     523    if (edit_options.line_state) 
     524    { 
     525        tty_setcolor (LINE_STATE_COLOR); 
     526        for (yp = 0; (edit_options.soft_wrap && yp <= linesize/ec +  
     527                    (linesize%ec != 0 ? 0 : -1) + 
     528            (linesize == 0 ? 1 : 0)) || (!edit_options.soft_wrap && yp < 1); ++ yp)  
     529        { 
     530            for (i = 0; i < LINE_STATE_WIDTH; i++) 
     531            { 
     532                edit_move (x1 + i - edit_options.line_state_width, y+yp); 
     533                if (yp == 0) 
     534                { 
     535                    if (status[i] == '\0') 
     536                        status[i] = ' '; 
     537                    tty_print_char (status[i]); 
     538                } else 
     539                    tty_print_char (' '); 
    427540            } 
    428541        } 
    429542    } 
    430543 
    431     if (edit_options.line_state) 
    432     { 
    433         tty_setcolor (LINE_STATE_COLOR); 
    434  
    435         for (i = 0; i < LINE_STATE_WIDTH; i++) 
    436         { 
    437             edit_move (x1 + i - edit_options.line_state_width, y); 
    438             if (status[i] == '\0') 
    439                 status[i] = ' '; 
    440             tty_print_char (status[i]); 
    441         } 
    442     } 
     544    edit->end_col = ec; 
     545    edit->buffer.end_col = ec; 
    443546 
    444547    edit_move (x1, y); 
    445548 
    446549    i = 1; 
    447     for (p = line; p->ch != 0; p++) 
    448     { 
     550    for (idx = 0, p = &line_[-edit->start_col]; (edit_options.soft_wrap && linesize -- > 0) || ( 
     551                                    !edit_options.soft_wrap && (linesize -- + edit->start_col > 0) && p->ch != 0  
     552                                    ); p++, idx++) 
     553    {                        
     554                                                                         
    449555        int style; 
    450556        unsigned int textchar; 
    451557        int color; 
    452  
    453         if (cols_to_skip != 0) 
     558        if (!edit_options.soft_wrap && cols_to_skip != 0) 
    454559        { 
    455560            cols_to_skip--; 
    456561            continue; 
    457562        } 
    458563 
     564        /* Position each physical line */ 
     565        if (edit_options.soft_wrap && idx%ec == 0) 
     566            edit_move (x1, y++); 
     567 
    459568        style = p->style & 0xFF00; 
    460569        textchar = p->ch; 
    461570        /* If non-printable - use black background */ 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    482591        { 
    483592            if (i > edit_options.word_wrap_line_length + edit->start_col) 
    484593                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    485             i++; 
    486594        } 
     595        i++; 
    487596 
    488597        tty_print_anychar (textchar); 
    489598    } 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    492601/* --------------------------------------------------------------------------------------------- */ 
    493602/** b is a pointer to the beginning of the line */ 
    494603 
    495 static void 
    496 edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_col) 
     604static MCELineData * 
     605edit_prepare_this_line (WEdit * edit, off_t b, long order_idx, long row, long start_col, long end_col, long soft_last_row_idx, gboolean draw, long base_line) 
    497606{ 
     607    long line_count, cur_line, prev_line; 
     608    MCELineData *line_data; 
    498609    Widget *w = WIDGET (edit); 
    499     line_s line[MAX_LINE_LEN]; 
    500     line_s *p = line; 
     610    line *p; 
    501611    off_t q; 
    502     int col, start_col_real; 
     612    int wrap_line_len, line_size, start_col_real = 0; 
     613    int col; 
     614    int color; 
    503615    int abn_style; 
    504616    int book_mark = 0; 
    505     char line_stat[LINE_STATE_WIDTH + 1] = "\0"; 
    506617 
    507     if (row > w->rect.lines - 1 - EDIT_TEXT_VERTICAL_OFFSET - 2 * (edit->fullscreen ? 0 : 1)) 
    508         return; 
     618    q = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     619    line_size = edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     620    line_data = (MCELineData *) g_malloc0(sizeof(MCELineData) + sizeof(line) *  
     621                                        (line_size + /* sentinel —→ */ 1 +  
     622                                       edit_buffer_count_tabs(&edit->buffer,b,q, 
     623                                                            FALSE)*8)); 
     624    p = line_data->ldata;                                                        
    509625 
    510     if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_COLOR)) 
    511         book_mark = BOOK_MARK_COLOR; 
    512     else if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_FOUND_COLOR)) 
    513         book_mark = BOOK_MARK_FOUND_COLOR; 
    514  
    515     if (book_mark != 0) 
    516         abn_style = book_mark << 16; 
     626    /* Helper var */ 
     627    if (edit_options.soft_wrap) 
     628        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    517629    else 
    518         abn_style = MOD_ABNORMAL; 
     630        wrap_line_len = abs(edit_options.word_wrap_line_length); 
    519631 
    520     end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    521632    if (!edit->fullscreen) 
    522633    { 
    523634        end_col--; 
    524635        if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
    525636            end_col--; 
    526637    } 
     638    wrap_line_len = end_col; 
    527639 
    528     q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0); 
    529     col = (int) edit_move_forward3 (edit, b, 0, q); 
    530     start_col_real = col + edit->start_col; 
     640    line_count = edit_buffer_count_lines(&edit->buffer, edit->start_display, q-1, FALSE); 
     641    line_count+=base_line+(line_count>0?-1:0); 
     642 
     643    line_data->soft_last_row = soft_last_row_idx; 
     644    line_data->row = row; 
     645    line_data->plines_count = line_size / wrap_line_len + ((line_size % wrap_line_len) ? 1 : 0); 
     646    if (!edit_options.soft_wrap) 
     647        line_data->plines_count = 0; 
     648    line_data->index = line_count+(line_count>0?-1:0); 
     649    line_data->scr_index = line_data->index - edit->start_line; 
     650    line_data->order_idx = order_idx; /* for investigation */ 
     651    line_data->size = line_size; 
     652    line_data->q = !edit_options.soft_wrap ? edit->start_col : 0; 
     653    line_data->ec = end_col; 
     654    line_data->visible = (order_idx <= line_data->soft_last_row); 
     655 
     656    if (!edit_options.soft_wrap) 
     657        line_data->plines_count = 0; 
     658 
     659    if (book_mark_query_color (edit, line_data->index, BOOK_MARK_COLOR)) 
     660        book_mark = BOOK_MARK_COLOR; 
     661    else if (book_mark_query_color (edit, line_data->index, BOOK_MARK_FOUND_COLOR)) 
     662        book_mark = BOOK_MARK_FOUND_COLOR; 
     663 
     664    line_data->bookmarked = book_mark; 
     665 
     666    if (book_mark != 0) 
     667        abn_style = book_mark << 16; 
     668    else 
     669        abn_style = MOD_ABNORMAL; 
     670    if (!edit_options.soft_wrap) 
     671    { 
     672        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     673        if (!edit->fullscreen) 
     674        { 
     675            end_col--; 
     676            if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
     677                end_col--; 
     678        } 
     679    } 
     680 
     681    color = edit_get_syntax_color (edit, b - 1); 
     682    if (edit_options.soft_wrap) 
     683    { 
     684        q = b; 
     685        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     686    }  
     687    else 
     688    { 
     689        q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0, FALSE, 0); 
     690        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     691        line_data->start_col_real = start_col_real = col + edit->start_col; 
     692    } 
    531693 
    532694    if (edit_options.line_state) 
    533695    { 
    534         long cur_line; 
    535  
    536         cur_line = edit->start_line + row; 
    537         if (cur_line <= edit->buffer.lines) 
    538             g_snprintf (line_stat, sizeof (line_stat), "%7ld ", cur_line + 1); 
     696        int line_cnt=0; 
     697        cur_line = line_data->index; 
     698        if (line_data->order_idx == line_data->scr_index || cur_line+1 < line_cnt) 
     699            g_snprintf (line_data->status, sizeof (line_data->status), 
     700                       "%7li ", cur_line + 1); 
    539701        else 
    540702        { 
    541             memset (line_stat, ' ', LINE_STATE_WIDTH); 
    542             line_stat[LINE_STATE_WIDTH] = '\0'; 
     703            memset (line_data->status, ' ', LINE_STATE_WIDTH); 
     704            line_data->status[LINE_STATE_WIDTH] = '\0'; 
    543705        } 
    544  
     706        prev_line = cur_line + 1; 
    545707        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR)) 
    546             g_snprintf (line_stat, 2, "*"); 
     708            g_snprintf (line_data->status, 2, "*"); 
    547709    } 
    548  
     710  
    549711    if (col <= -(edit->start_col + 16)) 
    550         start_col_real = start_col = 0; 
     712      start_col_real = start_col = 0; 
    551713    else 
    552714    { 
    553715        off_t m1 = 0, m2 = 0; 
    554716 
    555717        eval_marks (edit, &m1, &m2); 
    556  
    557         if (row <= edit->buffer.lines - edit->start_line) 
     718        if (order_idx <= edit->buffer.lines - edit->start_line) 
    558719        { 
    559720            off_t tws = 0; 
    560721 
    561             if (edit_options.visible_tws && tty_use_colors ()) 
    562                 for (tws = edit_buffer_get_eol (&edit->buffer, b); tws > b; tws--) 
     722            if (tty_use_colors () && edit_options.visible_tws) 
     723                for (tws = edit_buffer_get_eol (&edit->buffer, b, FALSE); tws > b; tws--) 
    563724                { 
    564725                    unsigned int c; 
    565726 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    568729                        break; 
    569730                } 
    570731 
    571             while (col <= end_col - edit->start_col) 
     732            while ((edit_options.soft_wrap && col <= line_data->size) ||  
     733                 (!edit_options.soft_wrap && col <= line_data->size)) 
    572734            { 
    573735                int char_length = 1; 
    574736                unsigned int c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    586748                    { 
    587749                        long x, cl; 
    588750 
    589                         x = (long) edit_move_forward3 (edit, b, 0, q); 
     751                        x = (long) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
    590752                        cl = MIN (edit->column1, edit->column2); 
    591753                        if (x >= cl) 
    592754                        { 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    614776                    p->style |= book_mark << 16; 
    615777                else 
    616778                { 
    617                     int color; 
    618  
    619779                    color = edit_get_syntax_color (edit, q); 
    620780                    p->style |= color << 16; 
    621781                } 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    623783                switch (c) 
    624784                { 
    625785                case '\n': 
    626                     col = end_col - edit->start_col + 1;        /* quit */ 
     786                    if (edit_options.soft_wrap) 
     787                        col = line_data->size + 1;        /* quit */ 
     788                    else 
     789                        col = line_data->size + 1; 
    627790                    break; 
    628791 
    629792                case '\t': 
    630793                    { 
    631                         int tab_over; 
     794                        int tab_over = 0; 
    632795                        int i; 
    633796 
    634797                        i = TAB_SIZE - ((int) col % TAB_SIZE); 
    635                         tab_over = (end_col - edit->start_col) - (col + i - 1); 
    636                         if (tab_over < 0) 
    637                             i += tab_over; 
     798 
     799                        /* Supress off-screen part only if not in Soft Wraps mode */ 
     800                        if(!edit_options.soft_wrap || edit_options.soft_wrap) 
     801                        { 
     802                            tab_over = end_col - (col + i - 1); 
     803                            if (tab_over < 0) 
     804                                i += tab_over; 
     805                        } 
    638806                        col += i; 
    639                         if ((edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
    640                             && enable_show_tabs_tws && tty_use_colors ()) 
     807                        if (tty_use_colors () && (edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
     808                            && enable_show_tabs_tws) 
    641809                        { 
    642810                            if ((p->style & MOD_MARKED) != 0) 
    643811                                c = p->style; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    669837                                p->style = c; 
    670838                                p++; 
    671839                            } 
    672                             else 
     840                            else if (i > 0) 
    673841                            { 
    674842                                p->ch = '>'; 
    675843                                p->style = c; 
    676844                                p++; 
    677845                            } 
    678846                        } 
    679                         else if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    680                                  && tty_use_colors ()) 
     847                        else if (tty_use_colors () && edit_options.visible_tws && q >= tws 
     848                                 && enable_show_tabs_tws) 
    681849                        { 
    682850                            p->ch = '.'; 
    683851                            p->style |= MOD_WHITESPACE; 
    684852                            c = p->style & ~MOD_CURSOR; 
    685853                            p++; 
    686                             while (--i != 0) 
     854                            while (--i > 0) 
    687855                            { 
    688856                                p->ch = ' '; 
    689857                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    695863                            p->ch |= ' '; 
    696864                            c = p->style & ~MOD_CURSOR; 
    697865                            p++; 
    698                             while (--i != 0) 
     866                            while (--i > 0) 
    699867                            { 
    700868                                p->ch = ' '; 
    701869                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    706874                    break; 
    707875 
    708876                case ' ': 
    709                     if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    710                         && tty_use_colors ()) 
     877                    if (tty_use_colors () && edit_options.visible_tws && q >= tws && enable_show_tabs_tws) 
    711878                    { 
    712879                        p->ch = '.'; 
    713880                        p->style |= MOD_WHITESPACE; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    796963                if (char_length > 1) 
    797964                    q += char_length - 1; 
    798965 
    799                 if (col > (end_col - edit->start_col + 1)) 
    800                 { 
     966                if ((edit_options.soft_wrap && col > (line_data->size + 1))  
     967                  || (!edit_options.soft_wrap && (col > line_data->size + 1))) 
     968                {                                                                        
    801969                    if (wide_width_char) 
    802970                    { 
    803971                        p--; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    814982    } 
    815983 
    816984    p->ch = 0; 
    817  
    818     print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark); 
     985    if (draw) 
     986        print_to_widget (edit, line_data); 
     987    return line_data; 
    819988} 
    820989 
    821990/* --------------------------------------------------------------------------------------------- */ 
    822991 
    823992static inline void 
    824 edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long end_column) 
     993edit_draw_this_char (WEdit * edit, off_t curs, long order_idx, long row, long start_column, long end_column) 
    825994{ 
     995    MCELineData *line_data; 
    826996    off_t b; 
    827997 
    828     b = edit_buffer_get_bol (&edit->buffer, curs); 
    829     edit_draw_this_line (edit, b, row, start_column, end_column); 
     998    b = edit_buffer_get_bol (&edit->buffer, curs, FALSE); 
     999        line_data = edit_prepare_this_line (edit, b, order_idx, row, start_column, end_column, 0, TRUE,0); 
     1000    edit->page_line_data->pdata[order_idx] = line_data; 
    8301001} 
    8311002 
    8321003/* --------------------------------------------------------------------------------------------- */ 
    edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long 
    8351006static inline void 
    8361007render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, long end_column) 
    8371008{ 
    838     static long prev_curs_row = 0; 
    839     static off_t prev_curs = 0; 
     1009    long base_line,y = 0,y_pos; 
     1010    MCELineData *line_data = NULL; 
    8401011 
    841     Widget *we = WIDGET (edit); 
    842     Widget *wh = WIDGET (we->owner); 
    843     WRect *w = &we->rect; 
     1012    Widget *w = WIDGET (edit); 
     1013    Widget *wh = WIDGET(w->owner); 
    8441014 
    845     int force = edit->force; 
    846     int y1, x1, y2, x2; 
    847     int last_line, last_column; 
     1015    int force = edit->force,prev_plines = 0; 
     1016    int y1,x1,y2,x2; 
     1017    int last_line,last_column; 
     1018    base_line = edit_buffer_count_lines(&edit->buffer,0,edit->start_display,FALSE); 
     1019    base_line += edit->start_display == 0 ? 1 : 0; 
     1020    GPtrArray *page_line_data = edit->page_line_data; 
    8481021 
     1022    if (edit->page_line_data == NULL) 
     1023            page_line_data = edit->page_line_data = g_ptr_array_new_full(LINES, g_free); 
     1024    g_ptr_array_set_size(edit->page_line_data, LINES); 
     1025 
     1026    y_pos = edit->array_row; 
    8491027    /* draw only visible region */ 
    8501028 
    8511029    last_line = wh->rect.y + wh->rect.lines - 1; 
    8521030 
    853     y1 = w->y; 
     1031    y1 = w->rect.y; 
    8541032    if (y1 > last_line - 1 /* buttonbar */ ) 
    8551033        return; 
    8561034 
    8571035    last_column = wh->rect.x + wh->rect.cols - 1; 
    8581036 
    859     x1 = w->x; 
     1037    x1 = w->rect.x; 
    8601038    if (x1 > last_column) 
    8611039        return; 
    8621040 
    863     y2 = w->y + w->lines - 1; 
     1041    y2 = w->rect.y + w->rect.lines - 1; 
    8641042    if (y2 < wh->rect.y + 1 /* menubar */ ) 
    8651043        return; 
    8661044 
    867     x2 = w->x + w->cols - 1; 
     1045    x2 = w->rect.x + w->rect.cols - 1; 
    8681046    if (x2 < wh->rect.x) 
    8691047        return; 
    8701048 
    render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, 
    8741052        /* draw only visible region */ 
    8751053 
    8761054        if (y2 <= last_line - 1 /* buttonbar */ ) 
    877             end_row = w->lines - 1; 
     1055            end_row = w->rect.lines - 1; 
    8781056        else if (y1 >= wh->rect.y + 1 /* menubar */ ) 
    8791057            end_row = wh->rect.lines - 1 - y1 - 1; 
    8801058        else 
    8811059            end_row = start_row + wh->rect.lines - 1 - 1; 
     1060        soft_last_row = end_row; 
    8821061 
    8831062        if (x2 <= last_column) 
    884             end_column = w->cols - 1; 
     1063            end_column = w->rect.cols - 1; 
    8851064        else if (x1 >= wh->rect.x) 
    8861065            end_column = wh->rect.cols - 1 - x1; 
    8871066        else 
    8881067            end_column = start_column + wh->rect.cols - 1; 
    8891068    } 
     1069    refresh_line_data(edit, page_line_data, start_column, end_column, end_row); 
    8901070 
     1071    if (edit_options.soft_wrap) 
     1072    { 
     1073        int i, lines_occupied = 0; 
     1074        for (i=1 /*skip 0*/; i<=end_row; ++i) 
     1075        { 
     1076            /* for i=1, it is line 0 that's 
     1077            * summed up, and so on */ 
     1078            lines_occupied = i + sum_plines_to_row(page_line_data, i); 
     1079            if (lines_occupied >= wh->rect.lines-1-1) 
     1080                break; 
     1081        } 
     1082        soft_last_row = i-1; 
     1083    } 
     1084        else 
     1085            soft_last_row = end_row; 
    8911086    /* 
    8921087     * If the position of the page has not moved then we can draw the cursor 
    8931088     * character only.  This will prevent line flicker when using arrow keys. 
    render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, 
    8991094 
    9001095        if ((force & REDRAW_PAGE) != 0) 
    9011096        { 
    902             b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0); 
     1097            b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, FALSE); 
    9031098            for (row = start_row; row <= end_row; row++) 
    9041099            { 
    905                 if (key_pending (edit)) 
    906                     return; 
    907                 edit_draw_this_line (edit, b, row, start_column, end_column); 
    908                 b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1100                line_data = edit_prepare_this_line (edit, b, row, row+prev_plines, 
     1101                    start_column, end_column, soft_last_row, row <= soft_last_row, 
     1102                    base_line); 
     1103                page_line_data->pdata[row] = line_data; 
     1104                prev_plines += (line_data->plines_count > 0) ? line_data->plines_count-1 : 0; 
     1105                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9091106            } 
    9101107        } 
    9111108        else 
    9121109        { 
    913             long curs_row = edit->curs_row; 
    9141110 
    915             if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < curs_row) 
     1111            if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < y_pos) 
    9161112            { 
    9171113                long upto; 
    9181114 
     1115                row = start_row; 
    9191116                b = edit->start_display; 
    920                 upto = MIN (curs_row - 1, end_row); 
    921                 for (row = start_row; row <= upto; row++) 
     1117                upto = MIN (y_pos - 1, end_row); 
     1118                while (row <= upto) 
    9221119                { 
    923                     if (key_pending (edit)) 
    924                         return; 
    925                     edit_draw_this_line (edit, b, row, start_column, end_column); 
    926                     b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1120                    line_data = edit_prepare_this_line (edit, b, row, row+prev_plines, 
     1121                        start_column, end_column, soft_last_row, row <= soft_last_row, 
     1122                        base_line); 
     1123                    page_line_data->pdata[row] = line_data; 
     1124                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count-1 : 0; 
     1125                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     1126                    row++; 
    9271127                } 
    9281128            } 
    929  
    9301129            /*          if (force & REDRAW_LINE)          ---> default */ 
     1130            y = (y_pos-1 < 0) ? 0 : y_pos-1; 
    9311131            b = edit_buffer_get_current_bol (&edit->buffer); 
    932             if (curs_row >= start_row && curs_row <= end_row) 
     1132            if (y_pos-y == 1) 
     1133                b = edit_buffer_get_backward_offset (&edit->buffer, b, 1, FALSE); 
     1134            while (y <= y_pos && y >= start_row && y <= end_row) 
    9331135            { 
    934                 if (key_pending (edit)) 
    935                     return; 
    936                 edit_draw_this_line (edit, b, curs_row, start_column, end_column); 
     1136                prev_plines = sum_plines_to_row(edit->page_line_data, y); 
     1137                line_data = edit_prepare_this_line (edit, b, y, y+prev_plines, 
     1138                start_column, end_column, soft_last_row, y <= soft_last_row,base_line); 
     1139                page_line_data->pdata[y] = line_data; 
     1140                y++; 
     1141                if (y <= y_pos) 
     1142                    b = edit_buffer_get_forward_offset(&edit->buffer, b, 1, 0, FALSE); 
    9371143            } 
    9381144 
    939             if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > curs_row) 
     1145            if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > y_pos) 
    9401146            { 
    941                 b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
    942                 for (row = MAX (curs_row + 1, start_row); row <= end_row; row++) 
     1147                row = MAX (y_pos+1, start_row); 
     1148                prev_plines = sum_plines_to_row(page_line_data, row); 
     1149                b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, row, 0, FALSE); 
     1150                for (; row <= end_row; row++) 
    9431151                { 
    944                     if (key_pending (edit)) 
    945                         return; 
    946                     edit_draw_this_line (edit, b, row, start_column, end_column); 
    947                     b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1152                    line_data = edit_prepare_this_line (edit, b, row, row+prev_plines, start_column, end_column, soft_last_row, row <= soft_last_row,base_line); 
     1153                    page_line_data->pdata[row] = line_data; 
     1154                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count-1 : 0; 
     1155                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9481156                } 
    9491157            } 
    9501158 
    951             if ((force & REDRAW_LINE_ABOVE) != 0 && curs_row >= 1) 
     1159            if ((force & REDRAW_LINE_ABOVE) != 0 && y_pos >= 1) 
    9521160            { 
    953                 row = curs_row - 1; 
     1161                row = y_pos - 1; 
    9541162                b = edit_buffer_get_backward_offset (&edit->buffer, 
    9551163                                                     edit_buffer_get_current_bol (&edit->buffer), 
    956                                                      1); 
     1164                                                     1, FALSE); 
    9571165                if (row >= start_row && row <= end_row) 
    9581166                { 
    959                     if (key_pending (edit)) 
    960                         return; 
    961                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1167                    prev_plines = sum_plines_to_row(edit->page_line_data, row); 
     1168                    line_data = edit_prepare_this_line (edit, b, row, row+prev_plines, start_column, end_column, soft_last_row, row <= soft_last_row,base_line); 
     1169                    page_line_data->pdata[row] = line_data; 
    9621170                } 
    9631171            } 
    964  
    965             if ((force & REDRAW_LINE_BELOW) != 0 && row < w->lines - 1) 
     1172            if ((force & REDRAW_LINE_BELOW) != 0 && y_pos < w->rect.lines - 1) 
    9661173            { 
    967                 row = curs_row + 1; 
     1174                row = y_pos + 1; 
    9681175                b = edit_buffer_get_current_bol (&edit->buffer); 
    969                 b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1176                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9701177                if (row >= start_row && row <= end_row) 
    9711178                { 
    972                     if (key_pending (edit)) 
    973                         return; 
    974                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1179                    prev_plines = sum_plines_to_row(edit->page_line_data, row); 
     1180                    line_data = edit_prepare_this_line (edit, b, row, row+prev_plines, start_column, end_column, soft_last_row, row <= soft_last_row,base_line); 
     1181                    page_line_data->pdata[row] = line_data; 
    9751182                } 
    9761183            } 
    9771184        } 
    9781185    } 
    979     else if (prev_curs_row < edit->curs_row) 
    980     { 
    981         /* with the new text highlighting, we must draw from the top down */ 
    982         edit_draw_this_char (edit, prev_curs, prev_curs_row, start_column, end_column); 
    983         edit_draw_this_char (edit, edit->buffer.curs1, edit->curs_row, start_column, end_column); 
    984     } 
    985     else 
    986     { 
    987         edit_draw_this_char (edit, edit->buffer.curs1, edit->curs_row, start_column, end_column); 
    988         edit_draw_this_char (edit, prev_curs, prev_curs_row, start_column, end_column); 
    989     } 
    9901186 
    9911187    edit->force = 0; 
    992  
    993     prev_curs_row = edit->curs_row; 
    994     prev_curs = edit->buffer.curs1; 
    9951188} 
    9961189 
    9971190/* --------------------------------------------------------------------------------------------- */ 
    edit_status (WEdit * edit, gboolean active) 
    10441237void 
    10451238edit_scroll_screen_over_cursor (WEdit * edit) 
    10461239{ 
    1047     WRect *w = &WIDGET (edit)->rect; 
     1240    Widget *w = WIDGET (edit); 
    10481241 
    10491242    long p; 
    10501243    long outby; 
    10511244    int b_extreme, t_extreme, l_extreme, r_extreme; 
    10521245 
    1053     if (w->lines <= 0 || w->cols <= 0) 
     1246    if (w->rect.lines <= 0 || w->rect.cols <= 0) 
    10541247        return; 
    10551248 
    1056     rect_resize (w, -EDIT_TEXT_VERTICAL_OFFSET, 
     1249    rect_resize (&w->rect, -EDIT_TEXT_VERTICAL_OFFSET, 
    10571250                 -(EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width)); 
    10581251 
    10591252    if (!edit->fullscreen) 
    1060         rect_grow (w, -1, -1); 
     1253        rect_grow (&w->rect, -1, -1); 
    10611254 
    10621255    r_extreme = EDIT_RIGHT_EXTREME; 
    10631256    l_extreme = EDIT_LEFT_EXTREME; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    10651258    t_extreme = EDIT_TOP_EXTREME; 
    10661259    if (edit->found_len != 0) 
    10671260    { 
    1068         b_extreme = MAX (w->lines / 4, b_extreme); 
    1069         t_extreme = MAX (w->lines / 4, t_extreme); 
     1261        b_extreme = MAX (w->rect.lines / 4, b_extreme); 
     1262        t_extreme = MAX (w->rect.lines / 4, t_extreme); 
    10701263    } 
    1071     if (b_extreme + t_extreme + 1 > w->lines) 
     1264    if (b_extreme + t_extreme + 1 > w->rect.lines) 
    10721265    { 
    10731266        int n; 
    10741267 
    10751268        n = b_extreme + t_extreme; 
    10761269        if (n == 0) 
    10771270            n = 1; 
    1078         b_extreme = (b_extreme * (w->lines - 1)) / n; 
    1079         t_extreme = (t_extreme * (w->lines - 1)) / n; 
     1271        b_extreme = (b_extreme * (w->rect.lines - 1)) / n; 
     1272        t_extreme = (t_extreme * (w->rect.lines - 1)) / n; 
    10801273    } 
    1081     if (l_extreme + r_extreme + 1 > w->cols) 
     1274    if (l_extreme + r_extreme + 1 > w->rect.cols) 
    10821275    { 
    10831276        int n; 
    10841277 
    10851278        n = l_extreme + r_extreme; 
    10861279        if (n == 0) 
    10871280            n = 1; 
    1088         l_extreme = (l_extreme * (w->cols - 1)) / n; 
    1089         r_extreme = (r_extreme * (w->cols - 1)) / n; 
     1281        l_extreme = (l_extreme * (w->rect.cols - 1)) / n; 
     1282        r_extreme = (r_extreme * (w->rect.cols - 1)) / n; 
    10901283    } 
    10911284    p = edit_get_col (edit) + edit->over_col; 
    10921285    edit_update_curs_row (edit); 
    1093     outby = p + edit->start_col - w->cols + 1 + (r_extreme + edit->found_len); 
     1286    outby = p + edit->start_col - w->rect.cols + 1 + (r_extreme + edit->found_len); 
    10941287    if (outby > 0) 
    10951288        edit_scroll_right (edit, outby); 
    10961289    outby = l_extreme - p - edit->start_col; 
    10971290    if (outby > 0) 
    10981291        edit_scroll_left (edit, outby); 
    10991292    p = edit->curs_row; 
    1100     outby = p - w->lines + 1 + b_extreme; 
     1293    outby = p - w->rect.lines + 1 + b_extreme; 
    11011294    if (outby > 0) 
    11021295        edit_scroll_downward (edit, outby); 
    11031296    outby = t_extreme - p; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    11051298        edit_scroll_upward (edit, outby); 
    11061299    edit_update_curs_row (edit); 
    11071300 
    1108     rect_resize (w, EDIT_TEXT_VERTICAL_OFFSET, 
     1301    rect_resize (&w->rect, EDIT_TEXT_VERTICAL_OFFSET, 
    11091302                 EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width); 
    11101303    if (!edit->fullscreen) 
    1111         rect_grow (w, 1, 1); 
     1304        rect_grow (&w->rect, 1, 1); 
    11121305} 
    11131306 
    11141307/* --------------------------------------------------------------------------------------------- */ 
  • src/editor/editoptions.c

    diff --git a/src/editor/editoptions.c b/src/editor/editoptions.c
    index 9e059f330..0cb57a0ff 100644
    a b static const char *wrap_str[] = { 
    5454    N_("&None"), 
    5555    N_("&Dynamic paragraphing"), 
    5656    N_("Type &writer wrap"), 
     57    N_("Soft wr&aps"), 
    5758    NULL 
    5859}; 
    5960 
    edit_options_dialog (WDialog * h) 
    138139    g_snprintf (wrap_length, sizeof (wrap_length), "%d", edit_options.word_wrap_line_length); 
    139140    g_snprintf (tab_spacing, sizeof (tab_spacing), "%d", TAB_SIZE); 
    140141 
    141     if (edit_options.auto_para_formatting) 
     142    if (edit_options.soft_wrap) 
     143        wrap_mode = 3; 
     144    else if (edit_options.auto_para_formatting) 
    142145        wrap_mode = 1; 
    143146    else if (edit_options.typewriter_wrap) 
    144147        wrap_mode = 2; 
    edit_options_dialog (WDialog * h) 
    150153            /* *INDENT-OFF* */ 
    151154            QUICK_START_COLUMNS, 
    152155                QUICK_START_GROUPBOX (N_("Wrap mode")), 
    153                     QUICK_RADIO (3, wrap_str, &wrap_mode, NULL), 
     156                    QUICK_RADIO (4, wrap_str, &wrap_mode, NULL), 
    154157                QUICK_STOP_GROUPBOX, 
    155158                QUICK_SEPARATOR (FALSE), 
    156159                QUICK_SEPARATOR (FALSE), 
    edit_options_dialog (WDialog * h) 
    221224    { 
    222225        edit_options.auto_para_formatting = TRUE; 
    223226        edit_options.typewriter_wrap = FALSE; 
     227        edit_options.soft_wrap = FALSE; 
    224228    } 
    225229    else if (wrap_mode == 2) 
    226230    { 
    227231        edit_options.auto_para_formatting = FALSE; 
    228232        edit_options.typewriter_wrap = TRUE; 
     233        edit_options.soft_wrap = FALSE; 
     234    } 
     235    else if (wrap_mode == 3) 
     236    { 
     237        edit_options.auto_para_formatting = FALSE; 
     238        edit_options.typewriter_wrap = FALSE; 
     239        edit_options.soft_wrap = TRUE; 
    229240    } 
    230241    else 
    231242    { 
    232243        edit_options.auto_para_formatting = FALSE; 
    233244        edit_options.typewriter_wrap = FALSE; 
     245        edit_options.soft_wrap = FALSE; 
    234246    } 
    235247 
    236248    /* Load or unload syntax rules if the option has changed */ 
  • src/editor/editsearch.c

    diff --git a/src/editor/editsearch.c b/src/editor/editsearch.c
    index 1bdf88350..1c2b33945 100644
    a b edit_do_search (WEdit * edit) 
    615615                edit->search_start = edit->search->normal_offset; 
    616616            found = TRUE; 
    617617 
    618             l += edit_buffer_count_lines (&edit->buffer, q, edit->search->normal_offset); 
     618            l += edit_buffer_count_lines (&edit->buffer, q, edit->search->normal_offset, FALSE); 
    619619            if (l != l_last) 
    620620                book_mark_insert (edit, l, BOOK_MARK_FOUND_COLOR); 
    621621            l_last = l; 
  • src/editor/editwidget.c

    diff --git a/src/editor/editwidget.c b/src/editor/editwidget.c
    index 05f03e83f..267739332 100644
    a b static unsigned int edit_dlg_init_refcounter = 0; 
    8989 
    9090/* --------------------------------------------------------------------------------------------- */ 
    9191/*** file scope functions ************************************************************************/ 
     92static cb_ret_t edit_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, 
     93                                      void *data); 
    9294/* --------------------------------------------------------------------------------------------- */ 
    9395/** 
    9496 * Init the 'edit' subsystem 
    edit_update_cursor (WEdit * edit, const mouse_event_t * event) 
    721723        long line_len; 
    722724 
    723725        line_len = 
    724             edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    725                                 edit_buffer_get_current_eol (&edit->buffer)); 
     726            edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, TRUE), 0, 
     727                                edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1,TRUE), FALSE, 0); 
    726728 
    727729        if (x > line_len - 1) 
    728730        { 
    edit_update_cursor (WEdit * edit, const mouse_event_t * event) 
    737739    } 
    738740 
    739741    if (y > edit->curs_row) 
    740         edit_move_down (edit, y - edit->curs_row, FALSE); 
     742        edit_move_down (edit, y - edit->curs_row, FALSE, TRUE); 
    741743    else if (y < edit->curs_row) 
    742         edit_move_up (edit, edit->curs_row - y, FALSE); 
     744        edit_move_up (edit, edit->curs_row - y, FALSE, TRUE); 
    743745    else 
    744         edit_move_to_prev_col (edit, edit_buffer_get_current_bol (&edit->buffer)); 
     746        edit_move_to_prev_col (edit, edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, TRUE)); 
    745747 
    746748    if (event->msg == MSG_MOUSE_CLICK) 
    747749    { 
    edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da 
    951953 
    952954    case MSG_DRAW: 
    953955        e->force |= REDRAW_COMPLETELY; 
     956        WMSG(e,MSG_CURSOR,7); 
    954957        edit_update_screen (e); 
    955958        return MSG_HANDLED; 
    956959 
    edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da 
    985988        { 
    986989            int y, x; 
    987990 
     991            if (edit_options.soft_wrap) 
     992                edit_apply_curs_exceptions(e); 
     993 
     994            if (parm != 7) 
     995            { 
     996                e->prev_size = e->buffer.size; 
     997                e->prev_curs1 = e->buffer.curs1; 
     998                e->prev_curs_col = e->curs_col; 
     999                e->prev_curs_row = e->curs_row; 
     1000            } 
     1001            x = (e->fullscreen ? 0 : 1) + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width + 
     1002                e->curs_col + e->start_col + e->over_col; 
    9881003            y = (e->fullscreen ? 0 : 1) + EDIT_TEXT_VERTICAL_OFFSET + e->curs_row; 
    989             x = (e->fullscreen ? 0 : 1) + EDIT_TEXT_HORIZONTAL_OFFSET + 
    990                 edit_options.line_state_width + e->curs_col + e->start_col + e->over_col; 
    9911004 
    9921005            widget_gotoyx (w, y, x); 
    9931006            return MSG_HANDLED; 
    edit_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) 
    11711184        break; 
    11721185 
    11731186    case MSG_MOUSE_SCROLL_UP: 
    1174         edit_move_up (edit, 2, TRUE); 
     1187        edit_move_up (edit, 2, TRUE, FALSE); 
    11751188        edit_total_update (edit); 
    11761189        break; 
    11771190 
    11781191    case MSG_MOUSE_SCROLL_DOWN: 
    1179         edit_move_down (edit, 2, TRUE); 
     1192        edit_move_down (edit, 2, TRUE, FALSE); 
    11801193        edit_total_update (edit); 
    11811194        break; 
    11821195 
    edit_add_window (WDialog * h, const WRect * r, const vfs_path_t * f, long fline) 
    13871400 
    13881401    group_add_widget_autopos (GROUP (h), w, WPOS_KEEP_ALL, NULL); 
    13891402    edit_set_buttonbar (edit, buttonbar_find (h)); 
     1403    edit_set_end_column(edit); 
    13901404    widget_draw (WIDGET (h)); 
    13911405 
    13921406    return TRUE; 
  • src/editor/editwidget.h

    diff --git a/src/editor/editwidget.h b/src/editor/editwidget.h
    index 769b91a1e..6fc0193e9 100644
    a b struct WEdit 
    9898    off_t found_start;          /* the found word from a search - start position */ 
    9999 
    100100    /* display information */ 
     101    long prev_size;             /* size at previous key action */ 
     102    gboolean flag, flag2;       /* flag – at eol, flag2 – at bol */ 
     103    long prev_curs1; 
     104    long prev_curs_col; 
     105    long prev_curs_row; 
    101106    long start_display;         /* First char displayed */ 
    102107    long start_col;             /* First displayed column, negative */ 
    103108    long max_column;            /* The maximum cursor position ever reached used to calc hori scroll bar */ 
    struct WEdit 
    105110    long curs_col;              /* column position on screen */ 
    106111    long over_col;              /* pos after '\n' */ 
    107112    int force;                  /* how much of the screen do we redraw? */ 
     113    long array_row;             /* Position of cursor in the rows array */ 
    108114    unsigned int overwrite:1;   /* Overwrite on type mode (as opposed to insert) */ 
    109115    unsigned int modified:1;    /* File has been modified and needs saving */ 
    110116    unsigned int loading_done:1;        /* File has been loaded into the editor */ 
    struct WEdit 
    113119    unsigned int highlight:1;   /* There is a selected block */ 
    114120    unsigned int column_highlight:1; 
    115121    unsigned int fullscreen:1;  /* Is window fullscreen or not */ 
    116     long prev_col;              /* recent column position of the cursor - used when moving 
     122    unsigned int soft_wrap:1;   /* Are lines being soft-wrapped when too long? */ 
     123    long prev_col;              /* Recent column position of the cursor - used when moving 
    117124                                   up or down past lines that are shorter than the current line */ 
    118125    long start_line;            /* line number of the top of the page */ 
     126    GPtrArray *page_line_data;  /* A temporary set of LINES-count MCELineData objects */ 
     127    long end_col;               /* Last column in current window */ 
    119128 
    120129    /* file info */ 
    121130    off_t mark1;                /* position of highlight start */ 
  • src/editor/format.c

    diff --git a/src/editor/format.c b/src/editor/format.c
    index 319306799..87a62546c 100644
    a b line_start (const edit_buffer_t * buf, long line) 
    7878    p = buf->curs1; 
    7979 
    8080    if (line < l) 
    81         p = edit_buffer_get_backward_offset (buf, p, l - line); 
     81        p = edit_buffer_get_backward_offset (buf, p, l - line, FALSE); 
    8282    else if (line > l) 
    83         p = edit_buffer_get_forward_offset (buf, p, line - l, 0); 
     83        p = edit_buffer_get_forward_offset (buf, p, line - l, 0, FALSE); 
    8484 
    85     p = edit_buffer_get_bol (buf, p); 
     85    p = edit_buffer_get_bol (buf, p, FALSE); 
    8686    while (strchr ("\t ", edit_buffer_get_byte (buf, p)) != NULL) 
    8787        p++; 
    8888    return p; 
    begin_paragraph (WEdit * edit, gboolean force, long *lines) 
    135135    *lines = edit->buffer.curs_line - i; 
    136136 
    137137    return edit_buffer_get_backward_offset (&edit->buffer, 
    138                                             edit_buffer_get_current_bol (&edit->buffer), *lines); 
     138                                            edit_buffer_get_current_bol (&edit->buffer), *lines, FALSE); 
    139139} 
    140140 
    141141/* --------------------------------------------------------------------------------------------- */ 
    end_paragraph (WEdit * edit, gboolean force) 
    161161                                edit_buffer_get_forward_offset (&edit->buffer, 
    162162                                                                edit_buffer_get_current_bol 
    163163                                                                (&edit->buffer), 
    164                                                                 i - edit->buffer.curs_line, 0)); 
     164                                                                i - edit->buffer.curs_line, 0, FALSE), FALSE); 
    165165} 
    166166 
    167167/* --------------------------------------------------------------------------------------------- */ 
    edit_indent_width (const WEdit * edit, off_t p) 
    377377           && q < edit->buffer.size - 1) 
    378378        q++; 
    379379    /* count the number of columns of indentation */ 
    380     return (long) edit_move_forward3 (edit, p, 0, q); 
     380    return (long) edit_move_forward3 (edit, p, 0, q, FALSE, FALSE); 
    381381} 
    382382 
    383383/* --------------------------------------------------------------------------------------------- */ 
  • src/setup.c

    diff --git a/src/setup.c b/src/setup.c
    index 68e6f37c1..8e7e4cc3a 100644
    a b static const struct 
    395395#ifdef USE_INTERNAL_EDIT 
    396396    { "editor_word_wrap_line_length", &edit_options.word_wrap_line_length }, 
    397397    { "editor_option_save_mode", &edit_options.save_mode }, 
     398    { "editor_soft_wraps", &edit_options.soft_wrap }, 
    398399#endif /* USE_INTERNAL_EDIT */ 
    399400    { NULL, NULL } 
    400401};