Cycles: svn merge -r39870:r40266 https://svn.blender.org/svnroot/bf-blender/trunk...
[blender-staging.git] / source / blender / blenkernel / intern / text.c
index 8bf0f6b8bdf8ef18d75777c32a9f25874ae8db79..2c507370288a8d339ae7c0baa231eb7cac9299a6 100644 (file)
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/blenkernel/intern/text.c
+ *  \ingroup bke
+ */
+
+
 #include <string.h> /* strstr */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
 
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_controller_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_text_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
 
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
-#include "BKE_node.h"
 #include "BKE_text.h"
-#include "BKE_utildefines.h"
 
-#ifndef DISABLE_PYTHON
-#include "BPY_extern.h"
-#endif
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
+#ifdef WITH_PYTHON
+#include "BPY_extern.h"
 #endif
 
 /***************/ /*
@@ -98,7 +99,7 @@ TMARK_EDITALL is set the group ID defines which other markers should be edited.
 The mrk->clr field is used to visually group markers where the flags may not
 match. A template system, for example, may allow editing of repeating tokens
 (in one group) but include other marked positions (in another group) all in the
-same template with the same colour.
+same template with the same color.
 
 Undo
 --
@@ -150,6 +151,13 @@ int txt_get_undostate(void)
        return undoing;
 }
 
+static void init_undo_text(Text *text)
+{
+       text->undo_pos= -1;
+       text->undo_len= TXT_INIT_UNDO;
+       text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
+}
+
 void free_text(Text *text)
 {
        TextLine *tmp;
@@ -165,27 +173,28 @@ void free_text(Text *text)
 
        if(text->name) MEM_freeN(text->name);
        MEM_freeN(text->undo_buf);
-#ifndef DISABLE_PYTHON
-       if (text->compiled) BPY_free_compiled_text(text);
+#ifdef WITH_PYTHON
+       if (text->compiled) BPY_text_free_code(text);
 #endif
 }
 
-Text *add_empty_text(char *name) 
+Text *add_empty_text(const char *name) 
 {
+       Main *bmain= G.main;
        Text *ta;
        TextLine *tmp;
        
-       ta= alloc_libblock(&G.main->text, ID_TXT, name);
+       ta= alloc_libblock(&bmain->text, ID_TXT, name);
        ta->id.us= 1;
        
        ta->name= NULL;
 
-       ta->undo_pos= -1;
-       ta->undo_len= TXT_INIT_UNDO;
-       ta->undo_buf= MEM_mallocN(ta->undo_len, "undo buf");
-               
+       init_undo_text(ta);
+
        ta->nlines=1;
        ta->flags= TXT_ISDIRTY | TXT_ISMEM;
+       if((U.flag & USER_TXT_TABSTOSPACES_DISABLE)==0)
+               ta->flags |= TXT_TABSTOSPACES;
 
        ta->lines.first= ta->lines.last= NULL;
        ta->markers.first= ta->markers.last= NULL;
@@ -229,18 +238,16 @@ static void cleanup_textline(TextLine * tl)
 int reopen_text(Text *text)
 {
        FILE *fp;
-       int i, llen, len, res;
+       int i, llen, len;
        unsigned char *buffer;
        TextLine *tmp;
-       char sfile[FILE_MAXFILE];
        char str[FILE_MAXDIR+FILE_MAXFILE];
        struct stat st;
 
        if (!text || !text->name) return 0;
        
        BLI_strncpy(str, text->name, FILE_MAXDIR+FILE_MAXFILE);
-       BLI_convertstringcode(str, G.sce);
-       BLI_split_dirfile_basic(str, NULL, sfile);
+       BLI_path_abs(str, G.main->name);
        
        fp= fopen(str, "r");
        if(fp==NULL) return 0;
@@ -259,9 +266,7 @@ int reopen_text(Text *text)
 
        /* clear undo buffer */
        MEM_freeN(text->undo_buf);
-       text->undo_pos= -1;
-       text->undo_len= TXT_INIT_UNDO;
-       text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
+       init_undo_text(text);
        
        fseek(fp, 0L, SEEK_END);
        len= ftell(fp);
@@ -276,11 +281,10 @@ int reopen_text(Text *text)
 
        fclose(fp);
 
