oleg-shilo / codemap.vscode

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

Improving Generic Map by Reworking levelIndent #86

Open omemisoglu opened 1 year ago

omemisoglu commented 1 year ago

Description

Implementing hierarchy level by promoting levelIndent to identify not a whitespace indent on files, but a hierarchy level among other mapping rules of a indent dependant programming language file.

Non-hiearachy Mapping Rules

Hierarchy Priority

Resolving Hierarchy with same Indentation

omemisoglu commented 1 year ago

Python Generic Mapper Example for Testing

"codemap.py": [
    // Cell Pattern
    {
        "pattern": "^ *#%% .*$",
        "clear": " *#%% *(?=.*$)",
        "prefix": "# ",
        "icon": "level1",
        "levelIndent": 1
    },
    // Class
    {
        "pattern": "^ *class \\w+(?=.*$)",
        "clear": "(([^#\\r\\n]*)class )(?=\\w+)",
        "prefix": "",
        "icon": "class",
        "levelIndent": 2
    },
    // Functions
    {
        "pattern": " *def \\w+(?=\\(.*\\).*)",
        "clear": " *def ",
        "prefix": "",
        "icon": "function",
        "levelIndent": 2
    },
    // Section Comment (Spyder)
    {
        "pattern": "^ *#### .*",
        "clear": " *#### *",
        "prefix": "- ",
        "icon": "level2"
    },
    // CONSTANTS
    {
        "pattern": "^ *[A-Z]+[A-Z0-9_]*(?= [=|:].*$)",
        "clear": "^ *",
        "prefix": "",
        "icon": "interface"
    }
]
oleg-shilo commented 1 year ago

I @omemisoglu can you please describe the problem you are trying to solve? It's not entirely clear to me.

We might be asking the regular expression technique too much to do.

Can you describe the scenario that exhibits the undesirable behaviour or fails?

omemisoglu commented 1 year ago

@oleg-shilo Thank yo for your reply. I want to have mapping elements in Python that can nest some chunks of a source code. However, when I start to use levelIndent properties by assigning levels to all of the mappings or some of the mappings, the codemap tree is not behaving the way I want. There are 7 mappings that I want to see outlined:

When applying the mapping below on the source code attached, the attached tree map is generated and the problems below occurred:

  1. IMPORTS and FUNCTIONS are Cell Comments which should not nest within each other, hence they are never indented.
  2. Imports should never nest

Codemap Example 01

codemap_01

// Cell Pattern
"codemap.py": [
        {
            "pattern": "^ *#%% .*$",
            "clear": " *#%% *(?=.*$)",
            "prefix": "# ",
            "icon": "level1",
            "levelIndent": 4
        },
        // Class
        {
            // "pattern": "^( *class )\\w+(?=.*$)",
            "pattern": "^ *class \\w+(?=.*$)",
            // "clear": "(^(([^#\\r\\n]*)class )(?=\\w+))|(\\(.*$)",
            "clear": " *class ",
            // "clear": "(([^#\\r\\n]*)class )(?=\\w+)",
            // "clear": "class|:|\\)|\\(",
            // "clear": "^(.*)class (?=\\w+))|(\\(.*$)",
            "prefix": "",
            "icon": "class",
            "levelIndent": 8
        },
        // Functions
        {
            "pattern": " *def \\w+(?=.*$)",
            // "pattern": "^( *)def (.*)$",
            "clear": " *def ",
            // "clear": "(([^#\\r\\n]*)def )(?=\\w+)",
            // "clear": "(^(([^#\\r\\n]*)def )(?=\\w+))|(\\(.*$)",
            // "clear": "^(.*)def (?=\\w+))|(\\(.*$)",
            // "clear": "def|:|\\)|\\(",
            "prefix": "",
            "icon": "function",
            "levelIndent": 8
        },
        // Section Comment (Spyder)
        {
            // "pattern": "^(.*)#### ([^a-z\\r\\n])(.*)",
            "pattern": "^ *#### .*",
            "clear": " *#### *",
            "prefix": "- ",
            "icon": "level2",
            "levelIndent": 4
        },
        // Marker Comment Custom
        {
            // "pattern": "^(.*)#### ([^a-z\\r\\n])(.*)",
            "pattern": "^ *## .*",
            "clear": " *## *",
            "prefix": "",
            "icon": "level3",
            "levelIndent": 12
        },
        // CONSTANTS
        {
            "pattern": "^ *[A-Z]+[A-Z0-9_]*(?= [=|:].*$)",
            "clear": "^ *",
            "prefix": "",
            "icon": "interface",
            "levelIndent": 12
        },
        // Imports
        {
            "pattern": "^((import [\\w\\. ]+)|(from [\\w\\. ]+ import [\\w\\. ]+))",
            "clear": "^ *",
            "prefix": "",
            "icon": "property",
            "levelIndent": 8
        }
],
oleg-shilo commented 1 year ago

Then I feel that you will have a way more manageable solution if you just implement your custom mapper in JS as a dedicated mapper.

Here is the sample: https://github.com/oleg-shilo/codemap.vscode/wiki/Adding-custom-mappers#mapping-with-a-dedicated-mapper

In fact, that was the idea behind custom mappers - implementing them in high-level languages and regex to be used only for trivial cases.

Instead of a declarative JSON section, you can have an Imperative code (JS file) and simply specify it in the user settings.

You can have your algorithm as complicated as you want. And you can even fall back to the use of regex :)

You will have ultimate flexibility and will not be bound by the contents of a generic mapper (e.g. processing ALL lines of the code) you are trying to use currently.

After all the only thing that you need to produce is a simple code tree specification (map definition) like this one:

def settings()|1|function
class NavigateCodeMap|4|class
    def highlight_line()|6|function
    def keep_going_down()|9|function
        def indented()|11|function
    def keep_going_up()|16|function
        def indented()|18|function
        def up()|23|function
def down()|26|function
oleg-shilo commented 1 year ago

And a mapping specification/definition is a collection of strings/lines where every line describes a code map item via a very simple format:

[indent]<name>|<line>|<icon>