Customizing for COBOL



  • Currently the settings I use with NotePad++ gives this view
    cc.PNG

    But I would love to have this view
    bb.PNG

    I also need to add tab stops at columns 7,8, 12 and 72 (hoping the tab stop would show as a vertical column).
    I don’t know anything about customization, fonts, etc. Could some one give me a hint.

    I particularly like the font above. Where to start? What to do?



  • Npp provides something called themes.
    See here for more information about it. If something is unclear let us know.



  • Do you know of a theme for COBOL language? Thanks.



  • @Emmad-Kareem

    Here is a misunderstanding, a theme is not for one language but for all. Npp comes with a whole bunch of them, which ones have you tried?



  • @Ekopalypse Thanks.



  • @Emmad-Kareem said in Customizing for COBOL:

    Do you know of a theme for COBOL language? Thanks.

    As @Ekopalypse states, there are many themes for “all” languages, not a specific theme for a specific language. That said, many of the themes in the Notepad++/themes directory have not been updated for quite some time and thus do not reflect the latest changes / additions of languages in Notepad++. For example, I use a custom theme based off the Oblivion theme and in checking this question, realized my theme did not have the Cobol language - so no styling.

    Pick the theme you want. If Cobol files do not have styling, the language probably isn’t included in your theme.

    1. Close Notepad++
    2. Open the theme file Notepad++/themes/YOUR_THEME_FILE.xml with Windows Notepad and open the Notepad++/stylers.xml.
    3. Copy the relevant section from Notepad++/stylers.xml into Notepad++/themes/YOUR_THEME_FILE.xml and save.
    4. Reopen Notepad++ and open your Cobol file. It should be styled, probably not to your liking.
    5. Use the Settings => Style Configurator to adjust the colors for your language (Cobol).

    To get you started, here is the relevant Cobol section from my theme:

            <LexerType name="cobol" desc="COBOL" ext="">
                <WordsStyle name="PREPROCESSOR" styleID="9" fgColor="A082BD" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="DEFAULT" styleID="11" fgColor="E0E2E4" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="DECLARATION" styleID="5" fgColor="A082BD" bgColor="293134" fontName="" fontStyle="1" fontSize="" keywordClass="instre1" />
                <WordsStyle name="INSTRUCTION WORD" styleID="16" fgColor="93C763" bgColor="293134" fontName="" fontStyle="1" fontSize="" keywordClass="instre2" />
                <WordsStyle name="KEYWORD" styleID="8" fgColor="93C763" bgColor="293134" fontName="" fontStyle="0" fontSize="" keywordClass="type1" />
                <WordsStyle name="NUMBER" styleID="4" fgColor="FFCD22" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="STRING" styleID="6" fgColor="EC7600" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="CHARACTER" styleID="7" fgColor="FF8409" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="OPERATOR" styleID="10" fgColor="E8E2B7" bgColor="293134" fontName="" fontStyle="1" fontSize="" />
                <WordsStyle name="COMMENT" styleID="1" fgColor="66747B" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="COMMENT LINE" styleID="2" fgColor="66747B" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="COMMENT DOC" styleID="3" fgColor="66747B" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="COMMENT LINE DOC" styleID="15" fgColor="66747B" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
                <WordsStyle name="COMMENT DOC KEYWORD" styleID="17" fgColor="66747B" bgColor="293134" fontName="" fontStyle="1" fontSize="" />
                <WordsStyle name="COMMENT DOC KEYWORD ERROR" styleID="18" fgColor="FF4040" bgColor="293134" fontName="" fontStyle="0" fontSize="" />
            </LexerType>
    

    Cheers.



  • @Emmad-Kareem said in Customizing for COBOL:

    I also need to add tab stops at columns 7,8, 12 and 72

    Thus far this part of the OP’s question has been missed by the responders. I can’t recall if this one has come up before, but it sure seems like it would have.

    Can Notepad++/Scintilla handle variable-width tab stop positions?



  • @Alan-Kilborn said in Customizing for COBOL:

    Can Notepad++/Scintilla handle variable-width tab stop positions?

    see discussion https://community.notepad-plus-plus.org/topic/18429/need-to-set-tab-stops-not-spacing from a couple years ago. @Ekopalypse was able to get the SCI_CLEARTABSTOPS/SCI_ADDTABSTOP messages via the PythonScript interface editor.clearTabStops()/editor.addTabStop() to set up a custom set of tab locations. Unfortunately, it’s on a per-line basis, and has to be re-applied frequently (every time the buffer is updated). Also, that sets it in pixels, not in characters, so you need to do some sort of conversion factor to convert character location to pixels.

    My guess is that it would need to be something like the following. Please note this is just a proof of concept and should be treated as code that would need debugging and extra work to make it 100%.

    # encoding=utf-8
    """in response to https://community.notepad-plus-plus.org/topic/21689/"""
    from Npp import *
    
    cols = (7,8,12, 72)
    pixperchar = 8
    
    def set_tab_via_callback():
        for linenum in range(editor.getLineCount()):
            editor.clearTabStops(linenum)
            for tabcol in cols:
                editor.addTabStop(linenum, tabcol*pixperchar)
    
    set_tab_via_callback()
    

    81087172-bf76-46df-8d66-cd0749d9f65e-image.png

    Instead of manually running the set_tab_via_callback(), you would have to add callbacks for that function; Eko’s post linked earlier hints at which callbacks are needed; you’d also need to calculate or hardcode the right pixperchar to convert characters to pixels correctly for your font; you’d probably also want a check in the callback to make sure it only runs the tab-changer if the active file is COBOL.

    Maybe Eko still has the example code that was played with (but not published) in that previous topic.

    ----
    PS (edit): I forgot to mention that I had to go to Settings > Preferences > Language > Tab Settings, and set cobol to not replace by space:
    67493b0a-bbf6-44a3-9491-9a287fdcb541-image.png



  • Here is what I posted at github regarding the language specific tab width.



  • @Ekopalypse said in Customizing for COBOL:

    Here is what I posted at github regarding the language specific tab width.

    That looks more like multiEdge than tabs, unless I’ve misunderstood. But the same basic concept should work (replacing the vertical edge clearing with a per-line loop that clears the tabs, and replacing the multiEdge adding with loops like add the tabs in a per-line loop.



  • @PeterJones

    you are right - my bad.



  • This merger of Eko’s script and mine comes close… I merged my proof-of-concept with Eko’s fancy wrapper-registering to give different updates on a per-language basis, and then checked against the suggested flow from 2 years ago

    But I couldn’t find what message(s) were meant by the suggested on_update_ui. I think it might have to be one or more Scintilla Notifications for that, so it would use a separate editor.addCallback() in addition to the notepad.addCallback()

    So with this version, it will update the tabs whenever you change into a COBOL window or switch the active file’s language to COBOL from something else.

    # encoding=utf-8
    """in response to https://community.notepad-plus-plus.org/topic/21689/
    
    Merge my suggestion with Eko's pointer to https://github.com/notepad-plus-plus/notepad-plus-plus/issues/9296#issuecomment-751706154
    """
    from Npp import editor, notepad, NOTIFICATION, EDGEVISUALSTYLE
    
    TAB_CONFIG = {}
    
    pixperchar = 8
    
    def register_lang(func):
        def wrapped():
            for linenum in range(editor.getLineCount()):
                editor.clearTabStops(linenum)
                func(linenum)
        TAB_CONFIG[func.__name__.replace('on_lang_','')] = wrapped
        return wrapped
    
    @register_lang
    def on_lang_cobol(linenum):
        for col in [7,8,12,72]:
            editor.addTabStop(linenum, (col-1)*pixperchar)
    
    @register_lang
    def on_lang_assembly(linenum):
        for col in [11, 18, 40, 79]:
            editor.addTabStop(linenum, (col-1)*pixperchar)
    
    
    def on_lang_default():
        pass
    
    
    def on_set_tab_stops(args):
        lang = notepad.getLanguageName(notepad.getLangType())
        config = lang.lower().replace('udf - ', '')
        func = TAB_CONFIG.get(config, on_lang_default)
        # print(func)
        func()
    
    notepad.clearCallbacks(on_set_tab_stops)
    notepad.callback(on_set_tab_stops, [NOTIFICATION.BUFFERACTIVATED, NOTIFICATION.LANGCHANGED])
    


  • updated with a scintilla MODIFIED notification, with the caveat that it will only trigger for non-zero linesAdded value – that is non zero if a line is added or deleted.

    it’s somewhat slow, but as you switch in to the file, or add or delete lines, the tabs will all be updated.

    # encoding=utf-8
    """in response to https://community.notepad-plus-plus.org/topic/21689/
    
    Merge my suggestion with Eko's pointer to https://github.com/notepad-plus-plus/notepad-plus-plus/issues/9296#issuecomment-751706154
    """
    from Npp import editor, notepad, NOTIFICATION, SCINTILLANOTIFICATION, EDGEVISUALSTYLE
    
    TAB_CONFIG = {}
    
    pixperchar = 8
    
    def register_lang(func):
        def wrapped():
            for linenum in range(editor.getLineCount()):
                editor.clearTabStops(linenum)
                func(linenum)
        TAB_CONFIG[func.__name__.replace('on_lang_','')] = wrapped
        return wrapped
    
    @register_lang
    def on_lang_cobol(linenum):
        for col in [7,8,12,72]:
            editor.addTabStop(linenum, (col-1)*pixperchar)
    
    @register_lang
    def on_lang_assembly(linenum):
        for col in [11, 18, 40, 79]:
            editor.addTabStop(linenum, (col-1)*pixperchar)
    
    
    def on_lang_default():
        pass
    
    
    def on_set_tab_stops(args):
        #print(str(args))
        lang = notepad.getLanguageName(notepad.getLangType())
        config = lang.lower().replace('udf - ', '')
        func = TAB_CONFIG.get(config, on_lang_default)
        # print(func)
        if 'linesAdded' in args:
            if args['linesAdded'] != 0:
                func()
        else:
            func()
    
    notepad.clearCallbacks(on_set_tab_stops)
    notepad.callback(on_set_tab_stops, [NOTIFICATION.BUFFERACTIVATED, NOTIFICATION.LANGCHANGED])
    editor.clearCallbacks(on_set_tab_stops)
    editor.callback(on_set_tab_stops, [SCINTILLANOTIFICATION.MODIFIED])
    


  • @Alan-Kilborn said in Customizing for COBOL:

    I also need to add tab stops at columns 7,8, 12 and 72

    Thus far this part of the OP’s question has been missed by the responders. I can’t recall if this one has come up before, but it sure seems like it would have.
    Can Notepad++/Scintilla handle variable-width tab stop positions?

    Does @dail 's Elastic TabStops plugin solve this? I honestly don’t know and haven’t tried it (never needed this), but sounds like it might?

    Cheers.



  • @Michael-Vincent ,

    I don’t use that either, but my impression was no. But I grabbed it to test briefly.

    27505caa-adc7-4577-99e1-a18fcc48caa7-image.png

    the tabstops in Elastic Tabstops will stretch to fit the longest piece of text: for example, with what about, x, and whatever, the first tabstop will be wide enough for the what about. And it allows different stops when you give a blank line between paragraphs/sections… but I don’t see a way to pre-define specific widths.



  • @Emmad-Kareem said in Customizing for COBOL:

    I also need to add tab stops at columns 7,8, 12 and 72 (hoping the tab stop would show as a vertical column).

    I don’t think anyone directly addressed this, either. With a recent Notepad++ version, you can have multiple vertical edges drawn: go to Settings > Preferences > Margins / Border / Edge, and fill in the Vertical Edge Settings:

    61df6b50-cb60-4365-886c-5eb79c696edf-image.png

    That example doesn’t have the pythonscript callbacks active, so the tab size is a fixed width. Here it is with Elastic Tabstops also active, with a dummy header line to try to force known tab stops:
    60b9f4cc-a526-4596-84e9-b3dff18f9d28-image.png

    The drawback to the multiple vertical edges is that it is the same for all languages. Though that multiEdge example that @Ekopalypse linked to will actually solve that problem for you.

    Speaking of the tab size/location, one thing you don’t mention: is COBOL okay with using TAB character between fields? Or do you need/want tab-to-spaces conversion (so when you hit TAB, it will actually use enough space characters to fill in the gap)? If you’re okay with keeping TAB as the TAB character, then either the PythonScript or an ElasticTabstops-with-header might work for you; if you need that spacing to be encoded as actual space characters (ASCII 32 = 0x20) in the file, then neither is going to supply what you need.


Log in to reply