Can I get Fl_Text_Editor/Display highlight_data styleBuffer as a pointer from a function?

73 views
Skip to first unread message

israel dahl

unread,
Aug 9, 2018, 5:16:13 PM8/9/18
to fltk.general
Here is what I am doing:
Multi-tabbed text editor with mutliple tabs that have Fl_Text_Editor [ o in my code examples below].
These are generated when the user wants them to be (clicking the add a tab button), each with their own text buffer accessed easily through o->buffer();

I want to use syntax highlighting, so create  an additional text buffer and assign it via the highlight_data, yet I can not find how to get and modify that.

I expect there to be some sort of function similar to
Fl_Text_Buffer * buff = o->highlight_data();

much like the:
o->buffer(my_buffer); 
some_other_buffer=o->buffer();

I am still using FLTK 1.3.3 so forgive me if this is in a modern version's documentation, but I cannot find it, and would very much like to, thanks!

Matthias Melcher

unread,
Aug 9, 2018, 7:14:33 PM8/9/18
to fltkg...@googlegroups.com
The attribute stuff in text editor is not obvious. I recommend that you look at the "editor" code in the "test" directory of the source distribution. It contains everything needed to highlight C++ code automatically.

israel dahl

unread,
Aug 9, 2018, 9:10:01 PM8/9/18
to fltk.general

The attribute stuff in text editor is not obvious. I recommend that you look at the "editor" code in the "test" directory of the source distribution. It contains everything needed to highlight C++ code automatically.
The "editor" code is similar to the walkthrough, my question is still unanswered, so let me ask more thoroughly, using that code as example:
This is the global definitions used... I do not want this, nor do I do this.  I have multiple Fl_Tabs with Fl_Group and Fl_Text_Editor inside these tabs.  They are generated on the fly when a user adds a new tab.
Fl_Text_Buffer     *textbuf = 0;
// Syntax highlighting stuff...
#define TS 14 // default editor textsize
Fl_Text_Buffer     *stylebuf = 0;

This DOES work, if I have one text buffer and one style buffer to match it.
I have multiple text buffers (one for each Fl_Text_Editor), but I want to have multiple style buffers to modify the style of EACH text buffer.

So my question:
Can I get a pointer to the highlight_data(...) (mostly just the Fl_Text_Buffer sent in... i.e. stylebuff) or do I have to simply deal with making a new style buffer at each update, and building it all over again, and re adding the highlight_data(...) to the Fl_Text_Editor

Sorry for my previous lack of clarity, I do hope this posting is much more clear.

Greg Ercolano

unread,
Aug 10, 2018, 12:32:10 AM8/10/18
to fltkg...@googlegroups.com
On 08/09/18 18:10, israel dahl wrote:
>
> The attribute stuff in text editor is not obvious. I recommend that you look at the "editor" code in the "test" directory of the source distribution. It contains everything needed to highlight C++ code automatically.
>
> The "editor" code is similar to the walkthrough, my question is still unanswered, so let me ask more thoroughly, using that code as examp|le:|
> |This is the global definitions used... I do not want this, nor do I do this.  I have multiple Fl_Tabs with Fl_Group and Fl_Text_Editor inside these tabs.  They are generated on the fly when a user adds a new tab.
> |
> |
> Fl_Text_Buffer    *textbuf =0;
> // Syntax highlighting stuff...
> #defineTS 14// default editor textsize
> Fl_Text_Buffer    *stylebuf =0;
> |
>
> This DOES work, if I have *one text buffer* and *one style buffer* to match it.
> I have *multiple* text buffers (one for each Fl_Text_Editor), but I want to have *multiple style buffers* to modify the style of EACH text buffer.

If you're making multiple editors, I would suggest creating your own subclass
of Fl_Text_Editor, e.g.

class MyEditor : public Fl_Text_Editor {
Fl_Text_Buffer *tbuf, *sbuf; // text + style buffers
..
static void MyStyleCallback(int pos, int nInserted, int nDeleted, int nRestyled, const char *del_text, void *userdata) {
MyEditor *edit = (MyEditor*)userdata;
..do stuff with edit->sbuf->text(), etc..
}
public:
// CTOR
MyEditor(int X,int Y,int W,int H..) : Fl_Text_Editor(X,Y,W,H..) {
tbuf = new Fl_Text_Buffer(); // create text buffer
sbuf = new Fl_Text_Buffer(); // create style buffer
buffer(tbuf); // assign text buffer to this editor
..
highlight_data(sbuf, ..); // assign style buffer to this editor
tbuf->add_modify_callback(MyStyleCallback, this); // assign a callback to handle style changes (if needed)
..
}

..
};

(Disclaimer: above hand typed, might be subject to errors)

Here the constructor creates and assigns the text and style buffers,
and keeps track of the text and style buffer pointers as members of the class
(in the above example, "tbuf" and "sbuf" respectively)

Then when you set up the "modify callback" (also in the constructor for your class),
you can set the user data for that callback to be the MyEditor instance (e.g. "this").

That way when the user makes changes to the editor, your "modify callback" (MyStyleCallback()
in the above example) will be passed the pointer to that MyEditor instance so you can then
access the text and style buffer pointer members, e.g.

static void MyStyleCallback(int pos, int nInserted, int nDeleted, int nRestyled,
const char *del_text, void *userdata) {
MyEditor *edit = (MyEditor*)userdata; // <-- GET THE POINTER TO THIS EDITOR INSTANCE
edit->tbuf.. // access the editor's text buffer
edit->sbuf.. // access the editor's style buffer
}

This callback tells you what range of characters in the buffers were changed,
so your callback can figure out what colors to assign to the style buffer
(e.g. edit->sbuf->text()) based on the text content (in e.g. edit->tbuf->text())

Since the text and style buffers are exactly parallel, the index#s for the changed
text (the "start" and "end") will be relevant for both buffers.

The editor manages the two buffers to keep them in sync.. your modify callback
just has to change the style buffer chars betwen pos and nInserted/nDeleted/etc
to be the appropriate characters.

You ONLY have to consider the changed text, not the entire buffer.


> So my question:
> Can I get a pointer to the highlight_data(...) (mostly just the Fl_Text_Buffer sent in... i.e. stylebuff)

Yes -- in the above example, edit->sbuf gets you a pointer to the style buffer,
and edit->sbuf->text() gets you a pointer to the actual char* array.

> or do I have to simply deal with making a new style buffer at each update,
> and building it all over again, and re adding the highlight_data(...) to the Fl_Text_Editor

No, you only assign the text and style buffers once during initialization
of the editor.. in the above example, that's done in the constructor once only.

