oleg-shilo / codemap.vscode

Code map (syntax tree) of the active document
MIT License
84 stars 28 forks source link

Set Indentation with generic mapper #32

Closed jharris1314 closed 4 years ago

jharris1314 commented 4 years ago

Can you set indentation with the generic mapper? If so, how?

oleg-shilo commented 4 years ago

If you are using regular tree view rendering then you cannot really control it. TreeView does.

However if you have TextMode enabled (my preferred mode btw 😄) then you can specify the size of indent by defining it as a non-whitespace string of any size:

image

And just to give you the idea about the difference between TreeView and Text mode:

TreeView mode:

image

Text mode:

image

jharris1314 commented 4 years ago

Thank you for the quick response. I am using Text mode. I am adding a prefix of " " (multiple spaces) for each item in the settings.json, but the spaces are not showing up in the Codemap Explorer.

{ "pattern": "LAYER:\\w*", "prefix": " ", "icon": "function" },

oleg-shilo commented 4 years ago

You cannot use "multiple spaces":

indent by defining it as a non-whitespace string of any size

TreeView always swallows spaces. You need to use any unicode character that is not a space and yet does not render anything on the screen. Thus the line below is a string of three characters 'U-00A0'     You can also copy it from codemap
image

jharris1314 commented 4 years ago

Copying them from codemap worked. Thanks for the help. This extension is incredibly helpful for navigating gcode.

Suggestion: It would be very useful if you could indent the icons in text mode.

oleg-shilo commented 4 years ago

Suggestion: It would be very useful if you could indent the icons in text mode.

Sorry mate, not possible :)

The text mos is intended to overcome rather very limited rendering capabilities of TreeView by allowing custom indent (like you did) in the text area of the tree node. We need it because TreeView does not allow us to customize the indent any other way. So we insert the empty text to emulate indent.

But the true indent, the one that shifts icons to the right side is just not customizable. Well at least with this state of VSCode API

juanbretti commented 4 years ago

The text mos is intended to overcome rather very limited rendering capabilities of TreeView by allowing custom indent (like you did) in the text area of the tree node. We need it because TreeView does not allow us to customize the indent any other way. So we insert the empty text to emulate indent.

Sorry, but I don't find it clear. I want to use the TreeView and have indentation using my custom mapping. Is that possible?

My mapping for Python looks like:

    {
        "pattern": "^(\\s*)#### (.*)----",
        "clear": "#|----",
        "prefix": "  ",
        "icon": "level3"
    },
    {
        "pattern": "^(\\s*)### (.*)----",
        "clear": "#|----",
        "prefix": " ",
        "icon": "level2"
    },
    {
        "pattern": "^(\\s*)## (.*)----",
        "clear": "#|----",
        "icon": "level1"
    },

Thanks!

oleg-shilo commented 4 years ago

Yes it is. If you are using "codemap.textMode" then you can set codemap.textModeLevelPrefixJust to any text you want and it will become your indent text multiplied by the indent level value. Just start experimenting and you will see the way.

If you are not using "codemap.textMode" then nothing you can do as VSCode does not allow that

juanbretti commented 4 years ago

@oleg-shilo , thank you for your reply and your time. I really appreciate it. To be honest, I don't know where should I add that codemap.textModeLevelPrefixJust. Can you give me some advice? I tried to check if that line was in another example inside the repo, but I wasn't able to find it. Thanks!

oleg-shilo commented 4 years ago

It's OK. You are welcome :o)

These are the extension setting. You can edit them by accessing through the extensions panel: image

Or directly in the settings file: image

The setting that you are looking for is codemap.textModeLevelPrefix. image

if you put lat's say www there then it will become your single level indent:

www<level1 tree view item>
wwwwww<level3 tree view item>
wwwwwwwww<level3 tree view item>

But of course you want to put invisible white space characters (e.g. spaces). But VSCode trims them so you need to put something else that is invisible but not a trim-able white space. I took a character 3 characters U+00A0 that I copied from CrahacterMap app of Windows. Thus if you want to double the indent then you simply convert the config value (by using clipboard) into 6 characters U+00A0.

Change the setting and see how it affects the appearance. This way you can find the solution you want.

juanbretti commented 4 years ago

@oleg-shilo , thank you very much for your response. But what I want is to be able to have this triangle:

