modify this for colorful scroll mark symbol.
#include "slick.sh"
#import "main.e"
#include "markers.sh"
int s_modtimeSymHighlight = -1;
int s_markertypeSymHighlight = -1;
int s_timerSymHighlight = -1;
_str s_searchString = '';
_str s_symTags[];
int s_keyColour:[];
int def_sym_highlight_delay = 5000;
static int scroll_mark_type[];
static int colorindex[];
static int gerror_scroll_mark_type = 0;
static int oldColor = 0;
struct SymColour
{
int m_ColourSymHighlight;
int m_cRef; // used for delayed color creation and selection.
int m_rgb;
int m_scolType;
} s_symColour[];
_command void CycleSymHighlight() name_info(',')
{
_str sym = cur_word(start_col);
if (length(sym) != 0)
{
int i;
boolean fAdd = true;
for (i = 0; i < s_symTags._length() && fAdd; i++)
{
if (s_symTags == sym)
{
fAdd = false;
if (s_keyColour._indexin(sym))
{
int iColour = s_keyColour:[sym];
s_symColour[iColour].m_cRef -= 1;
iColour = (iColour + 1) % s_symColour._length();
s_keyColour:[sym] = iColour;
s_symColour[iColour].m_cRef += 1;
EnsureColour(iColour);
UpdateScreen(true /* update now */)
}
}
}
if (fAdd)
{
ToggleSymHighlight();
}
}
}
static int _error_scroll_marker_get_type(int color)
{
int index;
for(index = 0; index < s_symColour._length(); index ++)
{
if(color == s_symColour[index].m_ColourSymHighlight)
{
break;
}
}
if(index >= s_symColour._length())
{
index = 0;
}
return scroll_mark_type[index];
}
void scrolllmarkerinfo()
{
int i = 0;
SCROLLBAR_MARKUP_INFO scrollMarkupInfo[];
//get_window_id(p_window_id);
_ScrollMarkupGetMarkup(p_window_id,scrollMarkupInfo);
message("len:"scrollMarkupInfo._length());
for (i = 0; i < scrollMarkupInfo._length(); i++) {
message("len:"scrollMarkupInfo._length()"line"scrollMarkupInfo.lineNumber"type"scrollMarkupInfo.type"len"scrollMarkupInfo.len);
_ScrollMarkupRemoveAllType(scrollMarkupInfo.type);
}
}
void removeallscrolllmarker(int wid)
{
int i = 0;
SCROLLBAR_MARKUP_INFO scrollMarkupInfo[];
_ScrollMarkupGetMarkup(wid,scrollMarkupInfo);
for (i = 0; i < scrollMarkupInfo._length(); i++) {
// message("len:"scrollMarkupInfo._length()"line"scrollMarkupInfo.lineNumber"type"scrollMarkupInfo.type"len"scrollMarkupInfo.len);
_ScrollMarkupRemoveAllType(scrollMarkupInfo.type);
}
}
void removeallmarker()
{
int i = 0;
SCROLLBAR_MARKUP_INFO scrollMarkupInfo[];
get_window_id(auto orig_view);
_ScrollMarkupGetMarkup(orig_view,scrollMarkupInfo);
for (i = 0; i < scrollMarkupInfo._length(); i++) {
// message("len:"scrollMarkupInfo._length()"line"scrollMarkupInfo.lineNumber"type"scrollMarkupInfo.type"len"scrollMarkupInfo.len);
_ScrollMarkupRemoveAllType(scrollMarkupInfo.type);
}
}
/* T O G G L E S Y M H I G H L I G H T */
/*----------------------------------------------------------------------------
%%Function: ToggleSymHighlight
%%Author: MarkSun
%%Owner: MarkSun
If the IP is on an identifier, either add it or remove it from the list
of identifiers we're tracking for highlighting purposes.
----------------------------------------------------------------------------*/
_command void ToggleSymHighlight() name_info(',')
{
int start_col;
int i;
_str sym;
if (_select_type()!='')
{
begin_select();
_deselect();
}
sym = cur_word(start_col);
if (length(sym) != 0)
{
boolean fAdd = true;
for (i = 0; i < s_symTags._length();i++)
{
if (s_symTags == sym)
{
fAdd = false;
s_symTags._deleteel(i);
break;
}
}
if (fAdd)
{
int cTags = s_symTags._length();
s_symTags[cTags] = sym;
s_symTags._sort("D");
if (s_symTags._length() != cTags + 1)
{
say("Failed to add tag: " :+ sym);
}
}
if (s_symTags._length() > 0)
{
s_searchString = _escape_re_chars(s_symTags[0], 'U');
for (i = 1; i < s_symTags._length(); i++)
{
s_searchString :+= '|' :+ _escape_re_chars(s_symTags, 'U');
}
}
else
{
s_searchString = '';
_StreamMarkerRemoveType (p_window_id, s_markertypeSymHighlight);
removeallmarker();
}
UpdateScreen(true /* update now */)
if (!fAdd && s_keyColour._indexin(sym))
{
int index = s_keyColour:[sym];
if (index < 0 || index > s_symColour._length())
{
say("bad index in keycolour for: " :+sym);
}
else
{
if (index > s_symColour._length())
{
say("bad index for symColour (index/sym): ":+index:+"/":+sym);
}
else if (s_symColour[index].m_cRef <= 0)
{
say("bad cRef in symColour when deleting: " :+ sym);
}
else
{
s_symColour[index].m_cRef -= 1;
s_keyColour._deleteel(sym);
}
}
}
else if (!fAdd)
{
say("Failed to remove keycolour for: ":+sym);
}
}
}
static void _InitSymColour()
{
s_symColour[0].m_ColourSymHighlight = -1;
s_symColour[0].m_rgb = _rgb(0xff, 0x00, 0x00);/* red */
s_symColour[0].m_cRef = 0;
s_symColour[1].m_ColourSymHighlight = -1;
s_symColour[1].m_rgb = _rgb(0x00, 0x00,0xff );/* green */
s_symColour[1].m_cRef = 0;
s_symColour[2].m_ColourSymHighlight = -1;
s_symColour[2].m_rgb = _rgb(0xff, 0x00, 0xff);/* red + blue */
s_symColour[2].m_cRef = 0;
s_symColour[3].m_ColourSymHighlight = -1;
s_symColour[3].m_rgb = _rgb(0xff, 0xff, 0x00);/* red + green */
s_symColour[3].m_cRef = 0;
s_symColour[4].m_ColourSymHighlight = -1;
s_symColour[4].m_rgb = _rgb(0x00, 0xff, 0xff);/* green + blue */
s_symColour[4].m_cRef = 0;
}
static void _InitScrollMark()
{
colorindex[0] = _AllocColor();
colorindex[1] = _AllocColor();
colorindex[2] = _AllocColor();
colorindex[3] = _AllocColor();
colorindex[4] = _AllocColor();
scroll_mark_type[0] = _ScrollMarkupAllocType();
_default_color(colorindex[0], _rgb(0x00, 0x00, 0x00), s_symColour[0].m_rgb, 0);
_ScrollMarkupSetTypeColor(scroll_mark_type[0],colorindex[0]);
_default_color(colorindex[1], _rgb(0x00, 0x00, 0x00), s_symColour[1].m_rgb, 0);
scroll_mark_type[1] = _ScrollMarkupAllocType();
_ScrollMarkupSetTypeColor(scroll_mark_type[1],colorindex[1]);
_default_color(colorindex[2], _rgb(0x00, 0x00, 0x00), s_symColour[2].m_rgb, 0);
scroll_mark_type[2] = _ScrollMarkupAllocType();
_ScrollMarkupSetTypeColor(scroll_mark_type[2],colorindex[2]);
_default_color(colorindex[3], _rgb(0x00, 0x00, 0x00), s_symColour[3].m_rgb, 0);
scroll_mark_type[3] = _ScrollMarkupAllocType();
_ScrollMarkupSetTypeColor(scroll_mark_type[3],colorindex[3]);
_default_color(colorindex[4], _rgb(0x00, 0x00, 0x00), s_symColour[4].m_rgb, 0);
scroll_mark_type[4] = _ScrollMarkupAllocType();
_ScrollMarkupSetTypeColor(scroll_mark_type[4],colorindex[4]);
}
_command void DbgDumpSymHighlight() name_info(',')
{
int i;
say ("--- SymHighlight dump: " :+ _time('L'));
say ("search string:");
say (" " :+ s_searchString);
say ("word list:");
for (i = 0; i < s_symTags._length(); i++)
{
say (" " :+ (i+1) :+ ": " :+ s_symTags);
}
say ("Colours index for words:");
for (i = 0; i < s_symTags._length(); i++)
{
if (s_keyColour._indexin(s_symTags))
{
say (" " :+ s_symTags :+ ": " :+ s_keyColour:[s_symTags] + 1);
}
else
{
say (" " :+ s_symTags :+ ": no current colour");
}
}
say ("colour cRefs:");
for (i = 0; i < s_symColour._length(); i++)
{
say (" " :+ (i + 1) :+ ": " :+ s_symColour.m_cRef);
}
say ("--- End SymHighlight dump");
}
void DoClearAllSymHighlightStructs()
{
int i;
s_symTags._makeempty();
s_searchString = '';
for (i = 0; i < s_symColour._length(); i++)
{
if (s_symColour.m_cRef > 0)
{
s_symColour.m_cRef = 0;
}
}
s_keyColour._makeempty();
}
/* C L E A R A L L S Y M H I G H L I G H T */
/*----------------------------------------------------------------------------
%%Function: ClearAllSymHighlight
%%Author: MarkSun
%%Owner: MarkSun
Bring up a dialog listing all identifiers that we are currently highlighting.
If you respond Yes, then clear the entire list.
----------------------------------------------------------------------------*/
_command void ClearAllSymHighlight() name_info(',')
{
_str result;
_str messageString = "Clear the following list?\n\n";
int i;
for (i = 0; i < s_symTags._length(); i++)
{
messageString :+= (i+1) :+ ": " :+ s_symTags :+ "\n";
}
//result=_message_box(messageString, '', MB_YESNO|MB_ICONQUESTION);
//if (result==IDYES)
{
DoClearAllSymHighlightStructs();
UpdateScreen(true);
}
_RemoveAllScrollMarker();
}
void _RemoveAllScrollMarker()
{
get_window_id( auto orig_view);
activate_window (_mdi.p_child);
for_each_mdi_child('removeallmarker','');
activate_window(orig_view);
}
void _UpdateWindow()
{
typeless p,m,ss,sf,sw,sr,sf2;
_save_pos2(p);
save_selection(m);
save_search(ss, sf, sw, sr, sf2);
_StreamMarkerRemoveType (p_window_id, s_markertypeSymHighlight);
removeallscrolllmarker(p_window_id);
if (s_symTags._length() != 0)
{
_deselect();
top();
// if ( !search('(?:' :+ s_searchString :+ ')', '<U@WXC') )
if ( !search(s_searchString, '<U@W') )
{
do
{
s = strip( get_text( match_length(), (int)_QROffset() ), 'T' );
long offset_highlight = _QROffset();
int length_Highlight = s._length();
int pos_marker = _StreamMarkerAdd( p_window_id,
offset_highlight,
length_Highlight,
true, 0,
s_markertypeSymHighlight, '');
_StreamMarkerSetTextColor(pos_marker, GetSymHighlightColour(s));
int line =(int) _QLineNumberFromOffset(offset_highlight);
int error_scroll_markup_type = _error_scroll_marker_get_type(GetSymHighlightColour(s));
// message("p_window_id:"p_window_id"p_line:"p_line"line:"line"s:"s":"s_markertypeSymHighlight"scroll:"error_scroll_markup_type);
_ScrollMarkupAdd(p_window_id, line, error_scroll_markup_type);
}
while (!repeat_search( '<U@W'));
}
}
restore_search( ss, sf, sw, sr, sf2);
restore_selection(m);
_restore_pos2(p);
refresh();
}
/* U P D A T E S C R E E N */
/*----------------------------------------------------------------------------
%%Function: UpdateScreen
%%Author: MarkSun
%%Owner: MarkSun
Goes through the current buffer and update the highlights based on current
information.
----------------------------------------------------------------------------*/
static void UpdateScreen(boolean fNow)
{
get_window_id( auto orig_view);
activate_window (_mdi.p_child);
if (s_modtimeSymHighlight != p_LastModified || fNow)
{
s_modtimeSymHighlight = p_LastModified;
for_each_mdi_child('-UpdateWindow','');
}
activate_window(orig_view);
}
/* S Y M H I G H L I G H T C A L L B A C K */
/*----------------------------------------------------------------------------
%%Function: SymHighlightCallback
%%Author: MarkSun
%%Owner: MarkSun
Callback to periodically ensure the current buffer has been updated.
----------------------------------------------------------------------------*/
void SymHighlightCallback()
{
if ( !p_mdi_child || command_state())
{
return;
}
if (_idle_time_elapsed() < def_sym_highlight_delay)
{
return;
}
UpdateScreen(false /* update now */);
}
static void EnsureColour(int iColour)
{
if (s_symColour[iColour].m_ColourSymHighlight == -1)
{
s_symColour[iColour].m_ColourSymHighlight = _AllocColor();
_default_color(s_symColour[iColour].m_ColourSymHighlight,
_rgb(0x00, 0x00, 0x00), s_symColour[iColour].m_rgb, 0);
}
}
static int IGetNextSymColour()
{
int i, iMac;
int iTarget = 0, iTargetVal = s_symColour[0].m_cRef;
iMac = s_symColour._length();
if (iTargetVal != 0)
{
for (i = 1; i < iMac; i++)
{
if (s_symColour.m_cRef < iTargetVal)
{
iTargetVal = s_symColour.m_cRef;
iTarget = i;
if (iTargetVal == 0)
break;
}
}
}
s_symColour[iTarget].m_cRef += 1;
EnsureColour(iTarget);
if (iTarget < 0 || iTarget >= iMac)
{
say ("Bad colour index returned in IGetNextSymColour: ":+iTarget);
}
return iTarget;
}
/* G E T S Y M H I G H L I G H T C O L O U R */
/*----------------------------------------------------------------------------
%%Function: GetSymHighlightColor
%%Author: Setup the highlighting colour
%%Owner: Setup the highlighting colour
----------------------------------------------------------------------------*/
static int GetSymHighlightColour(_str strKey)
{
if (!s_keyColour._indexin(strKey))
{
s_keyColour:[strKey] = IGetNextSymColour();
}
else if (s_keyColour:[strKey] < 0 || s_keyColour:[strKey] >= s_symColour._length())
{
say ("index for '":+strKey:+"' out of range: ":+s_keyColour:[strKey]);
s_keyColour:[strKey] = IGetNextSymColour();
}
else if (s_symColour[s_keyColour:[strKey]].m_cRef == 0)
{
say ("Hit recovery code in GetSymHighlightColour");
s_keyColour:[strKey] = IGetNextSymColour();
}
return s_symColour[s_keyColour:[strKey]].m_ColourSymHighlight;
}
/* D E F E R R E D I N I T S Y M H I G H L I G H T */
/*----------------------------------------------------------------------------
%%Function: DeferredInitSymHighlight
%%Author: MarkSun
%%Owner: MarkSun
Start up our callback function.
I do not know why deferring the init is good, I copied this from another
macro.
----------------------------------------------------------------------------*/
static void DeferredInitSymHighlight()
{
if ( !pos( "-mdihide", _editor_cmdline, 1, 'i' ) )
{
if ( s_markertypeSymHighlight < 0 )
s_markertypeSymHighlight = _MarkerTypeAlloc();
else
_StreamMarkerRemoveAllType( s_markertypeSymHighlight );
if ( s_timerSymHighlight >= 0 )
_kill_timer( s_timerSymHighlight );
_InitSymColour();
_InitScrollMark();
DoClearAllSymHighlightStructs();
s_timerSymHighlight = _set_timer( def_sym_highlight_delay, SymHighlightCallback );
}
}
/* D E F I N I T */
/*----------------------------------------------------------------------------
%%Function: definit
%%Author: MarkSun
%%Owner: MarkSun
Initialize this module.
----------------------------------------------------------------------------*/
definit()
{
s_modtimeSymHighlight = -1;
if (arg(1) != 'L')
{
s_timerSymHighlight = -1;
s_markertypeSymHighlight = -1;
}
_post_call( DeferredInitSymHighlight );
}
_command void removeallscrollmarker() name_info(',')
{
ClearAllSymHighlight();
}
_command void select_string() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
typeless mypos;
save_pos(mypos);
if (_in_string()) {
// find the start of the string
while (_in_string()) {
if (cursor_left_with_line_wrap()) {
break;
}
}
if (!_in_string())
cursor_right_with_line_wrap();
}
else {
// find first string on the line
_begin_line();
while (!_in_string()) {
if (cursor_right_with_line_wrap()) {
restore_pos(mypos);
return;
}
}
}
// move off the leading quote
cursor_right_with_line_wrap();
_select_char();
while (_in_string()) {
if (cursor_right_with_line_wrap()) {
break;
}
}
cursor_left_with_line_wrap();
_select_char();
restore_pos(mypos);
}