The editor's internals manages those buffers dynamically for you, enlarging/shrinking
them as the user adds/removes text. The internals also invoke your "modify callback"
whenever text changes, telling you what parts of the two buffers were changed,
so you can focus on just those characters in the buffer to adjust the colors as needed.

Greg Ercolano

unread,
Aug 10, 2018, 1:00:27 AM8/10/18
to fltkg...@googlegroups.com

Some follow up clarifications to my reply:

On 08/09/18 21:32, Greg Ercolano wrote:
>> This DOES work, if I have *one text buffer* and *one style buffer* to match it.
>> I have *multiple* text buffers (one for each Fl_Text_Editor), but I want to have
> *multiple style buffers* to modify the style of EACH text buffer.
>
> If you're making multiple editors, I would suggest creating your own subclass
> of Fl_Text_Editor, e.g.
>
> class MyEditor : public Fl_Text_Editor {
> Fl_Text_Buffer *tbuf, *sbuf; // text + style buffers

..emphasis on that bit there, "tbuf" and "sbuf" being members you use
to keep track of the text buffer and style buffer pointers yourself.

You initialize these in the constructor here:

> // CTOR
> MyEditor(int X,int Y,int W,int H..) : Fl_Text_Editor(X,Y,W,H..) {
> tbuf = new Fl_Text_Buffer(); // *create text buffer*
> sbuf = new Fl_Text_Buffer(); // *create style buffer*

..and assign them to the editor here:

> buffer(tbuf); // assign text buffer to this editor
> ..
> highlight_data(sbuf, ..); // assign style buffer to this editor

..and when you set up your modify callback here:

> tbuf->add_modify_callback(MyStyleCallback, this); // assign a callback to handle style changes (if needed)

..you've set up the callback user data to be a pointer to the editor,
so that your callback can then gain access the sbuf pointer:

> static void MyStyleCallback(int pos, int nInserted, int nDeleted, int nRestyled, const char *del_text, void *userdata) {
> MyEditor *edit = (MyEditor*)userdata; // GET INSTANCE TO EDITOR
> ..do stuff with edit->sbuf->text(), etc.. // ACCESS YOUR SBUF MEMBER

And one other point of clarification:

>> So my question:
>> Can I get a pointer to the highlight_data(...) (mostly just the Fl_Text_Buffer sent in... i.e. stylebuff)
>
> Yes -- in the above example, edit->sbuf gets you a pointer to the style buffer,
> and edit->sbuf->text() gets you a pointer to the actual char* array.

..just to clarify that last bit, to change the colors of the text, I'm not sure
if you can change the chars directly using the text() pointer (e.g. edit->sbuf->text()):

char *p = edit->sbuf->text(); // get pointer to style buffer's char* array
p[pos] = 'A'; // change the color of text at position 'p' to the color 'A'

That might not be allowed, in which case to make changes you'd have to use Fl_Text_Buffer's
methods to manipulate the buffer, e.g. replace() and insert() IIRC.

Definitely use the test/editor.cxx example for reference, looking closely at how its
modify callback is implemented (e.g. the "style_update()" function in that example)

It's possible our docs in 1.4.x are better at describing the stylebuffer stuff than the
older 1.3.x docs, I'm not sure. See e.g.

1. http://www.fltk.org/doc-1.4/classFl__Text__Display.html#ae09d61739b737a32868ffe0295a25dec
2. http://www.fltk.org/doc-1.4/classFl__Text__Buffer.html#a6a72d422478508c94baf5b6a7bc46740

Albrecht Schlosser

unread,
Aug 10, 2018, 5:38:30 AM8/10/18
to fltkg...@googlegroups.com
On 10.08.2018 07:00 Greg Ercolano wrote:
>
> Some follow up clarifications to my reply:
>
>> Yes -- in the above example, edit->sbuf gets you a pointer to the style buffer,
>> and edit->sbuf->text() gets you a pointer to the actual char* array.
>
> ..just to clarify that last bit, to change the colors of the text, I'm not sure
> if you can change the chars directly using the text() pointer (e.g. edit->sbuf->text()):
>
> char *p = edit->sbuf->text(); // get pointer to style buffer's char* array
> p[pos] = 'A'; // change the color of text at position 'p' to the color 'A'
>
> That might not be allowed, in which case to make changes you'd have to use Fl_Text_Buffer's
> methods to manipulate the buffer, e.g. replace() and insert() IIRC.

The text() method gives you a copy of the buffer's contents that you
must free() when done with it. You can modify it (i.e. it's "allowed",
not read-only) but this would be useless because it has no effect on the
real buffer contents.

... Unless you modify the data as in Greg's example above and use the
text(const char *text) method to reassign the entire modified text to
the buffer, but that would be wasteful. IMHO replace() and/or remove()
and insert() would be a better choice (confirming what Greg wrote already).

israel dahl

unread,
Aug 10, 2018, 8:38:44 AM8/10/18
to fltk.general
@Greg Ercolano
This is a great example, and thank you!  This is what would work the best in the easiest situation.
I like using FLUID for the interface design, so I wanted the style text buffer to be something I can access
similar to the object->buffer() to get the text buffer (maybe something like object->style_buffer(), or object->highlight_data()->buffer()),
without having to make a new implementation (so I could keep it visually in FLUID),
I suppose this is the best route to take though since this is easy and pretty trivial to do.  Thanks.

I have read the tutorial extensively and spent time looking through the "Syntax highlighting" portion,
the editor example text is the same as the tutorial, with some things spelled out more clearly, though the tutorial is great.
I simply hoped the FL_Text_Editor would have an internal variable for the style, that could be accessed like the internal variable
for the text buffer, or perhaps it has a struct containing the highlight data, which includes the buffer used for syntax highlighting.


@Albrecht Schlosser

It is a good point of clarification for anyone who does stumble across this not to modify the text directly.
I did mean modification in the way you reference, using the functions FLTK provides
style_buffer->remove_selection();
style_buffer->replace(...);
style_buffer->remove(...);
Or other relevant things, I mostly meant to ask if I there was a way to access
the highlight_data(style_buffer,....) style_buffer object after I send it in and use those functions on it.

Albrecht Schlosser

unread,
Aug 10, 2018, 9:08:39 AM8/10/18
to fltkg...@googlegroups.com
On 10.08.2018 14:38 israel dahl wrote:
>
> @Albrecht Schlosser
>
> [...] I mostly meant to ask if I there was a way to access
> the highlight_data(style_buffer,....) style_buffer object after I send
> it in and use those functions on it.

Yes, there is a way, but the according member variable is protected.
It's in Fl_Text_Display (the base class of Fl_Text_Editor):

Fl_Text_Buffer *mStyleBuffer;

So you could derive your own class from Fl_Text_Editor and write an
accessor method that returns the style buffer. It's not much less work
than Greg's proposal (you still need to derive a class) but you don't
need to store an extra pointer.

Note that you can use your own classes in fluid as well.

HTH.

FWIW: Besides that you could also add a public accessor method directly
to your version of FLTK by patching it.

I don't know if there are reasons NOT to add a public method to add the
protected mStyleBuffer member. There could well be reasons why it is
protected, but it may also be possible that a public accessor
(read-only) would be harmless. You could check the code yourself (sorry,
I'm too busy) and maybe file an STR to request a public accessor method
for the style buffer and maybe more if you think this is required or
useful.

Albrecht Schlosser

unread,
Aug 10, 2018, 9:12:07 AM8/10/18
to fltkg...@googlegroups.com
Sorry, there was a typo. Clarification:

On 10.08.2018 15:08 schrieb Schlosser wrote:
>
> I don't know if there are reasons NOT to add a public method to add the
> protected mStyleBuffer member.

should read: "... to *access* the protected mStyleBuffer member..."

israel dahl

unread,
Aug 21, 2018, 10:26:30 AM8/21/18
to fltk.general
I am still having issues with this, unfortunately.  It segfaults any time the callback is triggered after the initial loading.
I have tried both using the internal mStyleBuffer via get/set methods (similar to buffer()) and also adding a separate stylebuffer and textbuffer to my class

I even copied the editor example code directly into my project.

Since I do not know the internals of how the highlight_data function works (the docs are not very verbose there), nor do I know what it is expecting I am not entirely sure why it segfaults.

Can anyone enlighten me on this?

Greg Ercolano

unread,
Aug 21, 2018, 12:18:24 PM8/21/18
to fltkg...@googlegroups.com
On 08/21/18 07:26, israel dahl wrote:
> I am still having issues with this, unfortunately.  It segfaults any time the callback is triggered after the initial loading.
> I have tried both using the internal mStyleBuffer via get/set methods (similar to buffer()) and also adding a separate stylebuffer and textbuffer to my class
>
> I even copied the editor example code directly into my project.
>
> Since I do not know the internals of how the highlight_data function works (the docs are not very verbose there), nor do I know what it is expecting I am not entirely sure why it segfaults.
>
> Can anyone enlighten me on this?

Hmm, if you're getting segfaults out of even the editor example code,
then check your build environment.

Make sure the FLTK include files you're compiling with match the libs
you're linking with.

It's easy to get crashes with working code if you #include FLTK 1.3.x
files, but link against 1.4.x libs.

Assuming unix, check to make sure /usr/include/FL does not exist,
which might be pointing to an old FLTK version, and make sure your
compile and link lines both point at the same version of FLTK, e.g.

# COMPILE
g++ ... -I/usr/local/src/fltk-1.4.x ...

# LINK
ld ... -L/usr/local/src/fltk-1.4.x/lib ...

israel dahl

unread,
Aug 21, 2018, 1:39:53 PM8/21/18
to fltk.general


On Tuesday, August 21, 2018 at 11:18:24 AM UTC-5, Greg Ercolano wrote:
On 08/21/18 07:26, israel dahl wrote:
> I am still having issues with this, unfortunately.  It segfaults any time the callback is triggered after the initial loading.
> I have tried both using the internal mStyleBuffer via get/set methods (similar to buffer()) and also adding a separate stylebuffer and textbuffer to my class
>
> I even copied the editor example code directly into my project.
>
> Since I do not know the internals of how the highlight_data function works (the docs are not very verbose there), nor do I know what it is expecting I am not entirely sure why it segfaults.
>
> Can anyone enlighten me on this?

        Hmm, if you're getting segfaults out of even the editor example code,
        then check your build environment.

No not in the editor example.
That compiles fine, and my Makefile works great, I use a kind of template Makefile I made for all my FLTK programs (I have quite a few now).  I have also used cmake to compile FLTK programs, as well as g++ and of course fltk-config --compile.
This is not my first program, and certainly not the most complicated one (making an X11 dock indicator for volume control as well as battery levels using FLTK was more complicated than making a simple text editor following a well designed tutorial)

I included the code for the syntax highlighting in my editor
the functions
void stype_parse(const char* text, char * style, int length);
and
void update_style(int pos, int nInserted, int nDeleted, int, const char *, void *cbArg);

here is a bit of code to help make more sense
//stylebuffer is a part of my Fl_Syntax_Text_Editor class and is a Fl_Text_Buffer *
o
->highlight_data(o->stylebuffer, styletable, sizeof(styletable) / sizeof(styletable[0]), 'A', style_unfinished_cb, 0);
//textbuffer is a part of my Fl_Syntax_Text_Editor class and is a Fl_Text_Buffer *
o
->textbuffer->add_modify_callback(style_update, o);
/*
in style_update I access those variables using
:

((Fl_Syntax_Text_Editor *)cbArg)->stylebuffer
((Fl_Syntax_Text_Editor *)cbArg)->textbuffer
I have previously make sure those are not NULL, as well as the editor itself, but this does not help.
*/
o
->textbuffer->call_modify_callbacks();

But it will crash when I click on the Text_Editor with a segfault.
If I simply return instead of adding the modify callback the text editor program I made works perfectly well.
So, my main question is why the thing crashes.

How does highlight_data work, or the modify callbacks.  What do I need to check for?  I think it has to be something being NULL (why doesn't FLTK use std::string being a C++ library?), or being NULL (like some Fl_Widget*)

chris

unread,
Aug 21, 2018, 1:58:38 PM8/21/18
to fltkg...@googlegroups.com
Just a stab in the dark:

Did you also implement the things done with the

style_init()

method in the FLTK editor example, to set up the initial style buffer
sufficiently?

israel dahl

unread,
Aug 21, 2018, 2:21:17 PM8/21/18
to fltk.general


On Tuesday, August 21, 2018 at 12:58:38 PM UTC-5, chris wrote:
Just a stab in the dark:

Did you also implement the things done with the

  style_init()

AFAIK I did
method in the FLTK editor example, to set up the initial style buffer
sufficiently?
I do it in my constructor
// these are public member variables
changed
=0;
loading
=0;
// this sets the tab name to Untitled unless a file is chosen
filename
="Untitled";
textbuffer
= new Fl_Text_Buffer;
this->buffer(textbuffer);
char *style = new char[textbuffer->length() + 1];
char *text = textbuffer->text();
memset
(style, 'A', textbuffer->length());
stylebuffer
= new Fl_Text_Buffer(textbuffer->length());
style
[textbuffer->length()] = '\0';
style_parse
(text, style, textbuffer->length(),12);
stylebuffer
->text(style);
delete[] style;
free
(text);
If you notice any problems with it please let me know.
I really wish I could understand why/how this fails.
I guess I can attach my fld file of the program if anyone is interested in messing with it.

Greg Ercolano

unread,
Aug 21, 2018, 3:35:48 PM8/21/18
to fltkg...@googlegroups.com
On 08/21/18 10:39, israel dahl wrote:
> here is a bit of code to help make more sense
> |
> //stylebuffer is a part of my ||Fl_Syntax_Text_Editor ||class and is a Fl_Text_Buffer *
> o->highlight_data(o->stylebuffer,styletable,sizeof(styletable)/sizeof(styletable[0]),'A',style_unfinished_cb,0);
> |//|||textbuffer| is a part of my ||||Fl_Syntax_Text_Editor ||class and is a Fl_Text_Buffer *
> |o->textbuffer->add_modify_callback(style_update,o);
> /*
> in style_update I access those variables using|:
>
> |((Fl_Syntax_Text_Editor *)cbArg)->stylebuffer
> |((Fl_Syntax_Text_Editor *)cbArg)->|||textbuffer||
> I have previously make sure those are not NULL, as well as the editor itself, but this does not help.
> */
> o->textbuffer->call_modify_callbacks();
> |
>
> But it will crash when I click on the Text_Editor with a segfault.

Build with debugging enabled (-g) and run the app in gdb
so you can see where it's crashing.

You'll be able to get a calling stack to see where it's crashing.


> If I simply return instead of adding the modify callback the text editor program I made works perfectly well.
> So, my main question is why the thing crashes.

Well, one way to work towards determining this is to comment out the add modify code,
and slowly comment it back in a few lines at a time until it crashes.

Or, add fprintf(stderr) statements throughout that code to check pointers
for NULLs or overruns.

> How does highlight_data work,

The highlight data parallels the character buffer.
So if you have the text:

"hello world" // text

..then the highlight data should be the exact same sized string:

"hello world" // text
"AAAAAAAAAAA" // highlight data

..often "A" is used for normal text. Depends on the table you've set up
for mapping e.g. "A" to a normalcolor, and "B" to some other color, etc.

> or the modify callbacks.

The modify callback is called whenever the text editor contents is changed.

>  What do I need to check for?

The characters changed.

Your job in the modify callback is to:

> Detect inserted characters in the text, and enlarge the style buffer
> Detect deleted characters in the text, and shrink the style buffer
> Adjust the style buffer's contents for all modified text to be the color you want it to be

Look closely at the editor's style_update() code and understand analyze what
it's doing.

> I think it has to be something being NULL

Use gdb + debugging to find out why it's crashing.

When it crashes you can see the calling stack and function arguments
to see what's NULL (if anything), assuming you can't tell by peppering in
fprintf()'s.

I'd strongly suggest /studying/ the editor example's style_update() function.
Add printf()s to show the buffer's contents (text and style) so you can see what's
changing and when.

I recall that's what I did when I started doing serious style buffer work with
Fl_Text_Display.

> (why doesn't FLTK use std::string being a C++ library?),

Many embedded platforms don't support templates, and therefore the STL/STD lib.
So to support those platforms, FLTK avoids their use.

But this shouldn't matter; you can use STL/STD if you want to; the editor buffer's
methods do their own memory management (e.g. textbuf->replace()) and that's not
exposed to you. Whether it internally uses std or malloc or new is not a concern
of the app programmer.

AFAIK, the only new/delete and/or malloc/strdup/free stuff is just for temporary
values.. the editor's buffer handles its own memory management, you don't have
to know what it's doing internally.

> or being NULL (like some Fl_Widget*)

Use fprintf() or gdb to determine this.

A crash inside gdb will get you right away to the crash point, and state of the
program at the time of the crash so you can analyze the pointers and such with
gdb commands like "where" and "print" and such.

I have a cheat page on gdb commands if you're not familiar with them here:
http://seriss.com/cgi-bin/erco/view-cheat.cgi#GDB

Greg Ercolano

unread,
Aug 22, 2018, 12:29:11 PM8/22/18
to fltkg...@googlegroups.com
On 08/21/18 10:39, israel dahl wrote:
> How does highlight_data work, or the modify callbacks.  What do I need to check for?
FWIW, here's a simpler example than the editor that I whipped up.

This example just colors the chars 01234 in green, and 56789 in red.

Since it just colors individual digits, it reduces the code complexity in the
add_modify_callback(), so one can focus on the required mechanics of the widget.

Assuming this is considered useful, I'll see if I can add to our "examples" directory.

__________________________________________________________________________________ snip

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Text_Editor.H>

// Custom class to demonstrate a specialized text editor
class MyEditor : public Fl_Text_Editor {

Fl_Text_Buffer *tbuff; // text buffer
Fl_Text_Buffer *sbuff; // style buffer

// Modify callback handler
void ModifyCallback(int pos, // position of update
int nInserted, // number of inserted chars
int nDeleted, // number of deleted chars
int, // number of restyled chars (unused here)
const char*) { // text deleted (unused here)

// Nothing inserted or deleted?
if (nInserted == 0 && nDeleted == 0) return;

// Characters inserted into tbuff?
// Insert same number of chars into style buffer..
//
if (nInserted > 0) {
char *style = new char[nInserted + 1]; // temp buffer
memset(style, 'A', nInserted); // init style to "A"s
style[nInserted] = '\0'; // terminate string
sbuff->replace(pos, pos+nDeleted, style); // insert "A"s into style buffer
delete[] style; // done with temp buffer..
}

// Characters deleted from tbuff?
// Delete same number of chars from style buffer..
//
if ( nDeleted > 0 ) {
sbuff->remove(pos, pos + nDeleted);
return; // nothing more to do; deleting won't affect our single char coloring
}

// Focus on characters inserted
int start = pos;
int end = pos + nInserted;
//DEBUG fprintf(stderr, "add_modify_callback(): start/end=%d/%d, text='%.*s'\n", start, end, (end-start), tbuff->address(start));

// SIMPLE EXAMPLE:
// Color the digits 0-4 in green, 5-9 in red.
//
for ( int i=start; i<end; i++ ) {
unsigned int c = tbuff->char_at(i);
if ( strchr("01234", c) ) sbuff->replace(i, i, "B"); // style 'B' (green)
else if ( strchr("56789", c) ) sbuff->replace(i, i, "C"); // style 'C' (red)
else sbuff->replace(i, i, "A"); // style 'A' (black)
}
}

static void ModifyCallback_STATIC(int pos, // position of update
int nInserted, // number of inserted chars
int nDeleted, // number of deleted chars
int nRestyled, // number of restyled chars
const char *deletedText, // text deleted
void *cbarg) { // callback data
MyEditor *med = (MyEditor*)cbarg;
med->ModifyCallback(pos, nInserted, nDeleted, nRestyled, deletedText);
}

public:
MyEditor(int X,int Y,int W,int H) : Fl_Text_Editor(X,Y,W,H) {
// Style table for the respective styles
static const Fl_Text_Editor::Style_Table_Entry stable[] = {
// FONT COLOR FONT FACE FONT SIZE
// --------------- ----------- --------------
{ FL_BLACK, FL_COURIER, 14 }, // A - Black
{ FL_DARK_GREEN, FL_COURIER, 14 }, // B - Green
{ FL_RED, FL_COURIER, 14 }, // C - Red
};
tbuff = new Fl_Text_Buffer(); // text buffer
sbuff = new Fl_Text_Buffer(); // style buffer
buffer(tbuff);
int stable_size = sizeof(stable)/sizeof(stable[0]);
highlight_data(sbuff, stable, stable_size, 'A', 0, 0);
tbuff->add_modify_callback(ModifyCallback_STATIC, (void*)this);
}

void text(const char* val) {
tbuff->text(val);
}
};

int main() {
Fl_Window *win = new Fl_Window(720, 480, "Text Editor With Dynamic Coloring");
MyEditor *med = new MyEditor(10,10,win->w()-20,win->h()-20);
// Initial text in editor.
med->text("In this editor, digits 0-4 are shown in green, 5-9 shown in red.\n"
"So here's some numbers 0123456789.\n"
"Coloring is handled automatically by the add_modify_callback().\n"
"\n"
"You can type here to test. ");
win->resizable(med);
win->show();
return(Fl::run());
}

imm

unread,
Aug 22, 2018, 5:19:12 PM8/22/18
to general fltk
Hi Greg,

Well, I see your editor example and raise you - tabs!

ISTR the OP was interested in a tabbed editor with potentially
different styling on different tabs, so I thought I'd see if that
could be tacked on to your example. Seemed to work OK, though I'm not
convinced what I did is the most elegant solution in the end!

But here it is anyway.

+++++++++++++++++++++++++++++++++


#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Tabs.H>
// SIMPLE EXAMPLE:
// Color the digits 0-4 in green, 5-9 in red.
//
for ( int i=start; i<end; i++ ) {
unsigned int c = tbuff->char_at(i);
if ( strchr("01234", c) ) sbuff->replace(i, i, "B"); // style 'B' (green)
else if ( strchr("56789", c) ) sbuff->replace(i, i, "C"); // style 'C' (red)
else sbuff->replace(i, i, "A"); // style 'A' (black)
}
}

static void ModifyCallback_STATIC(int pos, // position of update
int nInserted, // number of inserted chars
int nDeleted, // number of deleted chars
int nRestyled, // number of restyled chars
const char *deletedText, // text deleted
void *cbarg) { // callback data
MyEditor *med = (MyEditor*)cbarg;
med->ModifyCallback(pos, nInserted, nDeleted, nRestyled, deletedText);
}

// Style table for the respective styles
Fl_Text_Editor::Style_Table_Entry stable[3];

public:
MyEditor(int X,int Y,int W,int H, Fl_Color CA, Fl_Color CB, Fl_Color
CC) : Fl_Text_Editor(X,Y,W,H) {
// // Style table for the respective styles
for (int idx = 0; idx < 3; ++idx)
{
stable[idx].font = FL_COURIER;
stable[idx].size = 14;
}
stable[0].color = CA;
stable[1].color = CB;
stable[2].color = CC;

tbuff = new Fl_Text_Buffer(); // text buffer
sbuff = new Fl_Text_Buffer(); // style buffer
buffer(tbuff);
int stable_size = sizeof(stable)/sizeof(stable[0]);
highlight_data(sbuff, stable, stable_size, 'A', 0, 0);
tbuff->add_modify_callback(ModifyCallback_STATIC, (void*)this);
}

void text(const char* val) {
tbuff->text(val);
}
};

int main() {

MyEditor *ee[3];

Fl_Double_Window *win = new Fl_Double_Window(720, 480, "Text Editor
With Dynamic Coloring");
win->begin();

Fl_Tabs* tabs = new Fl_Tabs(0, 0, 720, 480);

Fl_Group* t1 = new Fl_Group(0, 40, 720, 440, "TAB1");
t1->box(FL_THIN_UP_BOX);
ee[0] = new MyEditor(2,40,win->w()-5,win->h()-45, FL_BLACK,
FL_DARK_GREEN, FL_RED);
ee[0]->box(FL_THIN_DOWN_BOX);
t1->end();

Fl_Group* t2 = new Fl_Group(0, 40, 720, 440, "TAB2");
t2->box(FL_THIN_UP_BOX);
t2->hide();
ee[1] = new MyEditor(2,40,win->w()-5,win->h()-45, FL_RED, FL_BLUE, FL_MAGENTA);
ee[1]->box(FL_THIN_DOWN_BOX);
t2->end();

Fl_Group* t3 = new Fl_Group(0, 40, 720, 440, "TAB3");
t3->box(FL_THIN_UP_BOX);
t3->hide();
ee[2] = new MyEditor(2,40,win->w()-5,win->h()-45, FL_MAGENTA,
FL_DARK_YELLOW, FL_GREEN);
ee[2]->box(FL_THIN_DOWN_BOX);
t3->end();

tabs->end();

for (int idx = 0; idx < 3; ++idx)
{
// Initial text in editor.
ee[idx]->text("In this editor, digits 0-4 are shown in green, 5-9
shown in red.\n"
"So here's some numbers 0123456789.\n"
"Coloring is handled automatically by the add_modify_callback().\n"
"\n"
"You can type here to test. ");
}
win->end();
win->resizable(tabs);
win->show();
return(Fl::run());
}

// end of file //


================================================

imm

unread,
Aug 22, 2018, 5:20:30 PM8/22/18
to general fltk
Urgh! What happened to my formatting?
All my nicely indented code ruined...

I do not much care for this web interface now...

Greg Ercolano

unread,
Aug 22, 2018, 8:04:29 PM8/22/18
to fltk.general
On Wednesday, August 22, 2018 at 2:20:30 PM UTC-7, Ian MacArthur wrote:
Urgh! What happened to my formatting?
All my nicely indented code ruined...

Perhaps include as an attachment when using the web interface?

I do not much care for this web interface now...

I assume you mean the google groups interface?
I'm trying it here (typically I use the mailing list interface).

Testing with Firefox + google groups web interface:
__________________________________
No indent
    <-- 4 space indent
        <-- 8 space indent
__________________________________

And now again with fixed width font (Courier New):
__________________________________
No indent
    <-- 4 space indent
        <-- 8 space indent
__________________________________
 

israel dahl

unread,
Aug 24, 2018, 3:53:41 PM8/24/18
to fltk.general
Ok, I went through Ian/Greg's example and it all works now.
I kept the same style parsing code I previously had (really almost everything is the same).
The main difference is that I made a modify and static modify callback, and moved basically everything into the text editor subclass.

I suppose it was crashing because something was getting passed too many times, and it lost track of the address of the object somewhere.
all my gdb + std::cerr did not lead me to any idea of what was going wrong.... there was an FLTK function (named ?? by gdb... not helpful) that crashed every time... I am assuming it is the one related to the highlight_data function.

So long story short:
a non-static update_style() function with direct access to everything works really well called by a static one that just abstracts the void* cbarg to the class.
This is so obvious and makes complete sense.
I mark this solved

Greg Ercolano

unread,
Aug 28, 2018, 8:53:52 PM8/28/18
to fltkg...@googlegroups.com
On 08/24/18 12:53, israel dahl wrote:
> all my gdb + std::cerr did not lead me to any idea of what was going wrong.... there was an FLTK function
> (named ?? by gdb... not helpful) that crashed every time... I am assuming it is the one related to the
> highlight_data function.


For gdb to show the functions/variables within fltk (instead of "??")
you'd compile the fltk library with debugging enabled (configure --enable-debug)
and link your app with that.

If you're getting "??" for names from gdb, it means that function wasn't compiled
with the debugging flag (g++ -g). Without that, gdb can't resolve the function/variable
names, just the vm addresses.

When debugging is enabled, the binaries get larger because of all the symbol
information built into it that gdb would use, which is why debugging is not
on by default.

> I mark this solved

Great.

Greg Ercolano

unread,
Aug 28, 2018, 10:15:31 PM8/28/18
to fltkg...@googlegroups.com
On 08/22/18 09:29, Greg Ercolano wrote:
> On 08/21/18 10:39, israel dahl wrote:
>> How does highlight_data work, or the modify callbacks.  What do I need to check for?
> FWIW, here's a simpler example than the editor that I whipped up.
>
> This example just colors the chars 01234 in green, and 56789 in red.
>
> Since it just colors individual digits, it reduces the code complexity in the
> add_modify_callback(), so one can focus on the required mechanics of the widget.
>
> Assuming this is considered useful, I'll see if I can add to our "examples" directory.
>
> __________________________________________________________________________________ snip
> [..]

After some more in depth testing, I actually found a few bugs in the example code
I posted, which I'll include when I commit the code to the examples directory.

I noticed when inserting characters between the "01234" and "56789" in the example text
when the program opens, the colors started shifting.. a clear indication of a bug.

Reading the docs carefully, I realized I needed to change a few lines
of code in the example I posted.

#1: this change fixes an outright bug:

if (nInserted > 0) {
char *style = new char[nInserted + 1]; // temp buffer
memset(style, 'A', nInserted); // init style to "A"s
style[nInserted] = '\0'; // terminate string
- sbuff->replace(pos, pos+nDeleted, style); // insert "A"s into style buffer
+ sbuff->insert(pos, style); // insert "A"s into style buffer
delete[] style; // done with temp buffer..

..there's two problems there.

The use of 'nDeleted' seems wrong, as this is in a conditional where nInserted
is the focus, not nDeleted. Also, the use of replace() seems wrong, as insert()
is clearly the better choice.

The code I used for reference in this section is right out of the "editor" example,
so I think the editor has the same bug. But it's probably invisible in that application
due to the fact that code recalculates the colors *for the entire line*.

#2: I believe this change is also necessary:

- if ( strchr("01234", c) ) sbuff->replace(i, i, "B"); // style 'B' (green)
- else if ( strchr("56789", c) ) sbuff->replace(i, i, "C"); // style 'C' (red)
- else sbuff->replace(i, i, "A"); // style 'A' (black)
+ if ( strchr("01234", c) ) sbuff->replace(i, i+1, "B"); // style 'B' (green)
+ else if ( strchr("56789", c) ) sbuff->replace(i, i+1, "C"); // style 'C' (red)
+ else sbuff->replace(i, i+1, "A"); // style 'A' (black)

This is because, reading the docs for Fl_Text_Buffer::replace() carefully, note esp. the
description of 'end':

_________________________________________________________________________________
void Fl_Text_Buffer::replace(int start, int end, const char *text)

Deletes the characters between start and end, and inserts the null-terminated
string text in their place in the buffer.

Parameters
start byte offset to first character to be removed and new insert position
end byte offset *to character after last character to be removed*
text UTF-8 encoded and nul terminated text
_________________________________________________________________________________

..that 'after last character to be removed' bit implies that to change a single character,
you don't use start/end=i/i, you'd use start/end=i/i+1.

I'll post the final code in a bit, as soon as I do a few more checks.

Greg Ercolano

unread,
Aug 29, 2018, 3:19:26 PM8/29/18
to fltkg...@googlegroups.com
On 08/28/18 19:15, Greg Ercolano wrote:
 On 08/22/18 09:29, Greg Ercolano wrote:
 
After some more in depth testing, I actually found a few bugs in the example code

 
I posted, [..description and patches with changes snipped..]

 

 
I'll post the final code in a bit, as soon as I do a few more checks.

    OK, following up, here's the complete code
    with the mentioned fixes
highlighted in red:


#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Text_Editor.H>

// Custom class to demonstrate a specialized text editor
class MyEditor : public Fl_Text_Editor {

    Fl_Text_Buffer *tbuff;      // text buffer
    Fl_Text_Buffer *sbuff;      // style buffer

    // Modify callback handler
    void ModifyCallback(int pos,        // position of update
                        int nInserted,  // number of inserted chars
                        int nDeleted,   // number of deleted chars
                        int,            // number of restyled chars (unused here)
                        const char*) {  // text deleted (unused here)

        // Nothing inserted or deleted?
        if (nInserted == 0 && nDeleted == 0) return;

        // Characters inserted into tbuff?
        //     Insert same number of chars into style buffer..
        //
        if (nInserted > 0) {
            char *style = new char[nInserted + 1];  // temp buffer
            memset(style, 'A', nInserted);          // init style to "A"s
            style[nInserted] = '\0';                // terminate string
            sbuff->insert(pos, style);              // insert "A"s into style buffer
            delete[] style;                         // done with temp buffer..
        }

        // Characters deleted from tbuff?
        //    Delete same number of chars from style buffer..
        //
        if ( nDeleted > 0 ) {
            sbuff->remove(pos, pos + nDeleted);
            return;     // nothing more to do; deleting won't affect our single char coloring
        }

        // Focus on characters inserted
        int start  = pos;
        int end    = pos + nInserted;
        //DEBUG fprintf(stderr, "add_modify_callback(): start/end=%d/%d, text='%.*s'\n", start, end, (end-start), tbuff->address(start));

        // SIMPLE EXAMPLE:
        //     Color the digits 0-4 in green, 5-9 in red.
        //
        for ( int i=start; i<end; i++ ) {
            unsigned int c = tbuff->char_at(i);
            if      ( strchr("01234", c) ) sbuff->replace(i, i+1, "B");   // style 'B' (green)
            else if ( strchr("56789", c) ) sbuff->replace(i, i+1, "C");   // style 'C' (red)
            else                           sbuff->replace(i, i+1, "A");   // style 'A' (black)
        }
    }

    static void ModifyCallback_STATIC(int pos,                 // position of update
                                      int nInserted,           // number of inserted chars
                                      int nDeleted,            // number of deleted chars
                                      int nRestyled,           // number of restyled chars
                                      const char *deletedText, // text deleted
                                      void *cbarg) {           // callback data
        MyEditor *med = (MyEditor*)cbarg;
        med->ModifyCallback(pos, nInserted, nDeleted, nRestyled, deletedText);
    }

public:
    MyEditor(int X,int Y,int W,int H) : Fl_Text_Editor(X,Y,W,H) {
        // Style table for the respective styles
        static const Fl_Text_Editor::Style_Table_Entry stable[] = {
           // FONT COLOR      FONT FACE   FONT SIZE
           // --------------- ----------- --------------
           {  FL_BLACK,       FL_COURIER, 14 }, // A - Black
           {  FL_DARK_GREEN,  FL_COURIER, 14 }, // B - Green
           {  FL_RED,         FL_COURIER, 14 }, // C - Red
        };
        tbuff = new Fl_Text_Buffer();    // text buffer
        sbuff = new Fl_Text_Buffer();    // style buffer
        buffer(tbuff);
        int stable_size = sizeof(stable)/sizeof(stable[0]);
        highlight_data(sbuff, stable, stable_size, 'A', 0, 0);
        tbuff->add_modify_callback(ModifyCallback_STATIC, (void*)this);
    }

    void text(const char* val) {
        tbuff->text(val);
    }
};

int main() {
   Fl_Window *win = new Fl_Window(720, 480, "Text Editor With Dynamic Coloring");
   MyEditor  *med = new MyEditor(10,10,win->w()-20,win->h()-20);
   // Initial text in editor.
   med->text("In this editor, digits 0-4 are shown in green, 5-9 shown in red.\n"
             "So here's some numbers 0123456789.\n"
             "Coloring is handled automatically by the add_modify_callback().\n"
             "\n"
             "You can type here to test. ");
   win->resizable(med);
   win->show();
   return(Fl::run());
}




Ian MacArthur

unread,
Aug 29, 2018, 4:16:50 PM8/29/18
to fltkg...@googlegroups.com

> On 29 Aug 2018, at 03:15, Greg Ercolano wrote:
>
> ..that 'after last character to be removed' bit implies that to change a single character,
> you don't use start/end=i/i, you'd use start/end=i/i+1.
>

Yes - that’s consistent with what we found with the “tabs editor” test I think; though the need to go “beyond” the single character case is not all that obvious in the docs, perhaps?


Ian MacArthur

unread,
Aug 29, 2018, 4:28:44 PM8/29/18
to fltkg...@googlegroups.com


> On 29 Aug 2018, at 03:15, Greg Ercolano wrote:
>
> I noticed when inserting characters between the "01234" and "56789" in the example text
> when the program opens, the colors started shifting.. a clear indication of a bug.


This seems to be tied into the replace method start/end/(end+1) issue - in the last version of my tabs test, this works correctly, but in earlier iterations it fails as you describe.

With the end / end+1 thing sorted, it’s good however.




>
> The use of 'nDeleted' seems wrong, as this is in a conditional where nInserted
> is the focus, not nDeleted. Also, the use of replace() seems wrong, as insert()
> is clearly the better choice.

Indeed: in my tests, nDeleted is *always* zero at the point that this code runs, however, so in a sense it sort of does the “right thing” anyway, I think?



Greg Ercolano

unread,
Aug 29, 2018, 5:22:16 PM8/29/18
to fltkg...@googlegroups.com
BTW, the new example code was committed to svn as r13034 in 1.4.x
The docs actually seem clear to me on this particular item; that's in fact
how I caught the issue. Quoting the docs:

Parameters
start byte offset to first character to be removed and new insert position
end byte offset to character >>after last character to be removed<<
text UTF-8 encoded and nul terminated text

..that bit about >>after last character to be removed<< made perfect sense to me,
so I can't fault them.

An example showing how to replace a single character would nail it down, though.
I'll see about doing that.

So PEBKAC in my case, lol. I shouldn't have just taken the editor example's code
without double-checking all the parameters of the calls. Since the example was
a "quickie" to help the OP, didn't do a full check on everything.

>> The use of 'nDeleted' seems wrong, as this is in a conditional where nInserted
>> is the focus, not nDeleted. Also, the use of replace() seems wrong, as insert()
>> is clearly the better choice.
>
> Indeed: in my tests, nDeleted is *always* zero at the point that this code runs,
> however, so in a sense it sort of does the “right thing” anyway, I think?

Yes, I suppose so.

I wasn't sure about the odd case where if the user does a copy/paste operation
that replaces a large string with a smaller string; would that do a combo
of a delete and insert? e.g.

Run the example
Highlight the letters "au" in "automatically", and hit ^C to copy
Highlight the word "numbers" and hit ^V

That ^V operation does two things: first deletes the word "numbers",
then inserts the "automatically". This creates two invocations of the
add_modify_callback().

I would have thought that could be done in a single call where nInserted
and nDeleted might both be >0 in a single call, as the docs don't seem to
guard against that situation, but it's certainly clearer to treat such an
operation as two separate calls, to get the order of operations right.

Ian MacArthur

unread,
Aug 30, 2018, 4:14:34 PM8/30/18
to fltkg...@googlegroups.com

On 29 Aug 2018, at 22:22, Greg Ercolano wrote:
>
> I wasn't sure about the odd case where if the user does a copy/paste operation
> that replaces a large string with a smaller string; would that do a combo
> of a delete and insert? e.g.
>
> Run the example
> Highlight the letters "au" in "automatically", and hit ^C to copy
> Highlight the word "numbers" and hit ^V
>
> That ^V operation does two things: first deletes the word "numbers",
> then inserts the "automatically". This creates two invocations of the
> add_modify_callback().
>

Yes, that’s what I saw in my tests too. I was a bit surprised, that seemed unexpected...


> I would have thought that could be done in a single call where nInserted
> and nDeleted might both be >0 in a single call, as the docs don't seem to
> guard against that situation, but it's certainly clearer to treat such an
> operation as two separate calls, to get the order of operations right.

Yes, I agree. Doing it in 2 passes makes it cleaner, I think.

It does mean that our style callback (well, the modify callback in general) might possibly be simpler, as you “know” that certain operations will not happen together, I suppose?



Greg Ercolano

unread,
Aug 30, 2018, 4:32:04 PM8/30/18
to fltkg...@googlegroups.com
On 08/30/18 13:14, Ian MacArthur wrote:
>> I would have thought that could be done in a single call where nInserted
>> and nDeleted might both be >0 in a single call, as the docs don't seem to
>> guard against that situation, but it's certainly clearer to treat such an
>> operation as two separate calls, to get the order of operations right.
>
> Yes, I agree. Doing it in 2 passes makes it cleaner, I think.
>
> It does mean that our style callback (well, the modify callback in general)
> might possibly be simpler, as you “know” that certain operations will not
> happen together, I suppose?

I've created a thread on fltk.coredev for my reply:
Subject: Fl_Text_Buffer highlight_data/style buffer [moved from fltk.general]


israel dahl

unread,
Aug 30, 2018, 10:01:56 PM8/30/18
to fltk.general
I have yet another interesting question, since you guys are quite well versed (and I have of course read Mr. Ercolano's web page about FLTK examples numerous times)
Couldn't FLTK offer a Syntax Highlighted Text Editor out of the box?

And the other part of the question... would it be possible to rework the functions to leverage already available syntax highlighting configurations?
This may not be doable, since FLTK is cross platform....

If this is not possible, could it be possible to make a configurable plugin system of simple text files (or headers?) that could support more languages.

After watching the conversations on this thread I fully believe most of you here have more skill than I (I have only been doing this a few years now).

As a GNU/Linux user, syntax highlighting is pretty much the default standard for any good text editing program.

I completely understand if this is far beyond the scope of this discussion, it is a rather large project since languages have many variances (python, c and bash scripts do similar things very differently for example).

Greg Ercolano

unread,
Aug 30, 2018, 10:25:19 PM8/30/18
to fltkg...@googlegroups.com
On 08/30/18 19:01, israel dahl wrote:
> Couldn't FLTK offer a Syntax Highlighted Text Editor out of the box?

I think fluid's code editor is that; it highlights C++ syntax
in real time.

I'm not sure if the implementation allows for other languages easily..
for instance I doubt it uses an ascii-file to define the syntax parsing
the way e.g. VIM does with its syntax files.

I'd love to see someone come up with an 'advanced FLTK examples' page,
something like my cheat page, but for really advanced stuff.

We had some of this type of thing with FLTK extensions like FLEK, FLVW,
and others whose names escape me at the moment. But such libs take time
and effort to not only write, but keep alive..

israel dahl

unread,
Feb 2, 2019, 6:11:31 PM2/2/19
to fltk.general
Hey everyone, I solved this by using a heavily modified version of https://github.com/ArashPartow/lexertk
This might be a good way to create an Fl_Syntax_Text_editor to include in a later version of FLTK.
However, it does include things you don't want in fltk (std::string for example).  But it could offer a good idea, I know @Greg Ercolano has made a lot of the cool things I use frequently (thanks by the way).
It is extremely fast, and can reparse the entire file in much less time than the basic example code.

I just thought I'd throw this out here since you included the nanosvg code from one of our earlier discussions about creating an SVG Image in FLTK.

Thanks for all the help you all have given over the years, it has made me really enjoy the possibilities and learn more about my favorite toolkit!

Sanel Z.

unread,
Feb 3, 2019, 11:53:51 AM2/3/19
to fltkg...@googlegroups.com, israel dahl
You can also try with https://github.com/sanel/Fl_Highlight_Editor

New languages can be added easily and built-in interpreter will compile everything when object is loaded, so there will be minimal performance hit.

Best,
Sanel

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

israel dahl

unread,
Feb 5, 2019, 12:30:04 PM2/5/19
to fltk.general


On Sunday, February 3, 2019 at 10:53:51 AM UTC-6, Sanel Zukan wrote:
You can also try with https://github.com/sanel/Fl_Highlight_Editor

New languages can be added easily and built-in interpreter will compile everything when object is loaded, so there will be minimal performance hit.

Best,
Sanel

Hi Sanel,
I will check this out!  Does it parse the entire textbuffer on each modified callback?
I may make a secondary version of my text editor that uses yours and compare the two outputs.  Also, I am interested in how the styletable is handled, so I'll definitely look into it Thanks!

Sanel Zukan

unread,
Feb 6, 2019, 2:27:01 PM2/6/19
to israel dahl, fltk.general
> Does it parse the entire textbuffer on each modified callback?

Only modified parts.

> Also, I am interested in how the styletable is handled, so I'll
> definitely look into it Thanks!

Styletable is loaded and set when file extension is detected, based on
mode rules [1].

Modes are similar to Emacs modes - script files with custom keywords and
colors/faces for those keywords (eg. for c++ files [2]).

Faces are abstracted from color values (face is actually color + font +
font size) so creating new themes is fairly trivial. Here is example how
dark theme is defined [3].

[1] https://github.com/sanel/Fl_Highlight_Editor/blob/master/scheme/editor.ss#L157
[2] https://github.com/sanel/Fl_Highlight_Editor/blob/master/scheme/modes/c%2B%2B-mode.ss
[3] https://github.com/sanel/Fl_Highlight_Editor/blob/master/scheme/editor.ss#L223

Best,
Sanel

anmol....@gmail.com

unread,
Sep 27, 2021, 6:13:00 PM9/27/21
to fltk.general
Hi Sanel.

Is there a way to dynamically change the modes ? Or even the scheme from lite to dark ?
For example, one may decide to load the file via a string. When this happens - the loadfile() code is not used and the styletable is not loaded. 
The ability to set the styletable (modes) and change schemes dynamically is useful. 

Reply all
Reply to author
Forward
0 new messages