Ticket #3068: mcedit-vim-modeline-1.patch

File mcedit-vim-modeline-1.patch, 9.8 KB (added by twasilczyk, 6 years ago)

Added vim's modeline support - initial implementation

  • .gitignore

    diff --git a/.gitignore b/.gitignore
    index 310c62f..9e8b9e7 100644
    a b make.log 
    4646make.clang 
    4747make.gcc 
    4848make.tcc 
     49misc/ext.d/doc.sh 
     50misc/ext.d/misc.sh 
     51misc/ext.d/text.sh 
     52misc/ext.d/web.sh 
     53misc/syntax/Syntax 
     54src/man2hlp/man2hlp 
     55src/vfs/extfs/helpers/uc1541 
     56src/vfs/extfs/helpers/ulib 
     57tests/src/editor/test-data.txt 
  • src/editor/edit.c

    diff --git a/src/editor/edit.c b/src/editor/edit.c
    index 1c80466..1fe0a53 100644
    a b static const off_t option_filesize_default_threshold = 64 * 1024 * 1024; 
    142142/* --------------------------------------------------------------------------------------------- */ 
    143143/*** file scope functions ************************************************************************/ 
    144144/* --------------------------------------------------------------------------------------------- */ 
     145 
     146static gboolean 
     147edit_fake_half_tabs(WEdit *edit) 
     148{ 
     149    if (edit->force_halftabs == -1) 
     150        return option_fake_half_tabs; 
     151    return edit->force_halftabs; 
     152} 
     153 
     154static gboolean 
     155edit_fill_tabs_with_spaces(WEdit *edit) 
     156{ 
     157    if (edit->force_fill_tabs_with_spaces == -1) 
     158        return option_fill_tabs_with_spaces; 
     159    return edit->force_fill_tabs_with_spaces; 
     160} 
     161 
    145162/** 
    146163 * Load file OR text into buffers.  Set cursor to the beginning of file. 
    147164 * 
    insert_spaces_tab (WEdit * edit, gboolean half) 
    13931410static inline void 
    13941411edit_tab_cmd (WEdit * edit) 
    13951412{ 
    1396     if (option_fake_half_tabs && is_in_indent (&edit->buffer)) 
     1413    if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer)) 
    13971414    { 
    13981415        /* insert a half tab (usually four spaces) unless there is a 
    13991416           half tab already behind, then delete it and insert a 
    14001417           full tab. */ 
    1401         if (option_fill_tabs_with_spaces || !right_of_four_spaces (edit)) 
     1418        if (edit_fill_tabs_with_spaces(edit) || !right_of_four_spaces (edit)) 
    14021419            insert_spaces_tab (edit, TRUE); 
    14031420        else 
    14041421        { 
    edit_tab_cmd (WEdit * edit) 
    14091426            edit_insert (edit, '\t'); 
    14101427        } 
    14111428    } 
    1412     else if (option_fill_tabs_with_spaces) 
     1429    else if (edit_fill_tabs_with_spaces(edit)) 
    14131430        insert_spaces_tab (edit, FALSE); 
    14141431    else 
    14151432        edit_insert (edit, '\t'); 
    edit_move_block_to_right (WEdit * edit) 
    15451562        edit_cursor_move (edit, cur_bol - edit->buffer.curs1); 
    15461563        if (!edit_line_is_blank (edit, edit->buffer.curs_line)) 
    15471564        { 
    1548             if (option_fill_tabs_with_spaces) 
    1549                 insert_spaces_tab (edit, option_fake_half_tabs); 
     1565            if (edit_fill_tabs_with_spaces(edit)) 
     1566                insert_spaces_tab (edit, edit_fake_half_tabs(edit)); 
    15501567            else 
    15511568                edit_insert (edit, '\t'); 
    15521569            edit_cursor_move (edit, 
    edit_move_block_to_left (WEdit * edit) 
    15851602 
    15861603        edit_cursor_move (edit, cur_bol - edit->buffer.curs1); 
    15871604 
    1588         if (option_fake_half_tabs) 
     1605        if (edit_fake_half_tabs(edit)) 
    15891606            del_tab_width = HALF_TAB_SIZE; 
    15901607        else 
    15911608            del_tab_width = option_tab_spacing; 
    edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath) 
    20172034 * cursor on that line and show it in the middle of the screen. 
    20182035 */ 
    20192036 
     2037static off_t 
     2038mc_findinfile(int handle, const char *searchstr) 
     2039{ 
     2040    off_t offset_bak, offset_cur, filesize; 
     2041    char buff[10240]; 
     2042    ssize_t got; 
     2043    const char *found; 
     2044    size_t searchstr_len; 
     2045 
     2046    searchstr_len = strlen(searchstr); 
     2047 
     2048    offset_bak = mc_lseek(handle, 0, SEEK_CUR); 
     2049    if (offset_bak < 0) 
     2050        return -1; 
     2051 
     2052    filesize = mc_lseek(handle, 0, SEEK_END); 
     2053    offset_cur = mc_lseek(handle, offset_bak, SEEK_SET); 
     2054 
     2055    do { 
     2056        got = mc_read(handle, buff, sizeof(buff) - 1); 
     2057        if (got <= 0) 
     2058            return -1; 
     2059        buff[got] = '\0'; 
     2060 
     2061        found = strstr(buff, searchstr); 
     2062        if (found) 
     2063            return mc_lseek(handle, offset_cur + (found - buff), SEEK_SET); 
     2064 
     2065        offset_cur = mc_lseek(handle, 
     2066            offset_cur + (sizeof(buff) - 1) - searchstr_len, SEEK_SET); 
     2067    } while (offset_cur + searchstr_len < filesize); 
     2068 
     2069    return -1; 
     2070} 
     2071 
     2072static void 
     2073scan_modeline(WEdit *edit, const vfs_path_t *filename) 
     2074{ 
     2075    int fd; 
     2076    int conf_tabstop = -1; 
     2077    int conf_softtabstop = -1; 
     2078    int conf_expandtab = -1; 
     2079    int dst_halftabs = -1; 
     2080    int dst_fill_tabs_with_spaces = -1; 
     2081 
     2082    fd = mc_open(filename, O_RDONLY | O_BINARY); 
     2083    while (1) { 
     2084        off_t foundat; 
     2085        char buff[200]; 
     2086        char *s; 
     2087        ssize_t got; 
     2088        const char *foundstr; 
     2089 
     2090        foundat = mc_findinfile(fd, "\n/*"); 
     2091        if (foundat < 0) 
     2092            return; 
     2093 
     2094        got = mc_read(fd, buff, sizeof(buff) - 1); 
     2095        if (got <= 0) 
     2096            return; 
     2097        buff[got] = '\0'; 
     2098 
     2099        mc_lseek(fd, foundat + 3, SEEK_SET); 
     2100 
     2101        s = &buff[3]; 
     2102        while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r') 
     2103            s++; 
     2104 
     2105        if (strncmp(s, "vim:", 4) != 0) 
     2106            continue; 
     2107        s += 4; 
     2108 
     2109        foundstr = strstr(s, "tabstop="); 
     2110        if (foundstr) 
     2111            conf_tabstop=atoi(foundstr + 8); 
     2112        foundstr = strstr(s, "softtabstop="); 
     2113        if (foundstr) 
     2114            conf_softtabstop=atoi(foundstr + 12); 
     2115        foundstr = strstr(s, "expandtab"); 
     2116        if (foundstr) 
     2117            conf_expandtab = 1; 
     2118        foundstr = strstr(s, "noexpandtab"); 
     2119        if (foundstr) 
     2120            conf_expandtab = 0; 
     2121 
     2122        break; 
     2123    } 
     2124 
     2125    if (conf_softtabstop > 0 && conf_tabstop > 0 && 
     2126        conf_softtabstop * 2 == conf_tabstop) 
     2127    { 
     2128        dst_halftabs = 1; 
     2129    } 
     2130 
     2131    dst_fill_tabs_with_spaces = conf_expandtab; 
     2132 
     2133    edit->force_halftabs = dst_halftabs; 
     2134    edit->force_fill_tabs_with_spaces = dst_fill_tabs_with_spaces; 
     2135 
     2136    mc_close(fd); 
     2137} 
     2138 
    20202139WEdit * 
    20212140edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * filename_vpath, 
    20222141           long line) 
    edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * f 
    20542173        edit_save_size (edit); 
    20552174    } 
    20562175 
     2176    edit->force_halftabs = -1; 
     2177    edit->force_fill_tabs_with_spaces = -1; 
     2178 
     2179    scan_modeline(edit, filename_vpath); 
     2180 
    20572181    edit->drag_state = MCEDIT_DRAG_NORMAL; 
    20582182 
    20592183    edit->stat1.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 
    edit_move_to_prev_col (WEdit * edit, off_t p) 
    29093033    else 
    29103034    { 
    29113035        edit->over_col = 0; 
    2912         if (option_fake_half_tabs && is_in_indent (&edit->buffer)) 
     3036        if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer)) 
    29133037        { 
    29143038            long fake_half_tabs; 
    29153039 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    34023526            while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 > 0) 
    34033527                edit_backspace (edit, TRUE); 
    34043528        } 
    3405         else if (option_fake_half_tabs && is_in_indent (&edit->buffer) 
     3529        else if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer) 
    34063530                 && right_of_four_spaces (edit)) 
    34073531        { 
    34083532            int i; 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    34103534            for (i = 0; i < HALF_TAB_SIZE; i++) 
    34113535                edit_backspace (edit, TRUE); 
    34123536        } 
     3537        else if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer) 
     3538                 && is_aligned_on_a_tab(edit)) { 
     3539            int i; 
     3540 
     3541            edit_backspace (edit, TRUE); 
     3542            for (i = 0; i < HALF_TAB_SIZE; i++) 
     3543                edit_insert (edit, ' '); 
     3544            /* TODO: if (right_of_four_spaces(edit) && left_of_four_spaces(edit) 
     3545             * - replace spaces with a tab */ 
     3546        } 
    34133547        else 
    34143548            edit_backspace (edit, FALSE); 
    34153549        break; 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    34223556            if (option_cursor_beyond_eol && edit->over_col > 0) 
    34233557                edit_insert_over (edit); 
    34243558 
    3425             if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) 
     3559            if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) 
    34263560            { 
    34273561                int i; 
    34283562 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    34883622        edit->column_highlight = 1; 
    34893623    case CK_Left: 
    34903624    case CK_MarkLeft: 
    3491         if (option_fake_half_tabs && is_in_indent (&edit->buffer) && right_of_four_spaces (edit)) 
     3625        if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer) && right_of_four_spaces (edit)) 
    34923626        { 
    34933627            if (option_cursor_beyond_eol && edit->over_col > 0) 
    34943628                edit->over_col--; 
    edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) 
    35033637        edit->column_highlight = 1; 
    35043638    case CK_Right: 
    35053639    case CK_MarkRight: 
    3506         if (option_fake_half_tabs && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) 
     3640        if (edit_fake_half_tabs(edit) && is_in_indent (&edit->buffer) && left_of_four_spaces (edit)) 
    35073641        { 
    35083642            edit_cursor_move (edit, HALF_TAB_SIZE); 
    35093643            edit->force &= (0xFFF - REDRAW_CHAR_ONLY); 
    edit_move_down (WEdit * edit, long i, gboolean do_scroll) 
    39644098} 
    39654099 
    39664100/* --------------------------------------------------------------------------------------------- */ 
     4101 
     4102/* vim: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */ 
  • src/editor/editwidget.h

    diff --git a/src/editor/editwidget.h b/src/editor/editwidget.h
    index 90c73f6..1b45cfb 100644
    a b struct WEdit 
    163163    /* line break */ 
    164164    LineBreaks lb; 
    165165    gboolean extmod; 
     166 
     167    int force_halftabs; 
     168    int force_fill_tabs_with_spaces; 
    166169}; 
    167170 
    168171/*** global variables defined in .c file *********************************************************/