Fun with Line Flags!

, , , , , , , , Sunday, October 26, 2008

Lineflags, as defined below and in the macros that follow, are an important
element driving the attributes, behavior and display of specific types of lines
of text in a Slickedit editing session. Lineflags are used in such modules as
mouse.e, seldisp.e, util.e, builtins.e, surround.e, markfilt.e, guireplace.e,
javadoc.e and many more.

Some of the more common examples of commands that use lineflags include 'all',
'less', 'hide_all_comments', 'plusminus', 'show_braces', and 'show_paragraphs.'
A few of the uses of lineflags include the setting of levels of nested comments
and selectively displayed lines, the setting of 'no save' lines in Diffzilla,
the 'plus' or 'minus' bitmaps shown in the left margins of selective displays,
and even in the color or box appearance of the current line.

Additionally, lineflags account for the differently colored labels used to
identify 'inserted' and 'modified' lines in the lefthand margins or linenumbers
area of speacific lines in a file. Some types of lineflags set the visible
appearance of lines and some are used unseen in the background.

The basic function for manipulating lineflags, taken from Slickedit Help, is
'_lineflags', as follows. (For added flavor, I've included the bit values in
hex and decimal that are set by a few of the lineflags. I gathered these bits
from a source file in which the constants were set, in an earlier version of
Slickedit. I haven't been able to find them in the current Slickedit 2008 and
recent versions.)

Following this Help information, I present several of my 'Fun With Lineflags'
macros.)

int _lineflags(int newflags=0, int mask=newflags)

Gets or sets the line status flags for the current line. If the flags argument
is given, the line status flags for the current line are modified. mask
defaults to the same value as flags if it is not specified. The mask indicates
which bits will be set according to flags.

MLCOMMENTINDEX_LF
Indicates which multi-line comment. Only two are allowed. Must know which
multi-line comment we are in so we know what will terminate it.

MLCOMMENTLEVEL_LF
Indicates multi-line comment nest level.
Used by Difference Editor and Merge Editor. Lines with the NOSAVE_LF flag set
are not saved in the file. VIMARK_LF Used by VI emulation to mark lines.

MODIFY_LF
Line has been modified.

INSERTED_LINE_LF
Line was inserted.

HIDDEN_LF 0x00001000 4096
Indicates that this line should not be displayed.

PLUSBITMAP_LF 0x00004000 16384
Display "+" bitmap to left of this line.

MINUSBITMAP_LF 0x00002000 8192
Display "-" bitmap to left of this line.

CURLINEBITMAP_LF
Display current line bitmap.

LEVEL_LF 0x001F8000 2064384
Bits used to store selective display nest level.

NEXTLEVEL_LF 0x00008000 32768

The MLCOMMENT flags can not be modified.

Returns: int
The new current line status flags for the current line.


Examples:

if (_lineflags() & INSERTED_LINE_LF) {
messageNwait("This line was inserted");
}
if (_lineflags() & MODIFY_LF) {
messageNwait("This line was modified");
}
// Turn on hidden flag
_lineflags(HIDDEN_LF,HIDDEN_LF);
if (_lineflags() & HIDDEN_LF) {
messageNwait("HIDDEN flag is on");

}
// Turn off HIDDEN flag
_lineflags(0,HIDDEN_LF);
if (!(_lineflags() & HIDDEN_LF)) {
messageNwait("hidden flag is off");
}

Applies To:
Edit Window, Editor Control

Categories:
CursorMovement Functions, Edit Window Methods, Editor Control Methods


FUN WITH LINEFLAGS--GETTING DOWN TO BUSINESS

Below are several macros I created to explore possible novel uses of lineflags.
I've refrained from including a couple related commands because they are not
ready for prime time.

Try these on sample files that you can afford to mess up. Generally the
operations are easily reversible (as in the toggle commands), but be
particularly careful applying the NOSAVE_LF. In some situations NOSAVE Lines
may be deleted permanently when you close a file containing them.

