nedit macro list

nedit macro list



Here's a selection of macros for the nedit text editor. You can send any additons or modifications to me. If you need help on adding macros to nedit click here.

The macros are divided into 4 sections, editing, programming, word processing and other. There's also a list of changes.

_ editing

_ programming

_ word processing

_ other



_ changes

Jun 07 1999 Jun 03 1999 Jun 01 1999 Mar 31 1999 Feb 20 1999 Previous changes are listed here.


_ complete word

Completes a partly typed word by searching the text. Available in two versions, the version distributed with Nedit v5, which searches forwards and backwards to find a match, and a modifed version which just searches backwards, but gives alternatives with repeated use.

standard version
# Tuning parameters
ScanDistance = 200

# Search back to a word boundary to find the word to complete
startScan = max(0, $cursor - ScanDistance)
endScan = min($text_length, $cursor + ScanDistance)
scanString = get_range(startScan, endScan)
keyEnd = $cursor-startScan
keyStart = search_string(scanString, "<", keyEnd, "backward", "regex")
if (keyStart == -1)
    return
keyString = "<" substring(scanString, keyStart, keyEnd)

# search both forward and backward from the cursor position.  Note that
# using a regex search can lead to incorrect results if any of the special
# regex characters is encountered, which is not considered a delimiter
backwardSearchResult = search_string(scanString, keyString, keyStart-1, \
    	"backward", "regex")
forwardSearchResult = search_string(scanString, keyString, keyEnd, "regex")
if (backwardSearchResult == -1 && forwardSearchResult == -1) {
    beep()
    return
}

# if only one direction matched, use that, otherwise use the nearest
if (backwardSearchResult == -1)
    matchStart = forwardSearchResult
else if (forwardSearchResult == -1)
    matchStart = backwardSearchResult
else {
    if (keyStart - backwardSearchResult <= forwardSearchResult - keyEnd)
    	matchStart = backwardSearchResult
    else
    	matchStart = forwardSearchResult
}

# find the complete word
matchEnd = search_string(scanString, ">", matchStart, "regex")
completedWord = substring(scanString, matchStart, matchEnd)

# replace it in the window
replace_range(startScan + keyStart, $cursor, completedWord)
modified version
if ($compword_end == $cursor)
	$compword_rep++
else
{
	$compword_rep = 1
	$compword_init = $cursor	
	
	# search back to a word boundary to find the word to complete

	$compword_start = search("<", $cursor, "backward", "regex", "wrap")

	if ($compword_start == -1)
		return

	$compword = "<" get_range($compword_start, $cursor)
}

s=$cursor

for (i=0; i<=$compword_rep; i++)
	s=search($compword, s-1, "backward", "regex", "wrap")

if (s==$compword_start) 
{
	beep()
	$compword_rep=0
	s=$compword_start
	se=$compword_init
}
else
	se = search(">", s, "regex")

replace_range($compword_start, $cursor, get_range(s, se))

$compword_end = $cursor
You'll need to add $compword_end=0 to your .neditmacro file.

top changes

_ fill selection with character

if ($selection_start == -1) {
    beep()
    return
}

# Ask the user what character to fill with
fillChar = string_dialog("Fill selection with what character?", "OK", "Cancel")
if ($string_dialog_button == 2)
    return

# Count the number of lines in the selection
nLines = 0
for (i=$selection_start; i<$selection_end; i++)
    if (get_character(i) == "\n")
    	nLines++

# Create the fill text
rectangular = $selection_left != -1
line = ""
fillText = ""
if (rectangular) {
    for (i=0; i<$selection_right-$selection_left; i++)
	line = line fillChar
    for (i=0; i=0 && get_character(i)!="\n"; i--)
    	    startIndent++
    	for (i=0; i<$wrap_margin-startIndent; i++)
    	    fillText = fillText fillChar
    	fillText = fillText "\n"
	for (i=0; i<$wrap_margin; i++)
	    line = line fillChar
	for (i=0; i=$selection_start && get_character(i)!="\n"; \
	    	i--)
	    fillText = fillText fillChar
    }
}

# Replace the selection with the fill text
replace_selection(fillText)
top changes

_ make C prototypes

Creates a list of prototypes from the definitions in the current file.
if ($selection_start == -1) {
    start = 0
    end = $text_length
} else {
    start = $selection_start
    end = $selection_end
}
string = get_range(start, end)
nDefs = 0
searchPos = 0
prototypes = ""
staticPrototypes = ""
for (;;) {
    headerStart = search_string(string, \
	    "^[a-zA-Z]([^;#\"'{}=><!/]|\n)*\\)[ \t]*\n?[ \t]*{", \
	    searchPos, "regex")
    if (headerStart == -1)
	break
    headerEnd = search_string(string, ")", $search_end,"backward") + 1
    prototype = substring(string, headerStart, headerEnd) ";\n"
    if (substring(string, headerStart, headerStart+6) == "static")
	staticPrototypes = staticPrototypes prototype
    else
    			prototypes = prototypes prototype
    searchPos = headerEnd
    nDefs++
}
if (nDefs == 0) {
    dialog("No function declarations found")
    return
}
replace_range(0, 0, prototypes staticPrototypes)
select(0, length(prototypes) + length(staticPrototypes))
set_cursor_pos(0)
top changes

_ ispell

A shell script to run the ispell spell checker from a spawned XTerm.

Command Input: Either
Command Output: Same Window
Output Replaces Input: ON
Save file before executing command: ON
  cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp
A more advanced version puts the temporary file in the /tmp directory, and uses $$ (the process ID of the shell) in the file name so you don't have to worry about clashes between simultaneous ispell sessions:
  cat > /tmp/ispell.$$; xterm -title "Spell Check" -e
   ispell -S /tmp/ispell.$$; cat /tmp/ispell.$$; rm /tmp/ispell.$$
top changes

_ smart home

Moves between the begining of a line and the first non-whitespace character.
c = $cursor
beginning_of_line()
if (c == $cursor)
	forward_word()
top changes

_ nmake

A shell script which can be used to run make from nedit.
#! /bin/sh

exec 2> /dev/null

while true ; do
  sh -c 'echo $$ ; exec sleep 2147483647' > $HOME/.sleeppid
  make 2>&1 | tee .nmake_output
  echo ""
  echo ""
done

Use this macro to run make:
$mopos = 0
save()
shell_command("kill `cat ~/.sleeppid`", "")

The following will goto any errors produced:
mo = read_file(".nmake_output")

# skip past any compiler lines

while (substring(mo, $mopos, $mopos+3) == "g++")
{
	search_string(mo, "$", $mopos, "regex")
	$mopos = $search_end + 1
}

# check for make's error message

if (substring(mo, $mopos, $mopos+3) == "***")
{
	beep()
}
else
{
	errl = -1
	while (errl == -1)
	{
		# get filename and line number

		brk = search_string(mo, ":", $mopos)
		fname = substring(mo, $mopos, brk)

    		search_string(mo, ":", brk+1)
    		errl = substring(mo, brk+1, $search_end-1)

		# discard any message lines

		if (substring(mo, brk+2, brk+7) == "In fu" || \
		    substring(mo, brk+2, brk+7) == "In me" || \
		    substring(mo, $search_end+1, $search_end+6) == "(Each" || \
		    substring(mo, $search_end+1, $search_end+6) == "for e")
			errl = -1

		# goto next line

		search_string(mo, "$", $mopos, "regex")
		$mopos = $search_end + 1
	}

	# goto file and line

	focus_window(fname)
    	goto_line_number(errl)
}

top changes

_ get previous

Copies the corresponding character from the previous line.
process_up()
p = $cursor
end_of_line()
c=""
if (p != $cursor)
{
    set_cursor_pos(p)
    c = get_character($cursor)
}
process_down()
insert_string(c)
Note that you can get the character from the next line by swapping the process_up() and process_down().

top changes

_ swap characters

Swaps the character at the cursor postion, and the next character to the right. The if statement emulates the emacs 'feature'.
if (search("$", $cursor, "regex") == $cursor)
{
	backward_character()
	backward_character()
}
c = get_character($cursor)
delete_next_character()
forward_character()
insert_string(c)
This version transposes the chars on either side of the cursor instead of the next two:
if (search("^", $cursor, "regex") != $cursor) {
  backward_character()
  c = get_character($cursor)
  delete_next_character()
  forward_character()
  insert_string(c)
  backward_character()
  }
else
  beep()
top changes

_ select word/line/file

Acts like the clicking mouse. For best results, bind to shift+return.
if ($selection_start == -1)
	$select_level = 1

if ($select_level == 1)
{
	# select word

	forward_word()
	backward_word()
	start=$cursor
	end = search("\t| |$", $cursor, "regex")
}

if ($select_level == 2)
{
	# select line

	start = search("^", $cursor, "regex", "backward")
	end = search("$", $cursor, "regex")
}

if ($select_level == 3)
{
	# select file

	start = 0
	end = $text_length
}

if ($select_level == 4)
{
	$select_level = 0
	start = $cursor
	end = $cursor
}

$select_level++
select(start,end)
You may want to add $select_level=0 to your .neditmacro file.

top changes

_ goto matching

This should be a standard feature right? The if statement allows you to be on either side of the { or } etc.
c = get_character($cursor-1)

if (search_string("{}()[]<>\"", c, 0) == -1)
	forward_character()

match()

if ($selection_start != -1)
{
	if ($cursor == $selection_start+1)
		set_cursor_pos($selection_end)
	else
		set_cursor_pos($selection_start)
}

select($cursor, $cursor)
top changes

_ add pre tags and convert

Adds <pre> tags either side of the selection, and replaces <, > and & with their HTML escape sequences.

requires selection
sel=get_selection()
if (search_string(sel, "&", 0) != -1)
	replace_in_selection("&", "&amp")
if (search_string(sel, "<", 0) != -1)
	replace_in_selection("<", "&lt")
if (search_string(sel, ">", 0) != -1)
	replace_in_selection(">", "&gt")
s=$selection_start
e=$selection_end
select($cursor,$cursor)
set_cursor_pos(s)
insert_string("<pre>\n")
set_cursor_pos(e+6)
insert_string("</pre>\n")
top changes

_ add italic tags

Here's a macro that inserts HTML italic tags. If there is a selection, it's surrounded by <I> and </I>. If there is no selection it inserts </I> or <I> depending on whether there is an open start-italic tag or not. Easy to modify for other tag pairs.
#  If there is a selection put <I> before it and </I> after it.
#  If there is no selection insert <I> if italic mode is off, else </I>

