Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDLE Add indent guide #90824

Closed
primexx mannequin opened this issue Feb 6, 2022 · 9 comments
Closed

IDLE Add indent guide #90824

primexx mannequin opened this issue Feb 6, 2022 · 9 comments
Assignees
Labels
3.11 only security fixes topic-IDLE type-feature A feature request or enhancement

Comments

@primexx
Copy link
Mannequin

primexx mannequin commented Feb 6, 2022

BPO 46666
Nosy @rhettinger, @terryjreedy, @aivarannamaa
Files
  • npp-indent-guide.png: screenshot of indent guide in notepad++
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/terryjreedy'
    closed_at = <Date 2022-02-12.02:42:44.583>
    created_at = <Date 2022-02-06.21:52:47.588>
    labels = ['expert-IDLE', 'type-feature', '3.11']
    title = 'IDLE Add indent guide'
    updated_at = <Date 2022-02-25.12:25:33.471>
    user = 'https://bugs.python.org/primexx'

    bugs.python.org fields:

    activity = <Date 2022-02-25.12:25:33.471>
    actor = 'aivarannamaa'
    assignee = 'terry.reedy'
    closed = True
    closed_date = <Date 2022-02-12.02:42:44.583>
    closer = 'terry.reedy'
    components = ['IDLE']
    creation = <Date 2022-02-06.21:52:47.588>
    creator = 'primexx'
    dependencies = []
    files = ['50608']
    hgrepos = []
    issue_num = 46666
    keywords = []
    message_count = 9.0
    messages = ['412672', '412698', '412702', '412706', '412707', '412708', '413105', '413114', '413991']
    nosy_count = 4.0
    nosy_names = ['rhettinger', 'terry.reedy', 'aivarannamaa', 'primexx']
    pr_nums = []
    priority = 'normal'
    resolution = 'third party'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue46666'
    versions = ['Python 3.11']

    @primexx
    Copy link
    Mannequin Author

    primexx mannequin commented Feb 6, 2022

    Request: support indent guide for IDLE in editor window (i.e. not interactive shell)

    there appears to not be currently support for indent guides in idle

    one take is that idle is meant for small scripts and one should seek out a more complex IDE if it gets to the point of needing indent lines https://stackoverflow.com/q/66231105

    i think that there would still be value in indent lines even in IDLE. it is a popular IDE for beginners and even in short scripts there can still be sufficiently large indented blocks, relatively speaking. it doesn't take that much code for indent guides to become helpful.

    @primexx primexx mannequin added 3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Feb 6, 2022
    @primexx primexx mannequin assigned terryjreedy Feb 6, 2022
    @primexx primexx mannequin added 3.8 only security fixes topic-IDLE 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes labels Feb 6, 2022
    @primexx primexx mannequin assigned terryjreedy Feb 6, 2022
    @primexx primexx mannequin added the topic-IDLE label Feb 6, 2022
    @terryjreedy
    Copy link
    Member

    [Please just select the current development version. Others can be marked if and when backported. 3.8 and before only get security fixes. Same for 3.9 after about next May 31.]

    Please explain exactly what you want and rewrite something like the following.
    if a:
    if b:
    if c:
    pass
    if d:
    pass

    IDLE's code context feature (Options menu) could be considered an indent guide. In some ways, it is better.

    What you see in the editor is what is saved (including when running), so any non-code additions have to be removed first.

    @terryjreedy terryjreedy removed 3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes labels Feb 7, 2022
    @terryjreedy terryjreedy changed the title IDLE indent guide IDLE Add indent guide Feb 7, 2022
    @terryjreedy terryjreedy added type-feature A feature request or enhancement and removed 3.7 (EOL) end of life 3.8 only security fixes 3.9 only security fixes 3.10 only security fixes labels Feb 7, 2022
    @terryjreedy terryjreedy changed the title IDLE indent guide IDLE Add indent guide Feb 7, 2022
    @terryjreedy terryjreedy added the type-feature A feature request or enhancement label Feb 7, 2022
    @primexx
    Copy link
    Mannequin Author

    primexx mannequin commented Feb 7, 2022

    Please just select the current development version. Others can be marked if and when backported

    oh sorry about that!

    Please explain exactly what you want

    these dotted lines in the attached screenshot

    What you see in the editor is what is saved (including when running), so any non-code additions have to be removed first.

    yes, this would be a pure visual element in the editor, not modifying the actual code

    IDLE's code context feature (Options menu) could be considered an indent guide. In some ways, it is better.

    it is very useful indeed, but not quite the same as a persistent visual indicator imho

    thanks!

    @terryjreedy
    Copy link
    Member

    I loaded a .py file into N++ and see them. Under 3 x, there are clearly separate minidots. Under 10x, the dots are hardly visible. They are not characters in the text (cannot be copied) but a special manipulation of the column of pixels 'between' spaces. This must be a built-in feature of to the text widget. I suspect it involves special subpixel manipulation, perhaps requiring information from the monitor. AFAIK, Tk widgets do not have this feature. Unless there is a unicode char consisting of light dots on the very edge, we cannot even simulate this.

    @rhettinger
    Copy link
    Contributor

    If this were possible, it would be really nice to have.

    FWIW, the rich¹ project was able to pull this off in regular text terminal window:

    $ python3.10 -m pip install rich
    $ python3.10 -m rich.pretty
    {
    │   'foo': [1, 'Hello World!', 100.123, 323.232, 432324.0, {(1, 2, 3, 4), 5, 6, 7, 8}, ...],
    │   'bar': frozenset({1, 2, 3}),
    │   'defaultdict': defaultdict(<class 'list'>, {'crumble': ['apple', 'rhubarb', 'butter', 'sugar', 'flour']}),
    │   'counter': Counter({'apple': 1, 'orange': 1, 'pear': 1, 'kumquat': 2, 'duriandurianduriandu'+580: 1}),
    │   'atomic': (False, True, None),
    │   'Broken': <repr-error 'division by zero'>
    }

    ¹ https://rich.readthedocs.io/en/stable/index.html

    @terryjreedy
    Copy link
    Member

    '│' is a bit taller that ascii bar '|'; hex(ord('│')) = '0x2502'. It is a bit heavy. In this Windows Firefox box it is slightly lighter than | but in IDLE with Source Code Pro, it is slightly darder. Worse is being centered instead of on one edge.

    We would have to check it with multiple fixed-ascii-pitch fonts on multiple systems before using any non-ascii char. Does it always have the exact width of ascii ' ' or easier to check, ascii '|', so that is does not change the indent? This is easily tested in the Settings dialog Font tab sample box. Paste the following
    │││││││││││││││
    |||||||||||||||
    It passes with all but one of the Windows mono fonts I tried.

    I may ask a tk/tkinter question on SO about other possible options. Testing this one in code:

    if a:  # Put 1st bar on 4th space.
        if b:
       │    if c:
       │   │    pass
        if d:
       │    pass
    
    if a: # Put 1st bar on 5th space.
        if b:
        │   if c:
        │   │   pass
        if d:
        │   pass
    
    if a: # Put 1st bar on 1st space.if b:
    │   │   if c:
    │   │   │   passif d:
    │   │   pass

    The 2nd option looks best to me. The 3rd would be easier to program, as default tab indent would always be '│ '. In any case, copied code would not be runnable code. I would add this on the Option menu between Code Context and Line Numbers.

    I believe only updating the markers on demand would be much easier to program than dynamically updating them with each keystroke (checking key and whether whitespace in indent area).

    Before merging a PR (writen by someone else), someone other than me, such as Raymond, must test it in real use both for correctness, usefulness, and aesthetics. (I anticipate that I would fail it on the latter two.)

    @primexx
    Copy link
    Mannequin Author

    primexx mannequin commented Feb 11, 2022

    very informative discussion. i'll just say that if it's not possible to do purely visually, and it can only be done by modifying the textual content, then it probably should not be done at all. preserving the code (and copy+paste integrity) is more important. maybe this is actually something to raise with Tk first?

    @terryjreedy
    Copy link
    Member

    I am guessing that N++ or its GUI framework uses a transparent overlay. For tkinter, that would mean a transparent Canvas on which one could draw vertical dotted gray lines 1-pixel wide. However, Serhiy Storchaka in msg213643 of bpo-20920 said: "Tk supports alpha only for photo images and as an attribute of top-level window. It doesn't support alpha component in colors."

    I searched 'tkinter transparent canvas'.

    For pixel positioning, photos with transparent backgrounds can only be used on a canvas. This was one of the answers to https://stackoverflow.com/questions/53021603/how-to-make-a-tkinter-canvas-background-transparent
    More details, using pil(low) to make images, are in the following:
    https://www.tutorialspoint.com/how-to-make-a-tkinter-canvas-rectangle-transparent
    https://www.javaer101.com/en/article/921105.html

    Another answer to the SO question, for Windows only, was to pip install pywin32 and use various calls to make a canvas layered with a transparent colorkey. Perhaps the same could be done, at least on Windows, with ctypes.

    A top-level background is made (partially) transparent with "top.attributes('-alpha', d)" where d in [0.0-1.0]. On Windows, 'top.wm_attributes('-transparentcolor', keycolor) makes that keycolor actually be transparent, like the green/blue screen used in television and movies. But any keycolor pixel in the toplevel exposes the screen beneath the toplevel, not the widget in the toplevel. This detail is not clear in the tk docs.
    https://www.youtube.com/watch?v=75jbNpc8vN4
    What also is not clear is whether the keycolor applies only to the one toplevel or all toplevels, nor what happens when one toplevel is over another.

    I summarized the above so I or anyone else can find the information. I am closing this issue for now, but someone can reopen if the situation changes.

    @aivarannamaa
    Copy link
    Mannequin

    aivarannamaa mannequin commented Feb 25, 2022

    The guides could be implemented by tagging the indentation characters in the Text widget with tags configured with suitable bgstipple (https://www.tcl.tk/man/tcl/TkCmd/text.html#M45) bitmaps.

    I had some success with this in Thonny IDE, but abandoned the plan because bstipple is not supported on macOS (for some reason).

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 only security fixes topic-IDLE type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants