This chapter describes how to change the start-up and runtime behaviors of Source-Navigator. You can also customize menu items and keyboard shortcuts for the Editor; for more information see Editor of the User's Guide.
A general configuration file, .../share/etc/profile, is a system-wide configuration file for GUI language and database cache size. These form the default values that all users inherit for all the tools.
If you would like to customize Source-Navigator for a specific user, you may create a file called %USERPROFILE%/.sn/profile (on Windows) or $HOME/.sn/profile (on UNIX) to contain the configuration for that user's preferences.
The settings that may be customized are sn_language and encoding, which designates the language of the GUI, and sn_mailhost, which tells Source-Navigator how to connect to your mailer.
The format for a user's profile file is setting name:value, one entry per line.
see the character set encoding combo-box in the Project Preferences dialog |
||
An example profile file for the German user interface is:
language:germanThe information in the following section assumes that you are conversant with Tcl, which is used by Source-Navigator for program configuration tasks.
You can create a file called rc.tcl, which will be automatically loaded when Source-Navigator starts. If you have either a .../share/etc/rc.tcl or a $HOME/.sn/rc.tcl file, Source-Navigator reads and executes the file with the Tcl source command. The system-wide configuration file is read first; a user's own configuration file is read afterwards and can override the site-local defaults.
When a Source-Navigator project opens, a Tcl procedure called sn_rc (if it exists) is called with no input parameters. This enables you to:
Many events in Source-Navigator have a corresponding Tcl procedure that is called when the event occurs. This provides the facility to control the appearance and behavior of each tool. You can choose whether or not to implement each of these Tcl procedures in rc.tcl; it is not mandatory to do so.
When a Symbol Browser window is created, a Tcl procedure called sn_rc_symbolbrowser (if it exists) is called with the following input parameters:
The following example script lists the names of the button widgets of a Symbol Browser toolbar:
proc sn_rc_symbolbrowser {top menu} { set toolbar_frame $top.exp puts stdout [join [winfo children \ $toolbar_frame] "\n"] }
which, when using the default toolbar, provides output similar to:
.multisymbr-1.exp.tree .multisymbr-1.exp.class .multisymbr-1.exp.xref .multisymbr-1.exp.inc .multisymbr-1.exp.space .multisymbr-1.exp.retrfr
The following example code adds a new button that starts a DOS shell under Windows and an xterm application under UNIX:
proc sn_rc_symbolbrowser {top menu} { global tcl_platform set tool_frame $top.exp # Set a variable that identifies the text widget on # the status bar. set info $top.msg.msg # Create a new button on the toolbar. Note that the # button's command invokes the command line tool # in the background so that Source-Navigator is not # blocked while the tool is running. On Win32, we emulate # `xterm' with `cmd'. if {!$tcl_platform(platform) != "windows"} { set cmdline "exec xterm -T {Source-Navigator} &" set description xterm } else { set cmdline "exec cmd /c start cmd" set description shell } button $tool_frame.xterm -text $description \ -command $cmdline # Set the main window's status bar to read "xterm" # or "shell" when the mouse pointer is over the region # of the button. balloon_bind_info $tool_frame.xterm \ "Starts a new $description" bind $tool_frame.xterm <Leave> "set $top.msg {}" # Pack this button onto the toolbar. pack $tool_frame.xterm -side left }
You can use the rc.tcl file to add new menus to the menu bar or new menu items to existing menus.
The following example shows how to add a new menu with two submenus. The first procedure creates the menu and submenu items, and the next two are the procedures that each of the submenu items actually execute.
proc sn_rc_symbolbrowser {win menu} { # Abbreviate the name of the menu to "extras". set extras $menu.extras # Create a new menu called "Extras". menu $extras -tearoff 0 # Add a menu item to the menu. The second character is # the designated hot key. Place this menu fourth in # the menu bar. $menu insert 3 cascade -label Extras -underline 1 \ -menu $extras # Add two items to the menu. $extras add command -label Functions -command \ "custom_show_symbols Functions" -underline 0 $extras add command -label Methods -command \ "custom_show_symbols Methods" -underline 0 } proc custom_show_symbols {symboltype} { # Set the scope appropriately. switch -- $symboltype { "Methods" { set scope "md" } default { set scope "fu" } } if {[info commands paf_db_$scope] == ""} { sn_error_dialog \ "No symbols of the type <$scope> are available in the project." return } # Generate a unique name for our new top-level window # widget. set w .custom_win_$scope # See if the window already exists. if {![info exists $w]} { # Create a new top-level window with a unique name. toplevel $w # Change its title. wm title $w "[sn_read_option project-name] ($symboltype)" # Put a frame around this window and add scrollbars # that scroll through a listbox. frame $w.frm scrollbar $w.frm.scrollx -orient horizontal \ -relief sunken -command "$w.frm.symlist xview" scrollbar $w.frm.scrolly -relief sunken \ -command "$w.frm.symlist yview" # Create a listbox to hold the symbol names. listbox $w.frm.symlist -height 20 -width 40 \ -xscrollcommand "$w.frm.scrollx set" \ -yscrollcommand "$w.frm.scrolly set" # If the user double-clicks in the list box, find # the nearest entry in the list and pass the name of # the symbol to custom_edit_file. This will launch # us into the source file where that symbol is # defined. bind $w.frm.symlist <Double-1> { custom_edit_file [%W get [%W nearest %y]] } # Pack the widgets onto our new window. pack $w.frm.scrolly -side right -fill y pack $w.frm.scrollx -side bottom -fill x pack $w.frm.symlist -expand y -fill both pack $w.frm -fill both -expand y } else { # The window already exists, so just delete # everything from the listbox and we'll re-insert # the current items in the next step. $w.frm.symlist delete 0 end } # Put all of the database keys into the list. eval $w.frm.symlist insert end \ [paf_db_$scope seq -data] } proc custom_edit_file {key} { # We have been passed the key of a record from either # the function or method database tables. We need to # determine the filename and line number for the # editor to jump into the source code. # The key of a record takes the form: # { name, start_position, filename } if {[llength $key] == 3} { set pos [lindex $key 1] set filename [lindex $key 2] } else { set pos [lindex $key 2] set filename [lindex $key 3] } sn_edit_file {} $filename $pos }
Adding a Menu Item to the Menu Bar
All Source-Navigator Editor windows execute a Tcl procedure called sn_rc_editor (if it exists) at start-up. You can implement this procedure in the file rc.tcl as described in the section Adding Events to the rc.tcl File. The input parameters of this procedure are as follows:
You can add or change keyboard shortcuts for the Editor using commands shown in the following example rc.tcl file. This example demonstrates how the built-in Editor can be customized to emulate other popular editors.
Note that the bind command assigns the key bindings Ctrl+A and Ctrl+E to move the cursor to the beginning and end of a line, respectively.
proc sn_rc_editor {view text} { set top [winfo toplevel $view] set menu_frame $top.menu set tool_frame $top.exp # Bind Control-a to jump to the start of the line # (like emacs). bind $text <Control-a> { %W mark set insert "insert linestart" %W yview -pickplace insert break } # Bind Control-e to jump to the end of the line # (like emacs). bind $text <Control-e> { %W mark set insert "insert lineend" %W yview -pickplace insert break } }
For more information about bindings, see Practical Programming in Tcl and Tk by Brent B. Welch, page 285.
The following example shows how to change the behavior of the Compile button so it compiles the current source file using the Java bytecode compiler rather than gcc.
This example only works when the extended toolbar buttons are enabled. To enable them, from the File menu, select Project Preferences. Select the Edit tab and click the Extended toolbar buttons checkbox.
proc sn_rc_editor {view text} { set top [winfo toplevel $view] set menu_frame $top.menu set tool_frame $top.exp.editfr # MAKE SURE THAT THE EXTENDED TOOLBAR BUTTONS ARE ENABLED. # Reassign the command associated with the "compile" button. if {[winfo exists $tool_frame.compile]} { $tool_frame.compile config \ -command "custom_compile $view" } } proc custom_compile {view} { # Save the preconfigured "make" command line; we need # to tamper with it in this procedure. set temp [sn_read_option make-command] # Extract the filename. set file [$view cget -filename] # Set the "make" command line appropriately. if {[string match {*.jav*} $file]} { sn_modify_option make-command "javac \"$file\"" } # Byte-compile the source file. sn_make # Restore the "make" command line. sn_modify_option make-command $temp }
The following example shows how the Windows Notepad editor or the UNIX vi editor can be integrated into Editor's toolbar as an auxiliary editor.
This example only works when the extended toolbar buttons are enabled. To enable them, from the File menu, select Project Preferences. Select the Edit tab and click the Extended toolbar buttons checkbox.
proc sn_rc_editor {view text} { global tcl_platform set topw [winfo toplevel $view] set tool_frame $topw.exp # On Windows call Notepad to edit a file. if {$tcl_platform(platform) == "windows"} { # Create a new button to edit the file using Notepad. button $tool_frame.vi -text Notepad \ -command "exec notepad \[$view getfilename\]" balloon_bind_info $tool_frame.vi \ "Edit current file using the Notepad editor." } else { # Create a new button to edit the file using vi button $tool_frame.vi -text vi \ -command "exec xterm -T vi -e vi \[$view getfilename\]" balloon_bind_info $tool_frame.vi \ "Edit current file using vi" } # Pack this button onto the toolbar. pack $tool_frame.vi -side left }
This example shows how you can display project database information in a format that is different from what Source-Navigator usually provides.
proc html_doc {topw} { set actview [$topw ActiveWidget] set ed [MultiWindow& @@ list_find_editor $actview] if {$ed == ""} { bell; return } doc_start [list [$ed getfilename]] } proc sn_rc_editor {view editor} { # main window set topw [winfo toplevel $view] # add a menu entry for the html documentation set mn $topw.menu $mn.tools add command \ -label "HTML Documentation" \ -command "html_doc $topw" }
In the Editor, from the Tools menu, select HTML Documentation, and Source-Navigator brings up a browser window containing definitions and cross-references of the symbols in your project.
Generating an HTML Representation of the Project Database
Source-Navigator can receive and act upon messages from external tools such as a compiler or debugger through use of a configurable error format file that can be found in .../share/etc/sn_cmp_g.pat.
The contents of this error-format file is as follows; the comment above each regular expression illustrates the kind of text that the given expression can handle. More information on regular expressions can be found in the Grep of the User's Guide.
# Source-Navigator regular expressions for compiler, # debugger and grep patterns. # Source-Navigator supports also blanks, so the patterns # must be so defined that blanks could be a part of the filename # "filename.c", line 789 "([^" ]+)",[ ]+line[ ]+([0-9]+) # filename.c, line 789 ([^ ]+),[ ]+line[ ]+([0-9]+) # line 789, filename.c, line[ ]+([0-9]+),[ ]+([^, ]+) # [filename.c:789] \[([^\[: ]+):([0-9]+)\] # filename.c:789 ([^: ]+):[ ]*([0-9]+) # filename.c(789) ([^ ]+\.[^ ]+)\(([0-9]+)\) # filename.c(789,11) or filename.c(789.11) ([^ ]+\.[^ ]+)\(([0-9]+[,.][ ]*[0-9]+)\) # /dir/filename.c, 789 ([^/ ]+),[ ]+([0-9]+)
The lines beginning with the hash # symbol are comments showing matching patterns; the GNU regular expression describes the expressions. Every expression must contain two expressions enclosed in parentheses (for the file name and line number).