-       res= stat(str, &st);
+       stat(str, &st);
        text->mtime= st.st_mtime;
        
        text->nlines=0;
-       i=0;
        llen=0;
        for(i=0; i<len; i++) {
                if (buffer[i]=='\n') {
@@ -326,32 +330,34 @@ int reopen_text(Text *text)
        return 1;
 }
 
-Text *add_text(char *file, const char *relpath) 
+Text *add_text(const char *file, const char *relpath) 
 {
+       Main *bmain= G.main;
        FILE *fp;
-       int i, llen, len, res;
+       int i, llen, len;
        unsigned char *buffer;
        TextLine *tmp;
        Text *ta;
-       char sfile[FILE_MAXFILE];
        char str[FILE_MAXDIR+FILE_MAXFILE];
        struct stat st;
 
        BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
        if (relpath) /* can be NULL (bg mode) */
-               BLI_convertstringcode(str, relpath);
-       BLI_split_dirfile_basic(str, NULL, sfile);
+               BLI_path_abs(str, relpath);
        
        fp= fopen(str, "r");
        if(fp==NULL) return NULL;
        
-       ta= alloc_libblock(&G.main->text, ID_TXT, sfile);
+       ta= alloc_libblock(&bmain->text, ID_TXT, BLI_path_basename(str));
        ta->id.us= 1;
 
        ta->lines.first= ta->lines.last= NULL;
        ta->markers.first= ta->markers.last= NULL;
        ta->curl= ta->sell= NULL;
-       
+
+       if((U.flag & USER_TXT_TABSTOSPACES_DISABLE)==0)
+               ta->flags= TXT_TABSTOSPACES;
+
        fseek(fp, 0L, SEEK_END);
        len= ftell(fp);
        fseek(fp, 0L, SEEK_SET);        
@@ -359,9 +365,7 @@ Text *add_text(char *file, const char *relpath)
        ta->name= MEM_mallocN(strlen(file)+1, "text_name");
        strcpy(ta->name, file);
 
-       ta->undo_pos= -1;
-       ta->undo_len= TXT_INIT_UNDO;
-       ta->undo_buf= MEM_mallocN(ta->undo_len, "undo buf");
+       init_undo_text(ta);
        
        buffer= MEM_mallocN(len, "text_buffer");
        // under windows fread can return less then len bytes because
@@ -370,11 +374,10 @@ Text *add_text(char *file, const char *relpath)
 
        fclose(fp);
 
-       res= stat(str, &st);
+       stat(str, &st);
        ta->mtime= st.st_mtime;
        
        ta->nlines=0;
-       i=0;
        llen=0;
        for(i=0; i<len; i++) {
                if (buffer[i]=='\n') {
@@ -397,7 +400,13 @@ Text *add_text(char *file, const char *relpath)
                llen++;
        }
 
-       if (llen!=0 || ta->nlines==0) {
+       /* create new line in cases:
+          - rest of line (if last line in file hasn't got \n terminator).
+            in this case content of such line would be used to fill text line buffer
+          - file is empty. in this case new line is needed to start editing from.
+          - last characted in buffer is \n. in this case new line is needed to
+            deal with newline at end of file. (see [#28087]) (sergey) */
+       if (llen!=0 || ta->nlines==0 || buffer[len-1]=='\n') {
                tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
                tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
                tmp->format= NULL;
@@ -428,9 +437,15 @@ Text *copy_text(Text *ta)
        
        tan= copy_libblock(ta);
        
-       tan->name= MEM_mallocN(strlen(ta->name)+1, "text_name");
-       strcpy(tan->name, ta->name);
-       
+       /* file name can be NULL */
+       if(ta->name) {
+               tan->name= MEM_mallocN(strlen(ta->name)+1, "text_name");
+               strcpy(tan->name, ta->name);
+       }
+       else {
+               tan->name= NULL;
+       }
+
        tan->flags = ta->flags | TXT_ISDIRTY;
        
        tan->lines.first= tan->lines.last= NULL;
@@ -458,6 +473,8 @@ Text *copy_text(Text *ta)
        tan->curl= tan->sell= tan->lines.first;
        tan->curc= tan->selc= 0;
 
+       init_undo_text(tan);
+
        return tan;
 }
 
@@ -476,7 +493,7 @@ void unlink_text(Main *bmain, Text *text)
        for(scene=bmain->scene.first; scene; scene=scene->id.next)
                if(scene->r.dometext == text)
                        scene->r.dometext = NULL;
-       
+
        for(ob=bmain->object.first; ob; ob=ob->id.next) {
                /* game controllers */
                for(cont=ob->controllers.first; cont; cont=cont->next) {
@@ -514,7 +531,7 @@ void unlink_text(Main *bmain, Text *text)
                }
                
                if(update)
-                       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
        }
 
        /* pynodes */
@@ -552,7 +569,7 @@ void clear_text(Text *text) /* called directly from rna */
        txt_make_dirty(text);
 }
 
-void write_text(Text *text, char *str) /* called directly from rna */
+void write_text(Text *text, const char *str) /* called directly from rna */
 {
        int oldstate;
 
@@ -578,7 +595,7 @@ static void make_new_line (TextLine *line, char *newline)
        line->format= NULL;
 }
 
-static TextLine *txt_new_line(char *str)
+static TextLine *txt_new_line(const char *str)
 {
        TextLine *tmp;
 
@@ -676,8 +693,8 @@ int txt_get_span (TextLine *from, TextLine *to)
 static void txt_make_dirty (Text *text)
 {
        text->flags |= TXT_ISDIRTY;
-#ifndef DISABLE_PYTHON
-       if (text->compiled) BPY_free_compiled_text(text);
+#ifdef WITH_PYTHON
+       if (text->compiled) BPY_text_free_code(text);
 #endif
 }
 
@@ -984,8 +1001,8 @@ void txt_move_to (Text *text, unsigned int line, unsigned int ch, short sel)
                if ((*linep)->next) *linep= (*linep)->next;
                else break;
        }
-       if (ch>(*linep)->len)
-               ch= (*linep)->len;
+       if (ch>(unsigned int)((*linep)->len))
+               ch= (unsigned int)((*linep)->len);
        *charp= ch;
        
        if(!sel) txt_pop_sel(text);
@@ -1221,23 +1238,19 @@ char *txt_to_buf (Text *text)
        return buf;
 }
 
-int txt_find_string(Text *text, char *findstr, int wrap)
+int txt_find_string(Text *text, char *findstr, int wrap, int match_case)
 {
        TextLine *tl, *startl;
        char *s= NULL;
-       int oldcl, oldsl, oldcc, oldsc;
 
        if (!text || !text->curl || !text->sell) return 0;
        
        txt_order_cursors(text);
 
-       oldcl= txt_get_span(text->lines.first, text->curl);
-       oldsl= txt_get_span(text->lines.first, text->sell);
        tl= startl= text->sell;
-       oldcc= text->curc;
-       oldsc= text->selc;
        
-       s= strstr(&tl->line[text->selc], findstr);
+       if(match_case) s= strstr(&tl->line[text->selc], findstr);
+       else s= BLI_strcasestr(&tl->line[text->selc], findstr);
        while (!s) {
                tl= tl->next;
                if (!tl) {
@@ -1247,7 +1260,8 @@ int txt_find_string(Text *text, char *findstr, int wrap)
                                break;
                }
 
-               s= strstr(tl->line, findstr);
+               if(match_case) s= strstr(tl->line, findstr);
+               else s= BLI_strcasestr(tl->line, findstr);
                if (tl==startl)
                        break;
        }
@@ -1339,9 +1353,19 @@ char *txt_sel_to_buf (Text *text)
        return buf;
 }
 
+static void txt_shift_markers(Text *text, int lineno, int count)
+{
+       TextMarker *marker;
+
+       for (marker=text->markers.first; marker; marker= marker->next)
+               if (marker->lineno>=lineno) {
+                       marker->lineno+= count;
+               }
+}
+
 void txt_insert_buf(Text *text, const char *in_buffer)
 {
-       int i=0, l=0, j, u, len;
+       int i=0, l=0, j, u, len, lineno= -1, count= 0;
        TextLine *add;
 
        if (!text) return;
@@ -1356,7 +1380,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
 
        /* Read the first line (or as close as possible */
        while (in_buffer[i] && in_buffer[i]!='\n') {
-               txt_add_char(text, in_buffer[i]);
+               txt_add_raw_char(text, in_buffer[i]);
                i++;
        }
        
@@ -1366,6 +1390,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
 
        /* Read as many full lines as we can */
        len= strlen(in_buffer);
+       lineno= txt_get_span(text->lines.first, text->curl);
 
        while (i<len) {
                l=0;
@@ -1378,15 +1403,28 @@ void txt_insert_buf(Text *text, const char *in_buffer)
                        add= txt_new_linen(in_buffer +(i-l), l);
                        BLI_insertlinkbefore(&text->lines, text->curl, add);
                        i++;
+                       count++;
                } else {
+                       if(count) {
+                               txt_shift_markers(text, lineno, count);
+                               count= 0;
+                       }
+
                        for (j= i-l; j<i && j<(int)strlen(in_buffer); j++) {
-                               txt_add_char(text, in_buffer[j]);
+                               txt_add_raw_char(text, in_buffer[j]);
                        }
                        break;
                }
        }
-       
+
+       if(count) {
+               txt_shift_markers(text, lineno, count);
+               count= 0;
+       }
+
        undoing= u;
+
+       (void)count;
 }
 
 /******************/
@@ -1399,9 +1437,7 @@ static int max_undo_test(Text *text, int x)
                if(text->undo_len*2 > TXT_MAX_UNDO) {
                        /* XXX error("Undo limit reached, buffer cleared\n"); */
                        MEM_freeN(text->undo_buf);
-                       text->undo_len= TXT_INIT_UNDO;
-                       text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
-                       text->undo_pos=-1;
+                       init_undo_text(text);
                        return 0;
                } else {
                        void *tmp= text->undo_buf;
@@ -1426,7 +1462,7 @@ void txt_print_undo(Text *text)
 {
        int i= 0;
        int op;
-       char *ops;
+       const char *ops;
        int linep, charp;
        
        dump_buffer(text);
@@ -1863,13 +1899,13 @@ void txt_do_undo(Text *text)
 
                        
                        if (op==UNDO_INDENT) {
-                               unindent(text);
+                               txt_unindent(text);
                        } else if (op== UNDO_UNINDENT) {
-                               indent(text);
+                               txt_indent(text);
                        } else if (op == UNDO_COMMENT) {
-                               uncomment(text);
+                               txt_uncomment(text);
                        } else if (op == UNDO_UNCOMMENT) {
-                               comment(text);
+                               txt_comment(text);
                        }
 
                        text->undo_pos--;
@@ -2039,6 +2075,7 @@ void txt_do_redo(Text *text)
                        linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
                        linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
                        linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+                       (void)linep;
 
                        break;
                case UNDO_INDENT:
@@ -2078,13 +2115,13 @@ void txt_do_redo(Text *text)
                        }
 
                        if (op==UNDO_INDENT) {
-                               indent(text);
+                               txt_indent(text);
                        } else if (op== UNDO_UNINDENT) {
-                               unindent(text);
+                               txt_unindent(text);
                        } else if (op == UNDO_COMMENT) {
-                               comment(text);
+                               txt_comment(text);
                        } else if (op == UNDO_UNCOMMENT) {
-                               uncomment(text);
+                               txt_uncomment(text);
                        }
                        break;
                default:
@@ -2214,7 +2251,6 @@ static void txt_combine_lines (Text *text, TextLine *linea, TextLine *lineb)
                } while (mrk && mrk->lineno==lineno);
        }
        if (lineno==-1) lineno= txt_get_span(text->lines.first, lineb);
