Showing posts with label Slickedit. Show all posts
Showing posts with label Slickedit. Show all posts
, , , Saturday, April 12, 2014 1 comments

mark_duplicates command: Marks adjacent duplicate lines in the current buffer by prepending each duplicated line with ">> ", then displays the number of times lines are duplicated.

Two duplicate adjacent lines count as 1 duplicate, 3 duplicate adjacent lines count as 2 duplicates, 4 duplicate adjacent lines count as 3 duplicates, and so on.

This is Slickedit's remove_duplicates command, with a symbol (">> ") marking the duplicates and a count. No lines are removed. A possible useful option to add would be to fold the dupes into a  selective display, showing only the first instance of lines that are duplicated.
_command void mark_duplicates(_str ignore_case='') name_info(','VSARG2_EDITORCTL|VSARG2_REQUIRES_EDITORCTL|VSARG2_MARK)
{
   int start_line=0;
   int last_line=MAXINT;
   if (select_active2()) {
      if (_select_type()=='CHAR') {
         _select_type("","L","LINE");
      }
      _begin_select();
      start_line=p_line;
      _end_select();
      last_line=p_line;
   }
   _mark_duplicates(ignore_case,start_line,last_line);
}
/**
 * Marks duplicate adjacent lines in the current buffer.
 * Usually the buffer is sorted before calling this function.
 * 
 * @param ignore_case      'i' for case sensitive
 * @param start_line       starting line (inclusive)
 * @param last_line        last line (inclusive)
 * 
 * @appliesTo Edit_Window, Editor_Control
 * 
 * @categories Edit_Window_Methods, Editor_Control_Methods
 */
void _mark_duplicates(_str ignore_case='',int start_line=0,int last_line=MAXINT)
{
   // if this is a list box, then use the more effecient builtin method
   boolean listbox_object = (p_object == OI_LIST_BOX);
   if (listbox_object) {
      _lbremove_duplicates(ignore_case, start_line, last_line-start_line);
      return;
   }

   // convert case argument to boolean
   ignore_case=upcase(ignore_case)=='I';

   // compute the start line
   if (start_line>0) {
      p_line=start_line;
   } else {
      top();
      start_line=1;
   }

   // compute the last line
   if (last_line==MAXINT) {
      last_line=p_Noflines;
   }

   // go through the lines
   int count=last_line-start_line;
   int dupcount=0;
   _str previous_line='', line='';
   get_line(previous_line);

   if (ignore_case) {
      // case insensitive
      for (;count-->0;) {
         down();
         get_line(line);
         if (strieq(line,previous_line)) {
             dupcount=dupcount+1;
            up(); replace_line(">> ":+line);
            down(); replace_line(">> ":+line);
         }
         previous_line=line;
      }
   } else {
      // case sensitive
      for (;count-->0;) {
         down();
         get_line(line);
         if ( line:==previous_line ) {
             dupcount=dupcount+1;
            up(); replace_line(">> ":+line);
            down(); replace_line(">> ":+line);
         }
         previous_line=line;
      }
      message("Duplicate count = " dupcount);
   }
}

Count Lines Traversed

, , , , , , , , , , , Tuesday, March 17, 2009 0 comments

// Using the cursor-up or cursor-down keys,
// display on the message line the total number
// of lines the cursor has moved.


// Assign
a key combination to the line_counter
// command. Press the key combo to start the counter.
// It initializes with a value of 0. Press ESC to stop.
//
// Move your cursor up or down to reach your target.
// The target is typically a certain number of lines you
// want to traverse, or some specific text you want to
// reach. With each cursor-up/down keystroke the displayed
// count will decrement or increment by 1.
Moving the
// cursor up
will decrement the number of lines;
// moving the cursor down increments the line count.
// Change this if you want.
//
// This macro can actually be valuable once in a while.
// But I must plead ignorant for now; I've forgotten what I
// use it for!

_command line_counter() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
lines=0;
message('Number of lines traversed='lines)

for (;;) {
key = get_event();
keyname=event2name(key);

if (keyname=='DOWN') {
cursor_down();
++lines;
}

if (keyname=='UP') {
cursor_up();
--lines;
}
message('Linecount='lines)

if (keyname=='ESC') {
message('Linectr cancelled')
break;
}
}
}

Count Paragraphs

, , , , , , , , , Tuesday, December 30, 2008 0 comments

COUNT PARAGRAPHS in a document

// count number of paragraphs in buffer
// FYI: the macro counts the first paragraph properly
// regardless of whether it is proceeded by a blank line
// at the top of file

// count number of paragraphs in buffer or range

_command coupar,count_paragraphs() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY)
{
#define PARAGRAPH_SKIP_CHARS ' \t '
#define PARAGRAPH_SEP_RE ('(^['PARAGRAPH_SKIP_CHARS']*$)')
#define SKIP_PARAGRAPH_SEP_RE ('^~(['PARAGRAPH_SKIP_CHARS']*$)')

if (p_Noflines==0) {
message('Empty file');
stop;
} else {
para_count=1;
}
_save_pos2(p);
top();up();

for (;;) {
_begin_line;
/* skip paragraph separator lines */
status=search(SKIP_PARAGRAPH_SEP_RE,'r');
if ((status==BOTTOM_OF_FILE_RC) || (status==STRING_NOT_FOUND_RC)) {

get_line(line);
if (line=='') {
para_count = para_count - 1;
}

message(para_count ' paragraphs');
break;
} else {
/* Search for paragraph separator line. */
status=search(PARAGRAPH_SEP_RE,'r');
if ((status==BOTTOM_OF_FILE_RC) || (status==STRING_NOT_FOUND_RC)) {
message(para_count ' paragraphs');
break;
}
++para_count;
}
}
_restore_pos2(p);
}

