-
-
Notifications
You must be signed in to change notification settings - Fork 27
Macro Examples
This file is automatically loaded from the ~/.config/nedit-ng
directory at startup (or ~/Library/Preferences/nedit-ng
for Mac) and it contains user-defined macro subroutines. These subroutines can be used in all macro commands.
Some text files may contain physical Tab characters. To be sure to find both spaces and tabs when searching for whitespace, use a regex like [ \\t]*
The double \\
is used to achieve a single \ . Or use the whitespace escape, \s
. More detail at Nedit-ng meta characters
Open xterm terminal and execute the first argument in a csh shell. If the first argument does not exist or is an empty string an interactive csh terminal window is started. Macro remains running until the xterm is closed.
define xterm_csh {
# first argument is command to be executed
command = $1
# allow execution with line selection by removing newline from the end of the command
last_char = get_character($selection_end - 1)
if ( last_char == "\n") {
command = replace_substring( command, $selection_end - 1 - $selection_start, $selection_end, "" )
}
# if multiline command support is really wanted, replace following code lines with uncommented next line
#command = replace_in_string( command, "\\n", ";", "regex", "copy" )
if ( search_string( command, "\\n", 0 , "regex" ) > -1 ) {
dialog("Newline not allowed in xterm_csh command")
return
}
# single quotes in command must be replaced with a sequence of single quote, double quoted signle quote, single quote
command = replace_in_string( command, "'", "'\"'\"'", "literal", "copy" )
term = "xterm" # actual terminal command
title = " -T \"nedit xterm_csh\"" # title definition for the terminal
geometry = " -geometry 260x70" # width and height
execute = " -e csh -fc " # executing csh command without sourcing users .cshrc
wait = "; echo press enter;$<" # additional prompt to require user input for closing terminal
if ( command == "" ) {
# empty command so open a terminal
shell_command(term title geometry, "")
} else {
# execute command in a terminal window and wait for <enter> from user
shell_command(term title geometry execute "'" command wait "'" , "")
}
}
Run selected single-line text with xterm_csh subroutine, or prompt for a command to be executed
if ( get_selection() != "" ) {
xterm_csh(get_selection())
} else {
command = string_dialog("Give semicolon separated commands to be executed in xterm")
xterm_csh(command)
}
Replace newline characters with semicolon in selected text and execute with xterm_csh
lines=get_selection()
command = replace_in_string( lines, "\n", ";", "regex", "copy" )
xterm_csh(command)
This macro selects code from the current cursor position to next matching if clause end statement (else, elsif or end if). Nested if clauses are included in the selection. Comments are ignored.
# match for starting if clause
startmatch = "\\yif\\y"
# match for continued if clauses
contmatch = "\\yelsif\\y|\\yelse\\y"
# match for ignoring start
nostart = "\\yend\\s+if\\y"
# match for ending if clause
endmatch = contmatch "|\\yend\\s+if\\y"
# match for comments that should not be considered
ignore = "--.*"
start = $cursor
endsel = $cursor
fcount = 1
# repeat while inside if clauses
while ( fcount > 0 ) {
eol = search( "\n", endsel )
if ( eol < 0 ) {
# reached end of file
break
}
# taking one extra character to both ends for \\y to match
line = get_range(endsel - 1, eol + 1)
# remove VHDL comment from line
line = replace_in_string( line, ignore, "", "regex", "copy" )
if ( search_string( line, nostart, 0, "regex" ) > -1 ) {
# do not increment if clause counter with "end if"
} else if ( search_string( line, startmatch, 0, "regex" ) > -1 ) {
# starting if clause found, so increment if clause counter
fcount = fcount + 1
}
if ( search_string( line, endmatch, 0, "regex" ) > -1 ) {
# end if clause found
fcount = fcount - 1
if ( fcount == 0 ) {
# matching end found, so select text and stop
select( start, search( endmatch, eol, "regex", "backward" ) + 1 )
break
} else if ( search_string( line, contmatch , 0, "regex" ) > -1 ) {
# increment counter due to continued elsif statment
fcount = fcount + 1
}
}
endsel = eol + 1
}
This example is for hexadecimal numbered lines with space indentation, use d in place of X for decimal numbers. Replacing first X with b and %${w}X with %0${w}X changes hex values to (zero-filled) binary values.
command = "perl -e 'my @l = <STDIN>;$w=length sprintf \"%X\", $#l;map {printf \"%${w}X $_\", $i++} @l'"
numbered = shell_command( command, get_selection() )
replace_selection(numbered)
A version with decimal numbering, and the numbers start from 1. Matches the native nedit-ng line numbers, useful at times.
command = "perl -e 'my @l = <STDIN>;$w=length sprintf \"%d\", $#l; $i=1; map {printf \"%${w}d $_\", $i++} @l'"
numbered = shell_command( command, get_selection() )
replace_selection(numbered)
Use shell grep command to remove all lines which don't contain selected text. Macro can be changed to remove lines with selected text by adding -v to grep command
leave = get_selection()
if ( search_string( leave, "\n", 0, "regex" ) > -1) {
dialog("Selection ust not conatin newline")
} else {
select(0, $text_length)
text = get_selection()
replace_range(0, $text_length, shell_command( "grep '" leave "'", text ))
}
if ($selection_start == -1) {
replace_all("^(.*\\n)\\1+", "\\1", "regex")
} else {
replace_in_selection("^(.*\\n)\\1+", "\\1", "regex")
}
Use Perl to reverse order of the characters in a selection. (To avoid the text shifting down, don't select the end-of-line of the last line).
if ( get_selection() == "" ) {
dialog("Select text", "OK")
} else {
selStart = $selection_start
selEnd = $selection_end
reversed = shell_command("perl -e 'print scalar reverse q{"get_selection() "}'", "")
replace_range(selStart, selEnd, reversed)
}
if ($selection_start > -1) {
string = get_selection()
} else {
string = string_dialog("Give string to grep")
}
matches = shell_command("grep -ni '" string "' * | grep -v ^grep:", "")
if ( matches != "" ) {
selection = list_dialog( "Select a line to go", matches )
if ( selection != "" ) {
file = selection
file = replace_in_string(file, ":.*", "", "regex")
line = selection
line = replace_in_string(line, ":(\\d+).*", ":\\1", "regex")
line = replace_in_string(line, ".*:", "", "regex")
open($file_path file)
focus_window($file_path file)
goto_line_number(line)
}
}
text = get_selection()
lineCount = 0
while ( search_string( text, "\\n", 0, "regex" ) > -1 ) {
line = substring( text, 0, $search_end - 1 )
text = replace_substring(text, 0, $search_end, "")
if ( line != "" ) {
lineData[lineCount] = line
# replace tabulators with space
lineData[lineCount] = replace_in_string(lineData[lineCount], "^\\t+", " ", "regex", "copy")
# remove all tabulators and leading and trailing spaces
lineData[lineCount] = replace_in_string(lineData[lineCount], "^\\s+", "", "regex", "copy")
lineData[lineCount] = replace_in_string(lineData[lineCount], "\\s+$", "", "regex", "copy")
# replace all consecutive space characters with single space
lineData[lineCount] = replace_in_string(lineData[lineCount], "\\s\\s*", " ", "regex", "copy")
itemCount = lineData[lineCount]
# remove all non-whitespace characters
itemCount = replace_in_string(itemCount, "\\S+", "", "regex", "copy")
# length of spaces is item count - 1
if ( itemCount < length(itemCount) + 1 ) {
itemCount = length(itemCount) + 1
}
}
lineCount = lineCount + 1
}
for (i = 0; i < lineCount; i++) {
colWidth[i] = 0
transposedIndex = 0
while ( search_string( lineData[i], "\\s", 0, "regex" ) > -1 ) {
transposedItem = substring( lineData[i], 0, $search_end - 1 )
lineData[i] = replace_substring( lineData[i], 0, $search_end, "" )
if ( colWidth[i] < length(transposedItem) ) {
colWidth[i] = length(transposedItem)
}
if ( i == 0 ) {
transposedData[transposedIndex] = transposedItem
} else {
transposedData[transposedIndex] = transposedData[transposedIndex] " " transposedItem
}
transposedIndex = transposedIndex + 1
}
if ( i == 0 ) {
transposedData[transposedIndex] = lineData[i]
} else {
transposedData[transposedIndex] = transposedData[transposedIndex] " " lineData[i]
}
if ( colWidth[i] < length(lineData[i]) ) {
colWidth[i] = length(lineData[i])
}
transposedIndex = transposedIndex + 1
while ( transposedIndex < itemCount ) {
transposedData[transposedIndex] = " "
transposedIndex = transposedIndex + 1
}
}
# creating transposed data with space alignment
newLines = ""
for (i = 0; i < itemCount; i++) {
itemArr = split(transposedData[i], " ")
for ( item in itemArr ) {
# adding space to align data
for ( j = 0; j < colWidth[item] - length(itemArr[item]); j++ ) {
newLines = newLines " "
}
newLines = newLines itemArr[item]
# add space unless last item in line
if ( item < lineCount - 1 ) {
newLines = newLines " "
}
}
newLines = newLines "\n"
}
replace_selection(newLines)
Tabulators are considered as single characters, so alignment will most likely fail if tabulators exist in the selected lines
matchString = string_dialog("Give string of alignment")
# allow using spacial characters as alignment, must be escaped for regex
matchString = replace_in_string( matchString, "([\(\)\{\}<>])", "\\\\\\1", "regex", "copy" )
maxDistance = 0
selectedText = get_selection()
# remove last newline to avoid extra newline at the end of replaced text
selectedText = replace_in_string( selectedText, "\\n$", "", "regex", "copy" )
itemArr = split(selectedText, "\n")
# iterate through all lines and check longest distance to alignment string
for ( item in itemArr ) {
itemDistance = search_string( itemArr[item], matchString, 0, "regex" )
if ( itemDistance > maxDistance ) {
maxDistance = itemDistance
}
}
newLines = ""
# second iteration, now in the numerical order of the lines in the associative array
for ( i = 0; i < itemArr[] ; i++ ) {
itemDistance = search_string( itemArr[i], matchString, 0, "regex" )
# create space filler to be added before the string of alignment in each line
if ( ( itemDistance > -1 ) && ( itemDistance < maxDistance ) ) {
fillSpaces = ""
for ( j = 1; j <= maxDistance - itemDistance; j++ ) {
fillSpaces = fillSpaces " "
}
itemArr[i] = replace_in_string( itemArr[i], matchString, fillSpaces matchString, "regex", "copy" )
}
# add modified or the original line with a newline
newLines = newLines itemArr[i] "\n"
}
replace_selection(newLines)
These are small things that are sometimes in other editors as standard.
Transposed characters are a common typo. Often mapped to Ctrl-T. (Goes a bit whacko transposing a literal tab character).
define transpose_char {
if (search("^", $cursor, "regex") != $cursor) {
backward_character()
c = get_character($cursor)
delete_next_character()
forward_character()
insert_string(c)
backward_character()
}
else
beep()
}
}
This deletes the current line. If bound to a keystroke, it's an easy way to delete a succession of lines. If you overshoot, the Undo command (Meta Z) will bring them back one by one. Also, it doesn't affect the clipboard, convenient if you have new text waiting in the clipboard to replace the deleted line(s).
define delete_line {
beginning_of_line()
a=$cursor
end_of_line()
forward_character()
replace_range(a,$cursor,"")
}
This duplicates the current line, leaving cursor in the new line. If bound to a keystroke, it's an easy way to duplicate one line, or create a block of duplicate lines. The duplicates can be undone with Undo.
define dup_line {
col=$column
beginning_of_line()
a=$cursor
end_of_line()
forward_character()
line=get_range(a,$cursor)
insert_string(line)
backward_character()
beginning_of_line()
for(j=0; j<col; j++)
forward_character()
}
This creates a copy of the current line to the right of itself.
define dup_line_horiz {
col=$column
beginning_of_line()
a=$cursor
end_of_line()
line=get_range(a,$cursor)
insert_string(" ")
insert_string(line)
beginning_of_line()
for(j=0; j<col; j++) # leave cursor where it was, there are other choices
forward_character()
}
This is useful for situations where you want to use the names in a list ..
name1
name2
name3
twice ..
print("name1 = ", name1);
print("name2 = ", name2);
or thrice .. (how many times do you get to say thrice eh ?)
print(name1, "stored as", name1 + "-new", "new value is", $name1-new); # ignore the language details
You could also use copy/paste of a rectangular selection in some cases, or the Unix paste
command.
Select one or more lines and slide them up or down through the text. Surrounding lines flow around the block. A common task in editing code.
define shift_selection_up {
if(get_selection() == "") {
beep()
return
}
s = get_selection()
cut_clipboard()
s2 = replace_in_string(s, "(?n[^\n])", "", "regex") # delete all chars except newline.
lines = length(s2) # count the newlines, this seems clunky,
# t_print("number of lines: " lines "\n") # but I can't see a $lines_in_selection or lines_in_selection()
process_up()
beginning_of_line()
paste_clipboard()
endsel = $cursor
for(j=0; j<lines; j++)
process_up()
select($cursor, endsel) # re-select the same block, for further shifting
}
define shift_selection_down {
if(get_selection() == "") {
beep()
return
}
s = get_selection()
cut_clipboard()
s2 = replace_in_string(s, "(?n[^\n])", "", "regex")
lines = length(s2)
process_down()
beginning_of_line()
paste_clipboard()
endsel = $cursor
for(j=0; j<lines; j++)
process_up()
select($cursor, endsel) # re-select the same block, for further shifting
}
Nedit by default doesn't show the number of lines in a file, maybe because it's expensive to keep updating it, esp. in a very large file. This macro shows the number of lines in a popup dialog.
define show_num_lines_in_file {
orig_pos = $cursor
orig_line_num = $line
top_line_in_pane = $top_line
end_of_file()
total_lines = $line
set_cursor_pos(orig_pos) # restore cursor pos
scroll_dist = $line - top_line_in_pane
scroll_up(scroll_dist) # adjust pane scroll position
dialog("Lines = " total_lines, "Ok")
# debug
# dialog("Lines = " total_lines " (line " orig_line_num ", top pane line " top_line_in_pane ", scroll dist " scroll_dist, "Ok")
}
Here's a bit of fun - show the built-in variables. Educational, slightly. This was on Mac.
define show_args {
insert_string("Some function args using $1 style: " $1 ", " $2 ", " $3 "\n")
insert_string("Some function args using $args[1] style: " $args[1] ", " $args[2] ", " $args[3] "\n")
}
define show_internal_vars {
show_args(1, "string2", 333)
insert_string("$active_pane " $active_pane "\n")
insert_string("$auto_indent " $auto_indent "\n")
insert_string("$calltip_ID " $calltip_ID "\n")
insert_string("$cursor " $cursor "\n")
insert_string("$column " $column "\n")
insert_string("$display_width " $display_width "\n")
insert_string("$em_tab_dist " $em_tab_dist "\n")
insert_string("$empty_array " "[] (faked, $empty_array stringify fails)\n")
insert_string("$file_format " $file_format "\n")
insert_string("$file_name " $file_name "\n")
insert_string("$file_path " $file_path "\n")
insert_string("$font_name " $font_name "\n")
insert_string("Note, next 3 vars deprecated, always same as main font in nedit-ng \n")
insert_string("$font_name_bold " $font_name_bold "\n")
insert_string("$font_name_bold_italic " $font_name_bold_italic "\n")
insert_string("$font_name_italic " $font_name_italic "\n")
insert_string("$highlight_syntax " $highlight_syntax "\n")
insert_string("$incremental_backup " $incremental_backup "\n")
insert_string("$incremental_search_line " $incremental_search_line "\n")
insert_string("$language_mode " $language_mode "\n")
insert_string("$line " $line "\n")
insert_string("$locked " $locked "\n")
insert_string("$make_backup_copy " $make_backup_copy "\n")
insert_string("$max_font_width " $max_font_width "\n")
insert_string("$min_font_width " $min_font_width "\n")
insert_string("$modified " $modified "\n")
insert_string("$n_display_lines " $n_display_lines "\n")
insert_string("$n_panes " $n_panes "\n")
insert_string("$overtype_mode " $overtype_mode "\n")
insert_string("$read_only " $read_only "\n")
insert_string("$selection_start " $selection_start "\n")
insert_string("$selection_end " $selection_end "\n")
insert_string("$selection_left " $selection_left "\n")
insert_string("$selection_right " $selection_right "\n")
insert_string("$server_name " $server_name "\n") # always seems empty
insert_string("$show_line_numbers " $show_line_numbers "\n")
insert_string("$show_matching " $show_matching "\n")
insert_string("$match_syntax_based " $match_syntax_based "\n")
insert_string("$statistics_line " $statistics_line "\n")
insert_string("$sub_sep " $sub_sep "\n")
insert_string("$tab_dist " $tab_dist "\n")
insert_string("$text_length " $text_length "\n")
insert_string("$top_line " $top_line "\n")
insert_string("$use_tabs " $use_tabs "\n")
insert_string("$VERSION " $VERSION "\n")
insert_string("$wrap_margin " $wrap_margin "\n")
insert_string("$wrap_text " $wrap_text "\n")
}
There are many old Nedit macro pages out there. They're slowly fading, you could make a case for duplicating them here, with acknowledgements. Examples:
The Special Astrophysical Observatory of the Russian Academy of Sciences (SAO RAS)
nedit.gmxhome.de This is currently not responding, but ..
The WayBack Machine still has nedit.gmxhome.de
You can find more with Google.
The old nedit.org This lapsed somehow, and has become a Finnish site about online casinos and taxes. However ..
The WayBack Machine still has nedit.org
Latest valid archive seems to be 28 Mar 2012 I didn't see any macros here, maybe an earlier archive would be better