-       if (!mrk) mrk= text->markers.first;
        
        tmp= MEM_mallocN(linea->len+lineb->len+1, "textline_string");
        
@@ -2354,7 +2390,22 @@ void txt_backspace_word (Text *text)
        txt_delete_sel(text);
 }
 
-int txt_add_char (Text *text, char add) 
+/* Max spaces to replace a tab with, currently hardcoded to TXT_TABSIZE = 4.
+ * Used by txt_convert_tab_to_spaces, indent and unintent.
+ * Remember to change this string according to max tab size */
+static char tab_to_spaces[] = "    ";
+
+static void txt_convert_tab_to_spaces (Text *text)
+{
+       /* sb aims to pad adjust the tab-width needed so that the right number of spaces
+        * is added so that the indention of the line is the right width (i.e. aligned
+        * to multiples of TXT_TABSIZE)
+        */
+       char *sb = &tab_to_spaces[text->curc % TXT_TABSIZE];
+       txt_insert_buf(text, sb);
+}
+
+static int txt_add_char_intern (Text *text, char add, int replace_tabs)
 {
        int len, lineno;
        char *tmp;
@@ -2368,6 +2419,12 @@ int txt_add_char (Text *text, char add)
                return 1;
        }
        
+       /* insert spaces rather than tabs */
+       if (add == '\t' && replace_tabs) {
+               txt_convert_tab_to_spaces(text);
+               return 1;
+       }
+
        txt_delete_sel(text);
        
        mrk= txt_find_marker_region(text, text->curl, text->curc-1, text->curl->len, 0, 0);
