applying smart indentation rules

Hi,
 I have been facing a problem regarding the implementation of smart indentation rules in my custom language service. i am not able to find out which interface should i implement and where should i write my rules.
  Please help me with the process.
   Thanks in advance..


Answer this question

applying smart indentation rules

  • bill_csharper

    Hi Dylan,
     I have implemented the interface in my languageservice class.But the main problem with the interface is that its method "getindentposition" is called only when we press up or down arrow keys moving cursor to a blank line but not when we press enter. There should be some method which takes the character as an argument value for invoking indentation because in that position only we can make our indentation rules. am i right ..
        If there is something else i should know about implementing indentation rules plz let me know. And also plz can u find any way to implement this interface and using its method and if it runs beautifully plz let me know.
      My code in the method is as follow :

    public int GetIndentPosition(IVsTextLayer pBaseLayer, int BaseBufferLineIndex, out int pIndentPosition)

    { string strTextString;

    int intLengthOfLine;

    pBaseLayer.GetLengthOfLine(BaseBufferLineIndex, out intLengthOfLine);

    pBaseLayer.GetLineText(BaseBufferLineIndex, 0,BaseBufferLineIndex, intLengthOfLine, out strTextString);

    string[] keys = strTextString.Split(new char[] { ' ' });

    foreach (string strKey in keys)

    {
    if(mlstopeningtaglist.Contains(strKey) == true||mlstclosingtaglist.Contains(strKey) == true)
    {
    if (mlstopeningtaglist.Contains(strKey) == true)
    {
    pIndentPosition = 4;
    }
    else if (mlstclosingtaglist.Contains(strKey) == true)
    {
    pIndentPosition = 4;
    }
    }
    else
    {
    pIndentPosition = 0;
    }
    }
    return VSConstants.S_OK;
    }

    mlstclosingtaglist and mlstopeningtaglist are arraylist containg keywords.
    Plz let me know if i have to add something else in the method
    jimmy



  • QXUE

    The only method on the IVsLanguageTextOps interface that might be useful to you is the Format method.  That is called when a user invokes the Edit.FormatSelection or Edit.FormatDocument commands.

    You will probably want to listen for the ECMD_RETURN command and do an indent on that line after the command is processed.



  • shadow_woman

    Jimmy,

    Have you tried implementing the IVsLanguageLineIndent interface (in textmgr2.idl if you are using native code or Microsoft.VisualStudio.TextManager.Interop.8.0.dll if you are using managed)

    Take a look at that interface and see if it answers your questions and then let me know if you are still having some problems.

    Thanks,

    Dylan

  • fariborz

    hi Dylan ..
      can IvsLanguageTextOps interface be a usefull one...
         plz reply

  • Ram_Madurai

    I have done the processing of making visual studio call oncommand method. But the main problem is that visual studio does'nt call OnCommand method when we press enter in our editor.

    Can u tell me how can we listen enter command in OnCommand method.



  • nitinbourai

    Jimmy,

    You will need to add yourself to the command filter.  If you get a pointer to the IVsTextView interface, you should be able to call AddCommandFilter and pass your command filter in.  You will then want to save the next command filter (It is passed back in the AddCommandFilter function) and forward commands on to it.  Then, when you receive an ECMD_RETURN command, after you've passed it on, you can do your indenting.

    Now if you are using the managed package framework, you can just override the OnCommand function in Source and listen there.

    Thanks,

    Dylan

  • Anthony at Beckman

    Hi Dylan..
       It is good to hear from u again. I am not able to get ECMD_RETURN command from vsstd2k commands can u be more detailed on this part of the story as it seems to be more interesting now when i have applied all of my methods and cant get any good results on indentation. 
        plz try to give me any coding hints also.
               Thanks
                jimmy

  • Aaron_Liu

    Hi Dylan

       actually i have made a different approach to the problem and succeeded to some extent the approach is as follows..

       in my scanner whenever i get the token of "if" and "end" i call the "reformatspan" method of  my source class which then call doformat method in source class. this method requires textspan and editarray as in parameters but i m getting the problem which is that whenever texteditor in exp hive is on screen,scanner is called from language service's getscanner method and parsing is done and since i m calling the reformatspan method from scanner class reformatspan is also called each time and hence it again format the span.

    my code in doformatting is as folows:

    private void DoFormatting(EditArray mgr, TextSpan span)

    {

    // Make sure there is one space after every comma unless followed

    // by a tab or comma is at end of line.

    IVsTextLines pBuffer = GetTextLines();

    if (pBuffer != null)

    {

    int startIndex = span.iStartIndex;

    // Loop over all lines in span

    for (int i = span.iStartLine; i <= span.iEndLine; i++)

    {

    string lineText;

    int lineLength;

    pBuffer.GetLengthOfLine(i, out lineLength);

    pBuffer.GetLineText(i, startIndex, i, startIndex+lineLength, out lineText);

    string replacementText = " ";

    TextSpan editTextSpan = new TextSpan();

    editTextSpan.iStartLine = i;

    editTextSpan.iEndLine = i;

    editTextSpan.iStartIndex = startIndex;

    mgr.Add(new EditSpan(editTextSpan, replacementText));

     

    }

    try

    { //Apply all edits

    mgr.ApplyEdits();

    }

    catch (Exception e)

    {

    System.Diagnostics.Trace.Write(e.Message);

    }

    }

    }

    Here span is the text span between the line of "if" and "end"

    Actually my problem is somewhat clear. can u plz find out the  solution.

    I have also tried OnCommand method but the problem is it is not called whenever i press enter. i had override the method in my class. 

      



  • NIKKOSTA

    I would highly recommend not reformatting in your scanner.  The scanner is used for colorization which is called every time the screen is painted.  Reformating code is a more expensive operation and should not be done each paint.  If you really want to reformat constantly, I would recommend doing it on a parse.

    You should be able to get the OnCommand override to work.  Is OnCommand not being called at all

    Thanks,

    Dylan



  • Anne292

    Hi Dylan,

    You are very right, actually i was also facing the same problem since i had called reformatspan from my scanner. So now i moved towards OnCommand method.I have overrided the method OnCommand in my derived source class, , but i am not been able to get it called  when i give the command in experimental hive.

    Plz tell me more about how to execute formatting on giving any command.



  • JvvJ

     

    Hi,

    i have given indentation to my editor at the time of parsing by capturing the charcters in OnCommand method and then applying edits on textspan and it is doing perfectly fine.

    But the problem i am facing now is that when i opens more than one file of my editor in one project in expiremental hive i am not able to get indentation in all of the files but in only one file which was opened with the adding of the new project.

    Plz tell me how can i get the solution.

    Thanx in advance..



  • Theron S.

    I have implemented it by implementing ViewFilter::HandleSmartIndent() method.
    This method called when pressed ENTER key from base.HandlePreExec, if (LanguagePreferences.IndentStyle == IndentingStyle.Smart).
    To support smart indenting, create new ViewFilter class and override HandleSmartIndent method,
    and return it from LanguageService::CreateViewFilter.

  • applying smart indentation rules