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

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

An update that removes the inline declaration assignments like: int q=Q()

  • lib/keybind.c

    From 9400f7bf583d0c67e46ce448dcb9f0e197ee88ec 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        | 530 ++++++++++++++++++++++++++++-------
     src/editor/edit.h        |   5 +
     src/editor/editbuffer.c  | 160 +++++++++--
     src/editor/editbuffer.h  |  23 +-
     src/editor/editcmd.c     |  49 ++--
     src/editor/editdraw.c    | 589 +++++++++++++++++++++++++++------------
     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, 1095 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..b6217f76e 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; 
     918    bol = edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1 - edit->flag, screen_lines); 
     919    screen_lines &= edit_options.soft_wrap; 
     920    edit->flag2 = TRUE; 
     921    edit->flag = FALSE; 
     922    edit_cursor_move (edit, bol - edit->buffer.curs1); 
    878923    edit->search_start = edit->buffer.curs1; 
    879924    edit->prev_col = edit_get_col (edit); 
    880925    edit->over_col = 0; 
    edit_cursor_to_bol (WEdit * edit) 
    883928/* --------------------------------------------------------------------------------------------- */ 
    884929/** goto end of line */ 
    885930 
    886 static void 
    887 edit_cursor_to_eol (WEdit * edit) 
     931void 
     932edit_cursor_to_eol (WEdit * edit, gboolean screen_lines) 
    888933{ 
    889     edit_cursor_move (edit, edit_buffer_get_current_eol (&edit->buffer) - edit->buffer.curs1); 
     934    off_t eol; 
     935    screen_lines &= edit_options.soft_wrap; 
     936    if (edit->flag) 
     937        return; 
     938    edit->flag2 = 0; 
     939 
     940    eol = edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1, screen_lines); 
     941 
     942    edit_cursor_move (edit, eol - edit->buffer.curs1); 
    890943    edit->search_start = edit->buffer.curs1; 
    891944    edit->prev_col = edit_get_col (edit); 
    892945    edit->over_col = 0; 
    edit_left_char_move_cmd (WEdit * edit) 
    10681121*/ 
    10691122 
    10701123static void 
    1071 edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction) 
     1124edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean direction, 
     1125                  gboolean screen_lines) 
    10721126{ 
    10731127    long p; 
    1074     long l = direction ? edit->buffer.curs_line : edit->buffer.lines - edit->buffer.curs_line; 
     1128    long l, cnt_; 
     1129    off_t curs1 = edit->buffer.curs1; 
     1130    off_t boln; 
     1131    int col, real_col, end_col; 
     1132    int offset, offset2; 
    10751133 
     1134    boln = edit_buffer_get_bol (&edit->buffer, curs1, FALSE); 
     1135    screen_lines &= edit_options.soft_wrap; 
     1136    if (do_scroll) 
     1137        screen_lines = FALSE; 
     1138    if (direction) 
     1139    { 
     1140        l = edit_buffer_count_lines (&edit->buffer, 0, curs1, screen_lines); 
     1141        if (l == 0) 
     1142            l++; 
     1143        p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1144        /* Count possible only "touched"/started screen line */ 
     1145        cnt_ = (p % edit->end_col == 0) ? 1 : 0; 
     1146        l += cnt_ - 1; 
     1147    } 
     1148    else 
     1149    { 
     1150        l = edit->buffer.lines - edit->buffer.curs_line; 
     1151        if (screen_lines && l < lines) 
     1152        { 
     1153            GPtrArray *page_line_data = edit->page_line_data; 
     1154            if (edit->page_line_data == NULL) 
     1155                page_line_data = edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     1156            g_ptr_array_set_size (edit->page_line_data, LINES); 
     1157            cnt_ = sum_plines_to_row_full (page_line_data, soft_last_row + 1, FALSE); 
     1158            l += cnt_; 
     1159            cnt_ = sum_plines_to_row_full (page_line_data, edit->array_row, FALSE); 
     1160            l -= 1 + cnt_; 
     1161            p = edit_move_forward3 (edit, boln, 0, curs1, FALSE, 0); 
     1162            cnt_ = p / edit->end_col - ((p % edit->end_col == 0) ? 1 : 0); 
     1163            l -= cnt_; 
     1164        } 
     1165    } 
    10761166    if (lines > l) 
    10771167        lines = l; 
    10781168 
    edit_move_updown (WEdit * edit, long lines, gboolean do_scroll, gboolean directi 
    10881178        else 
    10891179            edit_scroll_downward (edit, lines); 
    10901180    } 
    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); 
     1181    p = edit_get_cursor_offset (edit); 
     1182    edit_update_curs_col (edit); 
     1183    col = edit->curs_col; 
     1184    end_col = edit->end_col; 
     1185 
     1186    if ( /*m.right */ curs1 == edit->prev_curs1 + 1 && col == 0 && curs1 != boln && 
     1187        /*not flagged */ !edit->flag) 
     1188        real_col = end_col; 
     1189    else if ( /*m.left */ curs1 == edit->prev_curs1 - 1 && 
     1190             col == end_col - 1 && !edit->flag) 
     1191        real_col = end_col; 
     1192    else if (ABS (curs1 - edit->prev_curs1) != 1 && col == 0 && curs1 != boln && !edit->flag2) 
     1193        real_col = end_col; 
     1194    else 
     1195        real_col = col; 
     1196 
     1197    if (direction) 
     1198        p = edit_buffer_get_backward_offset (&edit->buffer, p, lines, screen_lines); 
     1199    else 
     1200        p = edit_buffer_get_forward_offset (&edit->buffer, p, lines, 0, screen_lines); 
     1201 
     1202    offset = edit_move_forward3 (edit, p, col, 0, FALSE, 0); 
     1203    offset2 = edit_move_forward3 (edit, p, real_col % end_col, 0, FALSE, 0); 
     1204    if (real_col == end_col && offset - 1 > 0 
     1205        && edit_buffer_get_byte_ex (&edit->buffer, offset - 1) == '\n' 
     1206        && edit_buffer_get_byte_ex (&edit->buffer, offset) != '\n') 
     1207        offset2 = offset - 1; 
     1208    edit_cursor_move (edit, offset2 - curs1); 
    10961209 
    10971210#ifdef HAVE_CHARSET 
    10981211    /* search start of current multibyte char (like CJK) */ 
    1099     if (edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
     1212    if (0 && edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size 
    11001213        && edit_buffer_get_current_byte (&edit->buffer) >= 256) 
    11011214    { 
    11021215        edit_right_char_move_cmd (edit); 
    static void 
    11581271edit_do_undo (WEdit * edit) 
    11591272{ 
    11601273    long ac; 
    1161     long count = 0; 
    11621274 
    11631275    edit->undo_stack_disable = 1;       /* don't record undo's onto undo stack! */ 
    11641276    edit->over_col = 0; 
    edit_do_undo (WEdit * edit) 
    12001312        { 
    12011313            edit->mark1 = ac - MARK_1; 
    12021314            edit->column1 = 
    1203                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1204                                            0, edit->mark1); 
     1315                (long) edit_move_forward3 (edit, 
     1316                                           edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1317                                           0, edit->mark1, FALSE, 0); 
    12051318        } 
    12061319        if (ac >= MARK_2 - 2 && ac < MARK_CURS - 2) 
    12071320        { 
    12081321            edit->mark2 = ac - MARK_2; 
    12091322            edit->column2 = 
    1210                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1211                                            0, edit->mark2); 
     1323                (long) edit_move_forward3 (edit, 
     1324                                           edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1325                                           0, edit->mark2, FALSE, 0); 
    12121326        } 
    12131327        else if (ac >= MARK_CURS - 2 && ac < KEY_PRESS) 
    12141328        { 
    12151329            edit->end_mark_curs = ac - MARK_CURS; 
    12161330        } 
    1217         if (count++) 
    1218             edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ 
     1331        edit->force |= REDRAW_PAGE; 
    12191332    } 
    12201333 
    12211334    if (edit->start_display > ac - KEY_PRESS) 
    12221335    { 
    12231336        edit->start_line -= 
    1224             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1337            edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) - 1; 
    12251338        edit->force |= REDRAW_PAGE; 
    12261339    } 
    12271340    else if (edit->start_display < ac - KEY_PRESS) 
    12281341    { 
    12291342        edit->start_line += 
    1230             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1343            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) - 1; 
    12311344        edit->force |= REDRAW_PAGE; 
    12321345    } 
    12331346    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    static void 
    12431356edit_do_redo (WEdit * edit) 
    12441357{ 
    12451358    long ac; 
    1246     long count = 0; 
    12471359 
    12481360    if (edit->redo_stack_reset) 
    12491361        return; 
    edit_do_redo (WEdit * edit) 
    12851397        { 
    12861398            edit->mark1 = ac - MARK_1; 
    12871399            edit->column1 = 
    1288                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark1), 
    1289                                            0, edit->mark1); 
     1400                (long) edit_move_forward3 (edit, 
     1401                                           edit_buffer_get_bol (&edit->buffer, edit->mark1, TRUE), 
     1402                                           0, edit->mark1, FALSE, 0); 
    12901403        } 
    12911404        else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) 
    12921405        { 
    12931406            edit->mark2 = ac - MARK_2; 
    12941407            edit->column2 = 
    1295                 (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, edit->mark2), 
    1296                                            0, edit->mark2); 
     1408                (long) edit_move_forward3 (edit, 
     1409                                           edit_buffer_get_bol (&edit->buffer, edit->mark2, TRUE), 
     1410                                           0, edit->mark2, FALSE, 0); 
    12971411        } 
    1298         /* more than one pop usually means something big */ 
    1299         if (count++) 
    1300             edit->force |= REDRAW_PAGE; 
     1412        edit->force |= REDRAW_PAGE; 
    13011413    } 
    13021414 
    13031415    if (edit->start_display > ac - KEY_PRESS) 
    13041416    { 
    13051417        edit->start_line -= 
    1306             edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display); 
     1418            edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display, FALSE) - 1; 
    13071419        edit->force |= REDRAW_PAGE; 
    13081420    } 
    13091421    else if (edit->start_display < ac - KEY_PRESS) 
    13101422    { 
    13111423        edit->start_line += 
    1312             edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS); 
     1424            edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS, FALSE) - 1; 
    13131425        edit->force |= REDRAW_PAGE; 
    13141426    } 
    13151427    edit->start_display = ac - KEY_PRESS;       /* see push and pop above */ 
    edit_auto_indent (WEdit * edit) 
    14041516 
    14051517    p = edit->buffer.curs1; 
    14061518    /* use the previous line as a template */ 
    1407     p = edit_buffer_get_backward_offset (&edit->buffer, p, 1); 
     1519    p = edit_buffer_get_backward_offset (&edit->buffer, p, 1, FALSE); 
    14081520    /* copy the leading whitespace of the line */ 
    14091521    while (TRUE) 
    14101522    {                           /* no range check - the line _is_ \n-terminated */ 
    edit_move_block_to_right (WEdit * edit) 
    16041716    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16051717        return; 
    16061718 
    1607     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1608     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1719    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1720    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16091721 
    16101722    do 
    16111723    { 
    edit_move_block_to_right (WEdit * edit) 
    16171729            else 
    16181730                edit_insert (edit, '\t'); 
    16191731            edit_cursor_move (edit, 
    1620                               edit_buffer_get_bol (&edit->buffer, cur_bol) - edit->buffer.curs1); 
     1732                              edit_buffer_get_bol (&edit->buffer, cur_bol, 
     1733                                                   FALSE) - edit->buffer.curs1); 
    16211734        } 
    16221735 
    16231736        if (cur_bol == 0) 
    16241737            break; 
    16251738 
    1626         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1739        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16271740    } 
    16281741    while (cur_bol >= start_bol); 
    16291742 
    edit_move_block_to_left (WEdit * edit) 
    16411754    if (!eval_marks (edit, &start_mark, &end_mark)) 
    16421755        return; 
    16431756 
    1644     start_bol = edit_buffer_get_bol (&edit->buffer, start_mark); 
    1645     cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1); 
     1757    start_bol = edit_buffer_get_bol (&edit->buffer, start_mark, FALSE); 
     1758    cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1, FALSE); 
    16461759 
    16471760    do 
    16481761    { 
    edit_move_block_to_left (WEdit * edit) 
    16711784        if (cur_bol == 0) 
    16721785            break; 
    16731786 
    1674         cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1); 
     1787        cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1, FALSE); 
    16751788    } 
    16761789    while (cur_bol >= start_bol); 
    16771790 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17481861                    } 
    17491862                } 
    17501863 
    1751                 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1); 
     1864                edit_cursor_move (edit, 
     1865                                  edit_move_forward3 (edit, p, col, 0, FALSE, 
     1866                                                      0) - edit->buffer.curs1); 
    17521867 
    17531868                for (l = col - edit_get_col (edit); l >= space_width; l -= space_width) 
    17541869                    edit_insert (edit, ' '); 
    edit_insert_column_from_file (WEdit * edit, int file, off_t * start_pos, off_t * 
    17691884/*** public functions ****************************************************************************/ 
    17701885/* --------------------------------------------------------------------------------------------- */ 
    17711886 
     1887 
     1888void 
     1889edit_apply_curs_exceptions (WEdit * e) 
     1890{ 
     1891    off_t bol_m2, bol, boln, eol, curs1, prev_curs1; 
     1892    long size, cnt_m2, col, end_col, psize; 
     1893 
     1894    bol_m2 = edit_buffer_get_bol (&e->buffer, e->buffer.curs1 + (e->buffer.curs1 - 2 >= 0 ? -2 : 0), TRUE); 
     1895    bol = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, TRUE); 
     1896    boln = edit_buffer_get_bol (&e->buffer, e->buffer.curs1, FALSE); 
     1897    eol = edit_buffer_get_eol (&e->buffer, e->buffer.curs1, TRUE); 
     1898    curs1 = e->buffer.curs1; 
     1899    prev_curs1 = e->prev_curs1; 
     1900    size = e->buffer.size; 
     1901    psize = e->prev_size; 
     1902    cnt_m2 = edit_move_forward3 (e, bol_m2, 0, eol, FALSE, 0); 
     1903    col = edit_move_forward3 (e, bol, 0, curs1, FALSE, 0); 
     1904    end_col = e->end_col; 
     1905 
     1906    edit_update_curs_row (e); 
     1907 
     1908    /* First one exception is turned on – the one 
     1909     * that increases cursor y position when at 
     1910     * first column and not at bol */ 
     1911    if (curs1 != boln && curs1 == bol && col == 0) 
     1912    { 
     1913        e->curs_row++; 
     1914        if (cnt_m2 <= end_col - 2) 
     1915            e->flag2 = 1; 
     1916    } 
     1917 
     1918    if (curs1 == bol && /*m.left */ curs1 < prev_curs1) 
     1919        e->flag2 = TRUE; 
     1920 
     1921    /* Remaining apply only for screen-long lines */ 
     1922    if (cnt_m2 <= end_col - 2) 
     1923        return; 
     1924 
     1925    /* The second exception – when moving at 
     1926     * col == 0 from a lower curs1 position (right), 
     1927     * meaning that it should be an end_col position 
     1928     */ 
     1929    if ( /*m.right */ curs1 == prev_curs1 + 1 && col == 0 && curs1 != boln 
     1930        && /*not flagged */ !e->flag) 
     1931    { 
     1932        if (psize + 1 != size) 
     1933        { 
     1934            e->flag = TRUE; 
     1935            e->curs_col = e->end_col; 
     1936            e->curs_row--; 
     1937        } 
     1938        e->flag2 = 0; 
     1939    } 
     1940    else if ( /*m.right */ curs1 == prev_curs1 + 1 && col == 1 && curs1 >= boln + 1 && 
     1941             /* flagged */ e->flag) 
     1942    { 
     1943        if (psize + 1 != size) 
     1944        { 
     1945            edit_cursor_move (e, -1); 
     1946            e->flag = FALSE; 
     1947            e->curs_col = 0; 
     1948        } 
     1949        e->flag2 = 1; 
     1950    } 
     1951    else if ( /*m.left */ curs1 == prev_curs1 - 1 && 
     1952             col == end_col - 1 && !e->flag) 
     1953    { 
     1954        if (psize != size + 1) 
     1955        { 
     1956            edit_cursor_move (e, 1); 
     1957            e->flag = TRUE; 
     1958            e->curs_col = end_col; 
     1959        } 
     1960        e->flag2 = 0; 
     1961    } 
     1962    else if (ABS (curs1 - prev_curs1) != 1 && col == 0 && curs1 != boln && !e->flag2) 
     1963    { 
     1964        e->curs_col = end_col; 
     1965        e->curs_row--; 
     1966        e->flag = TRUE; 
     1967    } 
     1968    else 
     1969    { 
     1970        e->flag = 0; 
     1971    } 
     1972} 
     1973 
    17721974/** User edit menu, like user menu (F2) but only in editor. */ 
    17731975 
    17741976void 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21242326        edit_save_size (edit); 
    21252327    } 
    21262328 
     2329    if (edit->page_line_data == NULL) 
     2330        edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     2331    g_ptr_array_set_size (edit->page_line_data, LINES); 
     2332 
    21272333    edit->drag_state = MCEDIT_DRAG_NONE; 
    21282334 
    21292335    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 
    21532359    edit_set_codeset (edit); 
    21542360#endif 
    21552361 
     2362    edit_set_end_column (edit); 
    21562363    if (!edit_load_file (edit)) 
    21572364    { 
    21582365        /* edit_load_file already gives an error message */ 
    edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon 
    21792386        edit_move_to_line (edit, line - 1); 
    21802387    } 
    21812388 
     2389 
    21822390    edit_load_macro_cmd (edit); 
    21832391 
    21842392    return edit; 
    edit_push_redo_action (WEdit * edit, long c) 
    25082716        edit->redo_stack_bottom = edit->redo_stack_pointer = 0; 
    25092717} 
    25102718 
     2719 
     2720/* --------------------------------------------------------------------------------------------- */ 
     2721 
    25112722/* --------------------------------------------------------------------------------------------- */ 
    25122723/** 
    25132724   Basic low level single character buffer alterations and movements at the cursor. 
    edit_insert (WEdit * edit, int c) 
    25312742    /* now we must update some info on the file and check if a redraw is required */ 
    25322743    if (c == '\n') 
    25332744    { 
     2745        edit->buffer.line_begin_offset = edit->buffer.curs1; 
    25342746        book_mark_inc (edit, edit->buffer.curs_line); 
    25352747        edit->buffer.curs_line++; 
    25362748        edit->buffer.lines++; 
    edit_backspace (WEdit * edit, gboolean byte_delete) 
    27242936void 
    27252937edit_cursor_move (WEdit * edit, off_t increment) 
    27262938{ 
     2939    gboolean scroll = FALSE; 
     2940    off_t idx; 
    27272941    if (increment < 0) 
    27282942    { 
    2729         for (; increment < 0 && edit->buffer.curs1 != 0; increment++) 
     2943        for (idx = 0; idx > increment && edit->buffer.curs1 != 0; idx--) 
    27302944        { 
    27312945            int c; 
    27322946 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27372951            c = edit_buffer_backspace (&edit->buffer); 
    27382952            if (c == '\n') 
    27392953            { 
     2954                edit->buffer.line_begin_offset = 0; 
     2955                for (int i = edit->buffer.curs1 - 1; i > 0; i--) 
     2956                { 
     2957                    unsigned char ch = edit_buffer_get_byte (&edit->buffer, i); 
     2958                    if (ch == '\n') 
     2959                    { 
     2960                        edit->buffer.line_begin_offset = i + 1; 
     2961                        break; 
     2962                    } 
     2963                } 
    27402964                edit->buffer.curs_line--; 
    27412965                edit->force |= REDRAW_LINE_BELOW; 
     2966                if (edit->buffer.curs_line < edit->start_line) 
     2967                    scroll = TRUE; 
    27422968            } 
    27432969        } 
     2970        if (scroll) 
     2971        { 
     2972            edit_scroll_upward (edit, edit->start_line - edit->buffer.curs_line); 
     2973        } 
    27442974    } 
    27452975    else 
    27462976    { 
    2747         for (; increment > 0 && edit->buffer.curs2 != 0; increment--) 
     2977        for (idx = 0; idx < increment && edit->buffer.curs2 != 0; idx++) 
    27482978        { 
    27492979            int c; 
    27502980 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27552985            c = edit_buffer_delete (&edit->buffer); 
    27562986            if (c == '\n') 
    27572987            { 
     2988                edit->buffer.line_begin_offset = edit->buffer.curs1; 
    27582989                edit->buffer.curs_line++; 
     2990                if (edit->buffer.curs_line - edit->start_line >= soft_last_row) 
     2991                    scroll = TRUE; 
    27592992                edit->force |= REDRAW_LINE_ABOVE; 
    27602993            } 
    27612994        } 
     2995        if (scroll) 
     2996        { 
     2997            edit_scroll_downward (edit, 
     2998                                  (edit->buffer.curs_line - edit->start_line) - soft_last_row); 
     2999            edit->force |= REDRAW_PAGE; 
     3000        } 
    27623001    } 
    27633002} 
    27643003 
    edit_cursor_move (WEdit * edit, off_t increment) 
    27673006/* If upto is zero returns index of cols across from current. */ 
    27683007 
    27693008off_t 
    2770 edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
     3009edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto, gboolean as_bytes, 
     3010                    off_t col_limit) 
    27713011{ 
    27723012    off_t p, q; 
    2773     long col; 
     3013    long col, col_acc = 0, btes = 0, prev_len = 0; 
     3014    int char_length = 1; 
     3015    int utf_ch; 
    27743016 
    27753017    if (upto != 0) 
    27763018    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27783020        cols = -10; 
    27793021    } 
    27803022    else 
    2781         q = edit->buffer.size + 2; 
     3023        q = edit->buffer.size + 1; 
    27823024 
    27833025    for (col = 0, p = current; p < q; p++) 
    27843026    { 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    27973039#ifdef HAVE_CHARSET 
    27983040        if (edit->utf8) 
    27993041        { 
    2800             int utf_ch; 
    2801             int char_length = 1; 
    2802  
     3042            char_length = 1; 
    28033043            utf_ch = edit_buffer_get_utf (&edit->buffer, p, &char_length); 
     3044 
    28043045            if (mc_global.utf8_display) 
    28053046            { 
    28063047                if (char_length > 1) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28163057#endif 
    28173058 
    28183059        if (c == '\n') 
    2819             return (upto != 0 ? (off_t) col : p); 
    2820         if (c == '\t') 
    2821             col += TAB_SIZE - col % TAB_SIZE; 
     3060        { 
     3061            return (upto != 0 ? (off_t) (as_bytes ? btes : col - col_acc) : p); 
     3062        } 
     3063 
     3064#ifdef HAVE_CHARSET 
     3065        if (edit->utf8) 
     3066        { 
     3067            btes += prev_len <= 1 ? char_length : 0; 
     3068            prev_len = prev_len <= 1 ? char_length : prev_len - 1; 
     3069        } 
     3070        else 
     3071            btes += 1; 
     3072#else 
     3073        btes += 1; 
     3074#endif 
     3075 
     3076        /* Treat tab specially, as it needs to use 
     3077         * whole line, not only screen line */ 
     3078        if (c == '\t' || utf_ch == '\t') 
     3079        { 
     3080            off_t boln; 
     3081            off_t qq, ncols = 0, acc = 0; 
     3082            int len, ch; 
     3083            boln = edit_buffer_get_bol (&edit->buffer, p, FALSE); 
     3084            qq = boln; 
     3085            len = -1; 
     3086            for (; len && qq <= p; 
     3087                 (ch = edit_buffer_get_utf (&edit->buffer, qq, &len)), 
     3088                 qq += len, ncols += 
     3089                 (g_unichar_iswide (ch) > 0) + (ch == '\t' ? (TAB_SIZE - (ncols % TAB_SIZE)) : len > 
     3090                                                0)) 
     3091            { 
     3092                /* Still modulo the line length */ 
     3093                if ((ncols - acc) >= edit->end_col) 
     3094                    acc += edit->end_col; 
     3095            } 
     3096            /* Apply precisely calculated cols */ 
     3097            col = ncols; 
     3098            if (boln != current) 
     3099                col -= acc; 
     3100        } 
    28223101        else if ((c < 32 || c == 127) && (orig_c == c 
    28233102#ifdef HAVE_CHARSET 
    28243103                                          || (!mc_global.utf8_display && !edit->utf8) 
    edit_move_forward3 (const WEdit * edit, off_t current, long cols, off_t upto) 
    28293108            col += 2; 
    28303109        else 
    28313110            col++; 
     3111 
     3112        if (col_limit > 0) 
     3113        { 
     3114            btes = ((col - col_acc) >= col_limit) ? 0 : btes; 
     3115            col_acc += ((col - col_acc) >= col_limit) ? col_limit : 0; 
     3116        } 
    28323117    } 
    2833     return (off_t) col; 
     3118 
     3119    return (off_t) (as_bytes ? btes : col - col_acc); 
    28343120} 
    28353121 
    28363122/* --------------------------------------------------------------------------------------------- */ 
    edit_get_cursor_offset (const WEdit * edit) 
    28433129} 
    28443130 
    28453131/* --------------------------------------------------------------------------------------------- */ 
     3132 
    28463133/** returns the current column position of the cursor */ 
    28473134 
    28483135long 
    28493136edit_get_col (const WEdit * edit) 
    28503137{ 
    2851     return (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2852                                       edit->buffer.curs1); 
     3138    gboolean screen = edit_options.soft_wrap ? 1 : 0; 
     3139    off_t bol, col; 
     3140    bol = edit_buffer_get_bol (&edit->buffer, edit->buffer.curs1, screen); 
     3141    col  = (long) edit_move_forward3 (edit, bol, 0, edit->buffer.curs1, FALSE, 0); 
     3142    col -= -2 * edit->start_col; 
     3143    return col; 
    28533144} 
    28543145 
    28553146/* --------------------------------------------------------------------------------------------- */ 
    edit_get_col (const WEdit * edit) 
    28573148/* --------------------------------------------------------------------------------------------- */ 
    28583149 
    28593150void 
    2860 edit_update_curs_row (WEdit * edit) 
     3151edit_update_curs_row (WEdit * e) 
    28613152{ 
    2862     edit->curs_row = edit->buffer.curs_line - edit->start_line; 
     3153    /* Helper variables */ 
     3154    edit_buffer_t *buf = &e->buffer; 
     3155    off_t curs1; 
     3156 
     3157    /* The screen-line count ↔ the cursor row */ 
     3158    int lines; 
     3159    curs1 = edit_get_cursor_offset (e); 
     3160    lines = edit_buffer_count_lines (buf, e->start_display, curs1, TRUE); 
     3161    /* Screen-line count should be 0-based */ 
     3162    e->curs_row = lines > 0 ? lines - 1 : 0; 
     3163    /* Non screen-lines line count */ 
     3164    e->array_row = edit_buffer_count_lines (buf, e->start_display, curs1, FALSE); 
     3165    /* Make the line count 0-based */ 
     3166    e->array_row > 0 ? e->array_row-- : 0; 
    28633167} 
    28643168 
    28653169/* --------------------------------------------------------------------------------------------- */ 
    edit_update_curs_row (WEdit * edit) 
    28673171void 
    28683172edit_update_curs_col (WEdit * edit) 
    28693173{ 
    2870     edit->curs_col = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 
    2871                                                 0, edit->buffer.curs1); 
     3174    edit->curs_col = edit_get_col (edit); 
    28723175} 
    28733176 
    28743177/* --------------------------------------------------------------------------------------------- */ 
    edit_scroll_upward (WEdit * edit, long i) 
    28933196    { 
    28943197        edit->start_line -= i; 
    28953198        edit->start_display = 
    2896             edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i); 
     3199            edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i, FALSE); 
    28973200        edit->force |= REDRAW_PAGE; 
    28983201        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    28993202    } 
    edit_scroll_downward (WEdit * edit, long i) 
    29083211{ 
    29093212    long lines_below; 
    29103213 
    2911     lines_below = edit->buffer.lines - edit->start_line - (WIDGET (edit)->rect.lines - 1); 
     3214    lines_below = edit->buffer.lines - edit->start_line - (soft_last_row - 1); 
    29123215    if (lines_below > 0) 
    29133216    { 
    29143217        if (i > lines_below) 
    29153218            i = lines_below; 
    29163219        edit->start_line += i; 
    29173220        edit->start_display = 
    2918             edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0); 
     3221            edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0, FALSE); 
    29193222        edit->force |= REDRAW_PAGE; 
    29203223        edit->force &= (0xfff - REDRAW_CHAR_ONLY); 
    29213224    } 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29583261    long over = edit->over_col; 
    29593262 
    29603263    edit_cursor_move (edit, 
    2961                       edit_move_forward3 (edit, p, prev + edit->over_col, 0) - edit->buffer.curs1); 
     3264                      edit_move_forward3 (edit, p, prev + edit->over_col, 0, FALSE, 
     3265                                          0) - edit->buffer.curs1); 
    29623266 
    29633267    if (edit_options.cursor_beyond_eol) 
    29643268    { 
    29653269        long line_len; 
    29663270 
    29673271        line_len = (long) edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0, 
    2968                                               edit_buffer_get_current_eol (&edit->buffer)); 
     3272                                              edit_buffer_get_current_eol (&edit->buffer), FALSE, 
     3273                                              FALSE); 
    29693274        if (line_len < prev + edit->over_col) 
    29703275        { 
    29713276            edit->over_col = prev + over - line_len; 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29983303                p = edit_buffer_get_current_bol (&edit->buffer); 
    29993304                edit_cursor_move (edit, 
    30003305                                  edit_move_forward3 (edit, p, edit->curs_col, 
    3001                                                       0) - edit->buffer.curs1); 
     3306                                                      0, FALSE, FALSE) - edit->buffer.curs1); 
    30023307                if (!left_of_four_spaces (edit)) 
    30033308                    edit_cursor_move (edit, 
    3004                                       edit_move_forward3 (edit, p, q, 0) - edit->buffer.curs1); 
     3309                                      edit_move_forward3 (edit, p, q, 0, FALSE, 
     3310                                                          FALSE) - edit->buffer.curs1); 
    30053311            } 
    30063312        } 
    30073313    } 
    void 
    30293335edit_move_to_line (WEdit * e, long line) 
    30303336{ 
    30313337    if (line < e->buffer.curs_line) 
    3032         edit_move_up (e, e->buffer.curs_line - line, FALSE); 
     3338        edit_move_up (e, e->buffer.curs_line - line, FALSE, FALSE); 
    30333339    else 
    3034         edit_move_down (e, line - e->buffer.curs_line, FALSE); 
     3340        edit_move_down (e, line - e->buffer.curs_line, FALSE, FALSE); 
    30353341    edit_scroll_screen_over_cursor (e); 
    30363342} 
    30373343 
    edit_execute_key_command (WEdit * edit, long command, int char_for_insertion) 
    32603566void 
    32613567edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    32623568{ 
    3263     WRect *w = &WIDGET (edit)->rect; 
    3264  
    32653569    if (command == CK_WindowFullscreen) 
    32663570    { 
    32673571        edit_toggle_fullscreen (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    33533657    /* An ordinary key press */ 
    33543658    if (char_for_insertion >= 0) 
    33553659    { 
     3660        off_t prev_curs_col, col; 
     3661 
     3662        if (edit->curs_col == 0) 
     3663            edit->force |= REDRAW_AFTER_CURSOR; 
     3664        prev_curs_col = edit->curs_col; 
     3665 
    33563666        /* if non persistent selection and text selected */ 
    33573667        if (!edit_options.persistent_selections && edit->mark1 != edit->mark2) 
    33583668            edit_block_delete_cmd (edit); 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34083718            edit->force |= REDRAW_PAGE; 
    34093719        } 
    34103720        else 
     3721        { 
    34113722            check_and_wrap_line (edit); 
     3723            edit->force |= REDRAW_AFTER_CURSOR; 
     3724        } 
     3725        col = edit_get_col (edit); 
     3726        if (prev_curs_col == edit->buffer.end_col - 1 && col == 0) 
     3727            edit->force |= REDRAW_AFTER_CURSOR; 
    34123728        edit->found_len = 0; 
    34133729        edit->prev_col = edit_get_col (edit); 
    34143730        edit->search_start = edit->buffer.curs1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34673783    case CK_Right: 
    34683784    case CK_MarkLeft: 
    34693785    case CK_MarkRight: 
    3470         edit->force |= REDRAW_CHAR_ONLY; 
     3786        edit->force |= REDRAW_LINE; 
    34713787        break; 
    34723788    default: 
    34733789        break; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    34973813        } 
    34983814        else 
    34993815            edit_backspace (edit, FALSE); 
     3816 
     3817        edit->force |= REDRAW_AFTER_CURSOR; 
    35003818        break; 
    35013819    case CK_Delete: 
    35023820        /* if non persistent selection and text selected */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    35633881        MC_FALLTHROUGH; 
    35643882    case CK_PageUp: 
    35653883    case CK_MarkPageUp: 
    3566         edit_move_up (edit, w->lines - 1, TRUE); 
     3884        edit_move_up (edit, soft_last_row, TRUE, FALSE); 
    35673885        break; 
    35683886    case CK_MarkColumnPageDown: 
    35693887        edit->column_highlight = 1; 
    35703888        MC_FALLTHROUGH; 
    35713889    case CK_PageDown: 
    35723890    case CK_MarkPageDown: 
    3573         edit_move_down (edit, w->lines - 1, TRUE); 
     3891        edit_move_down (edit, soft_last_row, TRUE, FALSE); 
    35743892        break; 
    35753893    case CK_MarkColumnLeft: 
    35763894        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36263944        MC_FALLTHROUGH; 
    36273945    case CK_Up: 
    36283946    case CK_MarkUp: 
    3629         edit_move_up (edit, 1, FALSE); 
     3947        edit_move_up (edit, 1, FALSE, TRUE); 
    36303948        break; 
    36313949    case CK_MarkColumnDown: 
    36323950        edit->column_highlight = 1; 
    36333951        MC_FALLTHROUGH; 
    36343952    case CK_Down: 
    36353953    case CK_MarkDown: 
    3636         edit_move_down (edit, 1, FALSE); 
     3954        edit_move_down (edit, 1, FALSE, TRUE); 
    36373955        break; 
    36383956    case CK_MarkColumnParagraphUp: 
    36393957        edit->column_highlight = 1; 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    36543972        MC_FALLTHROUGH; 
    36553973    case CK_ScrollUp: 
    36563974    case CK_MarkScrollUp: 
    3657         edit_move_up (edit, 1, TRUE); 
     3975        edit_move_up (edit, 1, TRUE, TRUE); 
    36583976        break; 
    36593977    case CK_MarkColumnScrollDown: 
    36603978        edit->column_highlight = 1; 
    36613979        MC_FALLTHROUGH; 
    36623980    case CK_ScrollDown: 
    36633981    case CK_MarkScrollDown: 
    3664         edit_move_down (edit, 1, TRUE); 
     3982        edit_move_down (edit, 1, TRUE, TRUE); 
    36653983        break; 
    36663984    case CK_Home: 
    36673985    case CK_MarkToHome: 
    3668         edit_cursor_to_bol (edit); 
     3986        edit_cursor_to_bol (edit, TRUE); 
    36693987        break; 
    36703988    case CK_End: 
    36713989    case CK_MarkToEnd: 
    3672         edit_cursor_to_eol (edit); 
     3990        edit_cursor_to_eol (edit, TRUE); 
    36733991        break; 
    36743992    case CK_Tab: 
    36753993        /* if text marked shift block */ 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37574075            if (p->next != NULL) 
    37584076            { 
    37594077                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); 
     4078                if (p->line >= edit->start_line + soft_last_row + 1 || p->line < edit->start_line) 
     4079                    edit_move_display (edit, p->line - (soft_last_row + 1) / 2); 
    37624080                edit_move_to_line (edit, p->line); 
    37634081            } 
    37644082        } 
    edit_execute_cmd (WEdit * edit, long command, int char_for_insertion) 
    37744092                    p = p->prev; 
    37754093            if (p->line >= 0) 
    37764094            { 
    3777                 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line) 
    3778                     edit_move_display (edit, p->line - w->lines / 2); 
     4095                if (p->line >= edit->start_line + soft_last_row + 1 || p->line < edit->start_line) 
     4096                    edit_move_display (edit, p->line - (soft_last_row + 1) / 2); 
    37794097                edit_move_to_line (edit, p->line); 
    37804098            } 
    37814099        } 
    37824100        break; 
    37834101 
     4102    case CK_SoftFolds: 
     4103        edit_options.soft_wrap = !edit_options.soft_wrap; 
     4104        edit->start_col *= !edit_options.soft_wrap; 
     4105        edit->force |= REDRAW_COMPLETELY; 
     4106        break; 
     4107 
    37844108    case CK_Top: 
    37854109    case CK_MarkToFileBegin: 
    37864110        edit_move_to_top (edit); 
    edit_stack_free (void) 
    40504374/** move i lines */ 
    40514375 
    40524376void 
    4053 edit_move_up (WEdit * edit, long i, gboolean do_scroll) 
     4377edit_move_up (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40544378{ 
    4055     edit_move_updown (edit, i, do_scroll, TRUE); 
     4379    screen_lines &= edit_options.soft_wrap; 
     4380    edit_move_updown (edit, i, do_scroll, TRUE, screen_lines); 
    40564381} 
    40574382 
    40584383/* --------------------------------------------------------------------------------------------- */ 
    40594384/** move i lines */ 
    40604385 
    40614386void 
    4062 edit_move_down (WEdit * edit, long i, gboolean do_scroll) 
     4387edit_move_down (WEdit * edit, long i, gboolean do_scroll, gboolean screen_lines) 
    40634388{ 
    4064     edit_move_updown (edit, i, do_scroll, FALSE); 
     4389    screen_lines &= edit_options.soft_wrap; 
     4390    edit_move_updown (edit, i, do_scroll, FALSE, screen_lines); 
    40654391} 
    40664392 
    40674393/* --------------------------------------------------------------------------------------------- */ 
  • 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..458072bc9 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; 
     149        byte = edit_buffer_get_byte (buf, first); 
     150        if (byte == '\t' || (all_kinds && byte == '\v')) 
     151            cnt++; 
     152        ++first; 
     153    } 
     154    return cnt; 
     155} 
     156 
    139157/* --------------------------------------------------------------------------------------------- */ 
    140158/** 
    141159 * Initialize editor buffers. 
    edit_buffer_get_byte_ptr (const edit_buffer_t * buf, off_t byte_index) 
    144162 */ 
    145163 
    146164void 
    147 edit_buffer_init (edit_buffer_t * buf, off_t size) 
     165edit_buffer_init (WEdit * e, edit_buffer_t * buf, off_t size) 
    148166{ 
    149167    buf->b1 = g_ptr_array_new_full (32, g_free); 
    150168    buf->b2 = g_ptr_array_new_full (32, g_free); 
     169    buf->edit_widget = e; 
     170    buf->end_col = 73; 
    151171 
    152172    buf->curs1 = 0; 
    153173    buf->curs2 = 0; 
    void 
    167187edit_buffer_clean (edit_buffer_t * buf) 
    168188{ 
    169189    if (buf->b1 != NULL) 
     190    { 
    170191        g_ptr_array_free (buf->b1, TRUE); 
     192    } 
    171193 
    172194    if (buf->b2 != NULL) 
     195    { 
    173196        g_ptr_array_free (buf->b2, TRUE); 
     197    } 
    174198} 
    175199 
    176200/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_clean (edit_buffer_t * buf) 
    182206  * 
    183207  * @return '\n' if byte_index is negative or larger than file size; byte at byte_index otherwise. 
    184208  */ 
     209int 
     210edit_buffer_get_byte_ex (const edit_buffer_t * buf, off_t byte_index) 
     211{ 
     212    char *p; 
     213 
     214    p = edit_buffer_get_byte_ptr (buf, byte_index); 
     215 
     216    return (p != NULL) ? *(unsigned char *) p : -1; 
     217} 
    185218 
    186219int 
    187220edit_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 
    323356 */ 
    324357 
    325358long 
    326 edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
     359edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last, gboolean screen_lines) 
    327360{ 
    328     long lines = 0; 
     361    long lines = 0, prev_eol = 0, eol; 
     362    screen_lines &= edit_options.soft_wrap; 
    329363 
    330364    first = MAX (first, 0); 
    331365    last = MIN (last, buf->size); 
    332366 
    333     while (first < last) 
    334         if (edit_buffer_get_byte (buf, first++) == '\n') 
    335             lines++; 
     367    if (first == last) 
     368        return 0; 
    336369 
     370    while (first <= last) 
     371    { 
     372        eol = edit_buffer_get_eol (buf, first, screen_lines); 
     373        /* Advance in buffer */ 
     374        if (edit_buffer_get_byte_ex (buf, eol) == '\n' || ~screen_lines || eol == prev_eol) 
     375            first = eol + 1; 
     376        else 
     377            first = eol; 
     378        prev_eol = eol; 
     379        /* Count line */ 
     380        lines++; 
     381    } 
    337382    return lines; 
    338383} 
    339384 
    edit_buffer_count_lines (const edit_buffer_t * buf, off_t first, off_t last) 
    348393 */ 
    349394 
    350395off_t 
    351 edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
     396edit_buffer_get_bol (const edit_buffer_t * buf, off_t current_bol, gboolean screen_lines) 
    352397{ 
    353     if (current <= 0) 
     398    off_t current_save = current_bol; 
     399    off_t current_eol = current_bol; 
     400    screen_lines &= edit_options.soft_wrap; 
     401    if (current_bol <= 0) 
     402    { 
    354403        return 0; 
    355  
    356     for (; edit_buffer_get_byte (buf, current - 1) != '\n'; current--) 
     404    } 
     405    for (; current_bol > 0 && edit_buffer_get_byte (buf, current_bol - 1) != '\n'; current_bol -= 1) 
    357406        ; 
    358407 
    359     return current; 
     408    for (; 
     409         (edit_buffer_get_byte (buf, current_eol) != '\n' || current_save == current_eol) 
     410         && current_eol < buf->size; current_eol += 1); 
     411 
     412 
     413    if (screen_lines) 
     414    { 
     415        off_t pos = current_save - 
     416            edit_move_forward3 (buf->edit_widget, current_bol, 0, current_save, TRUE, buf->end_col); 
     417        return pos; 
     418    } 
     419    return current_bol; 
    360420} 
    361421 
    362422/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_get_bol (const edit_buffer_t * buf, off_t current) 
    370430 */ 
    371431 
    372432off_t 
    373 edit_buffer_get_eol (const edit_buffer_t * buf, off_t current) 
     433edit_buffer_get_eol (const edit_buffer_t * buf, off_t current_eol, gboolean screen_lines) 
    374434{ 
    375     if (current >= buf->size) 
     435    off_t current_save = current_eol; 
     436    off_t current_bol = current_eol; 
     437    off_t q; 
     438    screen_lines &= edit_options.soft_wrap; 
     439    if (current_eol >= buf->size) 
    376440        return buf->size; 
    377441 
    378     for (; edit_buffer_get_byte (buf, current) != '\n'; current++) 
     442    for (; current_bol > 0 && edit_buffer_get_byte (buf, current_bol - 1) != '\n'; current_bol--) 
    379443        ; 
    380444 
    381     return current; 
     445    if (screen_lines) 
     446    { 
     447        off_t prev_eol = 0; 
     448        for (; 
     449             (edit_buffer_get_byte_ex (buf, current_eol) != '\n') && 
     450             current_eol <= buf->size && 
     451             (current_eol == current_save 
     452              || 
     453              ((q = 
     454                edit_move_forward3 (buf->edit_widget, current_bol, 0, current_eol, FALSE, 
     455                                    0) % buf->end_col) != 0)); 
     456             current_eol = 
     457             edit_move_forward3 (buf->edit_widget, current_eol, 1, 0, FALSE, 0), current_eol += 
     458             prev_eol == current_eol ? 1 : 0, prev_eol = current_eol) 
     459            ; 
     460        if (current_eol > buf->size && edit_buffer_get_byte_ex (buf, current_eol) != '\n') 
     461            current_eol = buf->size; 
     462    } 
     463    else 
     464        for (; (edit_buffer_get_byte (buf, current_eol) != '\n') && current_eol < buf->size; 
     465             current_eol++) 
     466            ; 
     467 
     468 
     469    return current_eol; 
    382470} 
    383471 
    384472/* --------------------------------------------------------------------------------------------- */ 
    edit_buffer_backspace (edit_buffer_t * buf) 
    638726 */ 
    639727 
    640728off_t 
    641 edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto) 
     729edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long lines, off_t upto, 
     730                                gboolean screen_lines) 
    642731{ 
     732    screen_lines &= edit_options.soft_wrap; 
    643733    if (upto != 0) 
    644         return (off_t) edit_buffer_count_lines (buf, current, upto); 
     734        return (off_t) edit_buffer_count_lines (buf, current, upto, screen_lines); 
    645735 
    646736    lines = MAX (lines, 0); 
    647737 
     738    if (lines > 0) 
     739    { 
     740        edit_update_curs_col (buf->edit_widget); 
     741        if (buf->edit_widget->curs_col == buf->end_col) 
     742            lines--; 
     743    } 
     744 
    648745    while (lines-- != 0) 
    649746    { 
    650         long next; 
     747        off_t next; 
     748        int byte; 
    651749 
    652         next = edit_buffer_get_eol (buf, current) + 1; 
    653         if (next > buf->size) 
     750        next = edit_buffer_get_eol (buf, current, screen_lines); 
     751        byte = edit_buffer_get_byte_ex (buf, next); 
     752 
     753        if (byte == '\n' || !screen_lines) 
     754            next++; 
     755        if (next > buf->size + 1) 
    654756            break; 
    655757        current = next; 
    656758    } 
    657  
    658759    return current; 
    659760} 
    660761 
    edit_buffer_get_forward_offset (const edit_buffer_t * buf, off_t current, long l 
    670771 */ 
    671772 
    672773off_t 
    673 edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines) 
     774edit_buffer_get_backward_offset (const edit_buffer_t * buf, off_t current, long lines, 
     775                                 gboolean screen_lines) 
    674776{ 
     777    screen_lines &= edit_options.soft_wrap; 
    675778    lines = MAX (lines, 0); 
    676     current = edit_buffer_get_bol (buf, current); 
     779    current = edit_buffer_get_bol (buf, current, screen_lines); 
    677780 
    678781    while (lines-- != 0 && current != 0) 
    679         current = edit_buffer_get_bol (buf, current - 1); 
     782    { 
     783        current = edit_buffer_get_bol (buf, current - 1, screen_lines); 
     784        if (screen_lines && current > 0 && 
     785            edit_buffer_get_byte_ex (buf, current) == '\n' && 
     786            edit_buffer_get_byte_ex (buf, current - 1) != '\n') 
     787            lines++; 
     788    } 
     789 
     790    if (current > 0 && screen_lines && edit_buffer_get_byte_ex (buf, current - 1) != '\n') 
     791        current = edit_buffer_get_eol (buf, current - 1, screen_lines); 
    680792 
    681793    return current; 
    682794} 
  • 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..4ba9cadbe 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    off_t b; 
     127 
     128    base_line = edit_buffer_count_lines (&edit->buffer, 0, edit->start_display, FALSE); 
     129    b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, FALSE); 
     130 
     131    for (row = start_row; row < end_row; row++) 
     132    { 
     133        int pplines_add = 0; 
     134        if (!edit_options.soft_wrap) 
     135            pplines_add = -prev_plines; 
     136        line_data = edit_prepare_this_line (edit, b, row, row + prev_plines + pplines_add, 
     137                                            start_column, end_column, -1, FALSE, base_line); 
     138        line_data->plines_count += pplines_add; 
     139        prev_ldata = (MCELineData *) page_line_data->pdata[row]; 
     140        if (prev_ldata == NULL || prev_ldata->plines_count != line_data->plines_count) 
     141            /* Return true if any plines changed */ 
     142            ret = TRUE; 
     143        page_line_data->pdata[row] = line_data; 
     144        prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     145        b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     146    } 
     147    return ret; 
     148} 
     149 
     150int 
     151sum_plines_to_row_full (GPtrArray * page_line_data, int row, gboolean count_only_second_etc_lines) 
     152{ 
     153    int prev_plines = 0; 
     154 
     155    if (!edit_options.soft_wrap) 
     156        return prev_plines; 
     157 
     158    for (int idx = 0; idx < row && idx < (long) page_line_data->len; idx++) 
     159    { 
     160        MCELineData *line_data = page_line_data->pdata[idx]; 
     161        if (line_data != NULL) 
     162            prev_plines += 
     163                (line_data->plines_count > 
     164                 0) ? line_data->plines_count - (count_only_second_etc_lines ? 1 : 0) : 0; 
     165        else 
     166            prev_plines += count_only_second_etc_lines ? 0 : 1; 
     167    } 
     168    return prev_plines; 
     169} 
     170 
    91171static inline void 
    92172printwstr (const char *s, int len) 
    93173{ 
    static inline void 
    101181status_string (WEdit * edit, char *s, int w) 
    102182{ 
    103183    char byte_str[16]; 
     184    off_t bol; 
     185    off_t col; 
    104186 
    105187    /* 
    106188     * If we are at the end of file, print <EOF>, 
    status_string (WEdit * edit, char *s, int w) 
    136218    } 
    137219 
    138220    /* The field lengths just prevent the status line from shortening too much */ 
     221    bol = edit_buffer_get_current_bol (&edit->buffer); 
     222    col = edit_move_forward3 (edit, bol, 0, 
     223                                    edit->buffer.curs1, FALSE, 0); 
     224 
    139225    if (edit_options.simple_statusbar) 
    140226        g_snprintf (s, w, 
    141227                    "%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s", 
    status_string (WEdit * edit, char *s, int w) 
    143229                    edit->modified ? 'M' : '-', 
    144230                    macro_index < 0 ? '-' : 'R', 
    145231                    edit->overwrite == 0 ? '-' : 'O', 
    146                     edit->curs_col + edit->over_col, 
     232                    col, 
    147233                    edit->buffer.curs_line + 1, 
    148234                    edit->buffer.lines + 1, (long) edit->buffer.curs1, (long) edit->buffer.size, 
    149235                    byte_str, 
    status_string (WEdit * edit, char *s, int w) 
    158244                    edit->modified ? 'M' : '-', 
    159245                    macro_index < 0 ? '-' : 'R', 
    160246                    edit->overwrite == 0 ? '-' : 'O', 
    161                     edit->curs_col + edit->over_col, 
     247                    col, 
    162248                    edit->start_line + 1, 
    163249                    edit->curs_row, 
    164250                    edit->buffer.curs_line + 1, 
    edit_status_fullscreen (WEdit * edit, int color) 
    185271    const int w = h->rect.cols; 
    186272    const int gap = 3;          /* between the filename and the status */ 
    187273    const int right_gap = 5;    /* at the right end of the screen */ 
    188     const int preferred_fname_len = 16; 
     274    const int preferred_fname_len = 14; 
    189275    char *status; 
    190276    size_t status_size; 
    191277    int status_len; 
    edit_draw_window_icons (const WEdit * edit, int color) 
    377463/* --------------------------------------------------------------------------------------------- */ 
    378464 
    379465static 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) 
     466print_to_widget (WEdit * edit, MCELineData * line_data) 
    382467{ 
     468    int linesize = line_data->size; 
     469    long row = edit_options.soft_wrap ? line_data->row : line_data->scr_index; 
     470    int q = line_data->q; 
     471    int start_col_real = line_data->start_col_real; 
     472    long ec = line_data->ec, idx; 
     473    line *line_ = line_data->ldata; 
     474    char *status = line_data->status; 
     475    int bookmarked = line_data->bookmarked; 
     476 
    383477    Widget *w = WIDGET (edit); 
    384     line_s *p; 
     478    line *p; 
    385479    int x, x1, y, cols_to_skip; 
    386     int i; 
    387     int wrap_start; 
     480    int i, yp; 
     481    int f_start; 
    388482    int len; 
    389483 
     484    if (row < line_data->row) 
     485    { 
     486        row = line_data->row; 
     487    } 
    390488    x = start_col_real; 
    391     x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     489    x1 = q + EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    392490    y = row + EDIT_TEXT_VERTICAL_OFFSET; 
    393491    cols_to_skip = abs (x); 
    394492 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    398496        y++; 
    399497    } 
    400498 
    401     tty_setcolor (EDITOR_NORMAL_COLOR); 
    402     if (bookmarked != 0) 
    403         tty_setcolor (bookmarked); 
     499    len = ec + 1 - q; 
     500    f_start = edit_options.word_wrap_line_length + edit->start_col; 
    404501 
    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) 
     502    for (idx = 0; idx < line_data->plines_count || idx == 0; idx++) 
    409503    { 
    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) 
     504        if (len > 0 && w->rect.y + y >= 0) 
    413505        { 
    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); 
     506            if (!edit_options.show_right_margin || f_start > ec) 
     507            { 
     508                tty_setcolor (EDITOR_NORMAL_COLOR); 
     509                if (bookmarked != 0) 
     510                    tty_setcolor (bookmarked); 
    421511 
    422             len -= wrap_start; 
    423             if (len > 0) 
     512                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     513            } 
     514            else if (f_start < 0) 
    424515            { 
    425516                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    426                 tty_draw_hline (w->rect.y + y, w->rect.x + x1 + wrap_start, ' ', len); 
     517                tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', len); 
     518            } 
     519            else 
     520            { 
     521                if (f_start > 0) 
     522                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1, ' ', f_start); 
     523 
     524                len -= f_start; 
     525                if (len > 0) 
     526                { 
     527                    tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
     528                    tty_draw_hline (w->rect.y + y + idx, w->rect.x + x1 + f_start, ' ', len); 
     529                } 
     530            } 
     531        } 
     532    } 
     533    if (edit_options.line_state) 
     534    { 
     535        tty_setcolor (LINE_STATE_COLOR); 
     536        for (yp = 0; (edit_options.soft_wrap && yp <= linesize / ec + 
     537                      (linesize % ec != 0 ? 0 : -1) + 
     538                      (linesize == 0 ? 1 : 0)) || (!edit_options.soft_wrap && yp < 1); ++yp) 
     539        { 
     540            for (i = 0; i < LINE_STATE_WIDTH; i++) 
     541            { 
     542                edit_move (x1 + i - edit_options.line_state_width, y + yp); 
     543                if (yp == 0) 
     544                { 
     545                    if (status[i] == '\0') 
     546                        status[i] = ' '; 
     547                    tty_print_char (status[i]); 
     548                } 
     549                else 
     550                    tty_print_char (' '); 
    427551            } 
    428552        } 
    429553    } 
    430554 
    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     } 
     555    edit->end_col = ec; 
     556    edit->buffer.end_col = ec; 
    443557 
    444558    edit_move (x1, y); 
    445559 
    446560    i = 1; 
    447     for (p = line; p->ch != 0; p++) 
     561    for (idx = 0, p = &line_[-edit->start_col]; 
     562         (edit_options.soft_wrap && linesize-- > 0) || (!edit_options.soft_wrap 
     563                                                        && (linesize-- + edit->start_col > 0) 
     564                                                        && p->ch != 0); p++, idx++) 
    448565    { 
     566 
    449567        int style; 
    450568        unsigned int textchar; 
    451569        int color; 
    452  
    453         if (cols_to_skip != 0) 
     570        if (!edit_options.soft_wrap && cols_to_skip != 0) 
    454571        { 
    455572            cols_to_skip--; 
    456573            continue; 
    457574        } 
    458575 
     576        /* Position each physical line */ 
     577        if (edit_options.soft_wrap && idx % ec == 0) 
     578            edit_move (x1, y++); 
     579 
    459580        style = p->style & 0xFF00; 
    460581        textchar = p->ch; 
    461582        /* If non-printable - use black background */ 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    482603        { 
    483604            if (i > edit_options.word_wrap_line_length + edit->start_col) 
    484605                tty_setcolor (EDITOR_RIGHT_MARGIN_COLOR); 
    485             i++; 
    486606        } 
     607        i++; 
    487608 
    488609        tty_print_anychar (textchar); 
    489610    } 
    print_to_widget (WEdit * edit, long row, int start_col, int start_col_real, 
    492613/* --------------------------------------------------------------------------------------------- */ 
    493614/** b is a pointer to the beginning of the line */ 
    494615 
    495 static void 
    496 edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_col) 
     616static MCELineData * 
     617edit_prepare_this_line (WEdit * edit, off_t b, long order_idx, long row, long start_col, 
     618                        long end_col, long soft_last_row_idx, gboolean draw, long base_line) 
    497619{ 
     620    long line_count, cur_line; 
     621    MCELineData *line_data; 
    498622    Widget *w = WIDGET (edit); 
    499     line_s line[MAX_LINE_LEN]; 
    500     line_s *p = line; 
     623    line *p; 
    501624    off_t q; 
    502     int col, start_col_real; 
     625    int wrap_line_len, line_size, start_col_real = 0; 
     626    int col; 
     627    int color; 
    503628    int abn_style; 
    504629    int book_mark = 0; 
    505     char line_stat[LINE_STATE_WIDTH + 1] = "\0"; 
    506630 
    507     if (row > w->rect.lines - 1 - EDIT_TEXT_VERTICAL_OFFSET - 2 * (edit->fullscreen ? 0 : 1)) 
    508         return; 
     631    q = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     632    line_size = edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     633    line_data = (MCELineData *) g_malloc0 (sizeof (MCELineData) + sizeof (line) * 
     634                                           (line_size + /* sentinel —→ */ 1 + 
     635                                            edit_buffer_count_tabs (&edit->buffer, b, q, 
     636                                                                    FALSE) * 8)); 
     637    p = line_data->ldata; 
    509638 
    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; 
     639    /* Helper var */ 
     640    if (edit_options.soft_wrap) 
     641        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    517642    else 
    518         abn_style = MOD_ABNORMAL; 
     643        wrap_line_len = abs (edit_options.word_wrap_line_length); 
    519644 
    520     end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
    521645    if (!edit->fullscreen) 
    522646    { 
    523647        end_col--; 
    524648        if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
    525649            end_col--; 
    526650    } 
     651    wrap_line_len = end_col; 
    527652 
    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; 
     653    line_count = edit_buffer_count_lines (&edit->buffer, edit->start_display, q - 1, FALSE); 
     654    line_count += base_line + (line_count > 0 ? -1 : 0); 
     655 
     656    line_data->soft_last_row = soft_last_row_idx; 
     657    line_data->row = row; 
     658    line_data->plines_count = line_size / wrap_line_len + ((line_size % wrap_line_len) ? 1 : 0); 
     659    if (!edit_options.soft_wrap) 
     660        line_data->plines_count = 0; 
     661    line_data->index = line_count + (line_count > 0 ? -1 : 0); 
     662    line_data->scr_index = line_data->index - edit->start_line; 
     663    line_data->order_idx = order_idx;   /* for investigation */ 
     664    line_data->size = line_size; 
     665    line_data->q = !edit_options.soft_wrap ? edit->start_col : 0; 
     666    line_data->ec = end_col; 
     667    line_data->visible = (order_idx <= line_data->soft_last_row); 
     668 
     669    if (!edit_options.soft_wrap) 
     670        line_data->plines_count = 0; 
     671 
     672    if (book_mark_query_color (edit, line_data->index, BOOK_MARK_COLOR)) 
     673        book_mark = BOOK_MARK_COLOR; 
     674    else if (book_mark_query_color (edit, line_data->index, BOOK_MARK_FOUND_COLOR)) 
     675        book_mark = BOOK_MARK_FOUND_COLOR; 
     676 
     677    line_data->bookmarked = book_mark; 
     678 
     679    if (book_mark != 0) 
     680        abn_style = book_mark << 16; 
     681    else 
     682        abn_style = MOD_ABNORMAL; 
     683    if (!edit_options.soft_wrap) 
     684    { 
     685        end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width; 
     686        if (!edit->fullscreen) 
     687        { 
     688            end_col--; 
     689            if (w->rect.x + w->rect.cols <= WIDGET (w->owner)->rect.cols) 
     690                end_col--; 
     691        } 
     692    } 
     693 
     694    color = edit_get_syntax_color (edit, b - 1); 
     695    if (edit_options.soft_wrap) 
     696    { 
     697        q = b; 
     698        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     699    } 
     700    else 
     701    { 
     702        q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0, FALSE, 0); 
     703        col = (int) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
     704        line_data->start_col_real = start_col_real = col + edit->start_col; 
     705    } 
    531706 
    532707    if (edit_options.line_state) 
    533708    { 
    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); 
     709        int line_cnt = 0; 
     710        cur_line = line_data->index; 
     711        if (line_data->order_idx == line_data->scr_index || cur_line + 1 < line_cnt) 
     712            g_snprintf (line_data->status, sizeof (line_data->status), "%7li ", cur_line + 1); 
    539713        else 
    540714        { 
    541             memset (line_stat, ' ', LINE_STATE_WIDTH); 
    542             line_stat[LINE_STATE_WIDTH] = '\0'; 
     715            memset (line_data->status, ' ', LINE_STATE_WIDTH); 
     716            line_data->status[LINE_STATE_WIDTH] = '\0'; 
    543717        } 
    544  
    545718        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR)) 
    546             g_snprintf (line_stat, 2, "*"); 
     719            g_snprintf (line_data->status, 2, "*"); 
    547720    } 
    548721 
    549722    if (col <= -(edit->start_col + 16)) 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    553726        off_t m1 = 0, m2 = 0; 
    554727 
    555728        eval_marks (edit, &m1, &m2); 
    556  
    557         if (row <= edit->buffer.lines - edit->start_line) 
     729        if (order_idx <= edit->buffer.lines - edit->start_line) 
    558730        { 
    559731            off_t tws = 0; 
    560732 
    561             if (edit_options.visible_tws && tty_use_colors ()) 
    562                 for (tws = edit_buffer_get_eol (&edit->buffer, b); tws > b; tws--) 
     733            if (tty_use_colors () && edit_options.visible_tws) 
     734                for (tws = edit_buffer_get_eol (&edit->buffer, b, FALSE); tws > b; tws--) 
    563735                { 
    564736                    unsigned int c; 
    565737 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    568740                        break; 
    569741                } 
    570742 
    571             while (col <= end_col - edit->start_col) 
     743            while ((edit_options.soft_wrap && col <= line_data->size) || 
     744                   (!edit_options.soft_wrap && col <= line_data->size)) 
    572745            { 
    573746                int char_length = 1; 
    574747                unsigned int c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    586759                    { 
    587760                        long x, cl; 
    588761 
    589                         x = (long) edit_move_forward3 (edit, b, 0, q); 
     762                        x = (long) edit_move_forward3 (edit, b, 0, q, FALSE, 0); 
    590763                        cl = MIN (edit->column1, edit->column2); 
    591764                        if (x >= cl) 
    592765                        { 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    614787                    p->style |= book_mark << 16; 
    615788                else 
    616789                { 
    617                     int color; 
    618  
    619790                    color = edit_get_syntax_color (edit, q); 
    620791                    p->style |= color << 16; 
    621792                } 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    623794                switch (c) 
    624795                { 
    625796                case '\n': 
    626                     col = end_col - edit->start_col + 1;        /* quit */ 
     797                    if (edit_options.soft_wrap) 
     798                        col = line_data->size + 1;      /* quit */ 
     799                    else 
     800                        col = line_data->size + 1; 
    627801                    break; 
    628802 
    629803                case '\t': 
    630804                    { 
    631                         int tab_over; 
     805                        int tab_over = 0; 
    632806                        int i; 
    633807 
    634808                        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; 
     809 
     810                        /* Supress off-screen part only if not in Soft Wraps mode */ 
     811                        if (!edit_options.soft_wrap || edit_options.soft_wrap) 
     812                        { 
     813                            tab_over = end_col - (col + i - 1); 
     814                            if (tab_over < 0) 
     815                                i += tab_over; 
     816                        } 
    638817                        col += i; 
    639                         if ((edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
    640                             && enable_show_tabs_tws && tty_use_colors ()) 
     818                        if (tty_use_colors () 
     819                            && (edit_options.visible_tabs || (edit_options.visible_tws && q >= tws)) 
     820                            && enable_show_tabs_tws) 
    641821                        { 
    642822                            if ((p->style & MOD_MARKED) != 0) 
    643823                                c = p->style; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    669849                                p->style = c; 
    670850                                p++; 
    671851                            } 
    672                             else 
     852                            else if (i > 0) 
    673853                            { 
    674854                                p->ch = '>'; 
    675855                                p->style = c; 
    676856                                p++; 
    677857                            } 
    678858                        } 
    679                         else if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    680                                  && tty_use_colors ()) 
     859                        else if (tty_use_colors () && edit_options.visible_tws && q >= tws 
     860                                 && enable_show_tabs_tws) 
    681861                        { 
    682862                            p->ch = '.'; 
    683863                            p->style |= MOD_WHITESPACE; 
    684864                            c = p->style & ~MOD_CURSOR; 
    685865                            p++; 
    686                             while (--i != 0) 
     866                            while (--i > 0) 
    687867                            { 
    688868                                p->ch = ' '; 
    689869                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    695875                            p->ch |= ' '; 
    696876                            c = p->style & ~MOD_CURSOR; 
    697877                            p++; 
    698                             while (--i != 0) 
     878                            while (--i > 0) 
    699879                            { 
    700880                                p->ch = ' '; 
    701881                                p->style = c; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    706886                    break; 
    707887 
    708888                case ' ': 
    709                     if (edit_options.visible_tws && q >= tws && enable_show_tabs_tws 
    710                         && tty_use_colors ()) 
     889                    if (tty_use_colors () && edit_options.visible_tws && q >= tws 
     890                        && enable_show_tabs_tws) 
    711891                    { 
    712892                        p->ch = '.'; 
    713893                        p->style |= MOD_WHITESPACE; 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    796976                if (char_length > 1) 
    797977                    q += char_length - 1; 
    798978 
    799                 if (col > (end_col - edit->start_col + 1)) 
     979                if ((edit_options.soft_wrap && col > (line_data->size + 1)) 
     980                    || (!edit_options.soft_wrap && (col > line_data->size + 1))) 
    800981                { 
    801982                    if (wide_width_char) 
    802983                    { 
    edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c 
    814995    } 
    815996 
    816997    p->ch = 0; 
    817  
    818     print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark); 
     998    if (draw) 
     999        print_to_widget (edit, line_data); 
     1000    return line_data; 
    8191001} 
    8201002 
    8211003/* --------------------------------------------------------------------------------------------- */ 
    8221004 
    8231005static inline void 
    824 edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long end_column) 
     1006edit_draw_this_char (WEdit * edit, off_t curs, long order_idx, long row, long start_column, 
     1007                     long end_column) 
    8251008{ 
     1009    MCELineData *line_data; 
    8261010    off_t b; 
    8271011 
    828     b = edit_buffer_get_bol (&edit->buffer, curs); 
    829     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1012    b = edit_buffer_get_bol (&edit->buffer, curs, FALSE); 
     1013    line_data = 
     1014        edit_prepare_this_line (edit, b, order_idx, row, start_column, end_column, 0, TRUE, 0); 
     1015    edit->page_line_data->pdata[order_idx] = line_data; 
    8301016} 
    8311017 
    8321018/* --------------------------------------------------------------------------------------------- */ 
    edit_draw_this_char (WEdit * edit, off_t curs, long row, long start_column, long 
    8351021static inline void 
    8361022render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, long end_column) 
    8371023{ 
    838     static long prev_curs_row = 0; 
    839     static off_t prev_curs = 0; 
     1024    long base_line, y = 0, y_pos; 
     1025    MCELineData *line_data = NULL; 
    8401026 
    841     Widget *we = WIDGET (edit); 
    842     Widget *wh = WIDGET (we->owner); 
    843     WRect *w = &we->rect; 
     1027    Widget *w = WIDGET (edit); 
     1028    Widget *wh = WIDGET (w->owner); 
    8441029 
    845     int force = edit->force; 
     1030    int force = edit->force, prev_plines = 0; 
    8461031    int y1, x1, y2, x2; 
    8471032    int last_line, last_column; 
     1033    GPtrArray *page_line_data; 
     1034    base_line = edit_buffer_count_lines (&edit->buffer, 0, edit->start_display, FALSE); 
     1035    base_line += edit->start_display == 0 ? 1 : 0; 
     1036    page_line_data = edit->page_line_data; 
    8481037 
     1038    if (edit->page_line_data == NULL) 
     1039        page_line_data = edit->page_line_data = g_ptr_array_new_full (LINES, g_free); 
     1040    g_ptr_array_set_size (edit->page_line_data, LINES); 
     1041 
     1042    y_pos = edit->array_row; 
    8491043    /* draw only visible region */ 
    8501044 
    8511045    last_line = wh->rect.y + wh->rect.lines - 1; 
    8521046 
    853     y1 = w->y; 
     1047    y1 = w->rect.y; 
    8541048    if (y1 > last_line - 1 /* buttonbar */ ) 
    8551049        return; 
    8561050 
    8571051    last_column = wh->rect.x + wh->rect.cols - 1; 
    8581052 
    859     x1 = w->x; 
     1053    x1 = w->rect.x; 
    8601054    if (x1 > last_column) 
    8611055        return; 
    8621056 
    863     y2 = w->y + w->lines - 1; 
     1057    y2 = w->rect.y + w->rect.lines - 1; 
    8641058    if (y2 < wh->rect.y + 1 /* menubar */ ) 
    8651059        return; 
    8661060 
    867     x2 = w->x + w->cols - 1; 
     1061    x2 = w->rect.x + w->rect.cols - 1; 
    8681062    if (x2 < wh->rect.x) 
    8691063        return; 
    8701064 
    render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, 
    8741068        /* draw only visible region */ 
    8751069 
    8761070        if (y2 <= last_line - 1 /* buttonbar */ ) 
    877             end_row = w->lines - 1; 
     1071            end_row = w->rect.lines - 1; 
    8781072        else if (y1 >= wh->rect.y + 1 /* menubar */ ) 
    8791073            end_row = wh->rect.lines - 1 - y1 - 1; 
    8801074        else 
    8811075            end_row = start_row + wh->rect.lines - 1 - 1; 
     1076        soft_last_row = end_row; 
    8821077 
    8831078        if (x2 <= last_column) 
    884             end_column = w->cols - 1; 
     1079            end_column = w->rect.cols - 1; 
    8851080        else if (x1 >= wh->rect.x) 
    8861081            end_column = wh->rect.cols - 1 - x1; 
    8871082        else 
    8881083            end_column = start_column + wh->rect.cols - 1; 
    8891084    } 
     1085    refresh_line_data (edit, page_line_data, start_column, end_column, end_row); 
    8901086 
     1087    if (edit_options.soft_wrap) 
     1088    { 
     1089        int i, lines_occupied = 0; 
     1090        for (i = 1 /*skip 0 */ ; i <= end_row; ++i) 
     1091        { 
     1092            /* for i=1, it is line 0 that's 
     1093             * summed up, and so on */ 
     1094            lines_occupied = i + sum_plines_to_row (page_line_data, i); 
     1095            if (lines_occupied >= wh->rect.lines - 1 - 1) 
     1096                break; 
     1097        } 
     1098        soft_last_row = i - 1; 
     1099    } 
     1100    else 
     1101        soft_last_row = end_row; 
    8911102    /* 
    8921103     * If the position of the page has not moved then we can draw the cursor 
    8931104     * 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, 
    8991110 
    9001111        if ((force & REDRAW_PAGE) != 0) 
    9011112        { 
    902             b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0); 
     1113            b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, start_row, 0, 
     1114                                                FALSE); 
    9031115            for (row = start_row; row <= end_row; row++) 
    9041116            { 
    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); 
     1117                line_data = edit_prepare_this_line (edit, b, row, row + prev_plines, 
     1118                                                    start_column, end_column, soft_last_row, 
     1119                                                    row <= soft_last_row, base_line); 
     1120                page_line_data->pdata[row] = line_data; 
     1121                prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1122                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9091123            } 
    9101124        } 
    9111125        else 
    9121126        { 
    913             long curs_row = edit->curs_row; 
    9141127 
    915             if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < curs_row) 
     1128            if ((force & REDRAW_BEFORE_CURSOR) != 0 && start_row < y_pos) 
    9161129            { 
    9171130                long upto; 
    9181131 
     1132                row = start_row; 
    9191133                b = edit->start_display; 
    920                 upto = MIN (curs_row - 1, end_row); 
    921                 for (row = start_row; row <= upto; row++) 
     1134                upto = MIN (y_pos - 1, end_row); 
     1135                while (row <= upto) 
    9221136                { 
    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); 
     1137                    line_data = edit_prepare_this_line (edit, b, row, row + prev_plines, 
     1138                                                        start_column, end_column, soft_last_row, 
     1139                                                        row <= soft_last_row, base_line); 
     1140                    page_line_data->pdata[row] = line_data; 
     1141                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1142                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
     1143                    row++; 
    9271144                } 
    9281145            } 
    929  
    9301146            /*          if (force & REDRAW_LINE)          ---> default */ 
     1147            y = (y_pos - 1 < 0) ? 0 : y_pos - 1; 
    9311148            b = edit_buffer_get_current_bol (&edit->buffer); 
    932             if (curs_row >= start_row && curs_row <= end_row) 
     1149            if (y_pos - y == 1) 
     1150                b = edit_buffer_get_backward_offset (&edit->buffer, b, 1, FALSE); 
     1151            while (y <= y_pos && y >= start_row && y <= end_row) 
    9331152            { 
    934                 if (key_pending (edit)) 
    935                     return; 
    936                 edit_draw_this_line (edit, b, curs_row, start_column, end_column); 
     1153                prev_plines = sum_plines_to_row (edit->page_line_data, y); 
     1154                line_data = edit_prepare_this_line (edit, b, y, y + prev_plines, 
     1155                                                    start_column, end_column, soft_last_row, 
     1156                                                    y <= soft_last_row, base_line); 
     1157                page_line_data->pdata[y] = line_data; 
     1158                y++; 
     1159                if (y <= y_pos) 
     1160                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9371161            } 
    9381162 
    939             if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > curs_row) 
     1163            if ((force & REDRAW_AFTER_CURSOR) != 0 && end_row > y_pos) 
    9401164            { 
    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++) 
     1165                row = MAX (y_pos + 1, start_row); 
     1166                prev_plines = sum_plines_to_row (page_line_data, row); 
     1167                b = edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, row, 0, 
     1168                                                    FALSE); 
     1169                for (; row <= end_row; row++) 
    9431170                { 
    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); 
     1171                    line_data = 
     1172                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1173                                                end_column, soft_last_row, row <= soft_last_row, 
     1174                                                base_line); 
     1175                    page_line_data->pdata[row] = line_data; 
     1176                    prev_plines += (line_data->plines_count > 0) ? line_data->plines_count - 1 : 0; 
     1177                    b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9481178                } 
    9491179            } 
    9501180 
    951             if ((force & REDRAW_LINE_ABOVE) != 0 && curs_row >= 1) 
     1181            if ((force & REDRAW_LINE_ABOVE) != 0 && y_pos >= 1) 
    9521182            { 
    953                 row = curs_row - 1; 
     1183                row = y_pos - 1; 
    9541184                b = edit_buffer_get_backward_offset (&edit->buffer, 
    9551185                                                     edit_buffer_get_current_bol (&edit->buffer), 
    956                                                      1); 
     1186                                                     1, FALSE); 
    9571187                if (row >= start_row && row <= end_row) 
    9581188                { 
    959                     if (key_pending (edit)) 
    960                         return; 
    961                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1189                    prev_plines = sum_plines_to_row (edit->page_line_data, row); 
     1190                    line_data = 
     1191                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1192                                                end_column, soft_last_row, row <= soft_last_row, 
     1193                                                base_line); 
     1194                    page_line_data->pdata[row] = line_data; 
    9621195                } 
    9631196            } 
    964  
    965             if ((force & REDRAW_LINE_BELOW) != 0 && row < w->lines - 1) 
     1197            if ((force & REDRAW_LINE_BELOW) != 0 && y_pos < w->rect.lines - 1) 
    9661198            { 
    967                 row = curs_row + 1; 
     1199                row = y_pos + 1; 
    9681200                b = edit_buffer_get_current_bol (&edit->buffer); 
    969                 b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0); 
     1201                b = edit_buffer_get_forward_offset (&edit->buffer, b, 1, 0, FALSE); 
    9701202                if (row >= start_row && row <= end_row) 
    9711203                { 
    972                     if (key_pending (edit)) 
    973                         return; 
    974                     edit_draw_this_line (edit, b, row, start_column, end_column); 
     1204                    prev_plines = sum_plines_to_row (edit->page_line_data, row); 
     1205                    line_data = 
     1206                        edit_prepare_this_line (edit, b, row, row + prev_plines, start_column, 
     1207                                                end_column, soft_last_row, row <= soft_last_row, 
     1208                                                base_line); 
     1209                    page_line_data->pdata[row] = line_data; 
    9751210                } 
    9761211            } 
    9771212        } 
    9781213    } 
    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     } 
    9901214 
    9911215    edit->force = 0; 
    992  
    993     prev_curs_row = edit->curs_row; 
    994     prev_curs = edit->buffer.curs1; 
    9951216} 
    9961217 
    9971218/* --------------------------------------------------------------------------------------------- */ 
    edit_status (WEdit * edit, gboolean active) 
    10441265void 
    10451266edit_scroll_screen_over_cursor (WEdit * edit) 
    10461267{ 
    1047     WRect *w = &WIDGET (edit)->rect; 
     1268    Widget *w = WIDGET (edit); 
    10481269 
    10491270    long p; 
    10501271    long outby; 
    10511272    int b_extreme, t_extreme, l_extreme, r_extreme; 
    10521273 
    1053     if (w->lines <= 0 || w->cols <= 0) 
     1274    if (w->rect.lines <= 0 || w->rect.cols <= 0) 
    10541275        return; 
    10551276 
    1056     rect_resize (w, -EDIT_TEXT_VERTICAL_OFFSET, 
     1277    rect_resize (&w->rect, -EDIT_TEXT_VERTICAL_OFFSET, 
    10571278                 -(EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width)); 
    10581279 
    10591280    if (!edit->fullscreen) 
    1060         rect_grow (w, -1, -1); 
     1281        rect_grow (&w->rect, -1, -1); 
    10611282 
    10621283    r_extreme = EDIT_RIGHT_EXTREME; 
    10631284    l_extreme = EDIT_LEFT_EXTREME; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    10651286    t_extreme = EDIT_TOP_EXTREME; 
    10661287    if (edit->found_len != 0) 
    10671288    { 
    1068         b_extreme = MAX (w->lines / 4, b_extreme); 
    1069         t_extreme = MAX (w->lines / 4, t_extreme); 
     1289        b_extreme = MAX (w->rect.lines / 4, b_extreme); 
     1290        t_extreme = MAX (w->rect.lines / 4, t_extreme); 
    10701291    } 
    1071     if (b_extreme + t_extreme + 1 > w->lines) 
     1292    if (b_extreme + t_extreme + 1 > w->rect.lines) 
    10721293    { 
    10731294        int n; 
    10741295 
    10751296        n = b_extreme + t_extreme; 
    10761297        if (n == 0) 
    10771298            n = 1; 
    1078         b_extreme = (b_extreme * (w->lines - 1)) / n; 
    1079         t_extreme = (t_extreme * (w->lines - 1)) / n; 
     1299        b_extreme = (b_extreme * (w->rect.lines - 1)) / n; 
     1300        t_extreme = (t_extreme * (w->rect.lines - 1)) / n; 
    10801301    } 
    1081     if (l_extreme + r_extreme + 1 > w->cols) 
     1302    if (l_extreme + r_extreme + 1 > w->rect.cols) 
    10821303    { 
    10831304        int n; 
    10841305 
    10851306        n = l_extreme + r_extreme; 
    10861307        if (n == 0) 
    10871308            n = 1; 
    1088         l_extreme = (l_extreme * (w->cols - 1)) / n; 
    1089         r_extreme = (r_extreme * (w->cols - 1)) / n; 
     1309        l_extreme = (l_extreme * (w->rect.cols - 1)) / n; 
     1310        r_extreme = (r_extreme * (w->rect.cols - 1)) / n; 
    10901311    } 
    10911312    p = edit_get_col (edit) + edit->over_col; 
    10921313    edit_update_curs_row (edit); 
    1093     outby = p + edit->start_col - w->cols + 1 + (r_extreme + edit->found_len); 
     1314    outby = p + edit->start_col - w->rect.cols + 1 + (r_extreme + edit->found_len); 
    10941315    if (outby > 0) 
    10951316        edit_scroll_right (edit, outby); 
    10961317    outby = l_extreme - p - edit->start_col; 
    10971318    if (outby > 0) 
    10981319        edit_scroll_left (edit, outby); 
    10991320    p = edit->curs_row; 
    1100     outby = p - w->lines + 1 + b_extreme; 
     1321    outby = p - w->rect.lines + 1 + b_extreme; 
    11011322    if (outby > 0) 
    11021323        edit_scroll_downward (edit, outby); 
    11031324    outby = t_extreme - p; 
    edit_scroll_screen_over_cursor (WEdit * edit) 
    11051326        edit_scroll_upward (edit, outby); 
    11061327    edit_update_curs_row (edit); 
    11071328 
    1108     rect_resize (w, EDIT_TEXT_VERTICAL_OFFSET, 
     1329    rect_resize (&w->rect, EDIT_TEXT_VERTICAL_OFFSET, 
    11091330                 EDIT_TEXT_HORIZONTAL_OFFSET + edit_options.line_state_width); 
    11101331    if (!edit->fullscreen) 
    1111         rect_grow (w, 1, 1); 
     1332        rect_grow (&w->rect, 1, 1); 
    11121333} 
    11131334 
    11141335/* --------------------------------------------------------------------------------------------- */ 
  • 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};