@@ -2401,6 +2458,16 @@ int txt_add_char (Text *text, char add)
        return 1;
 }
 
+int txt_add_char (Text *text, char add)
+{
+       return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES);
+}
+
+int txt_add_raw_char (Text *text, char add)
+{
+       return txt_add_char_intern(text, add, 0);
+}
+
 void txt_delete_selected(Text *text)
 {
        txt_delete_sel(text);
@@ -2439,11 +2506,22 @@ int txt_replace_char (Text *text, char add)
        return 1;
 }
 
-void indent(Text *text)
+void txt_indent(Text *text)
 {
        int len, num;
        char *tmp;
-       char add = '\t';
+
+       const char *add = "\t";
+       int indentlen = 1;
+       
+       /* hardcoded: TXT_TABSIZE = 4 spaces: */
+       int spaceslen = TXT_TABSIZE;
+
+       /* insert spaces rather than tabs */
+       if (text->flags & TXT_TABSTOSPACES){
+               add = tab_to_spaces;
+               indentlen = spaceslen;
+       }
        
        if (!text) return;
        if (!text->curl) return;
@@ -2452,19 +2530,19 @@ void indent(Text *text)
        num = 0;
        while (TRUE)
        {
-               tmp= MEM_mallocN(text->curl->len+2, "textline_string");
+               tmp= MEM_mallocN(text->curl->len+indentlen+1, "textline_string");
                
                text->curc = 0; 
-               if(text->curc) memcpy(tmp, text->curl->line, text->curc);
-               tmp[text->curc]= add;
+               if(text->curc) memcpy(tmp, text->curl->line, text->curc); /* XXX never true, check prev line */
+               memcpy(tmp+text->curc, add, indentlen);
                
                len= text->curl->len - text->curc;
-               if(len>0) memcpy(tmp+text->curc+1, text->curl->line+text->curc, len);
-               tmp[text->curl->len+1]=0;
+               if(len>0) memcpy(tmp+text->curc+indentlen, text->curl->line+text->curc, len);
+               tmp[text->curl->len+indentlen]= 0;
 
                make_new_line(text->curl, tmp);
                        
-               text->curc++;
+               text->curc+= indentlen;
                
                txt_make_dirty(text);
                txt_clean_text(text);
@@ -2491,11 +2569,21 @@ void indent(Text *text)
        }
 }
 
