Click here to Skip to main content
15,890,512 members
Articles / Programming Languages / C#
Article

Finding things in your favorite text editor with C#

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
23 Feb 20034 min read 102.6K   1.8K   43   8
A functional text editor add on for navigating source files. It shows concepts such as dynamic assembly loading for plugins, a textbox that does not ding when the enter key is pressed, and the use of abstract classes.

Sample Image - MethodFinder.jpg

Introduction

The .NET Framework provides a mind numbing array of classes to do most anything in windows. I spend a lot of time delving deep into those classes, learning their usage and nuances of them. Unfortunately, I have to do this at home because at work we use Object Pascal and PL/SQL. I use a simple text editor to write my C# code and even though it provides for my basic needs, sometimes it can be a bit lacking when dealing with larger source files.

So, I put my late night C# sessions to work for me and wrote a text editor extender application that allows me to navigate around large text files at break neck speeds. The application will allow you bring in a source file and if the plugin is available for your programming language, quickly bring up methods (or any piece of info the plugin provides) and navigate to them in your text editor. Overall, the application is pretty simple, but it provides a ton of utility.

While putting the application together, I had the opportunity to write in some interesting concepts.

  • Dynamic assembly loading using Assembly and Activator. The plugin mechanism operates on this.

  • Abstract Classes.

  • A text box that does not "ding" when hitting enter. (see the referenced newsgroup in the source to see where I got the idea originally)

  • Starting external processes.

  • Use of the ConfigurationSettings Class.

Background

For some time now I have been using the amazing and highly configurable text editor SciTE (thanks Neil Hodgson) to write my C# code (I am to poor (or cheap) to buy Visual Studio and obviously my company only has moderate interest). Because I got tired of switching between multiple IDEs, I recently started to write the majority of my Pascal and PL/SQL code in SciTE as well, but found that the standard search mechanism just wasn't doing it for some of our larger source files.

Enter GExperts. Programming in the Object Pascal, the IDE has a great set of plugins called GExperts. In paticular there is one called Procedure List. It takes the pascal source and presents you with a list of procedure calls that can be narrowed down by typing in the search box. Over time programming in the IDE, I came to rely on this plugin quite a bit for navigation. Unfortunately my text editor, and probably yours, does not provide this extremly useful functionality.

So with C# and a bit of forethought, I hacked out MethodFinder. With a couple tweaks, you can use it to enhance any text editor that provides commandline support for launching external tools and has the ability to specify files and line numbers when starting a file from the commandline.

Using MethodFinder and its code

