WorkspaceCompletionSupport.st
changeset 4789 8bc0605911b2
child 4802 a25143f6e512
equal deleted inserted replaced
4788:8ac7fbb56cb5 4789:8bc0605911b2
       
     1 "{ Package: 'stx:libwidg' }"
       
     2 
       
     3 EditTextViewCompletionSupport subclass:#WorkspaceCompletionSupport
       
     4 	instanceVariableNames:''
       
     5 	classVariableNames:''
       
     6 	poolDictionaries:''
       
     7 	category:'Interface-Smalltalk'
       
     8 !
       
     9 
       
    10 !WorkspaceCompletionSupport class methodsFor:'documentation'!
       
    11 
       
    12 documentation
       
    13 "
       
    14     A completion support using DWIM to complete code for Smalltalk (and JavaScript)
       
    15 
       
    16     [author:]
       
    17         Claus Gittinger
       
    18 
       
    19     [instance variables:]
       
    20 
       
    21     [class variables:]
       
    22 
       
    23     [see also:]
       
    24         DoWhatIMeanSupport
       
    25 
       
    26 "
       
    27 ! !
       
    28 
       
    29 !WorkspaceCompletionSupport methodsFor:'private'!
       
    30 
       
    31 computeCompletions
       
    32 
       
    33     |suggestions implementations actions anyFound contextOrNil|
       
    34 
       
    35     "/ a hack
       
    36     (editView topView isKindOf: DebugView) ifTrue:[
       
    37         contextOrNil := editView topView selectedContext.
       
    38     ].
       
    39 
       
    40     UserInformation ignoreIn:[
       
    41         anyFound := false.
       
    42         DoWhatIMeanSupport 
       
    43             codeCompletionForLanguage: editView editedLanguage
       
    44             method:editView editedMethod
       
    45             orClass:editView editedClass 
       
    46             context:contextOrNil 
       
    47             codeView:editView 
       
    48             into:[:listOfSuggestions :listOfActions :titleWhenAsking |
       
    49 "/ (listOfSuggestions contains:[:l | l isEmptyOrNil]) ifTrue:[self halt].
       
    50                     suggestions := listOfSuggestions collect:[:entry | entry isArray ifTrue:[entry first] ifFalse:[entry]].
       
    51                     implementations := listOfSuggestions collect:[:entry | entry isArray ifTrue:[entry second] ifFalse:[nil]].                            
       
    52                     actions := listOfActions.
       
    53                     anyFound := true.
       
    54                     nil "/ must return nil to avoid DWIM to do it itself (for now)
       
    55             ]
       
    56     ].
       
    57     "/ anyFound ifFalse:[self halt].
       
    58     "/ Transcript show:'suggestions: '; showCR:suggestions.
       
    59     "/ Transcript show:'actions: '; showCR:actions.  
       
    60     editView sensor
       
    61         pushUserEvent:#'suggestionsArrived:implementations:actions:autoSelect:'
       
    62         for:self
       
    63         withArguments:{suggestions . implementations . actions . autoSelect }
       
    64 
       
    65     "Created: / 26-09-2013 / 17:44:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    66 !
       
    67 
       
    68 suggestionsArrived:suggestionsArg implementations:implementationsArg actions:actionsArg autoSelect:autoSelectArg
       
    69     "the background process has generated some suggestions"
       
    70 
       
    71     |v suggestions implementations actions suggestionOffset keyAndSnippet indexOfSnippet|
       
    72 
       
    73     (editView sensor hasKeyPressEventFor:nil) ifTrue:[ 
       
    74         self closeCompletionView. 
       
    75         ^ self
       
    76     ].
       
    77 
       
    78     implementations := implementationsArg.
       
    79     actions := actionsArg.
       
    80 
       
    81     suggestions := suggestionsArg ? #().
       
    82     suggestions size > 20 ifTrue:[ 
       
    83         suggestions := suggestions copyTo:20.
       
    84         implementations := implementations copyTo:20.
       
    85         actions isArray ifTrue:[ actions := actions copyTo:20 ].
       
    86     ].
       
    87 
       
    88     "/ append snipplet, if any (can be easily reached via CRSR-up)
       
    89     suggestionOffset := 0.
       
    90     indexOfSnippet := nil.
       
    91     (keyAndSnippet := editView findAbbreviationKeyBeforeCursor) notNil ifTrue:[
       
    92         |abbrev sniplet i line|
       
    93 
       
    94         abbrev := keyAndSnippet first.
       
    95         sniplet := keyAndSnippet second.
       
    96 
       
    97         "/ if the abbreviation is simply at the end of a longer word, ignore the abbrev.
       
    98         line := editView lineStringBeforeCursor.
       
    99         i := line findLast:[:ch | ch isLetterOrDigit not].
       
   100         (i < (line size - abbrev size - 1)) ifFalse:[
       
   101             sniplet := sniplet copyWithout:$!!.
       
   102 
       
   103             "/ true, false and self are often found in both lists
       
   104             (suggestions includes:sniplet) ifFalse:[   
       
   105                 suggestions isEmpty ifFalse:[ suggestions := suggestions copyWith: '-' ]. 
       
   106                 suggestions := suggestions copyWith: ( '%1 %2'
       
   107                                         bindWith:(sniplet asStringCollection first "contractTo:25")
       
   108                                         with: ( ('("',abbrev,'" snippet)') colorizeAllWith:Color grey)).
       
   109                 indexOfSnippet := suggestions size.
       
   110 
       
   111                 "/ change below, when reversing the order in above code
       
   112                 "/ suggestionOffset := 2.
       
   113             ]
       
   114         ]
       
   115     ].
       
   116     suggestions isEmptyOrNil ifTrue:[
       
   117         self closeCompletionView.
       
   118         ^ self
       
   119     ].
       
   120     (v := completionView) isNil ifTrue: [
       
   121         ^ self
       
   122     ].
       
   123 
       
   124     v sensor
       
   125         pushUserEvent:#value
       
   126         for:[
       
   127             |top idx preselectIdx performCompletion|
       
   128 
       
   129             (v == completionView) ifTrue: [
       
   130                 top := v topView.
       
   131 
       
   132                 LastCompletions notNil ifTrue:[
       
   133                     "/ one of the last completions in list?
       
   134                     idx := LastCompletions findFirst:[:compl | suggestions includes:compl].
       
   135                     idx ~~ 0 ifTrue:[
       
   136                         preselectIdx := suggestions indexOf:(LastCompletions at:idx).
       
   137                     ].
       
   138                 ].
       
   139                 autoSelectArg ifTrue:[
       
   140                     (preselectIdx isNil and:[suggestions size == 1]) ifTrue:[
       
   141                         preselectIdx := 1.
       
   142                     ].
       
   143                 ].
       
   144                 preselectIdx notNil ifTrue:[
       
   145                     |pref|
       
   146 
       
   147                     pref := suggestions at:preselectIdx.
       
   148                     "/ for now, do not move to front (action needs the index)
       
   149                     suggestions at:preselectIdx put:(pref allBold).
       
   150 "/                    suggestions removeAtIndex:preselectIdx.                    
       
   151 "/                    suggestions addFirst:(pref allBold).
       
   152 "/                    implementations notNil ifTrue:[
       
   153 "/                        implementations removeAtIndex:preselectIdx.
       
   154 "/                        implementations addFirst:implementations.
       
   155 "/                    ]
       
   156                 ].
       
   157 
       
   158                 performCompletion :=
       
   159                     [:selectedListIndex | 
       
   160                         |indexInSuggestions|
       
   161 
       
   162                         self closeCompletionView.
       
   163                         indexInSuggestions := selectedListIndex - suggestionOffset.
       
   164                         (selectedListIndex == indexOfSnippet) ifTrue:[
       
   165                             "/ replace the sniplet
       
   166                             editView sensor pushUserEvent:#expandAbbreviation for:editView
       
   167                         ] ifFalse:[
       
   168                             LastCompletions isNil ifTrue:[
       
   169                                 LastCompletions := OrderedCollection new.
       
   170                             ].
       
   171                             LastCompletions add:(suggestions at:indexInSuggestions).
       
   172                             LastCompletions size > 200 ifTrue:[
       
   173                                 LastCompletions removeLast
       
   174                             ].
       
   175 
       
   176                             actions notNil ifTrue:[
       
   177                                 actions isBlock ifTrue:[
       
   178                                     actions value:indexInSuggestions
       
   179                                 ] ifFalse:[
       
   180                                     (actions at:indexInSuggestions) value
       
   181                                 ].
       
   182                             ].
       
   183                         ].
       
   184                         "/ disabled - user has made his choice; so don't show more suggestions
       
   185                         "/ editView sensor pushUserEvent:#updateCompletionList for:self
       
   186                     ].
       
   187 
       
   188                 ((suggestions size == 1) and:[preselectIdx == 1]) ifTrue:[
       
   189                     "/ do it, right here and now
       
   190                     performCompletion value:preselectIdx.
       
   191                 ] ifFalse:[
       
   192                     top open.
       
   193                     v list:suggestions 
       
   194                             expandTabs:false scanForNonStrings:false
       
   195                             includesNonStrings:false redraw:true.
       
   196 
       
   197                     implementations notNil ifTrue:[
       
   198                         implementations keysAndValuesDo:[:idx :impls |
       
   199                             |implsMenu|
       
   200 
       
   201                             impls notEmptyOrNil ifTrue:[
       
   202                                 implsMenu := Menu new.
       
   203                                 impls do:[:each |
       
   204                                     implsMenu addItem:(MenuItem new label:each name).
       
   205                                 ].
       
   206                                 v subMenuAt:idx put:implsMenu
       
   207                             ].
       
   208                         ].
       
   209                     ].
       
   210 
       
   211                     v enable:true.
       
   212                     preselectIdx notNil ifTrue:[
       
   213                         "/ very disturbing!!
       
   214                         v selection:preselectIdx.
       
   215                     ].
       
   216                     v extent:completionView preferredExtentForContents.
       
   217                     v action:performCompletion.
       
   218 
       
   219                     (top ~~ v) ifTrue:[
       
   220                         top resizeToFit.
       
   221                         top bottom > v device usableHeight ifTrue:[
       
   222                             top origin:((top origin x) @ (v device usableHeight - v height)).
       
   223                         ].
       
   224                         top raise.
       
   225                     ]
       
   226                 ]
       
   227             ]
       
   228         ]
       
   229 ! !
       
   230 
       
   231 !WorkspaceCompletionSupport class methodsFor:'documentation'!
       
   232 
       
   233 version
       
   234     ^ '$Header: /cvs/stx/stx/libwidg/WorkspaceCompletionSupport.st,v 1.1 2013-09-26 17:07:44 vrany Exp $'
       
   235 !
       
   236 
       
   237 version_CVS
       
   238     ^ '$Header: /cvs/stx/stx/libwidg/WorkspaceCompletionSupport.st,v 1.1 2013-09-26 17:07:44 vrany Exp $'
       
   239 ! !
       
   240