-void unindent(Text *text)
+void txt_unindent(Text *text)
 {
        int num = 0;
-       char remove = '\t';
+       const char *remove = "\t";
+       int indent = 1;
        
+       /* hardcoded: TXT_TABSIZE = 4 spaces: */
+       int spaceslen = TXT_TABSIZE;
+
+       /* insert spaces rather than tabs */
+       if (text->flags & TXT_TABSTOSPACES){
+               remove = tab_to_spaces;
+               indent = spaceslen;
+       }
+
        if (!text) return;
        if (!text->curl) return;
        if (!text->sell) return;
@@ -2504,15 +2592,14 @@ void unindent(Text *text)
        {
                int i = 0;
                
-               if (text->curl->line[i] == remove)
+               if (BLI_strncasecmp(text->curl->line, remove, indent) == 0)
                {
                        while(i< text->curl->len) {
-                               text->curl->line[i]= text->curl->line[i+1];
+                               text->curl->line[i]= text->curl->line[i+indent];
                                i++;
                        }
-                       text->curl->len--;
+                       text->curl->len-= indent;
                }
-                        
        
                txt_make_dirty(text);
                txt_clean_text(text);
@@ -2540,7 +2627,7 @@ void unindent(Text *text)
        }
 }
 
-void comment(Text *text)
+void txt_comment(Text *text)
 {
        int len, num;
        char *tmp;
@@ -2548,7 +2635,7 @@ void comment(Text *text)
        
        if (!text) return;
        if (!text->curl) return;
-       if (!text->sell) return;// Need to change this need to check if only one line is selected ot more then one
+       if (!text->sell) return;// Need to change this need to check if only one line is selected to more then one
 
        num = 0;
        while (TRUE)
@@ -2592,7 +2679,7 @@ void comment(Text *text)
        }
 }
 