if (-1 == $selection_start) {

#  No selection -- Insert tag to toggle italic mode

  on  = 0
  off = 0
  if (-1 != search("<I>", $cursor, "backward"))
    on = $search_end
  if (-1 != search("</I>", $cursor, "backward"))
    off = $search_end
  if (on <= off)
    insert-string("<I>")
  else
    insert-string("</I>")

  }

else {

# Put selection in italics
  x = get_selection()
  beginning_of_selection()
  insert-string("<I>")
  insert-string(x)
  insert-string("</I>")

  }

top changes

_ remove trailing spaces

Removes any whitespace from the end of lines in current file.
old = $text_length
replace_all("[ \t]*\n", "\n", "regex")
dialog("file size reduced by " old - $text_length " bytes", "OK")

top changes

_ COMET marker

COMET style marker, that is, use:
$comet_mark = "z"
mark("z")
to set the marker, and:
if ($comet_mark == "x")
{
	mark("z")
	$comet_mark = "z"
	goto_mark("x")
}
else
{
	mark("x")
	$comet_mark = "x"
	goto_mark("z")
}
to move between the current position and the marked position.

Two (or more) markers can be used by creating new macro entries using different mark letters and varibles, ie:
$comet_mark2 = "w"
mark("w")
and:
if ($comet_mark2 == "w")
{
        mark("y")
        $comet_mark2 = "y"
        goto_mark("w")
}
else
{
        mark("w")
        $comet_mark2 = "w"
        goto_mark("y")
}


top changes

_ add/remove # comment

Use this to add # comments:
replace_in_selection("^.*$", "# &", "regex")
and this to remove them:
replace_in_selection("^# ", "", "regex")
top changes

_ insert date

d=shell_command("date +\"%h %d 19%y\"", "")
insert_string(substring(d, 0, length(d)-1))
The substring call removes the newline character.

If your version of date supports %Y you can use:
d=shell_command("date +\"%h %d %Y\"", "")
insert_string(substring(d, 0, length(d)-1))
top changes

_ QEDIT cut/copy

QEDIT style cut/copy, which selects the current line if no existing selection.
if ($selection_start == -1)
	select(search("^", $cursor, "regex", "backward"), search("$", $cursor, "regex")+1)
copy_clipboard()
Change the final line for cut.

top changes

_ project macros

A set of macros for handling sets of files.

project.nm

The above macro package allows you to define projects and have all the files associated with the projects loaded/closed/saved etc. It maintains two directory pointers: one for the default macro directory and the other to the local directory of the editor. When a project is loaded, the desired location has to be selected. If the same files need to be opened in different places, it may make more sense to have another project macro defined for each location of the files. This also eliminates the possibility of accidentally editing the wrong projects a bit. This feature can also be emulated by creating a project with no literal path to the files, therefore the files would be loaded from the current directory.

Here is the setup needed for the alternative macro package (it uses the $HOME/.neditutil subdirectory for macros) :

Add this to .neditmacro:
# home must be set here to make it available for macro loading
tmpstr = shell_command("echo $HOME", "")
$HOME = substring(tmpstr, 0, length(tmpstr) - 1)
$NEDITDIR = $HOME "/.neditutil/" 
load_macro_file($NEDITDIR "projects.nm") 
project_init()
Place
projects.nm in $NEDITDIR, and create menu items to call the routines, ie:

Open Project > open_project()
Close Project > close_project()
Save Project > save_project()
Save Project As > save_project_as()
Save All > save_all()
Save All And Close > save_all() close_project()


top changes

_ find definition

With this you don't have to select the function before finding it's defintion, just place the cursor within the function name. The macro sets a mark before calling find_definition(), so you can go back to where you used the macro.
forward_word()
backward_word()
select($cursor, search("(", $cursor))

mark($def_mark)

$def_mark++
if ($def_mark == 10)
	$def_mark = 0

find_definition()
Use this to go back to the line containg the function call:
$def_mark--

if ($def_mark == -1)
	$def_mark = 9

goto_mark($def_mark)
You'll need to add $def_mark=0 to your .neditmacro file.

This version reconises function names that end in a space or ' as well as (.
forward_word()
backward_word()
# Does function name end with space or "(" or ' ?
space = search(" ", $cursor)
if (space < 0) {
 space = $text_length
}
quote = search("'", $cursor)
if (quote < 0 ) {
 quote = $text_lenght
}
parenth = search("(", $cursor)
if (parenth < 0)  {
 parenth = $text_length
}
endOfName = min( space, quote, parenth)
#dialog("endofname and cursor" endOfName, $cursor)
select($cursor, endOfName)

mark($def_mark)

$def_mark++
if ($def_mark == 10)
	$def_mark = 0

find_definition()
These macros obviously requires you to use tags, so you might want to use something like this to update your tags file:
save()
shell_command("ctags -w -T -o .tags -C *.cpp *.h", "")
load_tags_file(".tags")
top changes

_ find definition dialog

This brings up a dialog box to allow you to give the function name. Also, you don't need to type in the whole name, just the first couple of characters.
f="<"string_dialog("Enter function name")".*\\("
s=search(f, 0, "regex")
select(s, $search_end-1)

mark($def_mark)

$def_mark++
if ($def_mark == 10)
	$def_mark = 0

find_definition()
Again, you can use
this to go back to where you used the macro.

top changes

_ convert from/to unix/dos

The following change the line feed codes as neccesary. Should be faster than using shell commands.

unix2dos:
replace_all("([^\\r]|^)$", "\\1\\r", "regex")
dos2unix:
replace_all("\\r$", "", "regex")
top changes

_ previous position

You accidently hit Cntl-Home? D'oh! try this:
undo()
redo()
centerline()
You'll need the centerline macro.

top changes

_ send mail

# Ask for adress
mailto = string_dialog("Mail to: (default: alberto@coker)", "OK", "Cancel")
if ($string_dialog_button == 2) return

# Set default value if not given
if (mailto == "")
    mailto = "alberto@coker"

# If no selection, send the whole window contents
if ($selection_start == -1) {
    start = 0
    end = $text_length
} else {
    start = $selection_start
    end = $selection_end
}

# Issue the command
string = get_range(start, end)
shell_command("mail " mailto, string)

# Check command status
if ($shell_cmd_status == 0)
    dialog("Mail sent correctly")
else
    dialog("Mail not sent")
top changes

_ add/remove Ada comment

# Insert Ada-comments at the beginning of the lines in the selected block
# Made by: Ulf Henningson, Approve AB, Sweden. email: uh@approve.se

replace_in_selection("^.*$", "-- &", "regex")

# Removes Ada-comments at the beginning of the lines in the selected block
# Made by: Ulf Henningson, Approve AB, Sweden. email: uh@approve.se

replace_in_selection("(^[ \\\\t]*-- ?)(.*)$", "\\\\2", "regex")
top changes

_ add string to line start

Asks for a string to slide-in first on each line in the selection.
# Add string to line start
slideInString=string_dialog("Add string to line start:","OK","Dismiss")
if ($string_dialog_button==1 && $selection_start!=-1) {
  selstr=get_selection()
  p=0
  while(1) {
    p=search_string(selstr,"^",p,"regex","forward")
    if (p==-1 || p==length(selstr))
      break
    selstr=replace_substring(selstr,p,p,slideInString)
    p++
  }
  replace_selection(selstr)
}
top changes

_ expand then print

Pipes the selection or file through expand before sending it to the printer.
if ($selection_start == -1)
{
	p = dialog("Print file on:", "fir", "lwself", "Cancel")
	save()
}
else
	p = dialog("Print selection on:", "fir", "lwself", "Cancel")

if (p==1) pn="fir"
if (p==2) pn="lwself"

if (p < 3 && p > 0)
{
	if ($selection_start != -1)
		shell_command("expand -"$tab_dist" | lpr -P"pn" -J "$file_name" (selection)", get_selection())
	else
		shell_command("expand -"$tab_dist" | lpr -P"pn" -J "$file_name, get_range(0, $text_length))
}
top changes

_ place selected text at top of window

start_byte = $selection_start
if ($selection_start == -1) {
    start_byte = $cursor
}

# Count the number of new lines from the beginning
# of the file to the beginning of the selection
nl = 0
for (i = 0; i <= start_byte; i++)
   {
      if (get_character(i) == "\\n")
         {
         nl++
         }
   }

# position the line containing the beginning of the selection
# at the top of the pane
scroll_to_line(nl+1)
top changes

_ Borland IDE tab/shift+tab

Nedit v5 has shift_left/right_by_tab commands for changing the indent of the selection, the following macros simply bind these to the tab/shift+tab keys. As you can't use tab in the macro accelerator entry, you'll have to add the following to your .nedit file, after the nedit.macroCommands: \ line:
submenu>Tab:Tab::: {
	if ($selection_start == -1)
		process_tab()
	else
		shift_right_by_tab()
}
submenu>Shift Tab:Shift+Tab::: {
	if ($selection_start != -1)
		shift_left_by_tab()
}
changing submenu to something appropriate.

top changes

_ hide .bck files

Don't want to see .bck files when you ls? bind this to Ctrl+S:
save()
shell_command("mv "$file_name".bck ."$file_name".bck", "")
top changes

_ LaTeX enviroment

Use this macro after you have typed the name of a LaTeX enviroment, it will insert \begin{} and \end{}:
c = $cursor
backward_word()
select($cursor, c)
s = get_selection()
delete_selection()
insert_string("\\begin{"s"}\n")
c = $cursor
insert_string("\\end{"s"}")
set_cursor_pos(c)
Alternatively, these smart indent macros insert a corresponding \end{} after you type a \begin{}:

No initialization macro

Newline macro:
return -1
Type-in macro:
if ($2 == "}")
{
        start_env = search("{", $1, "regex", "backward")
        start_cmd = search("begin", start_env, "regex", "backward")
        if (start_env != $search_end)
                return
        env = get_range(start_env + 1, $1)
        newline()
        insert_string("\\end{" env "}\n")
        set_cursor_pos($1)
}
top changes

_ auto-uppercase

These smart indent macros automatically convert strings specified in $uppercase_strings after a delimiting character is typed, the example given is for VHDL.