// clf_toggle: this command toggles the 'current line' flag on any line you
// choose. 'clf' in the command name means 'current line flag.' In this
// particular implementation, the 'current line' flag appears as a green triangle
// in the left margin. You can toggle the current line flag on and off easily if
// you bind the command to a key. Each time the command is issued, the existing
// flag is toggled and the cursor moves down one line.

// toggle CLF (current line flag) for current line
_command clf_toggle()
{
if (!(_lineflags() & CURLINEBITMAP_LF)) {
_lineflags(CURLINEBITMAP_LF,CURLINEBITMAP_LF);
} else {
_lineflags(0,CURLINEBITMAP_LF);
}
down();
}


// turn ON ALL CLF indicators and flags in a file
// turn CLF ON for ALL lines
_command clf_all_lines()
{
if (p_mode_name=='Fileman') {
deselect_all();
} else {
save_pos(p)
top();up();
_lineflags(CURLINEBITMAP_LF,CURLINEBITMAP_LF);
for (;;) {
if (down()) break;
_lineflags(CURLINEBITMAP_LF,CURLINEBITMAP_LF);
}
restore_pos(p);
}
}


// turn OFF ALL CLF indicators and flags in a file
// turn CLF OFF for ALL lines
_command clf_no_lines()
{
if (p_mode_name=='Fileman') {
deselect_all();
} else {
save_pos(p)
top();up();
_lineflags(0,CURLINEBITMAP_LF);
for (;;) {
if (down()) break;
_lineflags(0,CURLINEBITMAP_LF);
}
restore_pos(p);
}
}

// turn CLF ON for lines matching search string in the current buffer
// for example, 'all_clf /VSARG2/' will add the current line flag to all
// lines containg 'VSARG2'--like the 'all' command. You might want to change the
// command name, since it can be confused with 'clf_all_lines.
_command all_clf(...) name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
int strcount;
int linecount;
_str searchstr=arg(1);
parse searchstr with delim +1 sstring(delim)opts

save_pos(p);
top(); up();

status=search(sstring, 'i>':+opts);
if (!status) {
strcount=1;
curline=p_line;
linecount=1;
_lineflags(CURLINEBITMAP_LF,CURLINEBITMAP_LF);
} else {
restore_pos(p);
message get_message(status);
stop;
}

for (;;) {
status=search(sstring, 'i>':+opts);
if (status !=0) {
break
} else {
_lineflags(CURLINEBITMAP_LF,CURLINEBITMAP_LF);
++strcount;

if (!(curline==p_line)) {
++linecount;
curline=p_line;
}

}
}
restore_pos(p);
message(strcount' occurrence(s) in ' linecount ' lines');
}


// 'NO-SAVE LINE' FLAG (displys the Slickedit default or user-set background
// color for 'no save' lines. 'NLF' means NOSAVE lineflag.)
// toggle NLF for current line
_command nlf_toggle() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
if (!(_lineflags() & 2)) {
_lineflags(NOSAVE_LF,NOSAVE_LF);
} else {
_lineflags(0,NOSAVE_LF);
}
cursor_down();
}

// turn NLF ON for ALL lines
_command nlf_all_lines()
{
if (p_mode_name=='Fileman') {
deselect_all();
} else {
save_pos(p)
top();up();
_lineflags(NOSAVE_LF,NOSAVE_LF);
for (;;) {
if (down()) break;
_lineflags(NOSAVE_LF,NOSAVE_LF);
}
restore_pos(p);
}
}

// turn NLF OFF for ALL lines
_command nlf_no_lines()
{
if (p_mode_name=='Fileman') {
deselect_all();
} else {
save_pos(p)
top();up();
_lineflags(0,NOSAVE_LF);
for (;;) {
if (down()) break;
_lineflags(0,NOSAVE_LF);
}
restore_pos(p);
}
}

// turn NLF ON for lines matching search string in current buffer
_command all_nlf(...) name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
int strcount;
int linecount;
_str searchstr=arg(1);
parse searchstr with delim +1 sstring(delim)opts

save_pos(p);
top(); up();

status=search(sstring, 'i>':+opts);
if (!status) {
strcount=1;
curline=p_line;
linecount=1;
_lineflags(NOSAVE_LF,NOSAVE_LF);
} else {
restore_pos(p);
message get_message(status);
stop;
}

