Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!europa.chnt.gtegsc.com!howland.reston.ans.net!news.sprintlink.net!malgudi.oar.net!news.erinet.com!netcom.com!kcooper
From: kcooper@netcom.com (Ken Cooper)
Subject: New edIt Extension: Rename Class
Message-ID: <kcooperDALI6C.HBI@netcom.com>
Keywords: edIt extension editor cooper peters rename class
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Date: Thu, 22 Jun 1995 22:23:00 GMT
Lines: 127
Sender: kcooper@netcom20.netcom.com

For those of you using our product edIt on Visual
Smalltalk Win32, here's a new goodie for you. It
provides the ability to rename classes in your
image easily, taking the references in your code
into account.

If you don't have edIt (heaven forbid!), you can
get a demonstration version from the Smalltalk
archives at st.cs.uiuc.edu, in the file
/pub/cooper/edIt/editdemo.exe.  If you'd
prefer a disk, send me email with your address,
and I'll have a demo sent to you.

This same code, along with several other edIt
extensions, is also available in the 
/pub/cooper/edIt directory on the Smalltalk
archive server.

Ken Cooper
Cooper & Peters, Inc.
----------------------- CUT HERE -----------------------

"This filein contains an edIt extension that allows you
to rename a class without fuss.  It first prompts the 
user for a class to rename, then for a new class name.
After renaming the class, and replacing all references
in the image, it opens a method browser showing all
the methods that were affected.

Category: Renaming
Key Binding: Ctrl-Y+R
Author: Ken Cooper (71571.407@compuserve.com)
Classes:
  CPFRClassReplacer
Methods:
  CPEdIt>>renameClass
  String>>isValidClassName
"!
CPFRReferencesInfo subclass: #CPFRClassReplacer
  instanceVariableNames: 
    ' classToRename '
  classVariableNames: ''
  poolDictionaries: ''   !


!CPFRClassReplacer methods !
 
crossMethodFindReplace

    | methodList methodFindReplaceInfo |


    CursorManager execute changeFor: [
        methodList := self scopeInfo
            methodsInCurrentScopeSatisfying: self criteriaBlock
            notifying: self notifyOfProgress.
    ].

    methodList isEmpty ifTrue: [
        self notifyNomatch.
        ^false
    ].

    methodFindReplaceInfo := self deepCopy.
    methodFindReplaceInfo scopeInfo scope: #method.
    classToRename rename: replaceText.
    CPMethodBrowser new
        labelWithoutPrefix: 'Methods altered by changing class ', self findText, ' to ', replaceText;
        findReplaceInfo: methodFindReplaceInfo;
        openOn: methodList.

    ^false
!

renameClass: aClass to: aName notifying: aPane

    classToRename := aClass.
    self findText: aClass name.
    self replaceText: aName.
    self replaceAll.
    self pane: aPane.
    self findReplace.
    
    
! !

!CPEdIt methods!
renameClass

    "Prompt the user for a class to rename, followed by the new name.
    Rename the class, replace all references to the class in the 
    image, and ohow a MethodBrowser containing all affected methods"
    | class newName validName |

    class := self outmostManager getClassFromUser.
    class isNil ifTrue: [ ^self ].
    [
        newName := Prompter prompt: 'New Class Name:' default: class name.
        newName isNil ifTrue: [ ^self ].
        newName := newName trimBlanks.
        (validName := newName isValidClassName) ifFalse: [
            MessageBox message: 'Invalid class name ', newName printString.
        ].
        validName.
    ] whileFalse: [].
    
    CPFRClassReplacer new
        renameClass: class
        to: newName
        notifying: self mainEditor.! !

!String methods!
isValidClassName

    | firstChar |
    #addedByCnP.
    self isEmpty ifTrue: [ ^false ].
    firstChar := self first.
    firstChar isUppercase ifFalse: [ ^false ].
    ((firstChar = $_) | firstChar isLetter) ifFalse: [ ^false ].
    
    ^(self reject: [ :c | c isAlphaNumeric | (c = $_) ]) isEmpty! !



CPCategoryManager current addMethod: #renameClass inClass: #CPEdIt toCategory: 'Renaming'.
CPKeyBindingsSet current bindKey: 'Ctrl-Y+R' toSelector: #renameClass inClass: #CPEdIt.!