Initialization macro:
$uppercase_strings="<([aA]bs|[aA]ccess|[aA]fter|[aA]ll|[aA]nd|\
[aA]rchitecture|[aA]rray|[aA]ssert|[aA]ttribute|[bB]egin|[bB]lock|[bB]ody|\
[bB]uffer|[bB]us|[cC]ase|[cC]omponent|[cC]onfiguration|[cC]onstant|[dD]isconnect|[dD]ownto|\
[eE]lse|[eE]lsif|[eE]nd|[eE]ntity|[eE]rror|[eE]xit|[fF]ailure|[fF]ile|[fF]or|\
[fF]unction|[gG]enerate|[gG]eneric|[gG]uarded|[iI]f|[iI]n|[iI]nout|[iI]s|\
[lL]abel|[lL]ibrary|[lL]inkage|[lL]oop|[mM]ap|[mM]od|[nN]and|[nN]ew|[nN]ext|\
[nN]or|[nN]ot|[nN]ote|[nN]ull|[oO]f|[oO]n|[oO]pen|[oO]r|[oO]thers|[oO]ut|\
[pP]ackage|[pP]ort|[pP]rocedure|[pP]rocess|[rR]ange|[rR]ecord|[rR]egister|\
[rR]em|[rR]eport|[rR]eturn|[sS]elect|[sS]everity|[sS]ignal|[tT]hen|[tT]o|[tT]ransport|\
[uU]nits|[uU]ntil|[uU]se|[wW]ait|[wW]arning|[wW]hen|[wW]hile|[wW]ith|[xX]or|\
[gG]roup|[iI]mpure|[iI]nertial|[lL]iteral|[pP]ostponed|[pP]ure|[rR]eject|\
[rR]ol|[rR]or|[sS]hared|[sS]la|[sS]ll|[sS]ra|[sS]rl|[uU]naffected|[vV]ariable|[xX]nor)>"
Newline macro:
anf=search("<", $cursor, "regex", "backward")
if (anf == -1) return -1

xstr=get_range(anf, $cursor)
if ( search_string(xstr, $uppercase_strings, 0, "regex") != -1) {
  startline=search("^", $cursor, "regex", "backward")
  start_to_cursor=get_range(startline, $cursor)
  if (search_string(start_to_cursor, "--", 0) == -1) {
    select(anf, $cursor)
    uppercase()
    deselect_all()
  }
}
return -1
Type-in macro:
if(search_string($2, "[A-Za-z0-9_]", 0, "regex" )==-1) {
  anf=search("<", $cursor-1, "regex", "backward")
  bnf=search("'event", $cursor, "backward")
  if ((anf == -1) && (bnf == -1)) return

  xstr=get_range(anf, $cursor)
  ystr=get_range(bnf, $cursor)
  if ((search_string(xstr, $uppercase_strings, 0, "regex") != -1) &&\
      (anf != -1)) {
    startline=search("^", $cursor-1, "regex", "backward")
    start_to_cursor=get_range(startline, $cursor)
    if (search_string(start_to_cursor, "--", 0) == -1) {
      select(anf, $cursor)
      uppercase()
      deselect_all()
    }
  }
  else {
    if ((search_string(ystr, "^'[eE]vent$", 0, "regex") != -1) &&\
        (bnf != -1)) {
      startline=search("^", $cursor-1, "regex", "backward")
      start_to_cursor=get_range(startline, $cursor)
      if (search_string(start_to_cursor, "--", 0) == -1) {
        select(bnf, $cursor)
        uppercase()
        deselect_all()
      }
    }
  }
}
top changes

_ dired

The following allow you to display directories and open subdirectories/files. One limitation is that you can only view files under the directory hierarchy where you start NEdit.

Insert the following in your .nedit file, the default key bindings are:

Shift-Home go to and display Nedit startup directory
Shift-Enter go to selected directory or open selected file
F12 refresh directory listing (same as doing "ls -laCF")