-void uncomment(Text *text)
+void txt_uncomment(Text *text)
 {
        int num = 0;
        char remove = '#';
@@ -2641,19 +2728,20 @@ void uncomment(Text *text)
        }
 }
 
-int setcurr_tab (Text *text)
+int setcurr_tab_spaces (Text *text, int space)
 {
        int i = 0;
        int test = 0;
-       char *word = ":";
-       char *comm = "#";
-       char back_words[4][7] = {"return", "break", "pass", "yield"};
+       const char *word = ":";
+       const char *comm = "#";
+       const char indent= (text->flags & TXT_TABSTOSPACES) ? ' ' : '\t';
+       static const char *back_words[]= {"return", "break", "continue", "pass", "yield", NULL};
        if (!text) return 0;
        if (!text->curl) return 0;
-       
-       while (text->curl->line[i] == '\t')
+
+       while (text->curl->line[i] == indent)
        {
-               //we only count thos tabs that are before any text or before the curs;
+               //we only count those tabs/spaces that are before any text or before the curs;
                if (i == text->curc)
                {
                        return i;
@@ -2663,31 +2751,36 @@ int setcurr_tab (Text *text)
        }
        if(strstr(text->curl->line, word))
        {
-               //if we find a : then add a tab but not if it is in a comment
-               int a, indent = 0;
-               for(a=0; text->curl->line[a] != '\0'; a++)
+               /* if we find a ':' on this line, then add a tab but not if it is:
+                *      1) in a comment
+                *      2) within an identifier
+                *      3) after the cursor (text->curc), i.e. when creating space before a function def [#25414] 
+                */
+               int a, is_indent = 0;
+               for(a=0; (a < text->curc) && (text->curl->line[a] != '\0'); a++)
                {
-                       if (text->curl->line[a]=='#') {
+                       char ch= text->curl->line[a];
+                       if (ch=='#') {
                                break;
-                       } else if (text->curl->line[a]==':') {
-                               indent = 1;
-                       } else if (text->curl->line[a]==']') {
-                               indent = 0;
+                       } else if (ch==':') {
+                               is_indent = 1;
+                       } else if (ch!=' ' && ch!='\t') {
+                               is_indent = 0;
                        }
                }
-               if (indent) {
-                       i++;
+               if (is_indent) {
+                       i += space;
                }
        }
 
-       for(test=0; test < 4; test++)
+       for(test=0; back_words[test]; test++)
        {
-               //if there are these 4 key words then remove a tab because we are done with the block
+               /* if there are these key words then remove a tab because we are done with the block */
                if(strstr(text->curl->line, back_words[test]) && i > 0)
                {
                        if(strcspn(text->curl->line, back_words[test]) < strcspn(text->curl->line, comm))
                        {
-                               i--;
+                               i -= space;
                        }
                }
        }
@@ -2699,7 +2792,7 @@ int setcurr_tab (Text *text)
 /*********************************/
 
 /* Creates and adds a marker to the list maintaining sorted order */
-void txt_add_marker(Text *text, TextLine *line, int start, int end, char color[4], int group, int flags) {
+void txt_add_marker(Text *text, TextLine *line, int start, int end, const unsigned char color[4], int group, int flags) {
        TextMarker *tmp, *marker;
 
        marker= MEM_mallocN(sizeof(TextMarker), "text_marker");