I’m happy to announce that I’ve now released an updated version (v1.2) of the DX_SourceOutliner. The binary of the tool (ready for installation) as well as the source code is available on the project’s Google Code Site. For details and background on the project, see this category of posts here on this blog.
What’s New?
In addition to several bug-fixes, this release also includes the initial implementation of the option to populate the tree with all open code editor files at the same time vs. the tree only containing elements from the currently-active source code document. As you can see from the screenshot at left, when the ‘Show All Open Documents’ checkbox is toggled on, an additional ‘parent node’ for the source file itself becomes visible above the level of ‘namespace’. The checkbox is toggled OFF when the tool window is initially loaded so that the default behavior of prior versions of the tool is retained.
Filtering Still ‘Flattens’ the Tree Structure
In this release, the behavior is still the same when activating the Filter controls: the treeview structure is automatically flattened as before so that users can visually make sense of the filter results displayed in the control. I have several ideas (some my own, others suggested to me by users) for how to improve this behavior in the next release of the tool, so look for more info on my ideas on this to come soon.
In the mean time, happy coding and I hope readers are able to find value in the tooling in its present form!
Thanks for this news buid works fine (DXCore v9.2.2 RC). The “All open documents” is very a good idea and very useful.
Hi, first of all, congrats on a very nice plugin.
Couple of observations though:
– source outline is not showing VB modules (should be easy to fix though as they are mostly the same as classes)
– clicking on function selects whole line with signature, which doesn’t make much sense as you’re usually not going to change or delete the whole line. Cursor should be moved to the beginning of the signature instead
– current location of cursor in editor isn’t tracked (function currently edited in editor isn’t selected in a tree)
– regions support is needed
Maybe you should check out Resharper’s File structure window for some ideas.
Do you think it would be possible to add these to 1.x until you figure out what do you want to do with 2.x?
@gz:
Thanks for the feedback.
re: VB Modules, great point. I am only ‘processing’ nodes for selected code elements I chose to handle and there most certainly isn’t any code in there to add nodes for type=Module (but as you point out it should be simple to do this).
re: a click selecting the entire line, this is actually ‘by design’ (and I’m not trying to be funny, I’m serious). Click behavior *should* function as follows…
+ Single-click: highlight the entire line where the element is declared, retain focus in the SourceOutliner tool window
+ Double-click: highlight *just* the name of the element within its declaration, change focus to the code editor window
This behavior is designed to achieve the following goals:
1) single-click permits you to use the tool to quickly browse thru your code elements (since focus is retained in the tool window)
2) single-click permits easy visual acquisition of the relevant line of code even though focus doesn’t shift to the editor window (since the entire line is highlighted); this solves the ‘where is the cursor again?’ problem where the editor hightlight when not having focus tends to be a light-color more difficult to read
3) double-click says “this is the element I want and its my intention to edit it now” and so moves focus to the editor and pre-defines the selected text in the editor to be the ‘name’ of the element in its declaration; this makes it trivial to then invoke a refactoring (e.g. using CR/R!, R#, or even native VS tools) on that member since its already pre-selected in the editor and the editor has focus
From your comments, it sounds to me like either…
a) this isn’t working for you the way I just described — in which case there is abug somewhere I need to address!
b) you have yet to double-click a node in the tree to observe how the double-click behavior differs from the single-click behavior — in which case it hightlights that I need to spend more time writing documentation 🙂
Can you advise which of the above is your case?
re: tracking the current location of the cursor in the treeview, this already *does* work for me as you describe (the code element that contains the active cursor in the editor is properly tracked in the tree) but I have observed that on some systems (my PC at work running Vista with not-very-impressive set of LCD panels, for example) the highlight color of the default VS color scheme makes it somewhat difficult to actually see the highlight of the item in the tree.
Can you take a look (closely, carefully, and in dim ambient lighting conditions) to ensure that this is in fact working for you and please let me know? Again, this *may* be a bug, but its more likely related to the contrast settings on your hardware and the color scheme of your software.
re: Regions support, this has been requested prior by others and while I personally consider Regions in code to be horrible, evil, and an indicator for an almost-mandatory refactoring effort needed to eliminate the need for them in your code, I recognize that others have differing (wrong, IMO 🙂 ) views and so I did look into it.
The trick with Regions is that they are NOT exposed in the CodeRush DOM model as CodeElements or LanguageElements (the two types of things that my code presently processes when building the tree) and so a somewhat different tree-building approach would be needed to handle them in this project (unlike handling VB.NET Modules which is probably just a quick extension to a few switch-case statements in my code).
As such, while I looked into Region support in tree for the existing codebase, the complexity of adding them now (combined with the fact that I do everything in my power to remove the need for them in my own work so, completely selfishly, adding region support will do NOTHING to benefit me immediately) means that there won’t be support for regions until I complete the v2 re-engineering effort for this thing.
Let me know re: all of the above and I will dig into the issues if in fact these behaviors you’re reporting are indeed happening as you describe since AFAIK the latest 1.x release of the tool already does all of what you’re asking for (except the Region support).
Thanks again for the feedback~!
-Steve B.
– clicking – works as you designed it, but in my opinion selecting the whole line is counter-intuitive and error-prone – i can imagine myself starting typing and thus deleting the signature quite often. If you need to find out which line are you at there is a dx plugin for painting the background of current line at Rory’s community plugin site. Text selection is really meant for different things.
– highlighting – i played with it a bit more, highlight does work, but only if you click on a line with signature – if you click anywhere else inside the code (say method body), tree selection doesn’t follow
– modules – we use them rather extensively, so this is really a showstopper for us
– regions – they are a nice way to organize code in bigger source files. There is always a point at which OOP purism gets counter-productive and gets in the way of just getting it done ™, and it doesn’t make sense to break code that belongs together into zillions of small units just for the sake of it. I’m not very familiar with dx api, but if it provides the line number of beginning and end of language elements it should be rather easy to insert region to a correct place at a code tree (just some idea off top of my head, first cache line numbers of region directives, then when creating the tree just check if current region’s line number is > than last element’s end line and < than next element’s beginning line) and insert.
Also, seriously check R#’s File structure window, it’s a nice example of how plugin like this should look and work. Unfortunately (for them?) it’s not open-source and lacks more advanced features, but imho combination of its basic ideas and your advanced features would create just one kickass code structure plugin.
Cheers
@gz:
Thanks for sticking with me and helping me to understand what you’re seeing when you use the tool and what you’re suggesting re: its improved behavior.
re: clicking, I can see your point that I am using ‘select’ as a stand-in for ‘highlight’ and your point is well-taken. I will indeed look into other/better techniques for highlighting text in the editor short of a ‘full’ select of the text.
In the double-click scenario this makes sense (‘accidentally’ typing and overwriting the name of the element by mistake) but can you help me understand what you mean when you say its counter-intuitive to select/highlight the entire line on single-click? Since focus remain in the tool window, the select (or let’s assume it becomes just a highlight as you recommend) is really just for visual reference to draw your eye to the target quickly. When you then click in the editor window to give it focus, isn’t the selected/hightlighted region deselected and the I-beam editor cursor appears at your click location?
re: modules, as I mentioned this is probably trivial to implement so I will certainly try to squeeze in the time to do so; not supporting modules in the tree is a clear impediment to ‘proper’ support of VB.NET so I think it makes all the sense in the world for me to support this code element in the tree.
re: Regions, we will have to agree to disagree on this design and philosophical point as our definition of ‘just get it done’ seems to fundamentally differ. My opinion about this is that if you are in just-get-it-done mode you stick a “//TODO: refactor this block of code into another more appropriate class” comment in the code rather than hide the mess behind a ‘region’ tag that doesn’t have much chance of drawing anyone’s attention to the design deficiency in a subsequent phase of the project when there is time to ‘just get it done right so that it can be maintained properly over its hopefully long life as a software solution’ instead of only time to ‘just get it done’. And if there’s no intention to maintain the project over a (hopefully) long life b/c its a one-off solution designed to be used for just a short period of time and then discarded, then why bother to put region tags in it in the first place since by definition nobody will come back behind your work to maintain it? 🙂
In any case, debates about Region tags feel to me like debates about hungarian notation, whether fields should be prefixed with “_” or “m_” (or nothing!), tabs vs. spaces, braces on a new line vs. same line as the method declaration, etc. This choice is the intersection of everyone’s own personal preferences with everyone’s own personal lessons learned from their own unique experiences. Mine tell me Regions are an indicator of a bigger design flaw that will near-certainly cause me larger grief later on in my project’s lifecycle and yours don’t so I avoid them and you don’t. To each their own.
But I’m allowing for the fact that not all people see it that way and that’s why I *do* plan to support Regions in the tool at some point. I don’t think it a reasonable position for me to take to say “I don’t like .NET language element A, B, or C so I won’t support them in the tool.” 🙂
Sadly, however, the idea of matching line numbers isn’t really entirely feasible since line-by-line isn’t actually how I’m ‘parsing’ the source code to display in the tree. DXCore exposes a semantic model of the source file’s structure that’s already in parent-child-grandchild tree structure and this is what I’m leveraging to parse the code DOM and interact with it. As far as I can tell from my (admittedly only brief) look at this model, Regions are not manifest in this tree structure and so another, completely different method would be needed for me to get at them and place them in the SourceOutliner tree. Obviously, I’m certain that there is *some* way DXCore exposes Region tags in its object model but since there is poor (mostly non-existent) documentation for the DXCore API, actually discovering how Regions are manifest in the DXCore API is disappointingly non-trivial. Its on the list ( http://code.google.com/p/dxsourceoutliner/issues/detail?id=2 , I actually added it *myself* in response to a request from someone else prior), but its just not a top priority right now. The project *is* open source and if this is of higher priority for you than it is for me, I will gladly accept a patch from you if you want to take it on.
re: the tree not ‘tracking’ properly when you are in the body of a method, can you perhaps e-mail me (or copy-paste into comments here) a block of source code that evidences this problem? In my test environment, the method declaration is properly highlighted in the tree when my cursor is in the body of the method as expected. Its possible that something your code does in its structure is confusing the active-node-tracking code in the SourceOutliner and I’d need to have some way of reproducing what you’re seeing in order to troubleshoot it since I cannot seem to reproduce this behavior on my end. Please try to get me something that demonstrates this issue and I will certainly try to resolve it in v1.x even as v2.x is under re-design.
Thanks again for the comments; I really do appreciate it as this kind of feedback and suggestions for improvement are the only way that this thing will continue to be able to improve and be of increasing utility to people.
-Steve B.
– clicking – imo, after you select function in tree, outliner’s job is done and focus should be moved to editor, as that is where your interest as a coder is. Sorry, I’ve only played with this for a short while and I didn’t notice that it isn’t so with your plugin.
– tree tracking – in editor, if you click directly to middle of method’s body FIRST, to a line containing some code, function selected in tree doesn’t change. If you click on signature line (or click on method in outliner), or an empty line, selection does change. I tested it on couple of .cs files from DXCore’s shared source plugin directory. I made a screenshot clearly showing cursor in a different method than tree selection. Also at the top there is screenshot from R#’s File structure window, showing how they handle regions (i like it a lot, especially since you can rename and move code around directly from tree). Check http://img31.imageshack.us/img31/7809/dxoutliner.gif .
– region sorting – as i said i’m not familiar with dxcore, but i find it hard to believe their api wouldn’t have a function to find out line number of every element. Check e.g.
http://dxcorecommunityplugins.googlecode.com/svn-history/r138/trunk/RedGreen/RedGreen/DxCoreUtils.cs , maybe this is it. If not, try to ask how to do it on their forum, I think Rory usually comes out with complete plugins as answers. Unfortunatelly I’m just too busy to learn their api, maybe one day.
C:\Program Files\DevExpress 2009.1\IDETools\System\CodeRush\SOURCES\CR_MemberMover might be also able to help you.
– also, one more thing, maybe an option to not to show namespace in a tree? especially when you only show entries from one file and there is only one namespace (most people probably organize code like that), it doesn’t provide any information and only wastes precious horizontal screen estate.
@gz:
re: clicking I’m not 100% certain what you’re saying here — are you confirming that the double-click setting the focus in the editor makes sense to you or are you saying that you would prefer the single-click also set focus to the editor?
re: tracking-current-item-context in the tree, I will take another look at the present behavior to see what conditions have to be true for this to occur; it does sound like you have identified a possible behavioral bug in re: how it behaves when you first click into the editor window in the body of a method
re: regions, trust me that the DXCore API isn’t line number based (and it eschews working with line-numbers in favor of its in-memory model of the source code tree). I have taken a quick look at the API to discover how Regions are represented and it looks to me as though each node in the DXCore Code DOM tree contains a property called element.ParentRegion that allows you to interrogate each node to determine what (if any!) region its located within (presumably element.ParentRegion==null means NO region).
This will permit me to support regions in v2 but will need to be done NOT by interating through the tree to see what elements are beneath region nodes (since there isn’t any concept of a region node in the DXCore API Code DOM) but instead by having to ask each element “what region is your parent?” and then manually affixing each node beneath a parent region node that I will need to manually construct myself.
Since this pattern of identifying regions and placing other nodes within them is very different than how I am presently processing the tree elements in the v1 code, this will need to wait for a v2 release.
re: not showing namespaces in the tree if there is only a single namespace in the sourcefile, this is a good idea to save on screen real-estate; I’ll look to factor this into the future work on the tool as well.
Right now, I’m thinking that ‘hide namespace in tree if only single namespace is present’ and ‘show regions in tree’ will probably be surfaced as user-settable options in v2.
– clicking – double-click makes sense, single click should imo just bring focus to editor at the beginning of signature line, with no text selection. Maybe make it configurable?
– regions – ok, good to hear you’ve found a solution. Maybe you could also make their visual representation more like something like R# has? It saves space, looks good and enables couple of nice function (rename, remove, move functions between regions).
Thanks for all the effort and good luck with your projects.