what i want

I have this on settings.json:

"codemap.py": [

    {
        "pattern": "^(\\s*)#### (.*)----",
        "clear": "#|----",
        "prefix": "  ",
        "icon": "level3"
    },
    {
        "pattern": "^(\\s*)### (.*)----",
        "clear": "#|----",
        "prefix": " ",
        "icon": "level2"
    },
    {
        "pattern": "^(\\s*)## (.*)----",
        "clear": "#|----",
        "icon": "level1"
    },
    {
        "pattern": "(?<![^\\r\\n\\t\\f\\v .])class (.*?)[(|:]",
        "clear": "class|:|\\)|\\(",
        "role": "class",
        "icon": "class"
    },
    {
        "pattern": "def (.*?)[(|:]",
        "clear": "def|:|\\(|\\)",
        "role": "function",
        "icon": "function"
    },
    {
        "pattern": "^(\\s*)# TODO: (.*)",
        "clear": "# TODO: ",
        "icon": "document"
    }
],
"codemap.location": "explorer",
"codemap.textMode": false,

And as example, I have this Python code:

## hola ----
### h2ola ----
def h2ola()
    pass
    def test():
        pass

But the result I have is:

no triangle

As you can see, I don't have the triangle at "h2ola". Is it possible to have it? As the same I have for def ():

Thanks!

oleg-shilo commented 4 years ago

The triangle symbol is an indicator of the node having children nodes. BTW you have no control over the appearance of parent node. TreeView does it for you.

So the appearance of the first h2ola node (without the triangle) is correct as it does not have children. The appearance of the second h2ola node (with the triangle) is also correct as it does have children.

juanbretti commented 4 years ago

What I would like to do, is these where father and child:

## hola ----
### h2ola ----

Is that possible? Or at least, the orange square to be indented to the right.

oleg-shilo commented 4 years ago

As you can see, I don't have the triangle at "h2ola".

So what you actually wanted to say is "As you can see, I don't have the triangle at "hola". Is it right?

juanbretti commented 4 years ago

@oleg-shilo , you are right... My example was confusing. Let's start again.

Screenshot 2020-09-19 143742

I have this Python code:

## Comment_level_1 ----
### Comment_level_2 ----
def function_1()
    pass
    def function_2():
        pass

I want to have a triangle (to expand and contract) the comment called "Comment_level_1". And want to have Comment_level_2 with an indentation. Something like this:

end

Do you think is possible?

oleg-shilo commented 4 years ago

:) The yes. The right description of your expectations is "As you can see, I don't have the triangle at "hola"."

All good then we are on the same page. I think it is what VS code supposed to do already as it is expected to nest level2 in the Level1 node.

I will revisit the nesting algorithm. May be there is a defect. Will let you know.

oleg-shilo commented 4 years ago

OK, there is a logical problem with your scenario.

You are trying to build a mapper for the syntax that does not have nesting level defined with the indent. Python code does it - every nested item is indented with an extra white spaces (e.g. 4 spaces) comparing to the parent position in the line. But your code comments do not.

Indent is how regex based generic mapper (one that you are using) knows which regex matching line is a parent and which one is a child.

Thus if you change your code as below, you will see that it produces the desired treeView output:

## Comment_level_1 ----
    ### Comment_level_2 ----
def function_1()
    pass
    def function_2():
        pass

Of course placing such an artificial indent on the Python comment line may not make sense in some cases.

Anyway a dedicated TS/JS mapper is a much better choice when your syntax is unable to encode the nesting via indent (Markdown). And this is exactly what Markdown mapper uses.

So normally I would advice you to go with a dedicated mapper but...

I see that the ability to deal with non-indented content from a generic mapper may be beneficial in some cases. Thus I have extended the generic mapper definition with an extra value levelIndent. This value defines not physical but logical indent that is assigned to the matching item that is non-indented at otherwise at runtime. For the cases of mixed indented/non-indented syntax like yours, this value needs to match the indent of the main (indented) syntax. Thus if your Python used 4 spaces to define first level nesting should be 4. And the second level - 8.

When applied to your sample it produces the desired outcome:

image

The enhancement will be available in the very next release.

juanbretti commented 4 years ago

@oleg-shilo , I will be waiting for the next release! Thank you!

juanbretti commented 4 years ago

Works very good! Thanks!