for (;;) {
status=search(sstring, 'i>':+opts);
if (status !=0) {
break
} else {
_lineflags(NOSAVE_LF,NOSAVE_LF);
++strcount;

if (!(curline==p_line)) {
++linecount;
curline=p_line;
}

}
}
restore_pos(p);
message(strcount' occurrence(s) in ' linecount ' lines');
}

// turn NLF AND CLF OFF for ALL lines
_command untag_all_nlfclf()
{
if (p_mode_name=='Fileman') {
deselect_all();
} else {
save_pos(p)
top();up();
_lineflags(0,CURLINEBITMAP_LF);
_lineflags(0,NOSAVE_LF);
for (;;) {
if (down()) break;
_lineflags(0,CURLINEBITMAP_LF);
_lineflags(0,NOSAVE_LF);
}
restore_pos(p);
}
}

// Setting PLUS and MINUS BITMAPS

// If a 'plus' and 'minus' bitmap is shown in left margin of the current line,
// running this command on that line will remove the bitmap and its associated
// lineflag.
_command set_plusminus_lf_off()
name_info(','VSARG2_REQUIRES_EDITORCTL) {
if (_lineflags() & (PLUSBITMAP_LF|MINUSBITMAP_LF)) {
_lineflags(0,PLUSBITMAP_LF|MINUSBITMAP_LF);
cursor_down();
}
}

// sets hidden lineflag on and hides the line
_command set_hidden_lf_on() name_info(','VSARG2_REQUIRES_EDITORCTL)
{
_lineflags(HIDDEN_LF,HIDDEN_LF);
if (!(_lineflags() & HIDDEN_LF)) {
messageNwait("hidden flag is off");
}
}

// hides lines in the numeric range specified in the argument
// For example, 'hide_lines 30 50' will hide file lines 30-50 and
// indicate them by showing a 'plus' mark (collapsed/hidden lines) in the margin

_command hide_lines(...) name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY|VSARG2_CMDLINE)
{
parse arg(1) with first_line last_line

if (first_line>last_line) {
p_line=last_line;
return(1);
}
p_line=first_line;
// IF we are on line#0 and we are not displaying tof line
if (_on_line0() && !_default_option('t')) {
++first_line;
status=down();
if (status || first_line>=last_line) {
p_line=last_line;
return(-1);
}
}
cur_lineflags=_lineflags();
up();
prev_lineflags=_lineflags();
// IF this is case 1 or 3
if (!(prev_lineflags & (PLUSBITMAP_LF|MINUSBITMAP_LF)) &&
(prev_lineflags & LEVEL_LF)==(cur_lineflags & LEVEL_LF)) {
new_level=(prev_lineflags& LEVEL_LF) + NEXTLEVEL_LF;
// messageNwait("hide_selection: case 1 or 3");
// IF this is case 2
} else if ((prev_lineflags & (PLUSBITMAP_LF|MINUSBITMAP_LF)) &&
!(cur_lineflags & (PLUSBITMAP_LF|MINUSBITMAP_LF))
) {
p_line=last_line;
return(0);
// IF this is case 4 or 5
} else {
p_line=last_line;
return(0);
}

_lineflags(PLUSBITMAP_LF,PLUSBITMAP_LF|MINUSBITMAP_LF);
down();
start_level=new_level-NEXTLEVEL_LF;
doEndLastLevel=true;
for (;;) {
level=(_lineflags() & LEVEL_LF);
if (levellast_line) {
break;
}
}
if (doEndLastLevel) {
for (;;) {
new_level= (_lineflags() & LEVEL_LF)+NEXTLEVEL_LF;
if (new_level /*(_lineflags() & LEVEL_LF)*/<=start_level+NEXTLEVEL_LF) { break; } _lineflags(HIDDEN_LF|new_level,HIDDEN_LF|LEVEL_LF); status=down(); if (status) break; } } p_line=last_line;
}


0 comments:

Post a Comment

GlossyBlue Blogger by Black Quanta. Theme & Icons by N.Design Studio
Entries RSS Comments RSS