Fun with Line Flags!

, , , , , , , , Sunday, October 26, 2008 0 comments

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;
}


Count occurrences matching search_string

, , , , , Sunday, September 21, 2008 0 comments

I'm sure this command could be improved, but it has served my needs just fine
for years. If you find problems or can suggest improvements, please post them.
Remember I'm not a professional programmer, so please take that into consideration.

dh

// Searches current buffer for search_string specified on the command line
// and returns a
total count of occurrences and a count of the number of lines
// containing the occurrences. Will accept all command line arguments that
// the "search" command accepts, including regular expressions
// in search_string. Can be used on visible lines in a selective display.
// Case insensitive search by default.

_command int cou,count(...) name_info(','VSARG2_REQUIRES_EDITORCTL)
{
int strcount;
int linecount;
_str search_string=arg(1);
parse search_string 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;
} else {
restore_pos(p);
message get_message(status);
stop;
}

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

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

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

About myslickeditmacros

, , , , , Thursday, September 4, 2008 1 comments

If this is your first time here, please read the following
important background information.


Here you'll find Slick-C macros of all kinds
, from overly simple to fairly complex. I'm a writer/editor/journalist by trade, not a professional developer. Slick-C programmers should find something 0f interest here, including plenty of code that can be tweaked or fixed.

The purpose of this blog is to address the shortage of Slick-C code on the Web, while stimulating discussion and encouraging code sharing.

I've used Slickedit in my daily work since approximately 1998. Currently I have 388 _command macros in my vusrmacs.e file. I'm sure there are other Slickedit users whose macro folders are wishing to burst free and benefit the larger community.

My professional roles are technical writer; editor and researcher of print and electronic publications; desktop publisher
; journalist. My programming experience has generally been limited to high-level scripting languages. I've spent a lot of time using numerous text editors and macro languages. Of the two kinds of Slickedit users named in the subtitle of this blog, I'm a Wordsmith rather than a Code Maven.

This blog is not meant to replace Slickedit Documentation, Slickedit Community Forums, "Hello World:" The Slickedit Developer Blog or other Slickedit-related sites. There's plenty of good stuff in those places. I'll post a listing of a bunch of good resources soon.

Many of "my" macros--perhaps a third--borrow from, or are based on, code examples or fragments that I've run across in the past 10 years. This includes lots of Slick-C code and ideas plucked from the guts of Slickedit's code modules themselves. And of course, I've borrowed liberally from third party sources.

If I've failed to credit the authors of any of the code on this blog, please contact me. The same goes for any code that duplicates functionality already built into Slickedit. Please call deprecated procedures to my attention. I will gladly remove, change or credit code in response to reasonable requests.

Again, most macros on this site are relatively simple. Some are simply shortcuts for frequently used commands, regular expressions or tedious command-line typing. I hope you find some of them useful.

Wordsmiths and Code Mavens, grab a Jolt and let's get started. Let's all take full advantage of what is probably the best, most complete and most full-featured text editor ever created.


Here's a simple macro I use frequently. It quickly counts the number of paragraphs in the current buffer and displays the result on the command line. This is helpful because I often work with documents containing hundreds of thousands of lines and thousands of blocks of text. If you wish to change the parameters for recognizing a paragraph, you can modify the #defines at the top of the macro.

// count_paragraphs: count number of paragraphs in buffer
_command coupar,count_paragraphs() name_info(','VSARG2_REQUIRES_EDITORCTLVSARG2_READ_ONLY)
{
#define PARAGRAPH_SKIP_CHARS ' \t '
#define PARAGRAPH_SEP_RE ('(^['PARAGRAPH_SKIP_CHARS']*$)')
#define SKIP_PARAGRAPH_SEP_RE ('^~(['PARAGRAPH_SKIP_CHARS']*$)')

if (p_Noflines==0) {
message('Empty file');
stop;
} else {
para_count=1;
}

_save_pos2(p);
top();up();

for (;;) {
_begin_line;
/* skip paragraph separator lines */
status=search(SKIP_PARAGRAPH_SEP_RE,'r');
if ((status==BOTTOM_OF_FILE_RC) (status==STRING_NOT_FOUND_RC)) {

get_line(line);
if (line=='') {
para_count = para_count - 1;
}

message(para_count ' paragraphs');
break;
} else {
/* Search for paragraph separator line. */
status=search(PARAGRAPH_SEP_RE,'r');
if ((status==BOTTOM_OF_FILE_RC) (status==STRING_NOT_FOUND_RC)) {
message(para_count ' paragraphs');
break;
}
++para_count;
}
}
_restore_pos2(p);
}


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