To use MethodFinder, download the zip file and double click the run command file. It will by default load the source file passed in. Because using the application is pretty simple, below describes some of the concepts in the source files (hopefully it peak interest in those who don't write code in a plain editor)

No dinging text box

A text box that doesn't ding when you hit enter in it. I found the basic code on google and modified it to suit my needs. I trap the enter and escape keys and then use a delegate to notify the main form when those keys are pressed. Always call the base.PreProcessMessage method to process messages you are not going to handle. Strange things will happen if you forget.
C#
public delegate void EnterNoDing(Keys keyCode);

//Non-Dinging OnEnterKey textbox. Below is the link to the newsgroup <BR>  //article. Credits to Stefan Sperling for the help (see newsgroup text <BR>  //file in the download)
public class NoDingTextBox : System.Windows.Forms.TextBox {
  const int WM_KEYDOWN=0x100;
  const int WM_KEYUP=0x101;

  public EnterNoDing NoDing;
  public override bool PreProcessMessage(<BR>                                    ref System.Windows.Forms.Message msg) {
    Keys keyCode=(Keys)(int)msg.WParam & Keys.KeyCode;
    if((msg.Msg==WM_KEYDOWN || msg.Msg==WM_KEYUP) &&<BR>                       (keyCode==Keys.Enter || keyCode==Keys.Escape)) {
      msg.WParam=(System.IntPtr)0;
      NoDing(keyCode);
      return true;
    }
    return base.PreProcessMessage(ref msg);
  }
}

Dynamic assembly loading

The snippet below loads up a plugin and checks its SupportedExtensions property to see if it is the correct plugin. It loads the assembly using the static Assembly.LoadFrom and creates an real instance using the static Activator.CreateInstance. If the plugin supports our files extension, it is returned and used to parse the code.
C#
Assembly ass = Assembly.LoadFrom(file);
Type[] types = ass.GetTypes();
foreach(Type t in types){

  //create the type
  Object o = Activator.CreateInstance(t);

  //see if it is a methodfinder
  if (o is MethodFinder){
    MethodFinder mf = (MethodFinder)o;
    //check to see if it supports our file extension
    if (mf.SupportedExtensions().ToLower().IndexOf(extension.ToLower()) >= 0){
      //load up the code
      mf.CodeText = codeText;
      //return the object
      return mf;
    }
  }
}

Start the editor

This simple snippet starts the editor defined in the configuration file and starts it with the parameters defined. Check out the configuration file to see how the string is formatted.
C#
//start a process with the command line
//and parameters to start the text editor
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Editor;
line = (Convert.ToInt32(line) + LineOffset).ToString();
//You may have to tweak the following to get it working for your editor.
psi.Arguments = string.Format(Arguments, FileName, line, text);
Console.WriteLine(psi.FileName + " " + psi.Arguments);
Process.Start (psi);

Writing a simple plugin.

While you can make it as complicated as you want, it is generally pretty simple to write a plugin that parses source for the MethodFinder (for example, I just care about statements with access modifiers in the C# plugin). All you need to do is derive from the abstract base MethodFinder,
C#
public class CSharpMethodFinder : MethodFinder{
override the SupportedExtensions property with the file extensions your source typically uses,
C#
public override string SupportedExtensions(){
  return "cs";
}
and provide an implementation for the overriden CodeText method.
C#
public override string CodeText{
  set {
    string[] r = value.Split('\n');
    string line;
    bool bInComment = false;

    for (int i = 0; i < r.Length; i++){
      line = r[i].Trim(' ', '\t','\r', '{', '}').ToLower();
      if (line.StartsWith("//") || line.StartsWith("/*") || <BR>              line.StartsWith("///")){
        bInComment = true;
      }
      if (line.IndexOf("*/") >= 0){
        bInComment = false;
      }
      if ((!bInComment) && (line.StartsWith("public")
                            || line.StartsWith("private")
                            || line.StartsWith("internal")
                            || line.StartsWith("protected")
                            )
          ){
        MethodFinderMatches.Add(<BR>                 new MethodFinderMatchEventArgs((i + 1).ToString(), line));
      }
      if (bInComment && (line.StartsWith("//") || line.StartsWith("///")) ){
        bInComment = false;
      }
    }
  }
}

Points of Interest

I had fun writing this and it is not an original idea, but hopefully somebody out there will find it useful enough to write more (and more advanced) plugins. If anyone has any other ideas or feature request, just let me know. If anyone writes a plugin, just send it to me and I will include it, with credit of course, in the application's zip.

Credits

If you are interested in using SciTE, it is available at http://www.scintilla.org. If you still have to slave away in Object Pascal's IDE and don't know about GExperts, checkout http://www.gexperts.org.

History

Posted 2/24/2003 - initial version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralGreat tool! but little problem Pin
SoTTo7-Jun-04 4:42
SoTTo7-Jun-04 4:42 
GeneralRe: Great tool! but little problem Pin
Dan Logan28-Jun-04 17:17
Dan Logan28-Jun-04 17:17 
Generalthe BEEP sound.... Pin
dynamic16-Jun-03 11:57
dynamic16-Jun-03 11:57 
GeneralRe: the BEEP sound.... Pin
Anonymous16-Jun-03 13:51
Anonymous16-Jun-03 13:51 
GeneralRe: the BEEP sound.... Pin
Dan Logan16-Jun-03 13:54
Dan Logan16-Jun-03 13:54 
GeneralRe: the BEEP sound.... Pin
dynamic16-Jun-03 14:10
dynamic16-Jun-03 14:10 
GeneralRe: the BEEP sound.... Pin
Dan Logan16-Jun-03 15:29
Dan Logan16-Jun-03 15:29 
GeneralRe: the BEEP sound.... Pin
J. Dunlap16-Jun-03 15:38
J. Dunlap16-Jun-03 15:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.