• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. How to create autocomplete text strings?

Stats

  • Locked Locked
  • Replies 5
  • Subscribers 144
  • Views 14957
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to create autocomplete text strings?

rish87
rish87 over 5 years ago

Hello,

I'm using cadence version 6.1.7.

I'm trying to create a GUI, which runs the commands written to the text field ( commands here are the procedures written by me).

for example when the user type "sel" in the text field it should indicates the procedures "select_by_name" and "select_by_prop". When user types "s" it should indicate "search_text", "select_by_name" and "select_by_prop" .

I want the text field to just works as the google search bar, the procedures names will be stored in a list.

Thank you

Harish

  • Cancel
  • mbracht
    mbracht over 5 years ago

    Hi Harish,

    If I get you right you want to implement the CIW command completion in a string field correct?
    Now without having tried this out, but I think you need for one to create the string field with a so called  "modify callback" - this is a callback that is triggered whenever any change is made in the field...typing a character in your case. The corresponding keyword argument to the hiCreateStringField() function is ?modifyCB. The list of functions could be retrieved with listFunctions(). For example to get a list of all function starting with "sel" you'd have to:
    (listFunctions "^sel")
    The resulting list could then be accommodated in a popup menu which needs in turn to have a callback that sets the string field value accordingly. As I said I haven't tried this out myself but that's how I would start.
    Just out of curiosity, why don't you use the builtin command completion of CIW?

    Max

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • rish87
    rish87 over 5 years ago in reply to mbracht

    Hi Max,

    Thanks for your valuable suggestions, I'll definitely try it out.

    Why I want to implement this is, when I'm using layout or schematic editor to run a command each time I have change the tab,instead by setting bindkey to this GUI, I can easily execute my procedures.

    Thanks 

    Harish

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 5 years ago in reply to rish87

    Hi  Harish,

    I had a similar problem, and this is how I solved it.

    procedure( BuildGui()
        let( (    ( theLibList nil ) )

            theLibList = sort( ddGetLibList()~>name nil )

            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            ;;; Creating the form fields...
            FindSourceLibraries = hiCreateStringField(
                ?name        'FindSourceLibraries    
                ?prompt        "Find Source Library(ies):"
                ?value        ""
                ?defValue    ""
                ?modifyCallback    "FindSourceLibrariesCB"
                ?editable    t
                ?enabled    t
            )
            
            SelectSourceLibraries = hiCreateListBoxField(
                ?name        'SelectSourceLibraries    
                ?choices    theLibList
                ;?callback    "SelectSourceLibrariesCB()"
                ?prompt        "Select Source Library(ies):"
                ?value        nil
                ?defValue    nil
                ?multipleSelect    t
                ?enabled    t
            )
            
            SelectAllSourceLibraries = hiCreateButton(
                ?name        'SelectAllSourceLibraries
                ?buttonText    "Select All Libraries"
                ?callback    "GuiForm->SelectSourceLibraries->value = GuiForm->SelectSourceLibraries->choices"
                ?enabled    t
            )
            
            InvertSourceLibraries = hiCreateButton(
                ?name        'InvertSourceLibraries
                ?buttonText    "Invert Library Selection"
                ?callback    "let( ( ( temp nil ) ) foreach( item GuiForm~>SelectSourceLibraries~>choices unless( member( item GuiForm~>SelectSourceLibraries~>value ) temp = append1( temp item ) ) ) GuiForm~>SelectSourceLibraries~>value = sort( temp nil ) )"
                ?enabled    t
            )
            
            SelectNoneSourceLibraries = hiCreateButton(
                ?name        'SelectNoneSourceLibraries
                ?buttonText    "De-select All Libraries"
                ?callback    "GuiForm->SelectSourceLibraries->value = nil"
                ?enabled    t
            )
            
            ;;;;;;;;;;;;;;;;;;;;;;
            ;;; Building the form...
            hiCreateAppForm(
                ?name         'GuiForm
                ?formTitle    "Batch Rename and Re-Reference Cells..."
                ;?callback    "FormPostProcessing()"
                ?dontBlock    t
                ?fields        list(
                            list( FindSourceLibraries        5:5        435:25        147 )
                            list( SelectSourceLibraries        5:35        435:250        150 )
                            list( SelectAllSourceLibraries        5:65        135:25        150 )
                            list( InvertSourceLibraries        5:95        135:25        150 )
                            list( SelectNoneSourceLibraries        5:125        135:25        150 )
                        ) ;;; end list ?fields
                ?buttonLayout    list(
                            'OKCancelApply
                        ) ;;; end list ?buttonLayout
                ?buttonDisabled    list( 'Help )
                ?unmapAfterCB    t
                ?initialSize    450:325
            ) ;;; end hiCreateAppForm
            ;;;;;;;;;;;;;;;;;;;;;;

            HiDisplayForm( GuiForm )

        ) ;;; end let
    ) ;;; end procedure BuildGui
    ;;;;;;;;;;;;;;;;;;;;;;

    ;;;;;;;;;;;;;;;;;;;;;;
    ;;; This procedure is used when typing a lib-name in the "Find Source Library(ies)" string field.
    ;;; While typing, it will update the list of libraries that match the given input.
    ;;; Three values are being passed to this procedure by the ?modifyCallback function of the string-field.
    ;;; So they have to be accepted as parameters to this procedure. It is not needed to use all of them.
    ;;; For LINT purposes, if a value is not used, prefix it with an underscore, so LINT will not complain.
    procedure( FindSourceLibrariesCB( _fieldName fieldValue _changeSource )
        let( (     ( theLibList nil )
            ( tempList  nil ) )

            theLibList = sort( ddGetLibList()~>name nil )
            GuiForm~>SelectSourceLibraries~>value = nil

            if( equal( fieldValue "" )
            then
                GuiForm~>SelectSourceLibraries~>choices = theLibList
            else
                foreach( item theLibList
                    when( rexMatchp( fieldValue item )
                        tempList = append1( tempList item )
                    )
                )

                GuiForm~>SelectSourceLibraries~>choices = tempList
            ) ;;; end of if

            UpdateFormBlock( GuiForm )
            
            ;;; Return true to accept the change of input in the string field. This is mandatory.
            t

        ) ;;; end of let
    ) ;;; end of procedure FindSourceLibrariesCB
    ;;;;;;;;;;;;;;;;;;;;;;

    ;;;;;;;;;;;;;;;;;;;;;;
    ;;; Function which is a wrapper around hiUpdateFormBlock
    ;;; which suppresses any warnings it produces
    procedure( UpdateFormBlock( @rest args )
        ;;; Define a global variable to store the null port in, to
        ;;; save reopening it next time
         unless( boundp( 'NullPort ) && openportp( NullPort )
            NullPort = outfile( "/dev/null" )
        ) ;;; unless

        ;;; Be good - force any buffered warning to be displayed - this means
        ;;; we don't swallow any warning unrelated to opening a cellView.
        ;;; This is done by creating a new warning (which we'll swallow in a moment)
        ;;; which forces what is in the buffer to be output.
        warn("")

        ;;; use SKILL's dynamic scoping to redefine woport to send all
        ;;; warnings to /dev/null - and get the final (unprinted) warning
        ;;; with getWarn()
        let( ( ( woport NullPort ) )
            apply( 'hiUpdateFormBlock args )
            getWarn()
        ) ;;; end let
    ) ;;; end procedure UpdateFormBlock
    ;;;;;;;;;;;;;;;;;;;;;;

    ;;;;;;;;;;;;;;;;;;;;;;
    ;;; Function which is a wrapper around hiUpdateFormBlock
    ;;; which suppresses any warnings it produces
    procedure( HiDisplayForm( @rest args )
        ;;; Define a global variable to store the null port in, to
        ;;; save reopening it next time
         unless( boundp( 'NullPort ) && openportp( NullPort )
            NullPort = outfile( "/dev/null" )
        ) ;;; unless

        ;;; Be good - force any buffered warning to be displayed - this means
        ;;; we don't swallow any warning unrelated to opening a cellView.
        ;;; This is done by creating a new warning (which we'll swallow in a moment)
        ;;; which forces what is in the buffer to be output.
        ;warn("")

        ;;; use SKILL's dynamic scoping to redefine woport to send all
        ;;; warnings to /dev/null - and get the final (unprinted) warning
        ;;; with getWarn()
        let( ( ( woport NullPort ) )
            apply( 'hiDisplayForm args )
            getWarn()
        ) ;;; end let
    ) ;;; end procedure HiDisplayForm
    ;;;;;;;;;;;;;;;;;;;;;;

    Just copy-past the code into an empty file and name it somthing like modifyCallbackExample.il . Save it somewhere and load it in the CIW:

    load("./modifyCallbackExample.il")

    To run:

    BuildGui()

    A form will pop-up. It has a few buttons, with easy-to-understand names, and a text-field in which you can type some text. The big field will contain all the libraries available. Just start typing with a name and see what happens. I guess this is what you're looking for.

    Good luck.

    Sjoerd

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Sheppie
    Sheppie over 5 years ago in reply to Sheppie
    Sheppie said:
    FindSourceLibrariesCB

    This is the procedure where the matching takes place. You can adapt this to do whatever you want. What I do is updating a different field then than the one which is used to type. It is not that difficult to update the field itself.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Sheppie

    Hi Sjoerd,

    Thanks for the good starting basis for this - very helpful (great to see somebody else volunteering code for others to use!)

    BTW, for your specific example you can use ddHiCreateLibraryComboField, ddHiCreateCellComboField, ddHiCreateViewComboField and ddHiLinkFields which cuts down the work by using something built-in that does the job - but obviously you can use your framework for other purposes...

    Regards,

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information