Author Topic: Navigate to hierarchy  (Read 21084 times)

titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Navigate to hierarchy
« on: March 14, 2008, 03:21:52 pm »
Hi All,

Does anyone know if it's possible to navigate to the project hierarchy ( with the file selected ) from a file that is open in the editor? For example, Eclipse has a right click pop-up menu, "Show in Explorer", or something like that. Is there something similar in SlickEdit?

thanks,

B

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Navigate to hierarchy
« Reply #1 on: March 15, 2008, 05:56:05 am »
Does anyone know if it's possible to navigate to the project hierarchy ( with the file selected ) from a file that is open in the editor? For example, Eclipse has a right click pop-up menu, "Show in Explorer", or something like that. Is there something similar in SlickEdit?

My own files toolbar (GFileman) provides this, plus "open from here" on a right click menu.  Slick team could easily add this to the files toolbar right click menu.  (An option for single click to open a file would be nice too).

I've attached a macro file utils2.e that provides a bunch of commands for exploring and opening, plus a macro file diff_last_two_buffers.e (written by Ryan Anderson from slickteam).  You can modify the SE right click context menu (the menu you get when you right click on an edit window) to add an extra submenu that provides all the commands you'll see in utils2.e, plus diff last two buffers.  The menu is called _ext_menu_default.  (If there's a selection active when you right click, you get the _ext_menu_default_sel menu).

You don't have to add the commands in utils2.e to the context menu if you don't want to - they have all short 2 or 3 character names (xp, xpc etc) so you can run easily from the cmd line.  If you use the xp (explore) command from the command line you can add a parameter that is the name of the folder you want to explorer.  If you have cmd line history enabled, every time you type the xp cmd on the cmd line, slick gives you a list of the values you've previously entered for the path  - so you can easily open "recent" folders.

In utils2.e, the default _ext_menu_default menu for slick V13 beta 2 is shown commented out and it has a sub-menu "Open / Explore / Copy / Diff" that I've added.

To modify your own right click menu, you can either use the "edit this menu" option on the default right click menu or you can use the "Menus" option on the macro menu and select _ext_menu_default.  To add a sub menu, position the "cursor" where you want the sub-menu to go, click insert (or next if you're at the end), check the "sub-menus" checkbox and enter a caption for the sub-menu (e.g.   "Open / Explore / Copy / Diff" ), then double click the "+" icon and create the sub-menu.

If you want to save time creating the sub-menu, you can do the steps I've listed above, but leave the sub-menu empty.  Then you can open an empty slick c file (or the attached utils2.e) and use the "insert form or menu source" command on the macros menu and insert the source for _ext_menu_default.  It should look similar to what you see in utils2.e already.  You can then edit the source for _ext_menu_default and add the sub-menu stuff for "Open / Explore / Copy / Diff"

Below is what the start of my _ext_menu_default menu looks like now - you can see the whole menu in utils2.e.  The new sub-menu is the third item in the right click menu.  After editing your own menu source you need to load it (use "load module" on the macros menu).  If you put the menu source in utils2.e, you might want to comment it out after loading because if you make future changes to the right click menu, the source in utils2.e won't be updated.  (Changes you make to system menus get added to a file vusrsx.x.x.x.e file in your config folder when you save your configuration or do a list-sys-objects cmd on the slick cmd line.)

If the explore commands aren't exactly what you want, you can modify them however you like.

Edit - forgot to mention, the code in utils2.e uses Windows Explorer by default but if you're not on Windows or want to use some other file manager, you can either change the get_explorer_cmd function in utils2.e or set the def_explorer_path def-var to a suitable string with appropriate switches (use set-var on the slick cmd line).  The folder path gets added to the end of this string and the whole string is passed to the slick shell cmd.

Graeme

Code: [Select]
_menu _ext_menu_default {
   "Quick Search","quick-search","","help Quick Search","Searches for word at cursor";
   "Quick Replace","quick-replace","","help Quick Replace","Replace the word at cursor";
   submenu "Open / Explore / Copy / Diff","","open-file or explore folder","" {
      "Open from here (op)","open-from","","","open from current buffer path";
      "Open from config (opc)","opc","","","open file from configuration folder";
      "Open from project root (opp)","opp","","","";
      "Open vsstack error file (opvss)","opvss","","","Open Slick C error file";
      "-","","","","";
      "Explore current buffer (xp)","xp","","","explore from folder of current buffer";
      "Explore config folder (xpc)","xpc","","","";
      "Explore installation folder (xps)","xps","","","";
      "Explore docs (xpdocs)","xpdocs","","","";
      "Explore project root (xpp)","xpp","","","";
      "-","","","","";
      "Copy cur buffer name to clipboard","curbuf-name-to-clip","","","";
      "Copy cur buffer path to clipboard","curbuf-path-to-clip","","","";
      "-","","","","";
      "Diff last two buffers (diff2)","diff2","","","";
   }
   "-","","","","";
   "Go to &Definition","push-tag","","help Go to Definition","Goes to definition or declaration for word at cursor";

   ...

« Last Edit: March 15, 2008, 09:28:50 am by Graeme »

titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #2 on: March 15, 2008, 02:11:08 pm »
Cool. Thanks for these. But can you navigate to the file in the Project hierarchy? Your script opens the file in Windows Explorer.

The use case for this is you have a very large workspace with many projects and each of those projects have many folders. You have a file open in the editor because you knew what the class name was. Now you want to see other files that exist at the same tree level and you want to visually see what project the file is in. Yes, a file manager will show this, but it's not very convenient to have to use 2 tools for 1 task.

thanks,

B

Ivan N. Zlatev

  • Community Member
  • Posts: 87
  • Hero Points: 5
Re: Navigate to hierarchy
« Reply #3 on: March 15, 2008, 02:58:34 pm »
Tools -> OS File Browser opens the directory where the file is in a new file manager for me. I do not know if that's what you want.

titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #4 on: March 15, 2008, 04:03:03 pm »
No, that's exactly what I DON'T want. :) Opening another tool is not useful. Does anyone use projects?

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Navigate to hierarchy
« Reply #5 on: March 16, 2008, 10:34:26 am »
Cool. Thanks for these. But can you navigate to the file in the Project hierarchy? Your script opens the file in Windows Explorer.

The use case for this is you have a very large workspace with many projects and each of those projects have many folders. You have a file open in the editor because you knew what the class name was. Now you want to see other files that exist at the same tree level and you want to visually see what project the file is in. Yes, a file manager will show this, but it's not very convenient to have to use 2 tools for 1 task.

thanks,

B

In your original post you mentioned "show in explorer" so I took a guess that you meant Windows Explorer but wasn't sure.  It's still slightly unclear what you want because you don't mention a specific toolbar.  Have you used the projects toolbar in "directory view" mode  - is that where you would like the file to be displayed.  To select directory view mode, right click on the project name then select auto folder -> directory view mode.  The slickedit help file doesn't yet describe what these modes do but I think it's on their todo list.  There are also other toolbars/dialogs for showing project files e.g. the files toolbar with the project tab selected or the open project file dialog.

Does the projects toolbar in directory view mode look like what you want  - if you have lots of files and folders you will most likely not be able to see the name of the project at the same time as the specific file - you would have to scroll the window.  Anyway, I don't see any sign of an easy way of bringing that toolbar up showing the currently edited file  - you would probably have to iterate through the _tbprojects_form._proj_tooltab_tree tree control to find the file, then figure out how to make that node of the tree visible and selected. 

It might be easier to create your own dialog showing the name of the project the file belongs to (what if it belongs to multiple projects?) and a list of files (in a listbox) in the same folder that also belong to that project.

Graeme



titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #6 on: March 16, 2008, 12:56:51 pm »
Quote
Does the projects toolbar in directory view mode look like what you want

Yes, that's what I'm talking about. Sorry I was unclear. I thought this was a no brainer when I posted it. I thought someone would have already solved this issue long ago. I am so used to using this feature in Eclipse. I guess I took it for granted. In Eclipse, it's actually "Show in Package Explorer" and "Show in Navigator". I may play around with the _tbprojects_form._proj_tooltab_tree as you suggest and try to write a script to do this. Wish me luck. :)

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 285
Re: Navigate to hierarchy
« Reply #7 on: March 16, 2008, 01:22:57 pm »
@titanandrews: The first part needed might be already implemented:
project.e - _WorkspaceFindProjectWithFile() [line 7929]: SE v12.0.3 r35
At least you can use it as a good starting point.
I'm using this simple maro to just show the information in the status bar:
Code: [Select]
_command _str buf2proj( _str filename = p_buf_name, _str workspaceName = _workspace_filename) name_info (','VSARG2_READ_ONLY|VSARG2_REQUIRES_EDITORCTL)
{
   _str projName = _WorkspaceFindProjectWithFile(filename,workspaceName,true,false);
   message ("Selected Project: '" projName "' containing '" filename "'" );
   return projName;
}
I afraid the finding the file and expanding the node in the Projects TB is a bit more work (@see 'ptoolbar.e')

Good luck,
HS2

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Navigate to hierarchy
« Reply #8 on: March 17, 2008, 11:19:35 am »
Here's some code that works to a point  -  i.e. it only works if the desired destination node has been previously expanded.  It still works if the tree is fully collapsed, as long as it had been previously expanded.  I guess this means the tree is only populated when needed - hence you still have to find a way to (partially) populate the tree.  Unfortunately I don't have time to look into that right now but you might get some ideas from _proj_tooltab_tree.on_change in ptoolbar.e.  Also, you will need to add some code to activate the toolbar in case it's not already visible, and select directory view mode.

Graeme


Code: [Select]
_command void showx() name_info(',')
{
   int state,bm1,bm2,flags;

   int hTree = _find_object('_tbprojects_form._proj_tooltab_tree');
   if (hTree > 0) {
      int index = hTree._TreeSearch(
         TREE_ROOT_INDEX,'GFileman.e' :+ "\t" :+  'L:\gp\vslick\config-test\GFileman\GFileman.e','TIH');
      if (index > 0)
      {

        hTree._TreeSetAllFlags(0,TREENODE_SELECTED);
        hTree._TreeGetInfo(index,state,bm1,bm2,flags);
        hTree._TreeSetInfo(index,state,bm1,bm2,flags|TREENODE_SELECTED);
        hTree._TreeSetCurIndex(index);

        //_message_box(hTree._TreeGetCaption(index));
         //_str s1 = hTree._TreeGetCaption(index);
         //int k;
         //for (k=8;k < s1._length();++k) {
         //   say(_asc(substr(s1,k,1)));
         //}
      }
   }
}


titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #9 on: March 18, 2008, 11:34:54 pm »
Yeah, that's a good start! But since the tree is lazily loaded, it looks like there's no way to programatically expand the nodes. I tried _TreeGetFirstChildIndex, but since the tree has not been previously expanded ( by the user ) it returns -1 ( no children ).  Kind of sucks.

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 285
Re: Navigate to hierarchy
« Reply #10 on: March 19, 2008, 12:00:35 am »
You could try '_TreeSetInfo(TREE_ROOT_INDEX, 1, ...);' to start expansion.
And also maybe these fct.s:
_TreeGetNextSiblingIndex();
_TreeBeginUpdate();
_TreeEndUpdate();
...

Good luck,
HS2

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Navigate to hierarchy
« Reply #11 on: March 19, 2008, 10:40:56 am »
Yeah, that's a good start! But since the tree is lazily loaded, it looks like there's no way to programatically expand the nodes. I tried _TreeGetFirstChildIndex, but since the tree has not been previously expanded ( by the user ) it returns -1 ( no children ).  Kind of sucks.

It is possible to programmatically expand a project node.  I've added some code (below) to the code I originally posted which populates the tree for a particular project and allows the desired file to be found by _TreeSearch  - from **1 to **2 in the code below.  I explicitly search for the project GFileman-cvs.vpj because I know that's the project name (The 'P' means prefix search but you shouldn't need that because you will have the full project name, but don't forget the hard tab).  The next lines after that are copied from _proj_tooltab_tree.on_change code in ptoolbar.e (case CHANGE_EXPANDED : ).  I think this results in all nodes for that project being fully populated.  You still need to find the name of the project that contains the file you're interested in  - hs2's suggestion of _WorkspaceFindProjectWithFile should work for that.  Not sure how to handle the situation of the file belonging to multiple projects.

Edit - you should probably call TreeBeginUpdate before you start populating the tree and TreeEndUpdate when you finish populating.

Graeme

Code: [Select]
_command void showx() name_info(',')
{
   int state,bm1,bm2,flags;

   int hTree = _find_object('_tbprojects_form._proj_tooltab_tree');
   if (hTree > 0) {
      // **1
      int index = hTree._TreeSearch(TREE_ROOT_INDEX,'GFileman-cvs.vpj', 'IPH'); 
      if (index < 0) {
         _message_box('Project not found');
         return;
      }
      if (hTree._projecttbIsProjectNode(index)
          && hTree._TreeGetFirstChildIndex(index)<0   ) {
         hTree.toolbarBuildFilterList(hTree._projecttbTreeGetCurProjectName(index),index);
         // Rebuilding the filter list for the project just expanded
         // will re-set the current index. Refocus the project node
         hTree._TreeSetCurIndex(index);
      }
      // **2

      int index2 = hTree._TreeSearch(
         TREE_ROOT_INDEX,'GFileman.e' :+ "\t" :+  'L:\gp\vslick\config-test\GFileman\GFileman.e','TIH');
      if (index2 > 0)
      {

        hTree._TreeSetAllFlags(0,TREENODE_SELECTED);
        hTree._TreeGetInfo(index2,state,bm1,bm2,flags);
        hTree._TreeSetInfo(index2,state,bm1,bm2,flags|TREENODE_SELECTED);
        hTree._TreeSetCurIndex(index2);

        //_message_box(hTree._TreeGetCaption(index));
         //_str s1 = hTree._TreeGetCaption(index);
         //int k;
         //for (k=8;k <= s1._length();++k) {
         //   say(_asc(substr(s1,k,1)));
         //}
      }
   }
}
« Last Edit: March 19, 2008, 11:53:10 am by Graeme »

titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #12 on: March 20, 2008, 01:00:15 pm »
Unfortunately, I don't have the luxury of using the _WorkspaceFindProjectWithFile function. I am using SE v11  :( 
Quote
You could try '_TreeSetInfo(TREE_ROOT_INDEX, 1, ...);' to start expansion.
And also maybe these fct.s:
_TreeGetNextSiblingIndex();
_TreeBeginUpdate();
_TreeEndUpdate();

I've tried those. None of them seem to help anything.

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Navigate to hierarchy
« Reply #13 on: March 24, 2008, 09:29:32 am »
Quote
Unfortunately, I don't have the luxury of using the _WorkspaceFindProjectWithFile function. I am using SE v11

SE V11 does have the _WorkspaceFindProjectWithFile function.  I've updated the macro I previously posted and it works fine for me in V11, but I haven't tested a workspace with multiple projects or a workspace where the file appears more than once. 

The call to _WorkspaceFindProjectWithFile function passes four arguments, the last of which is "quiet mode".  When this is set false (as below), the _WorkspaceFindProjectWithFile function will present a dialog if the file appears more than once, asking that one be chosen.  If you just want to show the first one found (if any) then set the fourth argument (quiet mode) to true.

The project toolbar gets activated by this macro but the "auto folder" mode (Directory view, custom view or package view) is left unchanged, so if you want directory view, you will have to select it manually.  There is a function called projecttbAutoFolders that allows to set the mode, but it can only be called from a menu, but you might be able to make your own version if you desperately wanted to switch modes automatically.  The status bar will also show the project name, filename and SlickEdit version number.

Graeme


Code: [Select]
// Search the workspace for the project containing the current file (or the
// specified file) and show the project toolbar with the file selected
_command void showx, locate_file_in_project_toolbar(_str filename = '', boolean quiet = false) name_info(',')
{
   int state,bm1,bm2,flags;

   if (filename == '') {
      if (_no_child_windows()) {
         _message_box('Error : no filename specified');
         return;
      }
      filename = _mdi.p_child.p_buf_name;
   }
   _str project_found = _WorkspaceFindProjectWithFile(filename, _workspace_filename, true, quiet);

   if (project_found == '') {
      _message_box('File not found : ' :+ filename);
      return;
   }
   message('Project : ' :+ project_found :+ '   File : ' :+ filename :+ '  SE ' :+ _getVersion());

   activate_projects();

   int hTree = _find_object('_tbprojects_form._proj_tooltab_tree');
   if (hTree > 0) {
      int index = hTree._TreeSearch(
         TREE_ROOT_INDEX, strip_filename(project_found,'P') :+ "\t" :+ project_found, 'IH'); 
      if (index < 0) {
         _message_box('Project not found in toolbar');
         return;
      }
      if (hTree._projecttbIsProjectNode(index)
          && hTree._TreeGetFirstChildIndex(index)<0   ) {
         hTree.toolbarBuildFilterList(hTree._projecttbTreeGetCurProjectName(index),index);
         // Rebuilding the filter list for the project just expanded
         // will re-set the current index. Refocus the project node
         hTree._TreeSetCurIndex(index);
      }

      int index2 = hTree._TreeSearch(
         TREE_ROOT_INDEX,strip_filename(filename,'P') :+ "\t" :+ filename, 'TIH');
      if (index2 > 0)
      {
        hTree._TreeSetAllFlags(0,TREENODE_SELECTED);
        hTree._TreeGetInfo(index2,state,bm1,bm2,flags);
        hTree._TreeSetInfo(index2,state,bm1,bm2,flags|TREENODE_SELECTED);
        hTree._TreeSetCurIndex(index2);
      }
   }
}

titanandrews

  • Community Member
  • Posts: 21
  • Hero Points: 2
Re: Navigate to hierarchy
« Reply #14 on: March 25, 2008, 06:15:28 pm »
I cannot thank you guys enough for all your help. I finally got the functionality I have been missing for so long. With a bit of tweaking of some code that you provided, I ended up with this script that works like a charm ( for me ). This is such a valuable macro!

Thanks again!

-B


Code: [Select]
#include "slick.sh"

/**
 *
 * @param hTree
 * @param caption
 *
 * @return boolean
 */
boolean findAndSelectCaption(int hTree, _str caption)
{
   int state,bm1,bm2,flags;
   int index = hTree._TreeSearch(TREE_ROOT_INDEX,caption,'TS');
   boolean found = false;
   if (index > 0)
   {       
        hTree._TreeSetAllFlags(0,TREENODE_SELECTED);
        hTree._TreeGetInfo(index,state,bm1,bm2,flags);
        hTree._TreeSetInfo(index,state,bm1,bm2,flags|TREENODE_SELECTED);
        hTree._TreeSetCurIndex(index);
        found = true;
   }   

   return found;
}

/**
 *
 * @param filename
 * @param ext
 *
 * @return _str
 */
_str buildCaption(_str filename, _str ext)
{
   _str newfile = strip_filename(filename,'E');
   newfile = newfile :+ '.' :+ ext;
   _str caption = strip_filename(newfile,'P');
   caption = caption :+ "\t" :+ newfile;

   return caption;
}

_command void showInProject(_str filename = p_buf_name) name_info(',')
{     
   int hTree = _find_object('_tbprojects_form._proj_tooltab_tree');
   _str caption = strip_filename(filename,'P');
   caption = caption :+ "\t" :+ filename;   
   if(hTree > 0)
   {                             
      boolean found = findAndSelectCaption(hTree, caption);
      if(!found)
      {     
         _str project_found = _WorkspaceFindProjectWithFile(filename, _workspace_filename, true, true);

         if (project_found == '')
         {
            message('No project containing the file ' :+ filename);
            return;
         }

         activate_projects();

         _str project_caption = buildCaption(project_found,'vpj');
         int index = hTree._TreeSearch(TREE_ROOT_INDEX, project_caption, 'T'); 

         if(index == -1)
         {
            project_caption = buildCaption(project_found,'vcproj');
            index = hTree._TreeSearch(TREE_ROOT_INDEX, project_caption, 'T'); 
         }
                 
         if(index == -1)
         {           
            project_caption = buildCaption(project_found,'csproj');
            index = hTree._TreeSearch(TREE_ROOT_INDEX, project_caption, 'T');
         }
         
         if(index != -1)
         {           
            if (hTree._projecttbIsProjectNode(index)
                && hTree._TreeGetFirstChildIndex(index) < 0)
            {
               hTree.toolbarBuildFilterList(hTree._projecttbTreeGetCurProjectName(index),index);
               // Rebuilding the filter list for the project just expanded
               // will re-set the current index. Refocus the project node
               hTree._TreeSetCurIndex(index);               
            }               
         }
         else
         {           
            message('No project containing the file ' :+ filename);
            return;
         }
                                                         
         found = findAndSelectCaption(hTree, caption);
         if(!found)
         {
            message('File not found : ' :+ filename);
         }
      }
   }
   else
   {
      message("Could not find the project tree.");
   }
}