//===========================================================================
// This module implements commands for highlighting all occurences of current
// word, selected text or regular expression with one of 7 predefined colors.
//
// 'highlight_textN' commands, where N is from 1 to 7, highlight all
// occurences of current word or selected text with color N. Selected text
// can not span more than current line. If cursor is on existing highlight
// then that highlight is cleared.
//
// 'highlight_reN' commands, where N is from 1 to 7, prompt user for a Perl
// regular expression and highlight all occurences with color N.
//
// 'highlight_text_clear_all' command clears all highlights created with
// 'highlight_textN' or 'highlight_reN' commands.
//
// Predefined colors are stored in 's_colors' array. You can change them
// to your taste.
//
// 'highlight_text_bind_keys' command binds 'highlight_textN', 'highlight_reN'
// and 'highlight_text_clear_all' commands all at once. Default bindings are
// Ctrl-1 to Ctrl-7, Ctrl-Shift-1 to Ctrl-Shift-7 and Ctrl-0 keys. Customize
// this command to your taste.
//
// By default searching for text to highlight is case-insensitive and not
// restricted to whole words. Two commands 'highlight_text_toggle_case_sensitive'
// and 'highlight_text_toggle_whole_word' toggle the flags.
//
// It is trivial to add more colors: add a color entry into 's_colors' and add
// new 'highlight_text'/'highlight_re' commands.
//===========================================================================
#pragma option (pedantic,on)
#include "slick.sh"
#include "markers.sh"
#import "seek.e"
#import "main.e"
#import "markfilt.e"
#import "mprompt.e"
#import "stdcmds.e"
#import "stdprocs.e"
//---------------------------------------------------------------------------
/**
* Colors used for highlights. Each 'highlight_textN' command corresponds to
* one of these colors. 'highlight_text1' uses color at index 0 and so on. You
* may change or rearrange colors here. If you want more colors, just add a
* color here and then add another 'highlight_text' and 'highlight_re' command
* using one of existing as a template.
*/
static int s_colors[] = {
0x0080FFFF, // yellow
0x0080FF80, // green
0x00FFFF80, // cyan
0x00FFC080, // blue
0x00FFA0FF, // magenta
0x00A0A0FF, // rose
0x0080C0FF // gold
};
//---------------------------------------------------------------------------
/**
* Holds information for highlighting with one color.
*/
struct HighlightInfo
{
int markerType; // separate marker type for easy removal of all markers with this color
int colorId; // color ID returned by _AllocColor()
_str text; // text to search for
boolean useRegEx; // use or not regular expressions
};
//---------------------------------------------------------------------------
/**
* Array for highlight information, one element per highlight color.
*
* This is a global variable, and as such it stays allocated and assigned even
* if this module is reloaded. The module is reloaded often during development
* and I don't want to exhaust editor's marker and color heaps, thus I
* initialize this array only if it is empty.
*
* Note that when this module is unloaded manually with unload() command, the
* global variables are removed completely and we probably get a resource leak.
*/
HighlightInfo g_highlightInfo[];
/**
* Global variable controlling if searches for highlight strings are
* case-sensitive. Toggled by 'highlight_text_toggle_case_sensitive' command.
*/
boolean g_highlightTextCaseSensitive = false;
/**
* Global variable controlling if searches for highlight strings are looking for
* whole words only. Toggled by 'highlight_text_toggle_whole_word' command.
*/
boolean g_highlightTextWholeWord = false;
/**
* Global variable holding update timer ID. It is global so that we may stop old
* timer when reloading this module during development.
*/
int g_highlightTextUpdateTimerId = -1;
//---------------------------------------------------------------------------
/**
* Keeps last value of p_LastModified property to update highlights only if any
* changes have been done to current buffer, including buffer switching.
*/
static int s_lastModified = 0;
/**
* Keeps last regular expression entered. Used as a prompt for a new one.
*/
static _str s_lastRegEx;
//===========================================================================
// Commands
//===========================================================================
//---------------------------------------------------------------------------
/**
* Binds 'highlight_textN', 'highlight_reN' and 'highlight_text_clear_all'
* commands at once.
*
* Customize to your taste.
*/
_command void highlight_text_bind_keys() name_info (',')
{
int tabIndex = find_index ('default_keys', EVENTTAB_TYPE);
bindCommandToKey (tabIndex, 'highlight_text_clear_all', 'C-0');
bindCommandToKey (tabIndex, 'highlight_text1', 'C-1');
bindCommandToKey (tabIndex, 'highlight_text2', 'C-2');
bindCommandToKey (tabIndex, 'highlight_text3', 'C-3');
bindCommandToKey (tabIndex, 'highlight_text4', 'C-4');
bindCommandToKey (tabIndex, 'highlight_text5', 'C-5');
bindCommandToKey (tabIndex, 'highlight_text6', 'C-6');
bindCommandToKey (tabIndex, 'highlight_text7', 'C-7');
bindCommandToKey (tabIndex, 'highlight_re1', 'C-S-1');
bindCommandToKey (tabIndex, 'highlight_re2', 'C-S-2');
bindCommandToKey (tabIndex, 'highlight_re3', 'C-S-3');
bindCommandToKey (tabIndex, 'highlight_re4', 'C-S-4');
bindCommandToKey (tabIndex, 'highlight_re5', 'C-S-5');
bindCommandToKey (tabIndex, 'highlight_re6', 'C-S-6');
bindCommandToKey (tabIndex, 'highlight_re7', 'C-S-7');
_config_modify_flags (CFGMODIFY_KEYS);
save_config();
}
//---------------------------------------------------------------------------
static void bindCommandToKey (int tabIndex, _str commandName, _str keyName)
{
int cmdIndex = find_index (commandName, COMMAND_TYPE);
int keyIndex = event2index (name2event (keyName));
if (!cmdIndex)
say ('Command '''commandName''' not found');
if (keyIndex < 0)
say ('Invalid key '''keyName'''');
if (cmdIndex && keyIndex >= 0)
set_eventtab_index (tabIndex, keyIndex, cmdIndex);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 1.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text1() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (0);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 2.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text2() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (1);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 3.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text3() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (2);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 4.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text4() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (3);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 5.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text5() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (4);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 6.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text6() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (5);
}
//---------------------------------------------------------------------------
/**
* Highlights all occurences of current word or selected text with color 7.
* Selected text can not span more than current line. If cursor is on existing
* highlight then that highlight is cleared.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_text7() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightCurrentText (6);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 1.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re1() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (0);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 2.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re2() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (1);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 3.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re3() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (2);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 4.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re4() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (3);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 5.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re5() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (4);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 6.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re6() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (5);
}
//---------------------------------------------------------------------------
/**
* Prompts user for a regular expression and highlights all occurences with
* color 7.
*
* Colors are hardcoded in 'highlight_text.e' module.
*/
_command void highlight_re7() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
highlightRegEx (6);
}
//---------------------------------------------------------------------------
/**
* Clears all highlights created with 'highlight_textN' or 'highlight_reN'
* commands.
*/
_command void highlight_text_clear_all() name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL|VSARG2_LINEHEX)
{
stopTimer();
int i;
for (i = 0; i < g_highlightInfo._length(); ++i) {
g_highlightInfo[i].text._makeempty();
refreshHighlightInAllBuffers (i);
}
}
//---------------------------------------------------------------------------
/**
* Toggles 'g_highlightTextCaseSensitive' global variable that affects case
* sensitivity of highlights searches.
*/
_command void highlight_text_toggle_case_sensitive() name_info (',')
{
g_highlightTextCaseSensitive = !g_highlightTextCaseSensitive;
int i;
for (i = 0; i < g_highlightInfo._length(); ++i)
refreshHighlightInAllBuffers (i);
message ('Text highlights are now case-'(g_highlightTextCaseSensitive ? '' : 'in')'sensitive');
}
//---------------------------------------------------------------------------
/**
* Toggles 'g_highlightTextCaseSensitive' global variable that affects case
* sensitivity of highlights searches.
*/
_command void highlight_text_toggle_whole_word() name_info (',')
{
g_highlightTextWholeWord = !g_highlightTextWholeWord;
int i;
for (i = 0; i < g_highlightInfo._length(); ++i)
refreshHighlightInAllBuffers (i);
message ('Text highlights now are '(g_highlightTextWholeWord ? '' : 'NOT ')'restricted to whole words');
}
//===========================================================================
// Implementation functions
//===========================================================================
//---------------------------------------------------------------------------
static void highlightCurrentText (int highlightIndex)
{
if (!_isEditorCtl (false))
return;
// First check if cursor is on any of our highlight and turn it off if so
int currHighlightIndex = getHighlightIndex();
if (currHighlightIndex != -1) {
g_highlightInfo[currHighlightIndex].text._makeempty();
maybeStopTimer();
refreshHighlightInAllBuffers (currHighlightIndex);
return;
}
if (highlightIndex < 0 || highlightIndex >= g_highlightInfo._length())
return;
// Now highlight current word or selection if it is longer than 2 characters,
// otherwise clear this highlight
_str text = getWordOrSelection();
if (text._length() < 2) {
g_highlightInfo[highlightIndex].text._makeempty();
maybeStopTimer();
}
else {
g_highlightInfo[highlightIndex].text = text;
g_highlightInfo[highlightIndex].useRegEx = false;
}
refreshHighlightInAllBuffers (highlightIndex);
}
//---------------------------------------------------------------------------
/**
* Implementation of 'highlight_reN' commands. Prompts user for a regular
* expression and highlights all occurences with color 'highlightIndex'.
*/
static void highlightRegEx (int highlightIndex)
{
if (!_isEditorCtl (false))
return;
_str prompt = (s_lastRegEx._length() > 0 ? s_lastRegEx : getWordOrSelection());
dlgResult := textBoxDialog (
'Enter Perl regular expression to highlight', // form caption
0, // flags
1440 * 4, // text box width
'Perl regular expressions', // help item
'', // buttons and captions
'', // retrieve name
'Expression:'prompt // prompt
);
if (dlgResult == COMMAND_CANCELLED_RC)
return;
_str text = strip (_param1);
if (text._length() > 3) {
s_lastRegEx = text;
g_highlightInfo[highlightIndex].text = text;
g_highlightInfo[highlightIndex].useRegEx = true;
refreshHighlightInAllBuffers (highlightIndex);
}
}
//---------------------------------------------------------------------------
/**
* Searches for text stored in 'g_highlightInfo' array at 'highlightIndex' and
* marks each match using corresponding color. If text is empty then just
* removes particular highlight.
*/
static void refreshHighlight (int highlightIndex)
{
if (highlightIndex < 0 || highlightIndex >= g_highlightInfo._length())
return;
_StreamMarkerRemoveType (p_window_id, g_highlightInfo[highlightIndex].markerType);
if (g_highlightInfo[highlightIndex].text._isempty())
return;
if (g_highlightInfo[highlightIndex].colorId < 0)
g_highlightInfo[highlightIndex].colorId = _AllocColor (/*fg*/ 0, /*bg*/s_colors[highlightIndex]);
save_pos (auto savePos);
save_search (auto s1, auto s2, auto s3, auto s4, auto s5);
top();
// Initialize search options
_str options = '@>'; // no error msg, place cursor at end of string
if (!g_highlightTextCaseSensitive)
options :+= 'I'; // case insensitive
if (g_highlightTextWholeWord)
options :+= 'W'; // word search
if (g_highlightInfo[highlightIndex].useRegEx)
options :+= 'L'; // use Perl regex
// Search for text and add a stream marker for each match
int status = search (g_highlightInfo[highlightIndex].text, options);
if (status != 0) {
// Search string not found. If this is because invalid regular
// expression is used then there is no need to keep it
if (status == INVALID_REGULAR_EXPRESSION_RC) {
message (get_message (INVALID_REGULAR_EXPRESSION_RC));
g_highlightInfo[highlightIndex].text._makeempty();
maybeStopTimer();
}
}
else {
// Got a match. Mark it and repeat
do {
int markerId = _StreamMarkerAdd (p_window_id, match_length ('S'), match_length(),
/*real offset*/ false, 0, g_highlightInfo[highlightIndex].markerType, '');
_StreamMarkerSetTextColor (markerId, g_highlightInfo[highlightIndex].colorId);
} while (repeat_search (options) == 0);
startTimer();
}
restore_search (s1, s2, s3, s4, s5);
restore_pos (savePos);
}
//---------------------------------------------------------------------------
/**
* Refreshes given highlight index in all buffers.
*/
static void refreshHighlightInAllBuffers (int highlightIndex)
{
int currWindowId;
save_view (currWindowId);
int currBufId = p_buf_id;
do {
if ( !(p_buf_flags & VSBUFFLAG_HIDDEN))
refreshHighlight (highlightIndex);
_next_buffer ('HNR');
} while (currBufId != p_buf_id);
activate_window (currWindowId);
}
//---------------------------------------------------------------------------
/**
* Starts update timer. The timer will be stopped when no more highlights are
* left.
*/
static void startTimer()
{
if (g_highlightTextUpdateTimerId < 0)
g_highlightTextUpdateTimerId = _set_timer (500, updateHighlightsTimerProc);
}
//---------------------------------------------------------------------------
/**
* Stops update timer.
*/
static void stopTimer()
{
if (g_highlightTextUpdateTimerId >= 0) {
_kill_timer (g_highlightTextUpdateTimerId);
g_highlightTextUpdateTimerId = -1;
}
}
//---------------------------------------------------------------------------
/**
* Stops update timer if there are no highlights left.
*/
static void maybeStopTimer()
{
int i;
for (i = 0; i < g_highlightInfo._length(); ++i) {
if (!g_highlightInfo[i].text._isempty())
return;
}
stopTimer();
}
//---------------------------------------------------------------------------
/**
* Refreshes all active highlights if editor is idle for more that 0.2 seconds
* and current buffer has changed.
*/
static void updateHighlightsTimerProc()
{
if (_no_child_windows() || _idle_time_elapsed() < 200)
return;
// Switch context to current MDI window
int saveWId = p_window_id;
p_window_id = _mdi.p_child;
// Check if buffer has been modified since last update (p_LastModified is
// incremented with each change)
if (s_lastModified != p_LastModified) {
s_lastModified = p_LastModified;
// Refresh highlights
int i;
for (i = 0; i < g_highlightInfo._length(); ++i) {
refreshHighlight (i);
}
}
p_window_id = saveWId;
}
//---------------------------------------------------------------------------
/**
* Returns index in 'g_highlightInfo' array if cursor is on text marked with one
* of our highlights. Returns -1 if no highlight at cursor position.
*/
static int getHighlightIndex()
{
int list[];
int offset = _nrseek();
int searchOffset = offset - p_col + 1; // search from the beginning of current line only
int i;
// Use _StreamMarkerFindList() to get a list of marks of specific (our) type
// at cursor position. If list is not empty then cursor is on a mark
for (i = 0; i < g_highlightInfo._length(); ++i) {
_StreamMarkerFindList (list, p_window_id, offset, 1, searchOffset, g_highlightInfo[i].markerType);
if (!list._isempty())
return i;
}
return -1;
}
//---------------------------------------------------------------------------
/**
* Returns a string containing current selection if selection is fully on the
* current line or current word.
*/
static _str getWordOrSelection()
{
if (select_active() && _select_type() != 'LINE' && _begin_select_compare() == 0 && _end_select_compare() == 0) {
// CHAR or BLOCK selection begins and ends on current line
int firstCol, lastCol, bufId;
_get_selinfo (firstCol, lastCol, bufId);
if (_select_type ('', 'I') || _select_type() == 'BLOCK')
++lastCol; // inclusive selection
//say ('firstCol='firstCol', lastCol='lastCol);
return strip (_expand_tabsc (firstCol, lastCol - firstCol));
}
else
return cur_word (0, '', true);
}
//---------------------------------------------------------------------------
_command void highlight_text_dump_debug_info() name_info (',')
{
say ('--- highlight_text.e dump begin');
int i;
for (i = 0; i < g_highlightInfo._length(); ++i) {
say (
(i+1)": marker type=" g_highlightInfo[i].markerType :+
", colorId=" g_highlightInfo[i].colorId :+
", regex=" g_highlightInfo[i].useRegEx :+
", text='" (g_highlightInfo[i].text._isempty() ? '' : g_highlightInfo[i].text) "'"
);
}
say ('g_highlightTextUpdateTimerId='g_highlightTextUpdateTimerId);
say ('s_lastModified='s_lastModified', p_LastModified='p_LastModified);
say ('--- highlight_text.e dump end');
}
//===========================================================================
// Module initialization
//===========================================================================
//---------------------------------------------------------------------------
definit()
{
boolean firstTimeInit = g_highlightInfo._isempty(); // this is the very first time this module is loaded
boolean haveHighlight = false;
int i;
// (Re)initialize g_highlightInfo array. For some reason SE gives runtime
// errors during multifile search if colors are allocates and set here.
// Therefore I deferred color initialization till the first use
for (i = 0; i < s_colors._length(); ++i) {
if (firstTimeInit) {
g_highlightInfo[i].markerType = _MarkerTypeAlloc(); // allocating markers here seems safe
_MarkerTypeSetFlags (g_highlightInfo[i].markerType, VSMARKERTYPEFLAG_AUTO_REMOVE);
g_highlightInfo[i].colorId = -1;
}
if (g_highlightInfo[i].colorId >= 0) {
_FreeColor (g_highlightInfo[i].colorId);
g_highlightInfo[i].colorId = -1;
}
if (!g_highlightInfo[i].text._isempty())
haveHighlight = true;
}
// Restart update timer if we already have any highlights. This may happen
// during development if this module is reloaded. Our timer ID variable is
// global, therefore we have a chance to stop the old timer first to avoid
// a leak of timer IDs and "Invalid function pointer" error when old timer
// tries to call nonexistent callback.
//
// Callback address can be made fixed by declaring callback globally, but it
// is not necessary if we stop an old timer here
if (haveHighlight) {
stopTimer();
startTimer();
}
}
//
/**
* Description: IDA-like Automatic Highlight for Slickedit 2007/2008
* Copyright: Megatops Software. 2007-11-1
* Author: Ding Zhaojie, zhaojie.ding@gmail.com
*
* ========================[ Revision History ]=============================
* Name Date Description
* ---------------------------------------------------------------------------
* Ding Zhaojie 2007-11-1 Initial version.
* Ding Zhaojie 2009-1-26 Supports selection highlighting.
*/
#pragma option(strict, on)
/************************* [ INCLUDE FILES ] ****************************/
#include 'slick.sh'
/************************* [ LOCAL DEFINITIONS ] ****************************/
#define HL_TIMER 100
#define HL_DELAY 10
/************************* [ DECLARATIONS ] ****************************/
/************************* [ PUBLIC DATA ] ****************************/
/************************* [ PRIVATE DATA ] ****************************/
static int timer = -1;
/************************* [ PRIVATE FUNCTIONS ] ****************************/
static void
get_highlight_text(_str &text, _str &flag)
{
typeless junk;
if (select_active()) {
int start_col = 0, end_col = 0, lines = 0;
_get_selinfo(start_col, end_col, junk, '', junk, junk, junk, lines);
if (_select_type('') != 'LINE' && lines == 1) {
text = _expand_tabsc(start_col, end_col - start_col);
flag = "";
return;
}
}
text = cur_word(junk);
flag = "W";
}
static void
highlight_timer()
{
static int last_bufid;
static _str last_word;
if (_no_child_windows() || (_idle_time_elapsed() < HL_DELAY)) {
return;
}
int orig_wid = p_window_id;
p_window_id = _mdi.p_child;
_str cur_word, flag;
get_highlight_text(cur_word, flag);
/* check last highlight, prevent do the same highlighting twice */
if (last_bufid == p_buf_id && cur_word == last_word) {
p_window_id = orig_wid;
return;
}
clear_highlights();
if (cur_word != "") {
typeless r1, r2, r3, r4, r5;
save_search(r1, r2, r3, r4, r5);
mark_all_occurences(cur_word, flag,
VSSEARCHRANGE_CURRENT_BUFFER, MFFIND_CURBUFFERONLY,
0, true, false, false);
message("IDA-like Highlight: \"" cur_word "\"");
restore_search(r1, r2, r3, r4, r5);
}
last_word = cur_word;
last_bufid = p_buf_id;
refresh();
p_window_id = orig_wid;
}
static void
start_module()
{
if (timer < 0) {
timer = _set_timer(HL_TIMER, highlight_timer);
message("IDA-like Highlight Activated!");
}
}
static void
end_module()
{
if (timer >= 0) {
_kill_timer(timer);
timer = -1;
clear_highlights();
message("IDA-like Highlight Deactivated!");
}
}
/************************* [ PUBLIC FUNCTIONS ] ****************************/
_command void
ida_like_highlight() name_info(',')
{
if (timer < 0) {
start_module();
} else {
end_module();
}
}
/* Kill ida_like_highlight if we load/unload the module */
void _on_load_module_ida_like_highlight(_str module)
{
end_module();
}
void _on_unload_module_ida_like_highlight(_str module)
{
end_module();
}
void _exit_ida_like_highlight()
{
end_module();
}
definit()
{
timer = -1;
}