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

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

Reformatted the patch to meet Hacking document. Other things like comparing NULL for pointers instead of if(ptr) already meet

  • lib/keybind.c

    From a7499a548ad1a05a9347a6868d918ba556853319 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.c            |   1 +
     lib/keybind.h            |   1 +
     lib/util.h               |   7 +
     src/editor/edit-impl.h   |  15 +-
     src/editor/edit.c        | 516 +++++++++++++++++++++++++++-------
     src/editor/edit.h        |   5 +
     src/editor/editbuffer.c  | 159 +++++++++--
     src/editor/editbuffer.h  |  23 +-
     src/editor/editcmd.c     |  49 ++--
     src/editor/editdraw.c    | 585 +++++++++++++++++++++++++++------------
     src/editor/editoptions.c |  16 +-
     src/editor/editsearch.c  |   2 +-
     src/editor/editwidget.c  |  31 ++-
     src/editor/editwidget.h  |  11 +-
     src/editor/format.c      |  14 +-
     src/keymap.c             |   1 +
     src/setup.c              |   1 +
     17 files changed, 1076 insertions(+), 361 deletions(-)
    
    diff --git a/lib/keybind.c b/lib/keybind.c
    index ebbc82eed..1e4c9681c 100644
    a b static name_keymap_t command_names[] = { 
    273273    ADD_KEYMAP_NAME (MarkAndDown), 
    274274 
    275275#ifdef USE_INTERNAL_EDIT 
     276    ADD_KEYMAP_NAME (SoftFolds), 
    276277    ADD_KEYMAP_NAME (Close), 
    277278    ADD_KEYMAP_NAME (Tab), 
    278279    ADD_KEYMAP_NAME (Undo), 
  • lib/keybind.h

    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..ee2e6044d 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, 
     139                            gboolean count_only_second_etc_lines); 
    138140 
    139141gboolean edit_add_window (WDialog * h, const WRect * r, const vfs_path_t * f, long fline); 
    140142WEdit *edit_find_editor (const WDialog * h); 
    void edit_menu_cmd (WDialog * h); 
    144146void user_menu (WEdit * edit, const char *menu_file, int selected_entry); 
    145147void edit_init_menu (WMenuBar * menubar); 
    146148void edit_save_mode_cmd (void); 
    147 off_t edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto); 
     149off_t edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto, 
     150                          gboolean as_btes, off_t len_limit); 
    148151void edit_scroll_screen_over_cursor (WEdit * edit); 
    149152void edit_render_keypress (WEdit * edit); 
    150153void edit_scroll_upward (WEdit * edit, long i); 
    151154void edit_scroll_downward (WEdit * edit, long i); 
    152155void edit_scroll_right (WEdit * edit, long i); 
    153156void 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); 
     157void edit_move_up (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines); 
     158void edit_move_down (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines); 
    156159void edit_move_to_prev_col (WEdit * edit, off_t p); 
    157160long edit_get_col (const WEdit * edit); 
    158161void edit_update_curs_row (WEdit * edit); 
    void edit_delete_line (WEdit * edit); 
    168171 
    169172int edit_delete (WEdit * edit, gboolean byte_delete); 
    170173int edit_backspace (WEdit * edit, gboolean byte_delete); 
     174void edit_move_to_top (WEdit * edit); 
     175void edit_move_to_bottom (WEdit * edit); 
     176void edit_cursor_to_bol (WEdit * edit, gboolean screen_lines); 
     177void edit_cursor_to_eol (WEdit * edit, gboolean screen_lines); 
    171178void edit_insert (WEdit * edit, int c); 
    172179void edit_insert_over (WEdit * edit); 
    173180void 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..697dddb77 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 
     262edit_set_end_column (WEdit * edit) 
     263{ 
     264    gboolean ret = FALSE; 
     265    Widget *w = WIDGET (edit); 
     266    Widget *wh = WIDGET (WIDGET (edit)->owner); 
     267    int x1, x2, last_column, start_column = 0, end_column; 
     268 
     269    int wh_cols = wh ? wh->rect.cols : COLS; 
     270    int wh_x = 0; 
     271 
     272    x1 = w->rect.x; 
     273    x2 = w->rect.x + w->rect.cols - 1; 
     274    if (x2 < x1 || x2 < wh_x) 
     275    { 
     276        /* Still, set a good, not overcomplicated, value */ 
     277        edit->end_col = edit->buffer.end_col = w->rect.cols - 1; 
     278        return ret;             /* false */ 
     279    } 
     280 
     281    last_column = wh_x + wh_cols - 1; 
     282    if (x2 <= last_column) 
     283        end_column = w->rect.cols - 1; 
     284    else if (x1 >= wh_x) 
     285        end_column = wh_cols - 1 - x1; 
     286    else 
     287        end_column = start_column + wh_cols - 1; 
     288 
     289    ret = (end_column <= COLS - 1) && (end_column > 0); 
     290    if (!ret) 
     291        end_column = 80; 
     292 
     293    edit->end_col = end_column; 
     294    edit->buffer.end_col = end_column; 
     295 
     296    return ret; 
     297} 
     298 
    259299/* --------------------------------------------------------------------------------------------- */ 
    260300 
    261301static char * 
    edit_load_file (WEdit * edit) 
    437477 
    438478    if (fast_load) 
    439479    { 
    440         edit_buffer_init (&edit->buffer, edit->stat1.st_size); 
     480        edit_buffer_init (edit, &edit->buffer, edit->stat1.st_size); 
    441481 
    442482        if (!edit_load_file_fast (&edit->buffer, edit->filename_vpath)) 
    443483        { 
    edit_load_file (WEdit * edit) 
    447487    } 
    448488    else 
    449489    { 
    450         edit_buffer_init (&edit->buffer, 0); 
     490        edit_buffer_init (edit, &edit->buffer, 0); 
    451491 
    452492        if (edit->filename_vpath != NULL 
    453493            && *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) != '\0') 
    is_blank (const edit_buffer_t * buf, off_t offset) 
    678718{ 
    679719    off_t s, f; 
    680720 
    681     s = edit_buffer_get_bol (buf, offset); 
    682     f = edit_buffer_get_eol (buf, offset) - 1; 
     721    s = edit_buffer_get_bol (buf, offset, FALSE); 
     722    f = edit_buffer_get_eol (buf, offset, FALSE) - 1; 
    683723    while (s <= f) 
    684724    { 
    685725        int c; 
    edit_find_line (WEdit * edit, long line) 
    708748        edit->line_numbers[1] = edit->buffer.curs_line; 
    709749        edit->line_offsets[1] = edit_buffer_get_current_bol (&edit->buffer); 
    710750        edit->line_numbers[2] = edit->buffer.lines; 
    711         edit->line_offsets[2] = edit_buffer_get_bol (&edit->buffer, edit->buffer.size); 
     751        edit->line_offsets[2] = edit_buffer_get_bol (&edit->buffer, edit->buffer.size, FALSE); 
    712752        edit->caches_valid = TRUE; 
    713753    } 
    714754    if (line >= edit->buffer.lines) 
    edit_find_line (WEdit * edit, long line) 
    736776    if (line > edit->line_numbers[j]) 
    737777        edit->line_offsets[i] = 
    738778            edit_buffer_get_forward_offset (&edit->buffer, edit->line_offsets[j], 
    739                                             line - edit->line_numbers[j], 0); 
     779                                            line - edit->line_numbers[j], 0, FALSE); 
    740780    else 
    741781        edit->line_offsets[i] = 
    742782            edit_buffer_get_backward_offset (&edit->buffer, edit->line_offsets[j], 
    743                                              edit->line_numbers[j] - line); 
     783                                             edit->line_numbers[j] - line, FALSE); 
    744784    edit->line_numbers[i] = line; 
    745785    return edit->line_offsets[i]; 
    746786} 
    edit_move_up_paragraph (WEdit * edit, gboolean do_scroll) 
    779819        } 
    780820    } 
    781821 
    782     edit_move_up (edit, edit->buffer.curs_line - i, do_scroll); 
     822    edit_move_up (edit, edit->buffer.curs_line - i, do_scroll, FALSE); 
    783823} 
    784824 
    785825/* --------------------------------------------------------------------------------------------- */ 
    edit_move_down_paragraph (WEdit * edit, gboolean do_scroll) 
    814854            if (edit_line_is_blank (edit, i) || i >= edit->buffer.lines) 
    815855                break; 
    816856    } 
    817     edit_move_down (edit, i - edit->buffer.curs_line, do_scroll); 
     857    edit_move_down (edit, i - edit->buffer.curs_line, do_scroll, FALSE); 
    818858} 
    819859 
    820860/* --------------------------------------------------------------------------------------------- */ 
    static void 
    823863edit_begin_page (WEdit * edit) 
    824864{ 
    825865    edit_update_curs_row (edit); 
    826     edit_move_up (edit, edit->curs_row, FALSE); 
     866    edit_move_up (edit, edit->curs_row, FALSE, FALSE); 
    827867} 
    828868 
    829869/* --------------------------------------------------------------------------------------------- */ 
    static void 
    832872edit_end_page (WEdit * edit) 
    833873{ 
    834874    edit_update_curs_row (edit); 
    835     edit_move_down (edit, WIDGET (edit)->rect.lines - edit->curs_row - 1, FALSE); 
     875    edit_move_down (edit, WIDGET (edit)->rect.lines - edit->curs_row - 1, FALSE, FALSE); 
    836876} 
    837877 
    838878 
    839879/* --------------------------------------------------------------------------------------------- */ 
    840880/** goto beginning of text */ 
    841881 
    842 static void 
     882void 
    843883edit_move_to_top (WEdit * edit) 
    844884{ 
    845885    if (edit->buffer.curs_line != 0) 
    edit_move_to_top (WEdit * edit) 
    855895/* --------------------------------------------------------------------------------------------- */ 
    856896/** goto end of text */ 
    857897 
    858 static void 
     898void 
    859899edit_move_to_bottom (WEdit * edit) 
    860900{ 
    861901    if (edit->buffer.curs_line < edit->buffer.lines) 
    862902    { 
    863         edit_move_down (edit, edit->buffer.lines - edit->curs_row, FALSE); 
     903        edit_move_down (edit, edit->buffer.lines - edit->curs_row, FALSE, FALSE); 
    864904        edit->start_display = edit->buffer.size; 
    865905        edit->start_line = edit->buffer.lines; 
    866906        edit_scroll_upward (edit, WIDGET (edit)->rect.lines - 1); 
    edit_move_to_bottom (WEdit * edit) 
    871911/* --------------------------------------------------------------------------------------------- */ 
    872912/** goto beginning of line */ 
    873913 
    874 static void 
    875 edit_cursor_to_bol (WEdit * edit) 
     914void 
     915edit_cursor_to_bol (WEdit * edit, gboolean screen_lines) 
    876916{ 
    877     edit_cursor_move (edit, edit_buffer_get_current_bol (&edit->buffer) - edit->buffer.curs1); 
     917    off_t bol = edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1 - edit->flag, screen_lines); 
     918    screen_lines &= edit_options.soft_wrap; 
     919    edit->flag2 = TRUE; 
     920    edit->flag = FALSE; 
     921    edit_cursor_move (edit, bol - edit->buffer.curs1); 
    878922    edit->search_start = edit->buffer.curs1; 
    879923    edit->prev_col = edit_get_col (edit); 
    880924    edit->over_col = 0; 
    edit_cursor_to_bol (WEdit * edit) 
    883927/* --------------------------------------------------------------------------------------------- */ 
    884928/** goto end of line */ 
    885929 
    886 static void 
    887 edit_cursor_to_eol (WEdit * edit) 
     930void 
     931edit_cursor_to_eol (WEdit * edit, gboolean screen_lines) 
    888932{ 
    889     edit_cursor_move (edit, edit_buffer_get_current_eol (&edit->buffer) - edit->buffer.curs1); 
     933    screen_lines &= edit_options.soft_wrap; 
     934    if (edit->flag) 
     935        return; 
     936    edit->flag2 = 0; 
     937    off_t eol = edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1, screen_lines); 
     938 
     939    edit_cursor_move (edit, eol - edit->buffer.curs1); 
    890940    edit->search_start = edit->buffer.curs1; 
    891941    edit->prev_col = edit_get_col (edit); 
    892942    edit->over_col = 0; 
    edit_left_char_move_cmd (WEdit * edit) 
    10681118*/ 
    10691119 
    10701120static void 
    1071 edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction) 
     1121edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction, 
     1122                  gboolean screen_lines) 
    10721123{ 
    10731124    long p; 
    1074     long l = direction ? edit->buffer.curs_line : edit->buffer.lines - edit->buffer.curs_line; 
     1125    long l, cnt_; 
     1126    off_t curs1 = edit->buffer.curs1; 
     1127    off_t boln = edit_buffer_get_bol (&edit->buffer, curs1, FALSE); 
     1128    int col, real_col, end_col; 
    10751129 
     1130    screen_lines &= edit_options.soft_wrap; 
     1131    if (do_scroll) 
     1132        screen_lines = FALSE; 
     1133    if (direction) 
     1134    { 
     1135        l = edit_buffer_count_lines (&edit->buffer, 0, curs1, screen_lines); 
     1136        if (l == 0) 
     1137            l++; 
     1138        p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1139        /* Count possible only "touched"/started screen line */ 
     1140        cnt_ = (p % edit->end_col == 0) ? 1 : 0; 
     1141        l += cnt_ - 1; 
     1142    } 
     1143    else 
     1144    { 
     1145        l = edit->buffer.lines - edit->buffer.curs_line; 
     1146        if (screen_lines && l < lines) 
     1147        { 
     1148            GPtrArray *page_line_data = edit->page_line_data; 
     1149            if (edit->page_line_data == NULL) 
     1150                page_line_data = edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     1151            g_ptr_array_set_size (edit->page_line_data, LINES); 
     1152            cnt_ = sum_plines_to_row_full (page_line_data, soft_last_row + 1, FALSE); 
     1153            l += cnt_; 
     1154            cnt_ = sum_plines_to_row_full (page_line_data, edit->array_row, FALSE); 
     1155            l -= 1 + cnt_; 
     1156            p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1157            cnt_ = p / edit->end_col - ((p % edit->end_col == 0) ? 1 : 0); 
     1158            l -= cnt_; 
     1159        } 
     1160    } 
    10761161    if (lines > l) 
    10771162        lines = l; 
    10781163 
    edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean directi 
    10881173        else 
    10891174            edit_scroll_downward (edit, lines); 
    10901175    } 
    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); 
     1176    p = edit_get_cursor_offset (edit); 
     1177    edit_update_curs_col (edit); 
     1178    col = edit->curs_col; 
     1179    end_col = edit->end_col; 
     1180 
     1181    if ( /*m.right */ curs1 == edit->prev_curs1 + 1 && col == 0 && curs1 != boln && 
     1182        /*not flagged */ !edit->flag) 
     1183        real_col = end_col; 
     1184    else if ( /*m.left */ curs1 == edit->prev_curs1 - 1 && 
     1185             col == end_col - 1 && !edit->flag) 
     1186        real_col = end_col; 
     1187    else if (ABS (curs1 - edit->prev_curs1) != 1 && col == 0 && curs1 != boln && !edit->flag2) 
     1188        real_col = end_col; 
     1189    else 
     1190        real_col = col; 
     1191 
     1192    if (direction) 
     1193        p = edit_buffer_get_backward_offset (&edit->buffer, p, lines, screen_lines); 
     1194    else 
     1195        p = edit_buffer_get_forward_offset (&edit->buffer, p, lines, 0, screen_lines); 
     1196 
     1197    int offset = edit_move_forward3 (edit, p, col, 0, FALSE, 0); 
     1198    int offset2 = edit_move_forward3 (edit, p, real_col % end_col, 0, FALSE, 0); 
     1199    if (real_col == end_col && offset - 1 > 0 
     1200        && edit_buffer_get_byte_ex (&edit->buffer, offset - 1) == '\n' 
     1201        && edit_buffer_get_byte_ex (&edit->buffer, offset) != '\n') 
     1202        offset2 = offset - 1; 
     1203    edit_cursor_move (edit, offset2 - curs1); 
    10961204 
    10971205#ifdef HAVE_CHARSET 
    10981206    /* search start of current multibyte char (like CJK) */ 
    1099     if (edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
     1207    if (0 && edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
    11001208        && edit_buffer_get_current_byte (&edit->buffer) >= 256) 
    11011209    { 
    11021210        edit_right_char_move_cmd (edit); 
    static void 
    11581266edit_do_undo (WEdit * edit) 
    11591267{ 
    11601268    long ac; 
    1161     long count = 0; 
    11621269 
    11631270    edit->undo_stack_disable = 1;       /* don't record undo's onto undo stack! */ 
    11641271    edit->over_col = 0; 
    edit_do_undo (WEdit * edit) 
    12001307        { 
    12011308            edit->mark1 = ac - MARK_1; 
    12021309            edit->column1 = 
    1203                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1204                                            0, edit->mark1); 
     1310                (long) edit_move_forward3 (edit, 
     1311                                           edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1312                                           0, edit->mark1, FALSE, 0); 
    12051313        } 
    12061314        if (ac >= MARK_2 - 2 && ac < MARK_CURS - 2) 
    12071315        { 
    12081316            edit->mark2 = ac - MARK_2; 
    12091317            edit->column2 = 
    1210                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1211                                            0, edit->mark2); 
     1318                (long) edit_move_forward3 (edit, 
     1319                                           edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1320                                           0, edit->mark2, FALSE, 0); 
    12121321        } 
    12131322        else if (ac >= MARK_CURS - 2 && ac < KEY_PRESS) 
    12141323        { 
    12151324            edit->end_mark_curs = ac - MARK_CURS; 
    12161325        } 
    1217         if (count++) 
    1218             edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ 
     1326        edit->force |= REDRAW_PAGE; 
    12191327    } 
    12201328 
    12211329    if (edit->start_display > ac - KEY_PRESS) 
    12221330    { 
    12231331        edit->start_line -= 
    1224             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1332            edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) - 1; 
    12251333        edit->force |= REDRAW_PAGE; 
    12261334    } 
    12271335    else if (edit->start_display < ac - KEY_PRESS) 
    12281336    { 
    12291337        edit->start_line += 
    1230             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1338            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) - 1; 
    12311339        edit->force |= REDRAW_PAGE; 
    12321340    } 
    12331341    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    static void 
    12431351edit_do_redo (WEdit * edit) 
    12441352{ 
    12451353    long ac; 
    1246     long count = 0; 
    12471354 
    12481355    if (edit->redo_stack_reset) 
    12491356        return; 
    edit_do_redo (WEdit * edit) 
    12851392        { 
    12861393            edit->mark1 = ac - MARK_1; 
    12871394            edit->column1 = 
    1288                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1289                                            0, edit->mark1); 
     1395                (long) edit_move_forward3 (edit, 
     1396                                           edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1397                                           0, edit->mark1, FALSE, 0); 
    12901398        } 
    12911399        else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) 
    12921400        { 
    12931401            edit->mark2 = ac - MARK_2; 
    12941402            edit->column2 = 
    1295                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1296                                            0, edit->mark2); 
     1403                (long) edit_move_forward3 (edit, 
     1404                                           edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1405                                           0, edit->mark2, FALSE, 0); 
    12971406        } 
    1298         /* more than one pop usually means something big */ 
    1299         if (count++) 
    1300             edit->force |= REDRAW_PAGE; 
     1407        edit->force |= REDRAW_PAGE; 
    13011408    } 
    13021409 
    13031410    if (edit->start_display > ac - KEY_PRESS) 
    13041411    { 
    13051412        edit->start_line -= 
    1306             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1413            edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) - 1; 
    13071414        edit->force |= REDRAW_PAGE; 
    13081415    } 
    13091416    else if (edit->start_display < ac - KEY_PRESS) 
    13101417    { 
    13111418        edit->start_line += 
    1312             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1419            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) - 1; 
    13131420        edit->force |= REDRAW_PAGE; 
    13141421    } 
    13151422    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    edit_auto_indent (WEdit * edit) 
    14041511 
    14051512    p = edit->buffer.curs1; 
    14061513    /* use the previous line as a template */ 
    1407     p = edit_buffer_get_backward_offset (&edit->buffer, p, 1); 
     1514    p = edit_buffer_get_backward_offset (&edit->buffer, p, 1, FALSE); 
    14081515    /* copy the leading whitespace of the line */ 
    14091516    while (TRUE) 
    14101517    {                           /* no range check - the line _is_ \n-terminated */ 
    edit_move_block_to_right (WEdit * edit) 
    16041711    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16051712        return; 
    16061713 
    1607     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1608     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1714    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1715    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16091716 
    16101717    do 
    16111718    { 
    edit_move_block_to_right (WEdit * edit) 
    16171724            else 
    16181725                edit_insert (edit, '\t'); 
    16191726            edit_cursor_move (edit, 
    1620                               edit_buffer_get_bol (&edit->buffer, cur_bol) - edit->buffer.curs1); 
     1727                              edit_buffer_get_bol (&edit->buffer, cur_bol, 
     1728                                                   FALSE) - edit->buffer.curs1); 
    16211729        } 
    16221730 
    16231731        if (cur_bol == 0) 
    16241732            break; 
    16251733 
    1626         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1734        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16271735    } 
    16281736    while (cur_bol >= start_bol); 
    16291737 
    edit_move_block_to_left (WEdit * edit) 
    16411749    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16421750        return; 
    16431751 
    1644     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1645     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1752    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1753    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16461754 
    16471755    do 
    16481756    { 
    edit_move_block_to_left (WEdit * edit) 
    16711779        if (cur_bol == 0) 
    16721780            break; 
    16731781 
    1674         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1782        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16751783    } 
    16761784    while (cur_bol >= start_bol); 
    16771785 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17481856                    } 
    17491857                } 
    17501858 
    1751                 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1); 
     1859                edit_cursor_move (edit, 
     1860                                  edit_move_forward3 (edit, p, col, 0, FALSE, 
     1861                                                      0) - edit->buffer.curs1); 
    17521862 
    17531863                for (l = col - edit_get_col (edit); l >= space_width; l -= space_width) 
    17541864                    edit_insert (edit, ' '); 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17691879/*** public functions ****************************************************************************/ 
    17701880/* --------------------------------------------------------------------------------------------- */ 
    17711881 
     1882 
     1883void 
     1884edit_apply_curs_exceptions (WEdit * e) 
     1885{ 
     1886    off_t bol_m2 = 
     1887        edit_buffer_get_bol (&e->buffer, e->buffer.curs1 + (e->buffer.curs1 - 2 >= 0 ? -2 : 0), 
     1888                             TRUE); 
     1889    off_t bol = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, TRUE); 
     1890    off_t boln = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, FALSE); 
     1891    off_t eol = edit_buffer_get_eol (&e->buffer, e->buffer.curs1, TRUE); 
     1892    off_t curs1 = e->buffer.curs1, prev_curs1 = e->prev_curs1; 
     1893    long size = e->buffer.size, psize = e->prev_size; 
     1894    long cnt_m2 = edit_move_forward3 (e, bol_m2, 0, eol, FALSE, 0); 
     1895    long col = edit_move_forward3 (e, bol, 0, curs1, FALSE, 0); 
     1896    long end_col = e->end_col; 
     1897    edit_update_curs_row (e); 
     1898 
     1899    /* First one exception is turned on – the one 
     1900     * that increases cursor y position when at 
     1901     * first column and not at bol */ 
     1902    if (curs1 != boln && curs1 == bol && col == 0) 
     1903    { 
     1904        e->curs_row++; 
     1905        if (cnt_m2 <= end_col - 2) 
     1906            e->flag2 = 1; 
     1907    } 
     1908 
     1909    if (curs1 == bol && /*m.left */ curs1 < prev_curs1) 
     1910        e->flag2 = TRUE; 
     1911 
     1912    /* Remaining apply only for screen-long lines */ 
     1913    if (cnt_m2 <= end_col - 2) 
     1914        return; 
     1915 
     1916    /* The second exception – when moving at 
     1917     * col == 0 from a lower curs1 position (right), 
     1918     * meaning that it should be an end_col position 
     1919     */ 
     1920    if ( /*m.right */ curs1 == prev_curs1 + 1 && col == 0 && curs1 != boln 
     1921        && /*not flagged */ !e->flag) 
     1922    { 
     1923        if (psize + 1 != size) 
     1924        { 
     1925            e->flag = TRUE; 
     1926            e->curs_col = e->end_col; 
     1927            e->curs_row--; 
     1928        } 
     1929        e->flag2 = 0; 
     1930    } 
     1931    else if ( /*m.right */ curs1 == prev_curs1 + 1 && col == 1 && curs1 >= boln + 1 && 
     1932             /* flagged */ e->flag) 
     1933    { 
     1934        if (psize + 1 != size) 
     1935        { 
     1936            edit_cursor_move (e, -1); 
     1937            e->flag = FALSE; 
     1938            e->curs_col = 0; 
     1939        } 
     1940        e->flag2 = 1; 
     1941    } 
     1942    else if ( /*m.left */ curs1 == prev_curs1 - 1 && 
     1943             col == end_col - 1 && !e->flag) 
     1944    { 
     1945        if (psize != size + 1) 
     1946        { 
     1947            edit_cursor_move (e, 1); 
     1948            e->flag = TRUE; 
     1949            e->curs_col = end_col; 
     1950        } 
     1951        e->flag2 = 0; 
     1952    } 
     1953    else if (ABS (curs1 - prev_curs1) != 1 && col == 0 && curs1 != boln && !e->flag2) 
     1954    { 
     1955        e->curs_col = end_col; 
     1956        e->curs_row--; 
     1957        e->flag = TRUE; 
     1958    } 
     1959    else 
     1960    { 
     1961        e->flag = 0; 
     1962    } 
     1963} 
     1964 
    17721965/** User edit menu, like user menu (F2) but only in editor. */ 
    17731966 
    17741967void 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21242317        edit_save_size (edit); 
    21252318    } 
    21262319 
     2320    if (edit->page_line_data == NULL) 
     2321        edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     2322    g_ptr_array_set_size (edit->page_line_data, LINES); 
     2323 
    21272324    edit->drag_state = MCEDIT_DRAG_NONE; 
    21282325 
    21292326    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 
    21532350    edit_set_codeset (edit); 
    21542351#endif 
    21552352 
     2353    edit_set_end_column (edit); 
    21562354    if (!edit_load_file (edit)) 
    21572355    { 
    21582356        /* edit_load_file already gives an error message */ 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21792377        edit_move_to_line (edit, line - 1); 
    21802378    } 
    21812379 
     2380 
    21822381    edit_load_macro_cmd (edit); 
    21832382 
    21842383    return edit; 
    edit_push_redo_action (WEdit * edit, long c) 
    25082707        edit->redo_stack_bottom = edit->redo_stack_pointer = 0; 
    25092708} 
    25102709 
     2710 
     2711/* --------------------------------------------------------------------------------------------- */ 
     2712 
    25112713/* --------------------------------------------------------------------------------------------- */ 
    25122714/** 
    25132715   Basic low level single character buffer alterations and movements at the cursor. 
    edit_insert (WEdit * edit, int c) 
    25312733    /* now we must update some info on the file and check if a redraw is required */ 
    25322734    if (c == '\n') 
    25332735    { 
     2736        edit->buffer.line_begin_offset = edit->buffer.curs1; 
    25342737        book_mark_inc (edit, edit->buffer.curs_line); 
    25352738        edit->buffer.curs_line++; 
    25362739        edit->buffer.lines++; 
    edit_backspace (WEdit * edit, gboolean byte_delete) 
    27242927void 
    27252928edit_cursor_move (WEdit * edit, off_t increment) 
    27262929{ 
     2930    gboolean scroll = FALSE; 
     2931    off_t idx; 
    27272932    if (increment < 0) 
    27282933    { 
    2729         for (; increment < 0 && edit->buffer.curs1 != 0; increment++) 
     2934        for (idx = 0; idx > increment && edit->buffer.curs1 != 0; idx--) 
    27302935        { 
    27312936            int c; 
    27322937 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27372942            c = edit_buffer_backspace (&edit->buffer); 
    27382943            if (c == '\n') 
    27392944            { 
     2945                edit->buffer.line_begin_offset = 0; 
     2946                for (int i = edit->buffer.curs1 - 1; i > 0; i--) 
     2947                { 
     2948                    unsigned char ch = edit_buffer_get_byte (&edit->buffer, i); 
     2949                    if (ch == '\n') 
     2950                    { 
     2951                        edit->buffer.line_begin_offset = i + 1; 
     2952                        break; 
     2953                    } 
     2954                } 
    27402955                edit->buffer.curs_line--; 
    27412956                edit->force |= REDRAW_LINE_BELOW; 
     2957                if (edit->buffer.curs_line < edit->start_line) 
     2958                    scroll = TRUE; 
    27422959            } 
    27432960        } 
     2961        if (scroll) 
     2962        { 
     2963            edit_scroll_upward (edit, edit->start_line - edit->buffer.curs_line); 
     2964        } 
    27442965    } 
    27452966    else 
    27462967    { 
    2747         for (; increment > 0 && edit->buffer.curs2 != 0; increment--) 
     2968        for (idx = 0; idx < increment && edit->buffer.curs2 != 0; idx++) 
    27482969        { 
    27492970            int c; 
    27502971 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27552976            c = edit_buffer_delete (&edit->buffer); 
    27562977            if (c == '\n') 
    27572978            { 
     2979                edit->buffer.line_begin_offset = edit->buffer.curs1; 
    27582980                edit->buffer.curs_line++; 
     2981                if (edit->buffer.curs_line - edit->start_line >= soft_last_row) 
     2982                    scroll = TRUE; 
    27592983                edit->force |= REDRAW_LINE_ABOVE; 
    27602984            } 
    27612985        } 
     2986        if (scroll) 
     2987        { 
     2988            edit_scroll_downward (edit, 
     2989                                  (edit->buffer.curs_line - edit->start_line) - soft_last_row); 
     2990            edit->force |= REDRAW_PAGE; 
     2991        } 
    27622992    } 
    27632993} 
    27642994 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27672997/* If upto is zero returns index of cols across from current. */ 
    27682998 
    27692999off_t 
    2770 edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
     3000edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto, gboolean as_bytes, 
     3001                    off_t col_limit) 
    27713002{ 
    27723003    off_t p, q; 
    2773     long col; 
     3004    long col, col_acc = 0, btes = 0, prev_len = 0; 
     3005    int char_length = 1; 
     3006    int utf_ch; 
    27743007 
    27753008    if (upto != 0) 
    27763009    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27783011        cols = -10; 
    27793012    } 
    27803013    else 
    2781         q = edit->buffer.size + 2; 
     3014        q = edit->buffer.size + 1; 
    27823015 
    27833016    for (col = 0, p = current; p < q; p++) 
    27843017    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27973030#ifdef HAVE_CHARSET 
    27983031        if (edit->utf8) 
    27993032        { 
    2800             int utf_ch; 
    2801             int char_length = 1; 
    2802  
     3033            char_length = 1; 
    28033034            utf_ch = edit_buffer_get_utf (&edit->buffer, p, &char_length); 
     3035 
    28043036            if (mc_global.utf8_display) 
    28053037            { 
    28063038                if (char_length > 1) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28163048#endif 
    28173049 
    28183050        if (c == '\n') 
    2819             return (upto != 0 ? (off_t) col : p); 
    2820         if (c == '\t') 
    2821             col += TAB_SIZE - col % TAB_SIZE; 
     3051        { 
     3052            return (upto != 0 ? (off_t) (as_bytes ? btes : col - col_acc) : p); 
     3053        } 
     3054 
     3055#ifdef HAVE_CHARSET 
     3056        if (edit->utf8) 
     3057        { 
     3058            btes += prev_len <= 1 ? char_length : 0; 
     3059            prev_len = prev_len <= 1 ? char_length : prev_len - 1; 
     3060        } 
     3061        else 
     3062            btes += 1; 
     3063#else 
     3064        btes += 1; 
     3065#endif 
     3066 
     3067        /* Treat tab specially, as it needs to use 
     3068         * whole line, not only screen line */ 
     3069        if (c == '\t' || utf_ch == '\t') 
     3070        { 
     3071            off_t boln = edit_buffer_get_bol (&edit->buffer, p, FALSE); 
     3072            off_t qq = boln, ncols = 0, acc = 0; 
     3073            int len = -1, ch; 
     3074            for (; len && qq <= p; 
     3075                 (ch = edit_buffer_get_utf (&edit->buffer, qq, &len)), 
     3076                 qq += len, ncols += 
     3077                 (g_unichar_iswide (ch) > 0) + (ch == '\t' ? (TAB_SIZE - (ncols % TAB_SIZE)) : len > 
     3078                                                0)) 
     3079            { 
     3080                /* Still modulo the line length */ 
     3081                if ((ncols - acc) >= edit->end_col) 
     3082                    acc += edit->end_col; 
     3083            } 
     3084            /* Apply precisely calculated cols */ 
     3085            col = ncols; 
     3086            if (boln != current) 
     3087                col -= acc; 
     3088        } 
    28223089        else if ((c < 32 || c == 127) && (orig_c == c 
    28233090#ifdef HAVE_CHARSET 
    28243091                                          || (!mc_global.utf8_display && !edit->utf8) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28293096            col += 2; 
    28303097        else 
    28313098            col++; 
     3099 
     3100        if (col_limit > 0) 
     3101        { 
     3102            btes = ((col - col_acc) >= col_limit) ? 0 : btes; 
     3103            col_acc += ((col - col_acc) >= col_limit) ? col_limit : 0; 
     3104        } 
    28323105    } 
    2833     return (off_t) col; 
     3106 
     3107    return (off_t) (as_bytes ? btes : col - col_acc); 
    28343108} 
    28353109 
    28363110/* --------------------------------------------------------------------------------------------- */ 
    edit_get_cursor_offset (const WEdit * edit) 
    28433117} 
    28443118 
    28453119/* --------------------------------------------------------------------------------------------- */ 
     3120 
    28463121/** returns the current column position of the cursor */ 
    28473122 
    28483123long 
    28493124edit_get_col (const WEdit * edit) 
    28503125{ 
    2851     return (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2852                                       edit->buffer.curs1); 
     3126    gboolean screen = edit_options.soft_wrap ? 1 : 0; 
     3127    off_t bol = edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, screen); 
     3128 
     3129    off_t col = (long) edit_move_forward3 (edit, bol, 0, edit->buffer.curs1, FALSE, 0); 
     3130    col -= -2 * edit->start_col; 
     3131    return col; 
    28533132} 
    28543133 
    28553134/* --------------------------------------------------------------------------------------------- */ 
    edit_get_col (const WEdit * edit) 
    28573136/* --------------------------------------------------------------------------------------------- */ 
    28583137 
    28593138void 
    2860 edit_update_curs_row (WEdit * edit) 
     3139edit_update_curs_row (WEdit * e) 
    28613140{ 
    2862     edit->curs_row = edit->buffer.curs_line - edit->start_line; 
     3141    /* Helper variables */ 
     3142    edit_buffer_t *buf = &e->buffer; 
     3143    off_t curs1 = edit_get_cursor_offset (e); 
     3144 
     3145    /* The screen-line count ↔ the cursor row */ 
     3146    int lines = edit_buffer_count_lines (buf, e->start_display, curs1, TRUE); 
     3147    /* Screen-line count should be 0-based */ 
     3148    e->curs_row = lines > 0 ? lines - 1 : 0; 
     3149    /* Non screen-lines line count */ 
     3150    e->array_row = edit_buffer_count_lines (buf, e->start_display, curs1, FALSE); 
     3151    /* Make the line count 0-based */ 
     3152    e->array_row > 0 ? e->array_row-- : 0; 
    28633153} 
    28643154 
    28653155/* --------------------------------------------------------------------------------------------- */ 
    edit_update_curs_row (WEdit * edit) 
    28673157void 
    28683158edit_update_curs_col (WEdit * edit) 
    28693159{ 
    2870     edit->curs_col = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 
    2871                                                 0, edit->buffer.curs1); 
     3160    edit->curs_col = edit_get_col (edit); 
    28723161} 
    28733162 
    28743163/* --------------------------------------------------------------------------------------------- */ 
    edit_scroll_upward (WEdit * edit, long i) 
    28933182    { 
    28943183        edit->start_line -= i; 
    28953184        edit->start_display = 
    2896             edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i); 
     3185            edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i, FALSE); 
    28973186        edit->force |= REDRAW_PAGE; 
    28983187        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    28993188    } 
    edit_scroll_downward (WEdit * edit, long i) 
    29083197{ 
    29093198    long lines_below; 
    29103199 
    2911     lines_below = edit->buffer.lines - edit->start_line - (WIDGET (edit)->rect.lines - 1); 
     3200    lines_below = edit->buffer.lines - edit->start_line - (soft_last_row - 1); 
    29123201    if (lines_below > 0) 
    29133202    { 
    29143203        if (i > lines_below) 
    29153204            i = lines_below; 
    29163205        edit->start_line += i; 
    29173206        edit->start_display = 
    2918             edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0); 
     3207            edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0, FALSE); 
    29193208        edit->force |= REDRAW_PAGE; 
    29203209        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    29213210    } 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29583247    long over = edit->over_col; 
    29593248 
    29603249    edit_cursor_move (edit, 
    2961                       edit_move_forward3 (edit, p, prev + edit->over_col, 0) - edit->buffer.curs1); 
     3250                      edit_move_forward3 (edit, p, prev + edit->over_col, 0, FALSE, 
     3251                                          0) - edit->buffer.curs1); 
    29623252 
    29633253    if (edit_options.cursor_beyond_eol) 
    29643254    { 
    29653255        long line_len; 
    29663256 
    29673257        line_len = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2968                                               edit_buffer_get_current_eol (&edit->buffer)); 
     3258                                              edit_buffer_get_current_eol (&edit->buffer), FALSE, 
     3259                                              FALSE); 
    29693260        if (line_len < prev + edit->over_col) 
    29703261        { 
    29713262            edit->over_col = prev + over - line_len; 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29983289                p = edit_buffer_get_current_bol (&edit->buffer); 
    29993290                edit_cursor_move (edit, 
    30003291                                  edit_move_forward3 (edit, p, edit->curs_col, 
    3001                                                       0) - edit->buffer.curs1); 
     3292                                                      0, FALSE, FALSE) - edit->buffer.curs1); 
    30023293                if (!left_of_four_spaces (edit)) 
    30033294                    edit_cursor_move (edit, 
    3004                                       edit_move_forward3 (edit, p, q, 0) - edit->buffer.curs1); 
     3295                                      edit_move_forward3 (edit, p, q, 0, FALSE, 
     3296                                                          FALSE) - edit->buffer.curs1); 
    30053297            } 
    30063298        } 
    30073299    } 
    void 
    30293321edit_move_to_line (WEdit * e, long line) 
    30303322{ 
    30313323    if (line < e->buffer.curs_line) 
    3032         edit_move_up (e, e->buffer.curs_line - line, FALSE); 
     3324        edit_move_up (e, e->buffer.curs_line - line, FALSE, FALSE); 
    30333325    else 
    3034         edit_move_down (e, line - e->buffer.curs_line, FALSE); 
     3326        edit_move_down (e, line - e->buffer.curs_line, FALSE, FALSE); 
    30353327    edit_scroll_screen_over_cursor (e); 
    30363328} 
    30373329 
    edit_execute_key_command (WEdit * edit, long command, int char_for_insertion) 
    32603552void 
    32613553edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    32623554{ 
    3263     WRect *w = &WIDGET (edit)->rect; 
    3264  
    32653555    if (command == CK_WindowFullscreen) 
    32663556    { 
    32673557        edit_toggle_fullscreen (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    33533643    /* An ordinary key press */ 
    33543644    if (char_for_insertion >= 0) 
    33553645    { 
     3646        off_t prev_curs_col, col; 
     3647 
     3648        if (edit->curs_col == 0) 
     3649            edit->force |= REDRAW_AFTER_CURSOR; 
     3650        prev_curs_col = edit->curs_col; 
     3651 
    33563652        /* if non persistent selection and text selected */ 
    33573653        if (!edit_options.persistent_selections && edit->mark1 != edit->mark2) 
    33583654            edit_block_delete_cmd (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34083704            edit->force |= REDRAW_PAGE; 
    34093705        } 
    34103706        else 
     3707        { 
    34113708            check_and_wrap_line (edit); 
     3709            edit->force |= REDRAW_AFTER_CURSOR; 
     3710        } 
     3711        col = edit_get_col (edit); 
     3712        if (prev_curs_col == edit->buffer.end_col - 1 && col == 0) 
     3713            edit->force |= REDRAW_AFTER_CURSOR; 
    34123714        edit->found_len = 0; 
    34133715        edit->prev_col = edit_get_col (edit); 
    34143716        edit->search_start = edit->buffer.curs1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34673769    case CK_Right: 
    34683770    case CK_MarkLeft: 
    34693771    case CK_MarkRight: 
    3470         edit->force |= REDRAW_CHAR_ONLY; 
     3772        edit->force |= REDRAW_LINE; 
    34713773        break; 
    34723774    default: 
    34733775        break; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34973799        } 
    34983800        else 
    34993801            edit_backspace (edit, FALSE); 
     3802 
     3803        edit->force |= REDRAW_AFTER_CURSOR; 
    35003804        break; 
    35013805    case CK_Delete: 
    35023806        /* if non persistent selection and text selected */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    35633867        MC_FALLTHROUGH; 
    35643868    case CK_PageUp: 
    35653869    case CK_MarkPageUp: 
    3566         edit_move_up (edit, w->lines - 1, TRUE); 
     3870        edit_move_up (edit, soft_last_row, TRUE, FALSE); 
    35673871        break; 
    35683872    case CK_MarkColumnPageDown: 
    35693873        edit->column_highlight = 1; 
    35703874        MC_FALLTHROUGH; 
    35713875    case CK_PageDown: 
    35723876    case CK_MarkPageDown: 
    3573         edit_move_down (edit, w->lines - 1, TRUE); 
     3877        edit_move_down (edit, soft_last_row, TRUE, FALSE); 
    35743878        break; 
    35753879    case CK_MarkColumnLeft: 
    35763880        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36263930        MC_FALLTHROUGH; 
    36273931    case CK_Up: 
    36283932    case CK_MarkUp: 
    3629         edit_move_up (edit, 1, FALSE); 
     3933        edit_move_up (edit, 1, FALSE, TRUE); 
    36303934        break; 
    36313935    case CK_MarkColumnDown: 
    36323936        edit->column_highlight = 1; 
    36333937        MC_FALLTHROUGH; 
    36343938    case CK_Down: 
    36353939    case CK_MarkDown: 
    3636         edit_move_down (edit, 1, FALSE); 
     3940        edit_move_down (edit, 1, FALSE, TRUE); 
    36373941        break; 
    36383942    case CK_MarkColumnParagraphUp: 
    36393943        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36543958        MC_FALLTHROUGH; 
    36553959    case CK_ScrollUp: 
    36563960    case CK_MarkScrollUp: 
    3657         edit_move_up (edit, 1, TRUE); 
     3961        edit_move_up (edit, 1, TRUE, TRUE); 
    36583962        break; 
    36593963    case CK_MarkColumnScrollDown: 
    36603964        edit->column_highlight = 1; 
    36613965        MC_FALLTHROUGH; 
    36623966    case CK_ScrollDown: 
    36633967    case CK_MarkScrollDown: 
    3664         edit_move_down (edit, 1, TRUE); 
     3968        edit_move_down (edit, 1, TRUE, TRUE); 
    36653969        break; 
    36663970    case CK_Home: 
    36673971    case CK_MarkToHome: 
    3668         edit_cursor_to_bol (edit); 
     3972        edit_cursor_to_bol (edit, TRUE); 
    36693973        break; 
    36703974    case CK_End: 
    36713975    case CK_MarkToEnd: 
    3672         edit_cursor_to_eol (edit); 
     3976        edit_cursor_to_eol (edit, TRUE); 
    36733977        break; 
    36743978    case CK_Tab: 
    36753979        /* if text marked shift block */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37574061            if (p->next != NULL) 
    37584062            { 
    37594063                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); 
     4064                if (p->line >= edit->start_line + soft_last_row + 1 || p->line < edit->start_line) 
     4065                    edit_move_display (edit, p->line - (soft_last_row + 1) / 2); 
    37624066                edit_move_to_line (edit, p->line); 
    37634067            } 
    37644068        } 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37744078                    p = p->prev; 
    37754079            if (p->line >= 0) 
    37764080            { 
    3777                 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) 
    3778                     edit_move_display (edit, p->line - w->lines / 2); 
     4081                if (p->line >= edit->start_line + soft_last_row + 1 || p->line < edit->start_line) 
     4082                    edit_move_display (edit, p->line - (soft_last_row + 1) / 2); 
    37794083                edit_move_to_line (edit, p->line); 
    37804084            } 
    37814085        } 
    37824086        break; 
    37834087 
     4088    case CK_SoftFolds: 
     4089        edit_options.soft_wrap = !edit_options.soft_wrap; 
     4090        edit->start_col *= !edit_options.soft_wrap; 
     4091        edit->force |= REDRAW_COMPLETELY; 
     4092        break; 
     4093 
    37844094    case CK_Top: 
    37854095    case CK_MarkToFileBegin: 
    37864096        edit_move_to_top (edit); 
    edit_stack_free (void) 
    40504360/** move i lines */ 
    40514361 
    40524362void 
    4053 edit_move_up (WEdit * edit, long i, gboolean do_scroll) 
     4363edit_move_up (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40544364{ 
    4055     edit_move_updown (edit, i, do_scroll, TRUE); 
     4365    screen_lines &= edit_options.soft_wrap; 
     4366    edit_move_updown (edit, i, do_scroll, TRUE, screen_lines); 
    40564367} 
    40574368 
    40584369/* --------------------------------------------------------------------------------------------- */ 
    40594370/** move i lines */ 
    40604371 
    40614372void 
    4062 edit_move_down (WEdit * edit, long i, gboolean do_scroll) 
     4373edit_move_down (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40634374{ 
    4064     edit_move_updown (edit, i, do_scroll, FALSE); 
     4375    screen_lines &= edit_options.soft_wrap; 
     4376    edit_move_updown (edit, i, do_scroll, FALSE, screen_lines); 
    40654377} 
    40664378 
    40674379/* --------------------------------------------------------------------------------------------- */ 
  • src/editor/edit.h

    diff --git a/src/editor/edit.h b/src/editor/edit.h
    index 358aa3f14..521591829 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..f1f718b82 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 
     142edit_buffer_count_tabs (edit_buffer_t * buf, off_t first, off_t last, gboolean all_kinds) 
     143{ 
     144    int cnt = 0; 
     145    last = last > buf->size ? buf->size : last; 
     146    while (first <= last) 
     147    { 
     148        int byte = edit_buffer_get_byte (buf, first); 
     149        if (byte == '\t' || (all_kinds && byte == '\v')) 
     150            cnt++; 
     151        ++first; 
     152    } 
     153    return cnt; 
     154} 
     155 
    139156/* --------------------------------------------------------------------------------------------- */ 
    140157/** 
    141158 * Initialize editor buffers. 
    edit_buffer_get_byte_ptr (const edit_buffer_t * buf, off_t byte_index) 
    144161 */ 
    145162 
    146163void 
    147 edit_buffer_init (edit_buffer_t * buf, off_t size) 
     164edit_buffer_init (WEdit * e, edit_buffer_t * buf, off_t size) 
    148165{ 
    149166    buf->b1 = g_ptr_array_new_full (32, g_free); 
    150167    buf->b2 = g_ptr_array_new_full (32, g_free); 
     168    buf->edit_widget = e; 
     169    buf->end_col = 73; 
    151170 
    152171    buf->curs1 = 0; 
    153172    buf->curs2 = 0; 
    void 
    167186edit_buffer_clean (edit_buffer_t * buf) 
    168187{ 
    169188    if (buf->b1 != NULL) 
     189    { 
    170190        g_ptr_array_free (buf->b1, TRUE); 
     191    } 
    171192 
    172193    if (buf->b2 != NULL) 
     194    { 
    173195        g_ptr_array_free (buf->b2, TRUE); 
     196    } 
    174197} 
    175198 
    176199/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_clean (edit_buffer_t * buf) 
    182205  * 
    183206  * @return '\n' if byte_index is negative or larger than file size; byte at byte_index otherwise. 
    184207  */ 
     208int 
     209edit_buffer_get_byte_ex (const edit_buffer_t * buf, off_t byte_index) 
     210{ 
     211    char *p; 
     212 
     213    p = edit_buffer_get_byte_ptr (buf, byte_index); 
     214 
     215    return (p != NULL) ? *(unsigned char *) p : -1; 
     216} 
    185217 
    186218int 
    187219edit_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 
    323355 */ 
    324356 
    325357long 
    326 edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
     358edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last, gboolean screen_lines) 
    327359{ 
    328     long lines = 0; 
     360    long lines = 0, prev_eol = 0, eol; 
     361    screen_lines &= edit_options.soft_wrap; 
    329362 
    330363    first = MAX (first, 0); 
    331364    last = MIN (last, buf->size); 
    332365 
    333     while (first < last) 
    334         if (edit_buffer_get_byte (buf, first++) == '\n') 
    335             lines++; 
     366    if (first == last) 
     367        return 0; 
    336368 
     369    while (first <= last) 
     370    { 
     371        eol = edit_buffer_get_eol (buf, first, screen_lines); 
     372        /* Advance in buffer */ 
     373        if (edit_buffer_get_byte_ex (buf, eol) == '\n' || ~screen_lines || eol == prev_eol) 
     374            first = eol + 1; 
     375        else 
     376            first = eol; 
     377        prev_eol = eol; 
     378        /* Count line */ 
     379        lines++; 
     380    } 
    337381    return lines; 
    338382} 
    339383 
    edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
    348392 */ 
    349393 
    350394off_t 
    351 edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
     395edit_buffer_get_bol (const edit_buffer_t * buf, off_t current_bol, gboolean screen_lines) 
    352396{ 
    353     if (current <= 0) 
     397    off_t current_save = current_bol; 
     398    off_t current_eol = current_bol; 
     399    screen_lines &= edit_options.soft_wrap; 
     400    if (current_bol <= 0) 
     401    { 
    354402        return 0; 
    355  
    356     for (; edit_buffer_get_byte (buf, current - 1) != '\n'; current--) 
     403    } 
     404    for (; current_bol > 0 && edit_buffer_get_byte (buf, current_bol - 1) != '\n'; current_bol -= 1) 
    357405        ; 
    358406 
    359     return current; 
     407    for (; 
     408         (edit_buffer_get_byte (buf, current_eol) != '\n' || current_save == current_eol) 
     409         && current_eol < buf->size; current_eol += 1); 
     410 
     411 
     412    if (screen_lines) 
     413    { 
     414        off_t pos = current_save - 
     415            edit_move_forward3 (buf->edit_widget, current_bol, 0, current_save, TRUE, buf->end_col); 
     416        return pos; 
     417    } 
     418    return current_bol; 
    360419} 
    361420 
    362421/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
    370429 */ 
    371430 
    372431off_t 
    373 edit_buffer_get_eol (const edit_buffer_t * buf, off_t current) 
     432edit_buffer_get_eol (const edit_buffer_t * buf, off_t current_eol, gboolean screen_lines) 
    374433{ 
    375     if (current >= buf->size) 
     434    off_t current_save = current_eol; 
     435    off_t current_bol = current_eol; 
     436    off_t q; 
     437    screen_lines &= edit_options.soft_wrap; 
     438    if (current_eol >= buf->size) 
    376439        return buf->size; 
    377440 
    378     for (; edit_buffer_get_byte (buf, current) != '\n'; current++) 
     441    for (; current_bol > 0 && edit_buffer_get_byte (buf, current_bol - 1) != '\n'; current_bol--) 
    379442        ; 
    380443 
    381     return current; 
     444    if (screen_lines) 
     445    { 
     446        off_t prev_eol = 0; 
     447        for (; 
     448             (edit_buffer_get_byte_ex (buf, current_eol) != '\n') && 
     449             current_eol <= buf->size && 
     450             (current_eol == current_save 
     451              || 
     452              ((q = 
     453                edit_move_forward3 (buf->edit_widget, current_bol, 0, current_eol, FALSE, 
     454                                    0) % buf->end_col) != 0)); 
     455             current_eol = 
     456             edit_move_forward3 (buf->edit_widget, current_eol, 1, 0, FALSE, 0), current_eol += 
     457             prev_eol == current_eol ? 1 : 0, prev_eol = current_eol) 
     458            ; 
     459        if (current_eol > buf->size && edit_buffer_get_byte_ex (buf, current_eol) != '\n') 
     460            current_eol = buf->size; 
     461    } 
     462    else 
     463        for (; (edit_buffer_get_byte (buf, current_eol) != '\n') && current_eol < buf->size; 
     464             current_eol++) 
     465            ; 
     466 
     467 
     468    return current_eol; 
    382469} 
    383470 
    384471/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_backspace (edit_buffer_t * buf) 
    638725 */ 
    639726 
    640727off_t 
    641 edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto) 
     728edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto, 
     729                                gboolean screen_lines) 
    642730{ 
     731    screen_lines &= edit_options.soft_wrap; 
    643732    if (upto != 0) 
    644         return (off_t) edit_buffer_count_lines (buf, current, upto); 
     733        return (off_t) edit_buffer_count_lines (buf, current, upto, screen_lines); 
    645734 
    646735    lines = MAX (lines, 0); 
    647736 
     737    if (lines > 0) 
     738    { 
     739        edit_update_curs_col (buf->edit_widget); 
     740        if (buf->edit_widget->curs_col == buf->end_col) 
     741            lines--; 
     742    } 
     743 
    648744    while (lines-- != 0) 
    649745    { 
    650         long next; 
     746        off_t next; 
     747        int byte; 
    651748 
    652         next = edit_buffer_get_eol (buf, current) + 1; 
    653         if (next > buf->size) 
     749        next = edit_buffer_get_eol (buf, current, screen_lines); 
     750        byte = edit_buffer_get_byte_ex (buf, next); 
     751 
     752        if (byte == '\n' || !screen_lines) 
     753            next++; 
     754        if (next > buf->size + 1) 
    654755            break; 
    655756        current = next; 
    656757    } 
    657  
    658758    return current; 
    659759} 
    660760 
    edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long l 
    670770 */ 
    671771 
    672772off_t 
    673 edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines) 
     773edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines, 
     774                                 gboolean screen_lines) 
    674775{ 
     776    screen_lines &= edit_options.soft_wrap; 
    675777    lines = MAX (lines, 0); 
    676     current = edit_buffer_get_bol (buf, current); 
     778    current = edit_buffer_get_bol (buf, current, screen_lines); 
    677779 
    678780    while (lines-- != 0 && current != 0) 
    679         current = edit_buffer_get_bol (buf, current - 1); 
     781    { 
     782        current = edit_buffer_get_bol (buf, current - 1, screen_lines); 
     783        if (screen_lines && current > 0 && 
     784            edit_buffer_get_byte_ex (buf, current) == '\n' && 
     785            edit_buffer_get_byte_ex (buf, current - 1) != '\n') 
     786            lines++; 
     787    } 
     788 
     789    if (current > 0 && screen_lines && edit_buffer_get_byte_ex (buf, current - 1) != '\n') 
     790        current = edit_buffer_get_eol (buf, current - 1, screen_lines); 
    680791 
    681792    return current; 
    682793} 
  • src/editor/editbuffer.h

    diff --git a/src/editor/editbuffer.h b/src/editor/editbuffer.h
    index def17eec5..00f094e81 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, 
     52                              gboolean screen_lines); 
     53off_t edit_buffer_get_bol (const edit_buffer_t * buf, off_t current, gboolean screen_lines); 
     54off_t edit_buffer_get_eol (const edit_buffer_t * buf, off_t current, gboolean screen_lines); 
    4955GString *edit_buffer_get_word_from_pos (const edit_buffer_t * buf, off_t start_pos, off_t * start, 
    5056                                        gsize * cut); 
    5157gboolean edit_buffer_find_word_start (const edit_buffer_t * buf, off_t * word_start, 
    int edit_buffer_delete (edit_buffer_t * buf); 
    5763int edit_buffer_backspace (edit_buffer_t * buf); 
    5864 
    5965off_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); 
     66                                      off_t upto, gboolean screen_lines); 
     67off_t edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines, 
     68                                       gboolean screen_lines); 
    6269 
    6370off_t edit_buffer_read_file (edit_buffer_t * buf, int fd, off_t size, 
    6471                             edit_buffer_read_file_status_msg_t * sm, gboolean * aborted); 
    edit_buffer_get_previous_byte (const edit_buffer_t * buf) 
    94101static inline off_t 
    95102edit_buffer_get_current_bol (const edit_buffer_t * buf) 
    96103{ 
    97     return edit_buffer_get_bol (buf, buf->curs1); 
     104    return edit_buffer_get_bol (buf, buf->curs1, FALSE); 
    98105} 
    99106 
    100107/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_get_current_bol (const edit_buffer_t * buf) 
    109116static inline off_t 
    110117edit_buffer_get_current_eol (const edit_buffer_t * buf) 
    111118{ 
    112     return edit_buffer_get_eol (buf, buf->curs1); 
     119    return edit_buffer_get_eol (buf, buf->curs1, FALSE); 
    113120} 
    114121 
    115122/* --------------------------------------------------------------------------------------------- */ 
  • src/editor/editcmd.c

    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index de624f249..e29c20671 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, 
     472                                   FALSE, 0); 
     473    d = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m2, TRUE), 0, m2, 
     474                                   FALSE, 0); 
    473475    b = MAX (MIN (c, d), MIN (edit->column1, edit->column2)); 
    474476    c = MAX (c, MAX (edit->column1, edit->column2)); 
    475477 
    edit_delete_column_of_text (WEdit * edit) 
    478480        off_t r, p, q; 
    479481 
    480482        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); 
     483        p = edit_move_forward3 (edit, r, b, 0, FALSE, 0); 
     484        q = edit_move_forward3 (edit, r, c, 0, FALSE, 0); 
    483485        p = MAX (p, m1); 
    484486        q = MIN (q, m2); 
    485487        edit_cursor_move (edit, p - edit->buffer.curs1); 
    edit_delete_column_of_text (WEdit * edit) 
    492494        if (n != 0) 
    493495            edit_cursor_move (edit, 
    494496                              edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1, 
    495                                                               0) - edit->buffer.curs1); 
     497                                                              0, FALSE) - edit->buffer.curs1); 
    496498    } 
    497499} 
    498500 
    edit_block_delete (WEdit * edit) 
    547549            edit_move_to_line (edit, curs_line); 
    548550            /* calculate line width and cursor position before cut */ 
    549551            line_width = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    550                                              edit_buffer_get_current_eol (&edit->buffer)); 
     552                                             edit_buffer_get_current_eol (&edit->buffer), FALSE, 
     553                                             FALSE); 
    551554            if (edit_options.cursor_beyond_eol && curs_pos > line_width) 
    552555                edit->over_col = curs_pos - line_width; 
    553556        } 
    edit_get_block (WEdit * edit, off_t start, off_t finish, off_t * l) 
    586589            int c; 
    587590            off_t x; 
    588591 
    589             x = edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, start), 0, start); 
     592            x = edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, start, TRUE), 0, 
     593                                    start, FALSE, 0); 
    590594            c = edit_buffer_get_byte (&edit->buffer, start); 
    591595            if ((x >= edit->column1 && x < edit->column2) 
    592596                || (x >= edit->column2 && x < edit->column1) || c == '\n') 
    edit_insert_column_of_text (WEdit * edit, unsigned char *data, off_t size, long 
    699703                    break; 
    700704                } 
    701705            } 
    702             edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1); 
     706            edit_cursor_move (edit, 
     707                              edit_move_forward3 (edit, p, col, 0, FALSE, 
     708                                                  FALSE) - edit->buffer.curs1); 
    703709 
    704710            for (l = col - edit_get_col (edit); l >= space_width; l -= space_width) 
    705711                edit_insert (edit, ' '); 
    eval_marks (WEdit * edit, off_t * start_mark, off_t * end_mark) 
    13001306        long col1, col2; 
    13011307        off_t diff1, diff2; 
    13021308 
    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); 
     1309        start_bol = edit_buffer_get_bol (&edit->buffer, *start_mark, FALSE); 
     1310        start_eol = edit_buffer_get_eol (&edit->buffer, start_bol - 1, FALSE) + 1; 
     1311        end_bol = edit_buffer_get_bol (&edit->buffer, *end_mark, FALSE); 
     1312        end_eol = edit_buffer_get_eol (&edit->buffer, *end_mark, FALSE); 
    13071313        col1 = MIN (edit->column1, edit->column2); 
    13081314        col2 = MAX (edit->column1, edit->column2); 
    13091315 
    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); 
     1316        diff1 = edit_move_forward3 (edit, start_bol, col2, 0, FALSE, 0) - 
     1317            edit_move_forward3 (edit, start_bol, col1, 0, FALSE, 0); 
     1318        diff2 = edit_move_forward3 (edit, end_bol, col2, 0, FALSE, 0) - 
     1319            edit_move_forward3 (edit, end_bol, col1, 0, FALSE, 0); 
    13141320 
    13151321        *start_mark -= diff1; 
    13161322        *end_mark += diff2; 
    edit_block_move_cmd (WEdit * edit) 
    14091415        x2 = x + edit->over_col; 
    14101416 
    14111417        /* 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) 
     1418        if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1, FALSE) == 
     1419             edit_buffer_get_eol (&edit->buffer, start_mark, FALSE)) && x2 > c1 && x2 <= c2) 
    14141420            return; 
    14151421 
    14161422        if (edit->buffer.curs1 > start_mark 
    1417             && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark)) 
     1423            && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark, FALSE)) 
    14181424        { 
    14191425            if (x > c2) 
    14201426                x -= b_width; 
    edit_block_move_cmd (WEdit * edit) 
    14291435 
    14301436        edit->over_col = MAX (0, edit->over_col - b_width); 
    14311437        /* calculate the cursor pos after delete block */ 
    1432         current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0); 
     1438        current = 
     1439            edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0, FALSE, 0); 
    14331440        edit_cursor_move (edit, current - edit->buffer.curs1); 
    14341441        edit_scroll_screen_over_cursor (edit); 
    14351442 
  • src/editor/editdraw.c

    diff --git a/src/editor/editdraw.c b/src/editor/editdraw.c
    index fbd1e095f..3067eee3f 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 *edit_prepare_this_line (WEdit * edit, off_t b, long order_idx, long row, 
     112                                            long start_col, long end_col, long soft_last_row, 
     113                                            gboolean draw, long base_line); 
     114 
     115gboolean refresh_line_data (WEdit * edit, GPtrArray * page_line_data, long start_column, 
     116                            long end_column, long end_row); 
     117 
     118gboolean 
     119refresh_line_data (WEdit * edit, GPtrArray * page_line_data, long start_column, long end_column, 
     120                   long end_row) 
     121{ 
     122    MCELineData *prev_ldata, *line_data; 
     123    gboolean ret = FALSE; 
     124    long base_line, row, start_row = 0; 
     125    int prev_plines = 0; 
     126 
     127    base_line = edit_buffer_count_lines (&edit->buffer, 0, edit->start_display, FALSE); 
     128    off_t b = 
     129        edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, FALSE); 
     130    for (row = start_row; row < end_row; row++) 
     131    { 
     132        int pplines_add = 0; 
     133        if (!edit_options.soft_wrap) 
     134            pplines_add = -prev_plines; 
     135        line_data = edit_prepare_this_line (edit, b, row, row + prev_plines + pplines_add, 
     136                                            start_column, end_column, -1, FALSE, base_line); 
     137        line_data->plines_count += pplines_add; 
     138        prev_ldata = (MCELineData *) page_line_data->pdata[row]; 
     139        if (prev_ldata == NULL || prev_ldata->plines_count != line_data->plines_count) 
     140            /* Return true if any plines changed */ 
     141            ret = TRUE; 
     142        page_line_data->pdata[row] = line_data; 
     143        prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     144        b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     145    } 
     146    return ret; 
     147} 
     148 
     149int 
     150sum_plines_to_row_full (GPtrArray * page_line_data, int row, gboolean count_only_second_etc_lines) 
     151{ 
     152    int prev_plines = 0; 
     153 
     154    if (!edit_options.soft_wrap) 
     155        return prev_plines; 
     156 
     157    for (int idx = 0; idx < row && idx < (long) page_line_data->len; idx++) 
     158    { 
     159        MCELineData *line_data = page_line_data->pdata[idx]; 
     160        if (line_data != NULL) 
     161            prev_plines += 
     162                (line_data->plines_count > 
     163                 0) ? line_data->plines_count - (count_only_second_etc_lines ? 1 : 0) : 0; 
     164        else 
     165            prev_plines += count_only_second_etc_lines ? 0 : 1; 
     166    } 
     167    return prev_plines; 
     168} 
     169 
    91170static inline void 
    92171printwstr (const char *s, int len) 
    93172{ 
    status_string (WEdit * edit, char *s, int w) 
    136215    } 
    137216 
    138217    /* The field lengths just prevent the status line from shortening too much */ 
     218    off_t bol = edit_buffer_get_current_bol (&edit->buffer); 
     219    off_t col = edit_move_forward3 (edit, bol, 0, 
     220                                    edit->buffer.curs1, FALSE, 0); 
    139221    if (edit_options.simple_statusbar) 
    140222        g_snprintf (s, w, 
    141223                    "%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s", 
    status_string (WEdit * edit, char *s, int w) 
    143225                    edit->modified ? 'M' : '-', 
    144226                    macro_index < 0 ? '-' : 'R', 
    145227                    edit->overwrite == 0 ? '-' : 'O', 
    146                     edit->curs_col + edit->over_col, 
     228                    col, 
    147229                    edit->buffer.curs_line + 1, 
    148230                    edit->buffer.lines + 1, (long) edit->buffer.curs1, (long) edit->buffer.size, 
    149231                    byte_str, 
    status_string (WEdit * edit, char *s, int w) 
    158240                    edit->modified ? 'M' : '-', 
    159241                    macro_index < 0 ? '-' : 'R', 
    160242                    edit->overwrite == 0 ? '-' : 'O', 
    161                     edit->curs_col + edit->over_col, 
     243                    col, 
    162244                    edit->start_line + 1, 
    163245                    edit->curs_row, 
    164246                    edit->buffer.curs_line + 1, 
    edit_status_fullscreen (WEdit * edit, int color) 
    185267    const int w = h->rect.cols; 
    186268    const int gap = 3;          /* between the filename and the status */ 
    187269    const int right_gap = 5;    /* at the right end of the screen */ 
    188     const int preferred_fname_len = 16; 
     270    const int preferred_fname_len = 14; 
    189271    char *status; 
    190272    size_t status_size; 
    191273    int status_len; 
    edit_draw_window_icons (const WEdit * edit, int color) 
    377459/* --------------------------------------------------------------------------------------------- */ 
    378460 
    379461static 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) 
     462print_to_widget (WEdit * edit, MCELineData * line_data) 
    382463{ 
     464    int linesize = line_data->size; 
     465    long row = edit_options.soft_wrap ? line_data->row : line_data->scr_index; 
     466    int q = line_data->q; 
     467    int start_col_real = line_data->start_col_real; 
     468    long ec = line_data->ec, idx; 
     469    line *line_ = line_data->ldata; 
     470    char *status = line_data->status; 
     471    int bookmarked = line_data->bookmarked; 
     472 
    383473    Widget *w = WIDGET (edit); 
    384     line_s *p; 
     474    line *p; 
    385475    int x, x1, y, cols_to_skip; 
    386     int i; 
    387     int wrap_start; 
     476    int i, yp; 
     477    int f_start; 
    388478    int len; 
    389479 
     480    if (row < line_data->row) 
     481    { 
     482        row = line_data->row; 
     483    } 
    390484    x = start_col_real; 
    391     x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     485    x1 = q + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    392486    y = row + EDIT_TEXT_VERTICAL_OFFSET; 
    393487    cols_to_skip = abs (x); 
    394488 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    398492        y++; 
    399493    } 
    400494 
    401     tty_setcolor (EDITOR_NORMAL_COLOR); 
    402     if (bookmarked != 0) 
    403         tty_setcolor (bookmarked); 
     495    len = ec + 1 - q; 
     496    f_start = edit_options.word_wrap_line_length + edit->start_col; 
    404497 
    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) 
     498    for (idx = 0; idx < line_data->plines_count || idx == 0; idx++) 
    409499    { 
    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) 
     500        if (len > 0 && w->rect.y + y >= 0) 
    413501        { 
    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); 
     502            if (!edit_options.show_right_margin || f_start > ec) 
     503            { 
     504                tty_setcolor (EDITOR_NORMAL_COLOR); 
     505                if (bookmarked != 0) 
     506                    tty_setcolor (bookmarked); 
    421507 
    422             len -= wrap_start; 
    423             if (len > 0) 
     508                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     509            } 
     510            else if (f_start < 0) 
    424511            { 
    425512                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    426                 tty_draw_hline (w->rect.y + y, w->rect.x + x1 + wrap_start, ' ', len); 
     513                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     514            } 
     515            else 
     516            { 
     517                if (f_start > 0) 
     518                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', f_start); 
     519 
     520                len -= f_start; 
     521                if (len > 0) 
     522                { 
     523                    tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
     524                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1 + f_start, ' ', len); 
     525                } 
     526            } 
     527        } 
     528    } 
     529    if (edit_options.line_state) 
     530    { 
     531        tty_setcolor (LINE_STATE_COLOR); 
     532        for (yp = 0; (edit_options.soft_wrap && yp <= linesize / ec + 
     533                      (linesize % ec != 0 ? 0 : -1) + 
     534                      (linesize == 0 ? 1 : 0)) || (!edit_options.soft_wrap && yp < 1); ++yp) 
     535        { 
     536            for (i = 0; i < LINE_STATE_WIDTH; i++) 
     537            { 
     538                edit_move (x1 + i - edit_options.line_state_width, y + yp); 
     539                if (yp == 0) 
     540                { 
     541                    if (status[i] == '\0') 
     542                        status[i] = ' '; 
     543                    tty_print_char (status[i]); 
     544                } 
     545                else 
     546                    tty_print_char (' '); 
    427547            } 
    428548        } 
    429549    } 
    430550 
    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     } 
     551    edit->end_col = ec; 
     552    edit->buffer.end_col = ec; 
    443553 
    444554    edit_move (x1, y); 
    445555 
    446556    i = 1; 
    447     for (p = line; p->ch != 0; p++) 
     557    for (idx = 0, p = &line_[-edit->start_col]; 
     558         (edit_options.soft_wrap && linesize-- > 0) || (!edit_options.soft_wrap 
     559                                                        && (linesize-- + edit->start_col > 0) 
     560                                                        && p->ch != 0); p++, idx++) 
    448561    { 
     562 
    449563        int style; 
    450564        unsigned int textchar; 
    451565        int color; 
    452  
    453         if (cols_to_skip != 0) 
     566        if (!edit_options.soft_wrap && cols_to_skip != 0) 
    454567        { 
    455568            cols_to_skip--; 
    456569            continue; 
    457570        } 
    458571 
     572        /* Position each physical line */ 
     573        if (edit_options.soft_wrap && idx % ec == 0) 
     574            edit_move (x1, y++); 
     575 
    459576        style = p->style & 0xFF00; 
    460577        textchar = p->ch; 
    461578        /* If non-printable - use black background */ 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    482599        { 
    483600            if (i > edit_options.word_wrap_line_length + edit->start_col) 
    484601                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    485             i++; 
    486602        } 
     603        i++; 
    487604 
    488605        tty_print_anychar (textchar); 
    489606    } 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    492609/* --------------------------------------------------------------------------------------------- */ 
    493610/** b is a pointer to the beginning of the line */ 
    494611 
    495 static void 
    496 edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_col) 
     612static MCELineData * 
     613edit_prepare_this_line (WEdit * edit, off_t b, long order_idx, long row, long start_col, 
     614                        long end_col, long soft_last_row_idx, gboolean draw, long base_line) 
    497615{ 
     616    long line_count, cur_line, prev_line; 
     617    MCELineData *line_data; 
    498618    Widget *w = WIDGET (edit); 
    499     line_s line[MAX_LINE_LEN]; 
    500     line_s *p = line; 
     619    line *p; 
    501620    off_t q; 
    502     int col, start_col_real; 
     621    int wrap_line_len, line_size, start_col_real = 0; 
     622    int col; 
     623    int color; 
    503624    int abn_style; 
    504625    int book_mark = 0; 
    505     char line_stat[LINE_STATE_WIDTH + 1] = "\0"; 
    506626 
    507     if (row > w->rect.lines - 1 - EDIT_TEXT_VERTICAL_OFFSET - 2 * (edit->fullscreen ? 0 : 1)) 
    508         return; 
     627    q = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     628    line_size = edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     629    line_data = (MCELineData *) g_malloc0 (sizeof (MCELineData) + sizeof (line) * 
     630                                           (line_size + /* sentinel —→ */ 1 + 
     631                                            edit_buffer_count_tabs (&edit->buffer, b, q, 
     632                                                                    FALSE) * 8)); 
     633    p = line_data->ldata; 
    509634 
    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; 
     635    /* Helper var */ 
     636    if (edit_options.soft_wrap) 
     637        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    517638    else 
    518         abn_style = MOD_ABNORMAL; 
     639        wrap_line_len = abs (edit_options.word_wrap_line_length); 
    519640 
    520     end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    521641    if (!edit->fullscreen) 
    522642    { 
    523643        end_col--; 
    524644        if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
    525645            end_col--; 
    526646    } 
     647    wrap_line_len = end_col; 
    527648 
    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; 
     649    line_count = edit_buffer_count_lines (&edit->buffer, edit->start_display, q - 1, FALSE); 
     650    line_count += base_line + (line_count > 0 ? -1 : 0); 
     651 
     652    line_data->soft_last_row = soft_last_row_idx; 
     653    line_data->row = row; 
     654    line_data->plines_count = line_size / wrap_line_len + ((line_size % wrap_line_len) ? 1 : 0); 
     655    if (!edit_options.soft_wrap) 
     656        line_data->plines_count = 0; 
     657    line_data->index = line_count + (line_count > 0 ? -1 : 0); 
     658    line_data->scr_index = line_data->index - edit->start_line; 
     659    line_data->order_idx = order_idx;   /* for investigation */ 
     660    line_data->size = line_size; 
     661    line_data->q = !edit_options.soft_wrap ? edit->start_col : 0; 
     662    line_data->ec = end_col; 
     663    line_data->visible = (order_idx <= line_data->soft_last_row); 
     664 
     665    if (!edit_options.soft_wrap) 
     666        line_data->plines_count = 0; 
     667 
     668    if (book_mark_query_color (edit, line_data->index, BOOK_MARK_COLOR)) 
     669        book_mark = BOOK_MARK_COLOR; 
     670    else if (book_mark_query_color (edit, line_data->index, BOOK_MARK_FOUND_COLOR)) 
     671        book_mark = BOOK_MARK_FOUND_COLOR; 
     672 
     673    line_data->bookmarked = book_mark; 
     674 
     675    if (book_mark != 0) 
     676        abn_style = book_mark << 16; 
     677    else 
     678        abn_style = MOD_ABNORMAL; 
     679    if (!edit_options.soft_wrap) 
     680    { 
     681        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     682        if (!edit->fullscreen) 
     683        { 
     684            end_col--; 
     685            if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
     686                end_col--; 
     687        } 
     688    } 
     689 
     690    color = edit_get_syntax_color (edit, b - 1); 
     691    if (edit_options.soft_wrap) 
     692    { 
     693        q = b; 
     694        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     695    } 
     696    else 
     697    { 
     698        q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0, FALSE, 0); 
     699        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     700        line_data->start_col_real = start_col_real = col + edit->start_col; 
     701    } 
    531702 
    532703    if (edit_options.line_state) 
    533704    { 
    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); 
     705        int line_cnt = 0; 
     706        cur_line = line_data->index; 
     707        if (line_data->order_idx == line_data->scr_index || cur_line + 1 < line_cnt) 
     708            g_snprintf (line_data->status, sizeof (line_data->status), "%7li ", cur_line + 1); 
    539709        else 
    540710        { 
    541             memset (line_stat, ' ', LINE_STATE_WIDTH); 
    542             line_stat[LINE_STATE_WIDTH] = '\0'; 
     711            memset (line_data->status, ' ', LINE_STATE_WIDTH); 
     712            line_data->status[LINE_STATE_WIDTH] = '\0'; 
    543713        } 
    544  
     714        prev_line = cur_line + 1; 
    545715        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR)) 
    546             g_snprintf (line_stat, 2, "*"); 
     716            g_snprintf (line_data->status, 2, "*"); 
    547717    } 
    548718 
    549719    if (col <= -(edit->start_col + 16)) 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    553723        off_t m1 = 0, m2 = 0; 
    554724 
    555725        eval_marks (edit, &m1, &m2); 
    556  
    557         if (row <= edit->buffer.lines - edit->start_line) 
     726        if (order_idx <= edit->buffer.lines - edit->start_line) 
    558727        { 
    559728            off_t tws = 0; 
    560729 
    561             if (edit_options.visible_tws && tty_use_colors ()) 
    562                 for (tws = edit_buffer_get_eol (&edit->buffer, b); tws > b; tws--) 
     730            if (tty_use_colors () && edit_options.visible_tws) 
     731                for (tws = edit_buffer_get_eol (&edit->buffer, b, FALSE); tws > b; tws--) 
    563732                { 
    564733                    unsigned int c; 
    565734 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    568737                        break; 
    569738                } 
    570739 
    571             while (col <= end_col - edit->start_col) 
     740            while ((edit_options.soft_wrap && col <= line_data->size) || 
     741                   (!edit_options.soft_wrap && col <= line_data->size)) 
    572742            { 
    573743                int char_length = 1; 
    574744                unsigned int c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    586756                    { 
    587757                        long x, cl; 
    588758 
    589                         x = (long) edit_move_forward3 (edit, b, 0, q); 
     759                        x = (long) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
    590760                        cl = MIN (edit->column1, edit->column2); 
    591761                        if (x >= cl) 
    592762                        { 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    614784                    p->style |= book_mark << 16; 
    615785                else 
    616786                { 
    617                     int color; 
    618  
    619787                    color = edit_get_syntax_color (edit, q); 
    620788                    p->style |= color << 16; 
    621789                } 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    623791                switch (c) 
    624792                { 
    625793                case '\n': 
    626                     col = end_col - edit->start_col + 1;        /* quit */ 
     794                    if (edit_options.soft_wrap) 
     795                        col = line_data->size + 1;      /* quit */ 
     796                    else 
     797                        col = line_data->size + 1; 
    627798                    break; 
    628799 
    629800                case '\t': 
    630801                    { 
    631                         int tab_over; 
     802                        int tab_over = 0; 
    632803                        int i; 
    633804 
    634805                        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; 
     806 
     807                        /* Supress off-screen part only if not in Soft Wraps mode */ 
     808                        if (!edit_options.soft_wrap || edit_options.soft_wrap) 
     809                        { 
     810                            tab_over = end_col - (col + i - 1); 
     811                            if (tab_over < 0) 
     812                                i += tab_over; 
     813                        } 
    638814                        col += i; 
    639                         if ((edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
    640                             && enable_show_tabs_tws && tty_use_colors ()) 
     815                        if (tty_use_colors () 
     816                            && (edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
     817                            && enable_show_tabs_tws) 
    641818                        { 
    642819                            if ((p->style & MOD_MARKED) != 0) 
    643820                                c = p->style; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    669846                                p->style = c; 
    670847                                p++; 
    671848                            } 
    672                             else 
     849                            else if (i > 0) 
    673850                            { 
    674851                                p->ch = '>'; 
    675852                                p->style = c; 
    676853                                p++; 
    677854                            } 
    678855                        } 
    679                         else if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    680                                  && tty_use_colors ()) 
     856                        else if (tty_use_colors () && edit_options.visible_tws && q >= tws 
     857                                 && enable_show_tabs_tws) 
    681858                        { 
    682859                            p->ch = '.'; 
    683860                            p->style |= MOD_WHITESPACE; 
    684861                            c = p->style & ~MOD_CURSOR; 
    685862                            p++; 
    686                             while (--i != 0) 
     863                            while (--i > 0) 
    687864                            { 
    688865                                p->ch = ' '; 
    689866                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    695872                            p->ch |= ' '; 
    696873                            c = p->style & ~MOD_CURSOR; 
    697874                            p++; 
    698                             while (--i != 0) 
     875                            while (--i > 0) 
    699876                            { 
    700877                                p->ch = ' '; 
    701878                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    706883                    break; 
    707884 
    708885                case ' ': 
    709                     if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    710                         && tty_use_colors ()) 
     886                    if (tty_use_colors () && edit_options.visible_tws && q >= tws 
     887                        && enable_show_tabs_tws) 
    711888                    { 
    712889                        p->ch = '.'; 
    713890                        p->style |= MOD_WHITESPACE; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    796973                if (char_length > 1) 
    797974                    q += char_length - 1; 
    798975 
    799                 if (col > (end_col - edit->start_col + 1)) 
     976                if ((edit_options.soft_wrap && col > (line_data->size + 1)) 
     977                    || (!edit_options.soft_wrap && (col > line_data->size + 1))) 
    800978                { 
    801979                    if (wide_width_char) 
    802980                    { 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    814992    } 
    815993 
    816994    p->ch = 0; 
    817  
    818     print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark); 
     995    if (draw) 
     996        print_to_widget (edit, line_data); 
     997    return line_data; 
    819998} 
    820999 
    8211000/* --------------------------------------------------------------------------------------------- */ 
    8221001 
    8231002static inline void 
    824 edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long end_column) 
     1003edit_draw_this_char (WEdit * edit, off_t curs, long order_idx, long row, long start_column, 
     1004                     long end_column) 
    8251005{ 
     1006    MCELineData *line_data; 
    8261007    off_t b; 
    8271008 
    828     b = edit_buffer_get_bol (&edit->buffer, curs); 
    829     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1009    b = edit_buffer_get_bol (&edit->buffer, curs, FALSE); 
     1010    line_data = 
     1011        edit_prepare_this_line (edit, b, order_idx, row, start_column, end_column, 0, TRUE, 0); 
     1012    edit->page_line_data->pdata[order_idx] = line_data; 
    8301013} 
    8311014 
    8321015/* --------------------------------------------------------------------------------------------- */ 
    edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long 
    8351018static inline void 
    8361019render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, long end_column) 
    8371020{ 
    838     static long prev_curs_row = 0; 
    839     static off_t prev_curs = 0; 
     1021    long base_line, y = 0, y_pos; 
     1022    MCELineData *line_data = NULL; 
    8401023 
    841     Widget *we = WIDGET (edit); 
    842     Widget *wh = WIDGET (we->owner); 
    843     WRect *w = &we->rect; 
     1024    Widget *w = WIDGET (edit); 
     1025    Widget *wh = WIDGET (w->owner); 
    8441026 
    845     int force = edit->force; 
     1027    int force = edit->force, prev_plines = 0; 
    8461028    int y1, x1, y2, x2; 
    8471029    int last_line, last_column; 
     1030    base_line = edit_buffer_count_lines (&edit->buffer, 0, edit->start_display, FALSE); 
     1031    base_line += edit->start_display == 0 ? 1 : 0; 
     1032    GPtrArray *page_line_data = edit->page_line_data; 
    8481033 
     1034    if (edit->page_line_data == NULL) 
     1035        page_line_data = edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     1036    g_ptr_array_set_size (edit->page_line_data, LINES); 
     1037 
     1038    y_pos = edit->array_row; 
    8491039    /* draw only visible region */ 
    8501040 
    8511041    last_line = wh->rect.y + wh->rect.lines - 1; 
    8521042 
    853     y1 = w->y; 
     1043    y1 = w->rect.y; 
    8541044    if (y1 > last_line - 1 /* buttonbar */ ) 
    8551045        return; 
    8561046 
    8571047    last_column = wh->rect.x + wh->rect.cols - 1; 
    8581048 
    859     x1 = w->x; 
     1049    x1 = w->rect.x; 
    8601050    if (x1 > last_column) 
    8611051        return; 
    8621052 
    863     y2 = w->y + w->lines - 1; 
     1053    y2 = w->rect.y + w->rect.lines - 1; 
    8641054    if (y2 < wh->rect.y + 1 /* menubar */ ) 
    8651055        return; 
    8661056 
    867     x2 = w->x + w->cols - 1; 
     1057    x2 = w->rect.x + w->rect.cols - 1; 
    8681058    if (x2 < wh->rect.x) 
    8691059        return; 
    8701060 
    render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, 
    8741064        /* draw only visible region */ 
    8751065 
    8761066        if (y2 <= last_line - 1 /* buttonbar */ ) 
    877             end_row = w->lines - 1; 
     1067            end_row = w->rect.lines - 1; 
    8781068        else if (y1 >= wh->rect.y + 1 /* menubar */ ) 
    8791069            end_row = wh->rect.lines - 1 - y1 - 1; 
    8801070        else 
    8811071            end_row = start_row + wh->rect.lines - 1 - 1; 
     1072        soft_last_row = end_row; 
    8821073 
    8831074        if (x2 <= last_column) 
    884             end_column = w->cols - 1; 
     1075            end_column = w->rect.cols - 1; 
    8851076        else if (x1 >= wh->rect.x) 
    8861077            end_column = wh->rect.cols - 1 - x1; 
    8871078        else 
    8881079            end_column = start_column + wh->rect.cols - 1; 
    8891080    } 
     1081    refresh_line_data (edit, page_line_data, start_column, end_column, end_row); 
    8901082 
     1083    if (edit_options.soft_wrap) 
     1084    { 
     1085        int i, lines_occupied = 0; 
     1086        for (i = 1 /*skip 0 */ ; i <= end_row; ++i) 
     1087        { 
     1088            /* for i=1, it is line 0 that's 
     1089             * summed up, and so on */ 
     1090            lines_occupied = i + sum_plines_to_row (page_line_data, i); 
     1091            if (lines_occupied >= wh->rect.lines - 1 - 1) 
     1092                break; 
     1093        } 
     1094        soft_last_row = i - 1; 
     1095    } 
     1096    else 
     1097        soft_last_row = end_row; 
    8911098    /* 
    8921099     * If the position of the page has not moved then we can draw the cursor 
    8931100     * 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, 
    8991106 
    9001107        if ((force & REDRAW_PAGE) != 0) 
    9011108        { 
    902             b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0); 
     1109            b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, 
     1110                                                FALSE); 
    9031111            for (row = start_row; row <= end_row; row++) 
    9041112            { 
    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); 
     1113                line_data = edit_prepare_this_line (edit, b, row, row + prev_plines, 
     1114                                                    start_column, end_column, soft_last_row, 
     1115                                                    row <= soft_last_row, base_line); 
     1116                page_line_data->pdata[row] = line_data; 
     1117                prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1118                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9091119            } 
    9101120        } 
    9111121        else 
    9121122        { 
    913             long curs_row = edit->curs_row; 
    9141123 
    915             if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < curs_row) 
     1124            if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < y_pos) 
    9161125            { 
    9171126                long upto; 
    9181127 
     1128                row = start_row; 
    9191129                b = edit->start_display; 
    920                 upto = MIN (curs_row - 1, end_row); 
    921                 for (row = start_row; row <= upto; row++) 
     1130                upto = MIN (y_pos - 1, end_row); 
     1131                while (row <= upto) 
    9221132                { 
    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); 
     1133                    line_data = edit_prepare_this_line (edit, b, row, row + prev_plines, 
     1134                                                        start_column, end_column, soft_last_row, 
     1135                                                        row <= soft_last_row, base_line); 
     1136                    page_line_data->pdata[row] = line_data; 
     1137                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1138                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     1139                    row++; 
    9271140                } 
    9281141            } 
    929  
    9301142            /*          if (force & REDRAW_LINE)          ---> default */ 
     1143            y = (y_pos - 1 < 0) ? 0 : y_pos - 1; 
    9311144            b = edit_buffer_get_current_bol (&edit->buffer); 
    932             if (curs_row >= start_row && curs_row <= end_row) 
     1145            if (y_pos - y == 1) 
     1146                b = edit_buffer_get_backward_offset (&edit->buffer, b, 1, FALSE); 
     1147            while (y <= y_pos && y >= start_row && y <= end_row) 
    9331148            { 
    934                 if (key_pending (edit)) 
    935                     return; 
    936                 edit_draw_this_line (edit, b, curs_row, start_column, end_column); 
     1149                prev_plines = sum_plines_to_row (edit->page_line_data, y); 
     1150                line_data = edit_prepare_this_line (edit, b, y, y + prev_plines, 
     1151                                                    start_column, end_column, soft_last_row, 
     1152                                                    y <= soft_last_row, base_line); 
     1153                page_line_data->pdata[y] = line_data; 
     1154                y++; 
     1155                if (y <= y_pos) 
     1156                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9371157            } 
    9381158 
    939             if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > curs_row) 
     1159            if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > y_pos) 
    9401160            { 
    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++) 
     1161                row = MAX (y_pos + 1, start_row); 
     1162                prev_plines = sum_plines_to_row (page_line_data, row); 
     1163                b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, row, 0, 
     1164                                                    FALSE); 
     1165                for (; row <= end_row; row++) 
    9431166                { 
    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); 
     1167                    line_data = 
     1168                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1169                                                end_column, soft_last_row, row <= soft_last_row, 
     1170                                                base_line); 
     1171                    page_line_data->pdata[row] = line_data; 
     1172                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1173                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9481174                } 
    9491175            } 
    9501176 
    951             if ((force & REDRAW_LINE_ABOVE) != 0 && curs_row >= 1) 
     1177            if ((force & REDRAW_LINE_ABOVE) != 0 && y_pos >= 1) 
    9521178            { 
    953                 row = curs_row - 1; 
     1179                row = y_pos - 1; 
    9541180                b = edit_buffer_get_backward_offset (&edit->buffer, 
    9551181                                                     edit_buffer_get_current_bol (&edit->buffer), 
    956                                                      1); 
     1182                                                     1, FALSE); 
    9571183                if (row >= start_row && row <= end_row) 
    9581184                { 
    959                     if (key_pending (edit)) 
    960                         return; 
    961                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1185                    prev_plines = sum_plines_to_row (edit->page_line_data, row); 
     1186                    line_data = 
     1187                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1188                                                end_column, soft_last_row, row <= soft_last_row, 
     1189                                                base_line); 
     1190                    page_line_data->pdata[row] = line_data; 
    9621191                } 
    9631192            } 
    964  
    965             if ((force & REDRAW_LINE_BELOW) != 0 && row < w->lines - 1) 
     1193            if ((force & REDRAW_LINE_BELOW) != 0 && y_pos < w->rect.lines - 1) 
    9661194            { 
    967                 row = curs_row + 1; 
     1195                row = y_pos + 1; 
    9681196                b = edit_buffer_get_current_bol (&edit->buffer); 
    969                 b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1197                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9701198                if (row >= start_row && row <= end_row) 
    9711199                { 
    972                     if (key_pending (edit)) 
    973                         return; 
    974                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1200                    prev_plines = sum_plines_to_row (edit->page_line_data, row); 
     1201                    line_data = 
     1202                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1203                                                end_column, soft_last_row, row <= soft_last_row, 
     1204                                                base_line); 
     1205                    page_line_data->pdata[row] = line_data; 
    9751206                } 
    9761207            } 
    9771208        } 
    9781209    } 
    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     } 
    9901210 
    9911211    edit->force = 0; 
    992  
    993     prev_curs_row = edit->curs_row; 
    994     prev_curs = edit->buffer.curs1; 
    9951212} 
    9961213 
    9971214/* --------------------------------------------------------------------------------------------- */ 
    edit_status (WEdit * edit, gboolean active) 
    10441261void 
    10451262edit_scroll_screen_over_cursor (WEdit * edit) 
    10461263{ 
    1047     WRect *w = &WIDGET (edit)->rect; 
     1264    Widget *w = WIDGET (edit); 
    10481265 
    10491266    long p; 
    10501267    long outby; 
    10511268    int b_extreme, t_extreme, l_extreme, r_extreme; 
    10521269 
    1053     if (w->lines <= 0 || w->cols <= 0) 
     1270    if (w->rect.lines <= 0 || w->rect.cols <= 0) 
    10541271        return; 
    10551272 
    1056     rect_resize (w, -EDIT_TEXT_VERTICAL_OFFSET, 
     1273    rect_resize (&w->rect, -EDIT_TEXT_VERTICAL_OFFSET, 
    10571274                 -(EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width)); 
    10581275 
    10591276    if (!edit->fullscreen) 
    1060         rect_grow (w, -1, -1); 
     1277        rect_grow (&w->rect, -1, -1); 
    10611278 
    10621279    r_extreme = EDIT_RIGHT_EXTREME; 
    10631280    l_extreme = EDIT_LEFT_EXTREME; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    10651282    t_extreme = EDIT_TOP_EXTREME; 
    10661283    if (edit->found_len != 0) 
    10671284    { 
    1068         b_extreme = MAX (w->lines / 4, b_extreme); 
    1069         t_extreme = MAX (w->lines / 4, t_extreme); 
     1285        b_extreme = MAX (w->rect.lines / 4, b_extreme); 
     1286        t_extreme = MAX (w->rect.lines / 4, t_extreme); 
    10701287    } 
    1071     if (b_extreme + t_extreme + 1 > w->lines) 
     1288    if (b_extreme + t_extreme + 1 > w->rect.lines) 
    10721289    { 
    10731290        int n; 
    10741291 
    10751292        n = b_extreme + t_extreme; 
    10761293        if (n == 0) 
    10771294            n = 1; 
    1078         b_extreme = (b_extreme * (w->lines - 1)) / n; 
    1079         t_extreme = (t_extreme * (w->lines - 1)) / n; 
     1295        b_extreme = (b_extreme * (w->rect.lines - 1)) / n; 
     1296        t_extreme = (t_extreme * (w->rect.lines - 1)) / n; 
    10801297    } 
    1081     if (l_extreme + r_extreme + 1 > w->cols) 
     1298    if (l_extreme + r_extreme + 1 > w->rect.cols) 
    10821299    { 
    10831300        int n; 
    10841301 
    10851302        n = l_extreme + r_extreme; 
    10861303        if (n == 0) 
    10871304            n = 1; 
    1088         l_extreme = (l_extreme * (w->cols - 1)) / n; 
    1089         r_extreme = (r_extreme * (w->cols - 1)) / n; 
     1305        l_extreme = (l_extreme * (w->rect.cols - 1)) / n; 
     1306        r_extreme = (r_extreme * (w->rect.cols - 1)) / n; 
    10901307    } 
    10911308    p = edit_get_col (edit) + edit->over_col; 
    10921309    edit_update_curs_row (edit); 
    1093     outby = p + edit->start_col - w->cols + 1 + (r_extreme + edit->found_len); 
     1310    outby = p + edit->start_col - w->rect.cols + 1 + (r_extreme + edit->found_len); 
    10941311    if (outby > 0) 
    10951312        edit_scroll_right (edit, outby); 
    10961313    outby = l_extreme - p - edit->start_col; 
    10971314    if (outby > 0) 
    10981315        edit_scroll_left (edit, outby); 
    10991316    p = edit->curs_row; 
    1100     outby = p - w->lines + 1 + b_extreme; 
     1317    outby = p - w->rect.lines + 1 + b_extreme; 
    11011318    if (outby > 0) 
    11021319        edit_scroll_downward (edit, outby); 
    11031320    outby = t_extreme - p; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    11051322        edit_scroll_upward (edit, outby); 
    11061323    edit_update_curs_row (edit); 
    11071324 
    1108     rect_resize (w, EDIT_TEXT_VERTICAL_OFFSET, 
     1325    rect_resize (&w->rect, EDIT_TEXT_VERTICAL_OFFSET, 
    11091326                 EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width); 
    11101327    if (!edit->fullscreen) 
    1111         rect_grow (w, 1, 1); 
     1328        rect_grow (&w->rect, 1, 1); 
    11121329} 
    11131330 
    11141331/* --------------------------------------------------------------------------------------------- */ 
  • 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..8db62e62c 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), 
     727                                0, edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1, TRUE), 
     728                                FALSE, 0); 
    726729 
    727730        if (x > line_len - 1) 
    728731        { 
    edit_update_cursor (WEdit * edit, const mouse_event_t * event) 
    737740    } 
    738741 
    739742    if (y > edit->curs_row) 
    740         edit_move_down (edit, y - edit->curs_row, FALSE); 
     743        edit_move_down (edit, y - edit->curs_row, FALSE, TRUE); 
    741744    else if (y < edit->curs_row) 
    742         edit_move_up (edit, edit->curs_row - y, FALSE); 
     745        edit_move_up (edit, edit->curs_row - y, FALSE, TRUE); 
    743746    else 
    744         edit_move_to_prev_col (edit, edit_buffer_get_current_bol (&edit->buffer)); 
     747        edit_move_to_prev_col (edit, edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, TRUE)); 
    745748 
    746749    if (event->msg == MSG_MOUSE_CLICK) 
    747750    { 
    edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da 
    951954 
    952955    case MSG_DRAW: 
    953956        e->force |= REDRAW_COMPLETELY; 
     957        WMSG (e, MSG_CURSOR, 7); 
    954958        edit_update_screen (e); 
    955959        return MSG_HANDLED; 
    956960 
    edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da 
    985989        { 
    986990            int y, x; 
    987991 
    988             y = (e->fullscreen ? 0 : 1) + EDIT_TEXT_VERTICAL_OFFSET + e->curs_row; 
     992            if (edit_options.soft_wrap) 
     993                edit_apply_curs_exceptions (e); 
     994 
     995            if (parm != 7) 
     996            { 
     997                e->prev_size = e->buffer.size; 
     998                e->prev_curs1 = e->buffer.curs1; 
     999                e->prev_curs_col = e->curs_col; 
     1000                e->prev_curs_row = e->curs_row; 
     1001            } 
    9891002            x = (e->fullscreen ? 0 : 1) + EDIT_TEXT_HORIZONTAL_OFFSET + 
    9901003                edit_options.line_state_width + e->curs_col + e->start_col + e->over_col; 
     1004            y = (e->fullscreen ? 0 : 1) + EDIT_TEXT_VERTICAL_OFFSET + e->curs_row; 
    9911005 
    9921006            widget_gotoyx (w, y, x); 
    9931007            return MSG_HANDLED; 
    edit_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) 
    11711185        break; 
    11721186 
    11731187    case MSG_MOUSE_SCROLL_UP: 
    1174         edit_move_up (edit, 2, TRUE); 
     1188        edit_move_up (edit, 2, TRUE, FALSE); 
    11751189        edit_total_update (edit); 
    11761190        break; 
    11771191 
    11781192    case MSG_MOUSE_SCROLL_DOWN: 
    1179         edit_move_down (edit, 2, TRUE); 
     1193        edit_move_down (edit, 2, TRUE, FALSE); 
    11801194        edit_total_update (edit); 
    11811195        break; 
    11821196 
    edit_add_window (WDialog * h, const WRect * r, const vfs_path_t * f, long fline) 
    13871401 
    13881402    group_add_widget_autopos (GROUP (h), w, WPOS_KEEP_ALL, NULL); 
    13891403    edit_set_buttonbar (edit, buttonbar_find (h)); 
     1404    edit_set_end_column (edit); 
    13901405    widget_draw (WIDGET (h)); 
    13911406 
    13921407    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..0d6ded653 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, 
     139                                            FALSE); 
    139140} 
    140141 
    141142/* --------------------------------------------------------------------------------------------- */ 
    end_paragraph (WEdit * edit, gboolean force) 
    161162                                edit_buffer_get_forward_offset (&edit->buffer, 
    162163                                                                edit_buffer_get_current_bol 
    163164                                                                (&edit->buffer), 
    164                                                                 i - edit->buffer.curs_line, 0)); 
     165                                                                i - edit->buffer.curs_line, 0, 
     166                                                                FALSE), FALSE); 
    165167} 
    166168 
    167169/* --------------------------------------------------------------------------------------------- */ 
    edit_indent_width (const WEdit * edit, off_t p) 
    377379           && q < edit->buffer.size - 1) 
    378380        q++; 
    379381    /* count the number of columns of indentation */ 
    380     return (long) edit_move_forward3 (edit, p, 0, q); 
     382    return (long) edit_move_forward3 (edit, p, 0, q, FALSE, FALSE); 
    381383} 
    382384 
    383385/* --------------------------------------------------------------------------------------------- */ 
  • src/keymap.c

    diff --git a/src/keymap.c b/src/keymap.c
    index 3f6cce420..2d95cc2d7 100644
    a b static const global_keymap_ini_t default_editor_keymap[] = { 
    472472    {"MacroStartStopRecord", "ctrl-r"}, 
    473473    {"MacroExecute", "ctrl-a"}, 
    474474    {"ShowNumbers", "alt-n"}, 
     475    {"SoftFolds", "alt-w"}, 
    475476    {"ShowTabTws", "alt-underline"}, 
    476477    {"SyntaxOnOff", "ctrl-s"}, 
    477478    {"Find", "alt-enter"}, 
  • 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};