The cd/open macro has been changed so that:

  • Will now check if the last character in the selection is "/" rather than just the character after the selection.
  • If the first character in the selection is "/", use the absolute path name. This resolves the problems of only viewing files under the directory in which you started.
  • Before trying to open a file, try to "cd" to that file. If no error is found, then it must also be a directory.
  • Changed the logic a bit so that it only calls "Dired>ls" once at the end.
  • If no selection exists, it will select the current word (bounded by whitespace).
    Dired>Home:Shift+Home:o:: {
    	if ($file_path == "")
    	   $nedit_cwd = "./"
    	else
    	   $nedit_cwd = $file_path
    	macro_menu_command("Dired>ls")
    }
    Dired>ls:F12::: {
    	if ($nedit_cwd == "")
    	   $nedit_cwd = "./"
    	select_all()
    	delete()
    	temp = " \\"" $nedit_cwd "\\""
    	cmd = "cd "  temp "; ls -laCF"
    	insert_string(shell_command(cmd,""))
    	mesg = "Your current directory is " $nedit_cwd "\\n"
    	insert_string(mesg)
    }
    Dired>cd/open:Shift+Return::: {
    	# If no selection, select the current word
    	if ($selection_start == -1) {
    		start=search("( |\\t|^)",$cursor,"regex","backward")+1
    		end=search("( |\\t|$)",$cursor,"regex")
    		if (end == -1) {
    		end=$text_length
    		}
    		# Handle case of first word in the file
    		if (start == 1) {
    		if (get_character(0) != " " && get_character(0) != "\\t") {
    			start=0
    		}
    		}
    		# Handle case of first word on the line
    		if (get_character(start-2) == "\\n") {
    		start=start-1
    		}
    		# Select text and return (click again to execute)
    		select(start,end)
    	}
    	
    	# Allow absolute paths
    	if (get_character($selection_start) == "/") {
    		$nedit_cwd = ""
    	}
    	
    	# Ignore trailing "*"
    	if (get_character($selection_end-1) == "*") {
    		select($selection_start,$selection_end-1)
    	}
    	
    	# should check character after selection or last char. of selection
    	# if its "/", it's a dir, otherwise, open selection
    	if (get_selection() == "." || get_selection() == "./") {
    		# do nothing
    		$nedit_cwd = $nedit_cwd
    	} else if (get_selection() == ".." || get_selection() == "../") {
    		# get rid of last directory
    		fee = substring($nedit_cwd,0,search_string($nedit_cwd,"/[^/]+/$",1,"regex"))
    		fee = fee "/"
    		# handle case of going to "/" only
    		if (fee == "/")
    		$nedit_cwd = $file_path
    		else
    		$nedit_cwd = fee
    	} else if (get_character($selection_end) == "/") {
    		$nedit_cwd = $nedit_cwd get_selection() "/"
    	} else if (get_character($selection_end-1) == "/") {
    		$nedit_cwd = $nedit_cwd get_selection()
    	} else {
    		# Try and cd, checking for errors
    		shell_command("cd " $nedit_cwd get_selection(),"")
    		if ($shell_cmd_status == 0) {
    		$nedit_cwd = $nedit_cwd get_selection() "/"
    		} else {
    		# nothing else - try to open file
    		open($nedit_cwd get_selection())
    		return
    		}
    	}
    	# Browse new directory
    	end_of_file()
    	macro_menu_command("Dired>ls")
    }
    
    top changes

    _ move to next/prev function

    next function
    set_cursor_pos($cursor + 2)
    c = search("^{", $cursor, "forward", "regex")
    if (c > $cursor)
     set_cursor_pos( c )
    else
     beep()
    
    prev function
    set_cursor_pos($cursor - 2)
    c = search("^{", $cursor, "backward", "regex")
    if (c < $cursor)
     set_cursor_pos( c )
    else
     beep()
    
    top changes

    _ trace IF/ELSE/END IF

    This macro traces matching IF/THEN/ELSE/END IF statements for VHDL. It's probably not hard to modify it for other languages. Just select either an IF, ELSE, ELSIF or END IF statement, start the macro and it will find the next IF/ELSE/ELSIF/END IF statement. Nesting of IF's is allowed, so it's just like matching braces. Selecting END IF and activating the macro will wrap back to the matching IF.
    level = 0
    
    # if selection != "END IF": search next matching ELSE/ELSIF/END IF command:
    if (search_string(get_selection(), "[eE][nN][dD][ \t]*[iI][fF]", 0, "regex") == -1)
    #   Analyse from selection to EOF:
      for (i=$selection_end; i<$text_length; i++) {
    #     VHDL comment: skip to EOL
        if (search_string(get_range(i, i+2), "--", 0) != -1) {
          i = search("$", i, "regex")
    #       If command "IF" is found: increase nesting-level:
        } else if (search_string(get_range(i, i+2), "[iI][fF]", 0, "regex") != -1) {
          level = level + 1
    #       If command "ELSIF" is found: select or skip depending on current nesting-level:
        } else if (search_string(get_range(i, i+5), "[eE][lL][sS][iI][fF]", 0, "regex") != -1) {
          if (level == 0) {
            select(i, i+5)
            break
          } else {
            i = i + 5    # skip to prevent the "IF" to be misinterpreted
          }
    #         If command "IF" is found: select it:
        } else if ((search_string(get_range(i, i+4), "[eE][lL][sS][eE]", 0, "regex") != -1) &&\
                 (level == 0)) {
          select(i, i+4)
          break
    #           If command "END IF" is found: select it or decrease current nesting-level:
        } else if (search_string(get_range(i, i+6), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") != -1) {
          if (level == 0) {
            select(i, i+6)
            break
          } else {
            level = level - 1
          }
          i = i + 6    # skip to prevent the "IF" to be misinterpreted
        }
      }     # end of for-loop
    else {  # selection was "END IF"; search backwards for matching "IF":
      for (i = $selection_start - 1; i >= 0; i--) {
    #   Search for an "IF" statement:
        if (search_string(get_range(i, i+2), "[iI][fF]", 0, "regex") != -1) {
    #     But the "IF" may not be an "END IF" or "ELSIF":
          if ((search_string(get_range(i-3, i+2), "[eE][lL][sS][iI][fF]", 0, "regex") == -1) &&\
              (search_string(get_range(i-4, i+2), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") == -1)) {
    #       First check for a comment:
            linestart = search("^", i, "regex", "backward")
            if (search_string(get_range(linestart, i), "--", 0) == -1) {
    #         If current nesting-level = 0: select, else decrease nesting-level:
              if (level == 0) {
                select(i, i+2)
                break
              } else
                level = level - 1
            } else
              level = level    # skip IF in comment
          } else
            level = level    # skip "ELSIF" or "END IF"
        } else {
    #     If "END IF" is found: increase current nesting-level:
          if (search_string(get_range(i, i+6), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") != -1) {
    #       First check for a comment:
            linestart = search("^", i, "regex", "backward")
            if (search_string(get_range(linestart, i), "--", 0) == -1)
              level = level + 1
          }
        }
      }
    
    # Move to selection:
    } 
    set_cursor_pos($selection_end)
    
    This version traces #ifdef/#else/#endif:
    level = 0
    
    # if selection != "#ENDIF": search next matching #ELSE/#ELIF/#ENDIF command:
    if (search_string(get_selection(), "#[eE][nN][dD][iI][fF]", 0, "regex") == -1)
    {
      startpos = $selection_start
    #   Analyse from selection to EOF:
      for (i=$selection_end; i<$text_length; i++)
      {
    #       If command "#IFDEF" is found: increase nesting-level:
         if (search_string(get_range(i, i+6), "#[iI][fF][dD][eE][fF]", 0, "regex") != -1)
         {
            level = level + 1
         }
         else
    #       If command "#ELIF" is found: select or skip depending on current nesting-level:
            if (search_string(get_range(i, i+5), "#[eE][lL][iI][fF]", 0, "regex") != -1)
               if (level == 0)
               {
                  select(i, i+5)
                  break
               }
               else
                  i = i + 5    # skip to prevent the "IF" to be misinterpreted
            else
    #         If command "#ELSE" is found: select it:
               if ((search_string(get_range(i, i+5), "#[eE][lL][sS][eE]", 0, "regex") != -1) &&\
                      (level == 0))
               {
                  select(i, i+5)
                  break
               }
               else
    #           If command "#ENDIF" is found: select it or decrease current nesting-level:
                  if (search_string(get_range(i, i+6), "#[eE][nN][dD][iI][fF]", 0, "regex") != -1)
                  {
                     if (level == 0)
                     {
                        select(i, i+6)
                        break
                     }
                     else
                     {
                        level = level - 1
                     }
                     i = i + 6    # skip to prevent the "IF" to be misinterpreted
                  }
      }
      select(startpos, $selection_end)
      set_cursor_pos($selection_end)
    }
    else    # selection was "#ENDIF"; search backwards for matching "#IFDEF":
    {
      endpos = $selection_end
      for (i = $selection_start - 1; i >= 0; i--)
      {
    #   Search for an "#IFDEF" statement:
         if (search_string(get_range(i, i+6), "#[iI][fF][dD][eE][fF]", 0, "regex") != -1)
    #       If current nesting-level = 0: select, else decrease nesting-level:
            if (level == 0) {
               select(i, i+6)
               break
            }
            else
              level = level - 1
          else
    #     If "#ENDIF" is found: increase current nesting-level:
            if (search_string(get_range(i, i+6), "#[eE][nN][dD][iI][fF]", 0, "regex") != -1)
              level = level + 1
      }
      select($selection_start, endpos)
      set_cursor_pos($selection_start)
    }
    
    # Move to selection:
    #set_cursor_pos($selection_end)
    
    top changes

    _ BibTeX entries

    Here is a generic BibTeX entry macro function, you can call it using one of the following:
    insertBibTeX("Article")
    insertBibTeX("Book")
    insertBibTeX("Phdthesis")
    insertBibTeX("Inproceedings")
    insertBibTeX("Incollection")
    insertBibTeX("Misc")
    insertBibTeX("Unpublished")
    
    Other entries can be added by modifying the function.

    Once you created the entry, this macro will take you to the next entry field:
    set_cursor_pos(search("{",$cursor)+1)
    
    top changes

    _ append to clipboard

    The following adds the selection to the end of the clipboard:
    if ($selection_start == -1)
    	string_to_clipboard("")
    else
    	string_to_clipboard(clipboard_to_string() get_selection())
    
    The if statement clears the clipboard if nothing is selected.

    If you like a little more sophisticated code, which inserts a space between the existing clipboard contens and the selection if the selection starts at the begin of a word or inserts a newline if selection begins at a new line, try
    if ($selection_start == -1)
    	string_to_clipboard("")
    else
    {
    	cString=clipboard_to_string()
    	addStr=get_selection()
    	if(cString=="") { 
            	string_to_clipboard(addStr)
    	} else {
            	cLastChar=substring(cString, length(cString)-1 , length(cString))
    
            	if(search("^", $selection_start, "regex") == $selection_start) {
                    	if(cLastChar!="\n") addStr="\n" addStr
            	} else if($selection_start==search("<", $selection_start, "regex")) {
                    	if(search_string(cLastChar, "[a-zA-Z_0-9]", 0, "regex") != -1 ) addStr=" " addStr
            	}
            	string_to_clipboard(cString addStr) 
    	}
    }
    
    top changes

    _ exchange clipboard with selection

    requires selection
    selectString = get_selection()
    mark("1")
    paste_clipboard()
    string_to_clipboard(selectString)
    goto_mark("1")
    
    top changes

    _ run grep

    alltext = get_range(0, $text_length)
    if ($selection_start == -1)
      selec = string_dialog("Grep word:","O.K.")
    else
      selec = get_selection()
    
    if (selec != "") {
      result = shell_command("grep -Fn \"" selec "\"", alltext)
      dialog(result)
    }
    
    This version outputs the results to another window and saves the window as a grepResults file. Each successive grep is appended to the same file as long as the window is open. This way you can keep a history of your recent greps. If you want to start a new grep log, close the window. The file will be overwritten with the next result. By having the results in a window, you can select files to open with 'Open Selected' and you can select line numbers to jump to with 'Goto Selected'. The format of the output is fairly readable so you know what you greped for and in what files. oh yeah, this version of the macro allows you to grep in other files using wild cards. The command line options on the grep command are changed because the SGI version of grep doesn't have the paramter -F.
    alltext = get_range(0, $text_length)
    cur_path = $file_path
    cur_file = $file_name
    if ($selection_start == -1)
      selec = string_dialog("Grep word:","OK")
    else
      selec = get_selection()
    
    if (selec != "")
    {
       fileSelec = string_dialog("File Selection (i.e. *.h *.c)  [CWD: " $file_path "]", "OK", "Current File Only", "Cancel")
    
       if(($string_dialog_button == 1) && (fileSelec != ""))
          result = shell_command("grep -n \"" selec "\" " fileSelec, "")
       else if($string_dialog_button == 2)
          result = shell_command("grep -n \"" selec "\" ", alltext)
       else if($string_dialog_button != 0)
          result = "No Files Were Selected"
    
       if(($string_dialog_button != 0) && ($string_dialog_button != 3))
       {
          curwin = focus_window(cur_path "grepResults")
          if(curwin == "")
          {
             new()
             focus_window("last")
          }
          set_cursor_pos($text_length)
          slash = search_string(result, "\\", 0)
          modResult = replace_substring(result, 0, slash+1, "\n")
          if($string_dialog_button == 2)
             textOut = "Grep For " selec " (in " cur_path cur_file")\n" modResult "nn"
          else
             textOut = "Grep For " selec " (in " cur_path fileSelec")\n" modResult "nn"
          replace_range($cursor, $text_length, textOut)
          set_cursor_pos($text_length)
          save_as("grepResults")
          open("grepResults")
       }
    }
    
    Alternatively, grepfiles.nm allows you to open files containing a string using dialog() buttons to select the files from those found by grep. The file is opened (if not opened already) and the search string found within it. This macro uses the element functions.

    You can bind a call to grepfiles() in a language specific way, selecting the file name search pattern which best suites that language. Otherwise, you can always invoke it as grepfiles("*"), if you want it to check everything out.

    Sadly, since the number of dialog buttons is limited and the dialog boxes may be quite large, only 5 files are presented at a time. What would be really nice would be a list-dialog in which the whole list could go...



    This macro runs grep on the current file and replaces the file with the result:
    string = string_dialog("grep for", \
              "grep", "Cancel")
      if ($string_dialog_button == 2 || $string_dialog_button == 0)
          return
      if ($selection_start == -1)
          body = get_range(0, $text_length)
      else
          body = get_selection()
      cmdOutput = shell_command("grep " string " > grep.txt", body)
      if ($shell_cmd_status != 0)
          dialog("grep command returned failed exit status\n" cmdOutput)
      else if (cmdOutput != "")
          dialog(cmdOutput)
    
    results = read_file( "grep.txt" )
    select_all()
    replace_selection( results )
    beginning_of_file()
    shell_command( "rm grep.txt", "")
    
    if you don't want to lose your text, this version shows the results in a new file:
    separate window:
    string = string_dialog("grep for", \
              "grep", "Cancel")
      if ($string_dialog_button == 2 || $string_dialog_button == 0)
          return
      if ($selection_start == -1)
          body = get_range(0, $text_length)
      else
          body = get_selection()
      cmdOutput = shell_command("grep " string " > grep.txt", body)
      if ($shell_cmd_status != 0)
          dialog("grep command returned failed exit status\n" cmdOutput)
      else if (cmdOutput != "")
          dialog(cmdOutput)
    
    open( "grep.txt" )
    
    top changes

    _ run sort

    if ($selection_start == -1)
      select_all()
    
    selection = get_selection()
    
    column = string_dialog("Sort column:")
    
    if (column != -1) {
      sorted = shell_command("sort -k " column, selection)
      replace_selection(sorted)
    }
    
    top changes

    _ RCS shell commands

    These shell commands allow you to check files into and out of RCS from nedit. Add the following to your .nedit file, after the nedit.shellCommands: \ line:
    RCS>checkout::o:DL:
            chmod a-w %; co %
    RCS>checkout/lock:Shift+Ctrl+L:l:DL:
            co -l %
    RCS>checkin:Shift+Ctrl+I:i:DSL:
            xterm -e ci -u %
    RCS>unlock::u:D:
            rcs -u %
    RCS>rcsinfo::r:D:
            rcsinfo
    RCS>rcsdiff::d:W:
            rcsdiff %
    
    The rcsinfo program is not part of RCS, but is a Perl script which duplicates the functionality of `sccs info'.

    Alternatively, you can use rcs.nm. The "Fast" macros work with a comment of "Checkpoint", otherwise the macros prompt for input.

    top changes

    _ Fortran shift left/right

    The comment lines are unaffected and the first 5 columns remain in same position.

    Fortran shift left
    start=$selection_start
    end=$selection_end
    deselect-all()
    i=start
    while(get_character(i)!= "\n")
       i--
    while(i<end-1) {
       a=get_character(++i)
       if (a!="c" && a!="C" && a!="\n") {
          l=0
          while(get_character(i+l)!="\n" && l<6)
             l++
          i=i+l
          if (l>5) {
             if (get_character(i)==" "){
                set_cursor_pos(i)
                delete-next-character()
                end=end-1
             }
          }
       }
       while(get_character(i)!="\n")
          i++
    }
    select(start,end)
    set_cursor_pos(end)
    
    Fortran shift right
    start=$selection_start
    end=$selection_end
    deselect-all()
    i=start
    while(get_character(i)!= "\n")
       i--
    while(i<end-1) {
       a=get_character(++i)
       if (a!="c" && a!="C" && a!="\n") {
          l=0
          while(get_character(i+l)!="\n" && l<6)
             l++
          i=i+l
          if (l>5) {
             set_cursor_pos(i)
             insert_string(" ")
             end+=1
          }
       }
       while(get_character(i)!="\n")
          i++
    }
    select(start,end)
    set_cursor_pos(end)
    
    top changes

    _ get enviroment varible

    This function returns the value of the enviroment varible passed to it, ie:

    $HOME=getenv("HOME")
    It requires that the whole enviroment is kept in the global varible $ENVSTR, which is faster than using several shell commands to get values. Add the following to your .neditmacro file:
    $ENVSTR=shell_command("setenv","")
    
    define getenv {
            if($n_args==0) return $ENVSTR
            else {
                    if(search_string($ENVSTR, "(^|[\n])" $1 "[=]", 0, "regex")!=-1) {
                            vn=$search_end
                            ve=search_string($ENVSTR, "\n", vn, "regex")
                            if(ve>=vn) return substring($ENVSTR, vn, ve)
                    } 
            }
            return ""
    }
    
    top changes

    _ join lines

    This macro adds the text in the current line to the end of the previous one, which is useful if you want to overrun the wrap margin. It adds a space to the end of the previous line, and takes into account any indentation. It fails if the current line is the last one in the file, anyone want to fix it? no.
    set_cursor_pos(search("^", $cursor, "regex", "backward"))
    s = $cursor
    process_up()
    set_cursor_pos(search("[^ \t]", $cursor, "regex"))
    process_down()
    select(s,$cursor)
    indent = get_selection()
    delete_selection()
    insert_string(" ")
    backward_character()
    backward_character()
    delete_next_character()
    set_cursor_pos(search("^", $cursor, "regex"))
    insert_string(indent"\n")
    backward_character()
    
    top changes

    _ DNS database macros

    Here's a language mode, a set of higlight patterns and a set of macros, dns.nm, for editing DNS database files. Some points:
    • language mode is set to DNS if a SOA record is find in the 200 first characters of the file
    • in the macro menu, "DNS - Increment Serial" will increment the serial number of the DNS file
    • in the macro menu, "DNS - SAVE ALL AND ACTIVATE" will go to each window open that is in DNS language mode and look if there was any changes. If changes were made to the db file, the serial number is incremented and the file is saved. If any db file was changed, the named daemon is refreshed.
    • this was made on an AIX system. So to refresh the named daemon, the command "refresh -s named" is used. The result of this command is displayed in a popup.
    • If you use a different system, you need to update the macro function dns_saveAndApply to do a kill -1 of the daemon.
    • you need to edit the files as root to be able to refresh the daemon
    • in the window background menu you have a macro "DNS - Find Reverse IP Address". Click in a line containing an address record, and select this macro. Assuming that all the RR for the reverse mapping are put in one file db.addr, Nedit will open that file and select the line containing the reverse address. If there is no such line, Nedit beeps.
    • in the window background menu you have a macro "DNS - Add Reverse IP Address". Click in a line containing an address record, or select a block of lines of address RRs. Selecting this macro will for each address record:
      • search the db.addr file (same assumptiom that you put all your reverse mapping records in this file) to see if there is already records with same name or same IP address. For each existing record found, a popup will propose you to either delete the old record or ignore it.
      • add the RR for the reverse mapping in the db.addr file. If the name in address record processed was not ending with a dot, the origin to add is taken either from a previous $ORIGIN record or from the /etc/named file primary record pointing to the file edited.
    To add in .nedit:
    nedit.macroCommands: \
    	DNS - Increment Serial@DNS:Shift+Ctrl+I::: {
    		dns_incrementSerial()
    	}
    	DNS - SAVE ALL AND ACTIVATE@DNS:::: {
    		dns_saveAndApply()
    		
    	}
    	}\n
    nedit.bgMenuCommands: \
    	DNS - Find Reverse IP Address@DNS:::: {
    		dns_findReverseIPAddress()
    	}
    	DNS - Add Reverse Ip Address:::: {
    		dns_addReverseAddresseBlock()
    	}\n
    nedit.highlightPatterns: DNS:1:0{
    		Comment:";":"$"::Comment::
    		Keyword:"<(IN|NS|MX|CNAME|A|PTR|$ORIGIN|$INCLUDE|HINFO|MB|MG|MINFO|MR|TXT|WKS)>":::Text Arg2::
    		IP Address:"[1-2]?[0-9]?[0-9]\\.[1-2]?[0-9]?[0-9]\\.[1-2]?[0-9]?[0-9]\\.[1-2]?[0-9]?[0-9]":::String2::
    		Integer:"<[0-9]+>":::String1::
    		SOA RR:"^[^ \\t]+[ \\t]+[A-Z]+[ \\t]+SOA[ \\t]+[^ \\t]+[ \\t]+[^ \\t]+[ \\t]+\\(":"^[^;]*\\)"::Text Key::
    		SOA Comment:";":"$"::Comment:SOA RR:
    	}
    nedit.languageModes: 	DNS::"^[^ \\t]+[ \\t]+[A-Z]+[ \\t]+SOA[ \\t]+":::::" "
    
    top changes

    _ fold C/C++

    fold.nm

    These (rather nasty) outline mechanism macros are intended for use with C/C++. One collapses matching brackets, parens, etc. to a single line, using control characters as separators. This line is a "fold". Another expands the first "fold" on the current line.

    You can nest folds.

    The first C/C++ comment following the first bracket of the fold is converted into a "fold comment", to remind you what's going on inside.

    Setting up highlighting (such as making fold comments stand out but making the fold content dim) helps make these folds useful.

    fold

    # Collapses the current selection if there is one, or
    # all text between match()-brackets.
    
    if ($selection_start != -1)
      fold_selection()
    else
      fold_bracket_match()
    
    unfold

    # Expands the first fold found on the current line, or
    # the next fold found in the file.
    
    fold_expand()
    
    Here are some highlight patterns, be careful about the ^Ls - they should be form feed characters.
    fold:"^L":"^L\\n"::Fold::
    fold comment:"(\\[\\[\\[)[^\\|]*(\\|\\|\\|)":::FoldComment:fold:
    fold comment boundary:"\\1\\2":""::Fold:fold comment:C
    
    top changes

    _ element functions

    These macro functions are loosely based on VMS' DCL f$element() lexical function.

    element.nm

    top changes

    _ align C++ comment

    This macro aligns a // comment with the one on the previous line.
    process_up()
    beginning_of_line()
    beginLine = $cursor
    find("//", "forward", "literal")
    refPos = $cursor - beginLine - 2
    
    
    find("//", "forward", "literal")
    backward_character()
    backward_character()
    commPos = $cursor
    beginning_of_line()
    beginPos = $cursor
    
    if( ( commPos - beginPos ) >= 20 )
    {
      if( ( commPos - beginPos ) < refPos )
      {
        find("//", "forward", "literal")
        backward_character()
        backward_character()
        while( ( $cursor - beginPos ) != refPos )
          insert_string(" ")
      }
      if( ( commPos - beginPos ) > refPos )
      {
        find("//", "forward", "literal")
        backward_character()
        backward_character()
        flag = 0
        while( ( ( $cursor - beginPos ) != refPos ) && ( flag == 0 ) )
        {
          previousChar = get_character( $cursor - 1 )
          if ( previousChar == " " )
          {
            delete_previous_character()
            previousChar = get_character( $cursor - 1 )
            if( previousChar != " " )
            {
              insert_string(" ")
              flag = 1
            }
          }
          else
            flag = 1
        }
      } 
    }
    
    process_down()
    beginning_of_line()
    
    while this macro moves the // to column 40, obviously you can change this to fit your coding style:
    find("//", "forward", "literal")
    backward_character()
    backward_character()
    commPos = $cursor
    beginning_of_line()
    beginPos = $cursor
    
    if( ( commPos - beginPos ) >= 20 )
    {
      if( ( commPos - beginPos ) < 40 )
      {
        find("//", "forward", "literal")
        backward_character()
        backward_character()
        while( ( $cursor - beginPos ) != 40 )
          insert_string(" ")
      }
      if( ( commPos - beginPos ) > 40 )
      {
        find("//", "forward", "literal")
        backward_character()
        backward_character()
        flag = 0
        while( ( ( $cursor - beginPos ) != 40 ) && ( flag == 0 ) )
        {
          previousChar = get_character( $cursor - 1 )
          if ( previousChar == " " )
          {
            delete_previous_character()
            previousChar = get_character( $cursor - 1 )
            if( previousChar != " " )
            {
              insert_string(" ")
              flag = 1
            }
          }
          else
            flag = 1
        }
      } 
    }
    
    process_down()
    beginning_of_line()
    
    top changes

    _ delete current line

    beginning_of_line()
    a=$cursor
    end_of_line()
    forward_character()
    replace_range(a,$cursor,"")
    
    top changes

    _ add space inside brackets

    add space after (
    find("(", "forward", "literal")
    nextChar = get_character( $cursor )
    if ( nextChar != " " )
    {
        forward_character()
        backward_character()
        insert_string(" ")
    }
    else
    {
        backward_character()
        forward_character()
    }
    
    add space before )
    find(")", "forward", "literal")
    previousChar = get_character( $cursor - 2 )
    if ( previousChar != " " )
    {
        backward_character()
        insert_string(" ")
        forward_character()
    }
    else
    {
        forward_character()
        backward_character()
    }
    
    top changes

    _ find line >80 chars

    This requires nedit 5.0.2 or higher.
    flag = 0
    while ( flag != 1 )
    {
      end_of_line()
      if ( $column > 80 )
      {
        beginning_of_line("extend")
        flag = 1
      }
      else
      {
        beginning_of_line()
        beginLine = $cursor
        process_down()
        if( $cursor == beginLine )
          return
      }
    }
    
    top changes

    _ modified upper/lower case

    Small macros to make upper/lower case change the case of the next character rather than the previous one.

    uppercase
    if ($selection_start == -1)
    {
    	forward_character()	
    	uppercase()
    }
    else
    	uppercase()
    
    lowercase
    if ($selection_start == -1)
    {
    	forward_character()	
    	lowercase()
    }
    else
    	lowercase()
    
    top changes

    _ multiple clipboards

    These macros allow you to use 10 cut/append/paste buffers. Below are the .neditmacro lines, macro files and macro menu entries. You will need a directory structure along the lines of:
    $HOME/nedit/macros/
    
    In here, put clipb.nm and make a clips directory. The clips are stored in files so that they are persistent across editing sessions.

    In .neditmacro:
    #Clipboard Macros
    
    $clipPath="<your home dir>/nedit/macros/clips/"
    load_macro_file("<your home dir>/nedit/macros/clipb.nm")
    
    Set the value of $clipPath according to where your directory is. Finally, the menu entries. Splice this into your .nedit. It puts Cut on Shift+Alt+<num>, Paste on Alt+<num>, Append onCtrl+Shift+Alt+<num> and show all on Shift+Alt+<SPACE> - make sure that doesn't clash with anything else you have defined.

    Also, you can see the contents of an individual buffer by pressing Alt+F0-F9.

    top changes

    _ open include files

    Here are some macros which will search for include files in C/C++ (ie starting with a #include) using a colon-separated list of paths in an environment variable, $NEDIT_INCLUDE_PATH. It's probably pretty fragile. To get this to work, add a macro menu item which calls open_include(). Note that you might have to fiddle with some of the shell commands if you're not using csh.

    The macros are slightly broken for relative paths. If you set your environment variable to ".:../include:/usr/include", edit a file in your source directory (for example), use the open_include() macro to open a file in ../include, the current directory is set to ../include in shell commands fired from that window, but remains in your source directory when the attempt is made to actually open the file.

    What that means is, within the header file you just opened, if you attempt to use open_include() to open another header file which is also in the include directory (header2.h, say), it will fail. The shell_command("test -r "...) command in the open_with_test() macro will indicate that the file "./header2.h" exists (because the shell process did a chdir() to ../include), but the open() command will fail because source/./header2.h won't exist.

    One (crude) way to fix that would be to assign your current directory to a global macro variable at startup and always prepend that to relative paths before opening files in open_with_test(). A better solution might be to remove the chdir() in shell.c, but I have no idea what else that might break.
        #
        #  $g_include_path -- this bit depends on your shell.
        #
        $g_include_path = ".:/usr/include:/usr/include/CC"  #  useful default
        include_path = shell_command("echo $NEDIT_INCLUDE_PATH", "")
    
        if($shell_cmd_status == 0)
        {
            #  Strip trailing newline.  You might want to do other checks here
            #  for 0-length path elements, etc.
            $g_include_path = substring(include_path, 0, length(include_path) -1)
        }
    
    
    #  open_with_test
    #
    #  If the given file is readable, this opens it & returns "yay".
    #  Otherwise it just returns "".
    #
    define open_with_test
    {
        filename = $1
        shell_command("test -r " filename, "")
        if($shell_cmd_status == 0)
        {
            open(filename)
            return "yay"
        }
        return ""
    }
    
    
    #  open_include
    #
    #  This attempts to find an #included file name in the current line and
    #  search for it in the global include path.
    #
    define open_include
    {
        #
        #  Try to get the filename from the current line.  All this does
        #  is look for a string delimited by <> or "".
        #
        #  There may be a better/built-in way to get the text of the current line.
        bpos = search("^", $cursor, "regex", "backward")
        epos = search("$", $cursor, "regex", "forward")
        line = get_range(bpos, epos)
    
        #  See if we can find a filename delimited by <>.  This is pretty fragile,
        #  & doesn't permit "< file.h >", etc.
        filename = replace_in_string(line, "^.+\\<(.+)\\>.*$", "\\1", "regex")
    
        if(filename == "")
        {
            #  OK, see if we can find a filename delimited by ""
            filename = replace_in_string(line, "^.+\"(.+)\".*$", "\\1", "regex")
        }
        if(filename == "")
        {
            dialog("No filename found in line " $line "!\n" \
                   "I'm looking for <filename> or \"filename\".", "Oops.")
            return ""
        }
    
        #
        #  We have a filename; now run through our list of paths & see
        #  if we can open the file.
        #
        include_path = $g_include_path
        path_separator = ":"
        bpos = 0
        epos = search_string(include_path, path_separator, bpos)
        while(epos > bpos)
        {
            path_bit = substring(include_path, bpos, epos)
            if(open_with_test(path_bit "/" filename) != "") return ""
            bpos = epos + length(path_separator)
            epos = search_string(include_path, path_separator, bpos)
        }
        #  Do the last element in the path.
        path_bit = substring(include_path, bpos, length(include_path))
        if(open_with_test(path_bit "/" filename) != "") return ""
    
        #
        #  Bummer!  Might as well open a file-open dialog...
        #
        open_dialog(filename)
    }
    
    top changes

    _ run cut

    requires selection
    col = string_dialog("cut", "OK", "Cancel")
    if ($string_dialog_button == 2) return
    start = $selection_start
    end = $selection_end
    string = get_range(start, end)
    out = shell_command("cut -c" col, string)
    insert_string(out)
    
    top changes

    _ run colrm

    requires selection
    col = string_dialog("colrm", "OK", "Cancel")
    if ($string_dialog_button == 2) return
    start = $selection_start
    end = $selection_end
    string = get_range(start, end)
    out = shell_command("colrm " col, string)
    insert_string(out)
    
    top changes

    _ list<>

    A short macro which is usefull when using the C++ STL. Type in the name of a type, then run this to add list<>:
    mark(0)
    backward_word()
    insert_string("list<")
    goto_mark(0)
    insert_string(">")
    
    top changes

    _ run par

    Here are two macros that will interface to the par paragraph reformatter. Source code for Par can be found here.

    If no selection exists, they will select the current paragraph.

    The first macro (Alt+Q) will simply run par with some default options. The second (Shift+Alt+Q) will prompt you for additional options.
    Format paragraph:Alt+Q::: {
    	# If no selection, select paragraph
    	if ($selection_start == -1) {
    		# select paragraph
    		start = search("^$", $cursor, "regex", "backward")+1
    		end = search("^$", $cursor, "regex")
    		select(start,end)
    	}
    	
    	# Get input and run par
    	input=get_selection()
    	result=shell_command("par -rTbgqR -B=.\\\\?_A_a -Q=_s\\\\>\\\\|",input)
    	
    	# Chech for errors and replace text
    	if ( $shell_cmd_status != 0 ) {
    		dialog(result,"Ok")
    	} else {
    		set_cursor_pos($selection_end+1)
    		replace_selection(result)
    	}
    }
    Format para. w/options:Shift+Alt+Q::: {
    	# If no selection, select paragraph
    	if ($selection_start == -1) {
    		# select paragraph
    		start = search("^$", $cursor, "regex", "backward")+1
    		end = search("^$", $cursor, "regex")
    		select(start,end)
    	}
    	
    	# Get input and run par
    	input=get_selection()
    	options=string_dialog("Par Options:","Ok","Cancel")
    	if  ( $string_dialog_button == 2 ) {
    		return
    	}
    	result=shell_command("par -rTbgqR -B=.\\\\?_A_a -Q=_s\\\\>\\\\| " options,input)
    	
    	# Chech for errors and replace text
    	if ( $shell_cmd_status != 0 ) {
    		dialog(result,"Ok")
    	} else {
    		set_cursor_pos($selection_end+1)
    		replace_selection(result)
    	}
    }
    
    top changes

    _ language specific comments

    These macros add/remove comments based on the current language mode to a block that is (non-rectangular) selected.

    These macros are similar, but add/remove the comment to the line at at the insertion point if there is no selection, and allow the comment string to be specified in the macro call. If no argument is given, the macro will call a second function which attempts to determine the correct comment for the current lanaguage mode.

    top changes

    _ select block

    With this macro you can select a block in C and C++. From the cursor position the brackets { and } will be found and the block will be selected.
    # Tuning parameters
    NumberUp=0
    NumberDown=0
    
    # Search back to a word boundary to find the word to complete
    keyUp=$cursor
    keyDown=$cursor
    
    while (NumberUp<=NumberDown)
    {
      keyUp = search("{", keyUp-1,"backward")
      if (keyUp == -1) {
        beep()
        return
      }
      else {
        NumberUp++
      }
      keyDown = search("}", keyDown-1,"backward")
      if (keyDown > keyUp) {
        NumberDown++
      }
      else
      {
        break
      }
    }
    storekeyUp=keyUp
    keyUp=$cursor
    keyDown=$cursor
    NumberUp=0
    NumberDown=0
    while (NumberUp<=NumberDown)
    {
      keyDown = search("}", keyDown+1,"forward")
      if (keyDown == -1) {
        beep()
        return
      }
      else {
        NumberDown++
      }
      keyUp = search("{", keyUp+1,"forward")
      if ((keyUp!=-1) && (keyUp < keyDown)) {
        NumberUp++
      }
      else
      {
        break
      }
    }
    select(storekeyUp,keyDown+1)
    
    top changes

    _ run LaTeX

    This macro runs LaTeX on the current file, LaTeX status messages are sent to the terminal. If any errors where reported the macro will move to the line contianing the error, and output the help message from the log file to the terminal. You'll need to add \scrollmode to the start of your LaTeX file.

    You can also add `rational latex' commands which modify the file before it's saved and allow you to change the LaTeX syntax, if you don't want to use these delete the relevant lines of the macro.

    Someone sent me a macro which you could use to send just the selection to LaTeX, but I lost it. Sorry kids. But it shouldn't be that difficult to rewrite. I'll sort it out sometime. I've also got a couple of other ideas on how to improve this macro, I was delaying it's `release' until I'd added them, but after 6 months of inactivity I decided I better just upload what was there. :)

    Also, you may want to look at this shell script which decides if one should run AMSTeX, LaTeX, or plain TeX.

    top changes

    _ Next and Prev NEdit window

    define next_win {
            n=focus_window("next")
            if(n!="") open(n)
            else open(focus_window("last"))
    }
    
    define prev_win {
    # needs functions first_win_name and prev_win_name (below)
            n=prev_win_name()
            if(n!="") open(n)
            else open(first_win_name())  =
    		
    }
    
    define first_win_name {
            wa=$file_path $file_name
            wn=focus_window("next")
            while(wn!="") {
                    wa=wn
                    wn=focus_window("next")
            }
            return wa
    }
    
    define prev_win_name {
            a=$file_path $file_name
            f=focus_window("last")
            if(a==f) return ""
            l=f
            while(f!="") {
                    f=focus_window("next")
                    if(f==a) break
                    else if (f!="")l=f
            }
            return l
    }
    
    top changes

    _ load macro files on demand

    Ever wished your NEdit would start as fast as it did before you added all those macros? Did you want to be able to give users a particular search path for them to pick up their (perhaps preset) macro files? You've got a macro which depends on another, but you can't remember whether you've already loaded it?

    Help is on its way!

    The macros supplied here (in a file I've called NEDIT_LOADED.nm) try to answer these problems, rather in the manner of the #import directive in Objective-C, or the require keyword in Perl. What you do is load the NEDIT_LOADED.nm file using the one-line .neditmacro file:
      load_macro_file("<path-to-files>/NEDIT_LOADED.nm")
    After that, wherever you have a macro which depends on another defined in a file, call
      NEDIT_require_macro_file("<your-macro-file-name>")
    to load it. NEDIT_require_macro_file() will search a path defined by the ":" or " " separated environment variable called $NEDIT_MACRO_SEARCH_PATH if the name supplied to it does not give an absolute path to the file. You can call it inside another macro file (for example, in my macro files, I add
      NEDIT_require_macro_file("element.nm")
    for the array handling routines), or at the start of a macro defined in NEdit's macro dialogs (I do this for my .html definitions, for example:
      NEDIT_require_macro_file("html.nm")
      html_add_markup_brackets("TT")
    
    where html_add_markup_brackets() is defined in the file "html.nm" somewhere on the $NEDIT_MACRO_SEARCH_PATH).

    Since NEDIT_require_macro_file() does a quick check (a search in a global string) before loading a file, it will only load that file once.

    Another useful function is the NEDIT_find_file_in_pathlist() which looks for a file of a given name in the given (newline-separated) path list. Based on Rusty Ballinger's include file search and open functions, this can be used in other contexts.

    A word of warning: if NEDIT_LOADED.nm cannot be found on the $NEDIT_MACRO_SEARCH_PATH, you'll get a warning dialog.

    ... And if you use VMS, I'm afraid you'll have to rewrite these calls... sorry.

    top changes

    _ handle tag files with multiple definitions

    To be able to handle tag files with multiple definitions for a symbol, I decided to do the whole thing in macros, and it works quite well. A multiple choice dialog box allows the user to choose the definition line from the tags file which applies; the macro then opens it up.

    Using these macros also allows a simple find jump history: essentially a position stack is managed (as a string) - the entries (lines) in the string are handled as tag entries. The whole thing works quite well.

    I use the background menu for all this stuff generally, but I have also defined the Ctrl-] key as a call to multitags_choose_quick() - after having become used to it in vi.

    The macros use other macro files: NEDIT_LOADED.nm (for file detection and macro file "inclusion"), element.nm (for handling strings as if they were arrays - usually of lines) and multichoice.nm (for the multiple choice dialogs).

    Although I have implemented a "return to previous" macro, I have not implemented a "goto to next in history list" macro, for people who want to go backwards and forwards through their find jump history.

    My only worry is that overuse of the find jump history will create an overgrown stack, or seriously impact memory.

    multitags.nm

    There is also a .nedit extract which calls these macros.

    top changes

    _ multiple choice dialogs

    multichoice(choices, n_opts, label_type) lists the choice text in choices (each line is a choice) with a button per choice, in a series of dialog boxes. The lines can be numbered (default), with the line numbers used for button labels, or the first word (contiguous non-space characters) can be used as button labels. Up to 7 buttons can be displayed per dialog. Returns the contents of the line chosen, or "".

    multichoice.nm

    top changes

    _ center cursor position

    centerline() attempts to center the cursor position in the current window.

    centerline.nm

    top changes

    _ tab column search

    This macro allows you to do a vertical search on tab-delimited columns of data, e.g. for a table of numbers, place your cursor on the column you want to search, runt the macro and then type in your search string, and it will jump down the column to the first occurance.

    tab column search.nm

    If instead your file uses fixed columns (spaces, etc.) instead of tabs, you can start with the above macro, remove the "count the number of tabs" bit, remove the "[^\t]*" bit from the search which uses the regex, and change the "build the regex" part to
        for(i = 0; i < $column; ++i) re = re "."
    
    Note that this fixed-column approach will fail horribly if your file contains tabs; I'm not sure what to do about that. Another difference is that it will only match strings which begin at the current column (rather than anywhere in the column as the tab-delimited one will).

    top changes

    _ insert closing HTML tag

    This "Insert closing HTML tag" macro checks, if tag is not closed somewhere between it and cursor position. If it is, it find previous openning tag and so it continues until find some unclosed tag or reach begining of document.

    So if you have following sequence <TABLE><TR><TD> first run of macro inserts </TD>, second </TR>, third </TABLE> and fourth nothing.

    If you'll uncomment last line of this macro, cursor will be moved to initial position after tag insertion, but I prefer it will not.
    position = $cursor
    start = $cursor
    closed = 1
    ab_start = $cursor
    
    while (closed == 1)
    {
    	search_start = search("\\<[a-zA-Z][-.a-zA-Z0-9]*", start, "regex", "backward")
    	pom = "</" get_range(search_start + 1, $search_end) ">"
    	search2 = search(pom, search_start, "literal", "forward")
    	if (search2 > -1 && search2 < ab_start)
    		closed = 1
    	else
    		closed = 0
    	start = search_start - 1
    }
    
    if (search_start < ab_start)
    	insert_string(pom)
    # set_cursor_pos(position)
    
    You can also use this simple macro for inserting elements, or marking a block of text as an element:
    elementName = string_dialog("Element name:", "OK", "Cancel")
    
    cursorPosition = $cursor
    
    if ($string_dialog_button == 1)
    {
            if ($selection_start == -1)
            {
                    insert_string("<" elementName "></" elementName ">")
                    set_cursor_pos(cursorPosition + length(elementName) + 2)
            }
            else
            {
                    selection = get_selection()
                    replace_selection("<" elementName ">" selection "</" elementName ">")
            }
    }
    
    top changes

    _ save selection as

    # Save selection as.. 
    # Made by: Nico Morskieft
    # Ask for file name      
    saveto = string_dialog("Enter file name","OK")
    
    # Check if file exist
    find_file = shell_command("ls " saveto , "")
    file_exist = search_string(find_file,"not found",0)
    if (file_exist == -1) {
      beep()
      choice = dialog("File exist, overwrite?", "Yes", "No")
    } else {
      choice = 1
    }
    
    if (choice == 1) 
    {
    # Save the selection
    succes = write_file(get_selection(), saveto)
    
    # Check if the save action was successful
    if (succes == 0)
      dialog("File NOT saved")
    }
    
    top changes

    _ convert to/from ascii/char

    ascii.nm

    top changes

    _ pgp5 shell commands

    Here's a script to run pgp5 from nedit. Functionality is limited but it covers the most used things.

    This uses two FIFO's to *help* prevent any data from making it's way on to the disk. Not fool proof. (Virtual memory, etc) The reason I NEEDED to use this fancy script is there is no other way to get stdout to pgp directly from nedit, because we need to start an xterm first. Major chicken and egg problem. Unfortunately I could not get adding keys to the key ring working using a pipe, so it uses a temporay file for that instead.

    The script will still work for OS's that don't have fifo's, just no disk protection. Make sure to edit the top of the script to set these and other options.

    To make your fifo's
    	cd ~/.pgp/
    	mknod pgpfifo0 p
    	mknod pgpfifi1 p
    
    Here are the ~/.nedit shell menu entries:
     	pgp > keys > insert pub::::\n\
    		nedit-pgp pubk\n\
    	pgp > keys > list:::D:\n\
    		nedit-pgp listk\n\
    	pgp > keys > add:::ID:\n\
    		nedit-pgp addk\n\
    	pgp > sign:::EX:\n\
    		nedit-pgp sign\n\
    	pgp > encrypt:::EX:\n\
    		nedit-pgp enc\n\
    	pgp > decrypt:::EX:\n\
    		nedit-pgp decr\n\
    	pgp > verify:::ED:\n\
    		nedit-pgp veri\n
    
    and this is the nedit-pgp shell script.

    top changes

    _ save current position

    These macros save/load the current cursor position in a bookmark file. Current position of file XXXX is stored in file $HOME/.nedit-XXXX.

    save current position
    cpos = $cursor
    tmpstr = shell_command("echo $HOME", "")
    $HOME = substring(tmpstr, 0, length(tmpstr) - 1)
    fname = $HOME"/.nedit-" $file_name
    if (write_file(cpos, fname) == 0)
       dialog("Can't save bookmark!", "OK")
    
    load formerly saved position
    cpos = $cursor
    tmpstr = shell_command("echo $HOME", "")
    $HOME = substring(tmpstr, 0, length(tmpstr) - 1)
    fname = $HOME"/.nedit-" $file_name
    cpos=read_file(fname)
    if ($read_status == 0)
       dialog("Can't load bookmark!", "OK")
    else set_cursor_pos(cpos)
    
    delete bookmark file
    tmpstr = shell_command("echo $HOME", "")
    $HOME = substring(tmpstr, 0, length(tmpstr) - 1)
    fname = $HOME"/.nedit-" $file_name
    cmdreturn=shell_command("rm " fname, "")
    dialog(cmdreturn, "OK")
    
    top changes

    _ LaTeX fill paragraph

    This macro is an alternative to "Fill Paragraph" when writing LaTeX. Often it occurs that you have a piece of LaTeX looking like this:
      \begin{verbatim}
        <<CODE>>
      \end{verbatim}
      And from this code, it shows that blah blah
      cow bear donkey
      farm
      blah blah blah
      \begin{verbatim}
        <<CODE>>
      \end{verbatim}
    
    Formatting (filling) the text in the middle is not easy, Nedit does not recognize the \begin{..} and \end{..} statements as paragraph delimiters, but the macro respects this when paragraph filling.

    top changes

    _ view manfile

    Opens a new nedit window for a manfile, if there's currently a selection, the selection text is used as the name of the manfile, otherwise you can type the name into a dialog box.

    If anyone can work out how to get man (or troff) to format it's output for a specfied number of columns, please let me know...

    if ($selection_start == -1)
    	c = string_dialog("man page for:")
    else
    	c = get_selection()
    p = shell_command("man "c, "")
    p = replace_in_string(p, ".\b", "", "regex")
    p = replace_in_string(p, "\n\n\n.*$\n\n\n\n\n\n.*$\n\n", "", "regex")
    p = substring(p, 2, length(p))
    write_file(p, "/tmp/man "c)
    open("/tmp/man "c)
    
    top changes

    _ make HTML tags

    This macro converts the selected text s into <a href="mailto:s">s</a> :
        selStart = $selection_start
        selEnd = $selection_end
        replace_range(selStart, selEnd, "<a href=\"mailto:" get_selection() "\">" get_selection() "</a>")
    
    And this one turns the currently selected text into a link with the target chosen in the dialog box (prepends http:// to the target):
        selStart = $selection_start
        selEnd = $selection_end
        target = string_dialog("Enter the target", "OK", "Cancel")
        if ($string_dialog_button == 1) {
    	replace_range(selStart, selEnd, "<a href=\"http://" target "\">" get_selection() "</a>")
        }
    
    top changes

    _ preserve cursor position after running expand

    l=$line
    c=$column
    shell_menu_command("expand")
    goto_line_number(l)
    beginning_of_line()
    while(c>0)
    {
    	c=c-1
    	forward_character()
    }
    
    top changes

    _ togglecase

    To toggle the case of a character you can check whether the result of a toupper/tolower conversion is the same as before; if it is not, you have toggled the case of your character. (You really need to do this a character at a time, however.)

    eg: in your .neditmacro:
    define togglecase
    {
    s = $1
    r = ""
    for (i = 0, c = substring(s, i, i+1); \
    	 c != ""; \
    	 i++, c = substring(s, i, i+1))
    	{
    	if (toupper(c) != c)
    		r = r toupper(c)
    	else
    		r = r tolower(c)
    	}
    return r
    }
    
    now you do a little macro to, say, convert your selection:
    replace_selection(togglecase(get_selection()))
    
    or convert the next character and move on:
    replace_range($cursor, $cursor+1, \
            togglecase(get_character($cursor)))
    forward_character()
    
    or to change the character behind the cursor:
    replace_range($cursor, $cursor-1, \
            togglecase(get_character($cursor-1))).
    

    _ show result of shell command in a new window

    Eg. using the cleartool command:
       type = MADS_CP_55.15
       cmd = "/usr/atria/bin/cleartool find -avobs -version 'lbtype(" type ")' -print"
       answer = shell_command(cmd, "")
       
       if (length(answer) == 0)
       {
          dialog("No match to the query\n\n" cmd "\n\n", "OK")
       }
       else
       {
          # Put the result into a new NEdit window
          new()
          focus_window("last")
          insert_string(answer)
       }
    top changes

    _ ClearCase tools

    This file contains macros for performing checkin, checkout, and uncheckout.

    You'll need to add entries the macro menu. Use Preferences->Default Settings->Customize Menus->Macro menus... and add calls to the macro functions the standard way. After saving the defaults, my .nedit file contains the following lines:
            ClearCase>checkin:Shift+Alt+Grave::: {\n\
                    CC_Checkin()\n\
            }\n\
            ClearCase>checkout:Alt+Grave::: {\n\
                    CC_Checkout()\n\
            }\n\
            ClearCase>uncheckout:::: {\n\
                    CC_Uncheckout()\n\
            }\n\
    
    The system has one problem. At checkout one normally enters a checkout comment. At checkin one wants to reuse it, but change it slightly. My macros extract the checkout comment, and present it at checkin, but you must either accept it "as is" or enter a totally new comment.

    A string_dialog() where one can supply default text would be nice. I have tried using an xterm for the checkin, but it slows down the process quite a lot, so I settled with the present approach.

    Alternatively, here's a few shell commands for ClearCase, add this to .nedit:
        ClearCase Tools>Checkout File::C:DL:\n\
            cleartool co -unr -nc %\n\
        ClearCase Tools>Checkin File (No Comment)::i:DSL:\n\
            cleartool ci -nc %\n\
        ClearCase Tools>Revert Changes::R:DL:\n\
            cleartool unco -rm %\n\
        ClearCase Tools>Show Changes:::W:\n\
            cleartool diff -ser -pred %\n\
        ClearCase Tools>Show Changes Graphically:Ctrl+Alt+D:G:D:\n\
            (cleartool diff -g -pred % &) >& /dev/null\n\
        ClearCase Tools>List Checkedout Files:::D:\n\
            cleartool lsco | grep $USER | gawk '{ print $5 " " $6 " " $7 " " $8}'\n\
        ClearCase Tools>List All Checkedout Files:Ctrl+Alt+L:L:D:\n\
            cleartool lsco -cview -avobs | gawk '{ print $5 " " $6 " " $7 " " $8}'\n\
        ClearCase Tools>Show Version Tree:Ctrl+Alt+T:T:D:\n\
            (cleartool xlsvtree % &) >& /dev/null\n\
        ClearCase Tools>Show File History:Ctrl+Alt+H:H:W:\n\
            cleartool lshistory %\n\
        ClearCase Tools>Show View:Ctrl+Alt+V:V:D:\n\
            cleartool pwv\n
    
    And this will run find on a specified directory:
    directory = string_dialog("Search from what directory?","Ok","Cancel")
    
    if ( $string_dialog_button == 2 || $string_dialog_button == 2 ||
    directory == "" )
        return
    
    string = string_dialog("Search For...","FixID","PR","Cancel")
    
    if ( $string_dialog_button == 1 )
        answer = shell_command("/usr/atria/bin/cleartool find " directory " -element 'attr_sub(FixID,==,\"" string "\")' -print", "")
    else if ( $string_dialog_button == 2 )
        answer = shell_command("/usr/atria/bin/cleartool find " directory " -element 'attr_sub(PR,==,\"" string "\")' -print", "")
    else
        return
    
    if ( $shell_cmd_status != 0 )
    {
        dialog("Error executing: " answer,"Ok")
        return
    }
    
    dialog("/usr/atria/bin/cleartool " "find " directory " -element 'attr_sub(FixID,==,\"" string "\")' -print\n\n" answer,"Ok")
    
    To show the output in a new window see this macro.

    top changes

    _ count occurances of string

    The following macro counts the occurrences of a string in the document, which is requested via a dialog box. If the button "OK" is chosen, then a literal (case insensitive) search is performed. If "Regular Exp." is chosen, then a regular expression search is performed.
      search_type = ""
    
      search_text = string_dialog( "String to find", "OK", "Regular Exp.", "Dismiss" )
    
      if ( $string_dialog_button == 1 )
        search_type = "literal"
      else if ( $string_dialog_button == 2 )
        search_type = "regex"
        
      if ( search_type != "" )
      {
        found = 0
        pos   = 0
    
        while ( pos != -1 )
        {
          pos = search( search_text, pos, search_type )
    
          if ( pos != -1)
          {
            pos   = pos + 1
            found = found + 1
          }
        }
    
        dialog( "String >>" search_text "<< found [" found "] times.", "OK" )
      }
    
    top changes

    _ goto header/source file

    if (search_string($file_name, ".h", 0) != -1)
     open($file_path substring($file_name, 0, length($file_name)-2) ".cpp") 
    else
     open($file_path substring($file_name, 0, length($file_name)-4) ".h")
    
    top changes

    _ open/save files on remote host

    Here are some macros that allow to open files on a remote host (if the .rhosts allows it) and save them there. Interesting if you edit files far over the internet.

    top changes

    _ swap two words

    This is a small macro for swapping two words. Simply highlight the first word, and this macro will swap it with the next, i.e. "first second" will become "second first"
    cut_clipboard()
    delete_next_character()
    forward_word()
    paste_clipboard()
    insert_string(" ")
    
    It's very rudimentary, and assumes the words are separated by a space. But it works.

    top changes

    _ toggle formatting codes

    This is a function to toggle formatting codes in languages like LaTeX, HTML, etc.

    top changes

    _ tab expand and `showtabspace'

    Check out this file...

    top changes

    _ convert text to HTML table

    An ascii table with text columns separated by tabs is converted to a HTML-table. Accordingly every new line generates a new table row.

    requires selection
    replace_in_selection ("(^.*$)", "<TR><TD>&", "regex")
    replace_in_selection("\t", "</TD><TD>")
    replace_in_selection("\n", "</TD></TR>\n")
    selection = get_selection()
    replace_selection("<TABLE>\n" selection "</TABLE>")
    deselect_all()
    
    top changes

    _ convert text to HTML list

    requires selection
    d = dialog("List type:", "Bulleted", "Numbered") 
    replace_in_selection ("(^.*$)", "    <LI>&", "regex")
    selection = get_selection()
    if (d == 1)
    replace_selection("<UL>\n" selection "</UL>")
    else
    replace_selection("<OL>\n" selection "</OL>")
    deselect_all()
    
    top changes

    _ perl script to identify the language of a file

    Here's a perl script that uses the information from .nedit to recognize the language of a file. The usual disclaimers concerning usability etc. apply, but it might just be a starting point for a useful application.

    top changes

    _ shift line up/down

    Everything you could desire is in this file.

    top changes

    _ plain text justification

    The reformat macro is slower than Ctrl-J, strangely enough... Also, it might be good to be able to distinguish between paragraphs in some way, when they are adjacent (not separated by a blank space). Apart from emptying spaces in otherwise empty lines and the indent lead-ins, these macros do not touch user-entered spaces or tabs: A space at the end of a line either remains at the end of a line, or finds itself in front of the next word (which used to be the first word on the following line).

    nice work...

    PlainText.nm

    top changes

    _ remove newlines and rewrap selection

    This (quick hack) macro removes all the newlines in a selection and rewraps the in way that it fits best in the current window size.

    Usage: Select paragraph to rewrap and run macro

    You can change the $wrap_margin in the macro to e.g. 80 if you always want to wrap to 80 colums.
    if ($selection_start == -1) {
        beep()
        return
    }
    
    replace_in_selection("\n", " ")
    
    s = get_selection()
    p = search_string(s, " ", $wrap_margin, "backward")
    k = 0
    end = 0
    while (p != -1 && end != 1)
    {
            s = replace_substring(s, p, p + 1, "\n")
            if (length(s) - $wrap_margin < p)
            {
                    end = 1
            }
            p = search_string(s, " ",p + $wrap_margin, "backward")
    }
    replace_selection(s)
    
    top changes

    _ change LaTeX environment

    You can use this macro to do the following: After changing the "begin"-part of a LaTeX environment simply invoke this macro and the corresponding "end" part is changed. E.g. change "\begin{equation}" to "\begin{eqnarray}" and the macro will change the corresponding "\end{equation}" to "\end{eqnarray}".

    top changes

    _ capitalize

    This macro capitalizes words according to the following rules:
    1. If no text is selected, the word the cursor is in or adjacent to is capitalized.
    2. If text is selected, the words within and adjacent to the selection are capitalized.
    The beginning and end of a word is defined by NEdit's < and > regular expression operators. The cursor (or selection boundary) is adjacent to a word if there are no whitespace or punctuation characters between it and the word.

    top changes

    _ remove string from line start

    This macro asks for a string that is removed from the beginning of each line within the selection. It is also possible to remove characters that are used by the regular expressions.

    top changes