forked from pharo-project/pharo
/
SmalltalkEditingState.class.st
128 lines (112 loc) · 4.26 KB
/
SmalltalkEditingState.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"
See EditingState comments.
SmalltalkEditingState is made to manage data for Smalltalk code editing sessions (such as a selector chooser).
Instance Variables:
selectorChooser <SelectorChooserMorph>
- selectorChooser
The basic selector chooser which is popup to fetch available selectors or class names begining with a prefix. The prefix is token from the current caret location (see SelectorChooserMorph comments).
"
Class {
#name : #SmalltalkEditingState,
#superclass : #EditingState,
#instVars : [
'selectorChooser'
],
#category : #'Text-Edition-Utilities'
}
{ #category : #'selector-chooser' }
SmalltalkEditingState >> chosenSelector: aSelector for: aTextMorph [
| newStart replacement caret prevSelection |
self closeSelectorChooser.
aSelector ifNil: [^ self].
aTextMorph editor selectPrecedingIdentifier.
prevSelection := aTextMorph selection.
newStart := aTextMorph editor startIndex.
caret := aTextMorph editor stopIndex.
replacement := String streamContents: [:strm | | kwds |
1 to: (kwds := aSelector keywords) size
do: [:i | strm nextPutAll: (kwds at: i).
i = 1 ifTrue: [caret := newStart + strm contents size + 1].
strm nextPutAll: (i < kwds size ifTrue: [' '] ifFalse: [' '])]].
prevSelection asString = replacement trimBoth
ifTrue: [aTextMorph flash]
ifFalse: [aTextMorph replaceSelectionWith: replacement].
aTextMorph selectFrom: caret to: caret - 1.
(aTextMorph respondsTo: #editView) ifTrue: [aTextMorph editView selectionInterval: aTextMorph editor selectionInterval].
]
{ #category : #'selector-chooser' }
SmalltalkEditingState >> closeSelectorChooser [
selectorChooser
ifNotNil: [ [selectorChooser delete] ensure: [selectorChooser := nil] ]
]
{ #category : #events }
SmalltalkEditingState >> focused: aBoolean from: aTextMorph [
super focused: aBoolean from: aTextMorph.
selectorChooser ifNotNil: [selectorChooser comeToFront]
]
{ #category : #events }
SmalltalkEditingState >> handlesKeyboard: evt from: aTextMorph [
^ (super handlesKeyboard: evt from: aTextMorph)
or: [selectorChooser notNil and: [selectorChooser handlesKeyboard: evt]]
]
{ #category : #events }
SmalltalkEditingState >> keystroke: aKeyboardEvent from: aTextMorph [
| asciiValue |
selectorChooser
ifNotNil: [(selectorChooser handlesKeyStroke: aKeyboardEvent)
ifTrue: [selectorChooser keyStroke: aKeyboardEvent.
^ true]].
asciiValue := aKeyboardEvent keyValue.
asciiValue = Character cr asciiValue
ifTrue: [self closeSelectorChooser.
^ true].
aKeyboardEvent controlKeyPressed
ifTrue: [self closeSelectorChooser.
^ true].
"aKeyboardEvent commandKeyPressed
ifTrue: [self closeSelectorChooser.
^ true]."
self updateSelectorChooserFrom: aTextMorph.
^ false
]
{ #category : #events }
SmalltalkEditingState >> mouseDown: anEvent from: aTextMorph [
super mouseDown: anEvent from: aTextMorph.
self closeSelectorChooser
]
{ #category : #'selector-chooser' }
SmalltalkEditingState >> querySymbolFrom: aTextMorph [
| pref |
aTextMorph editor hasSelection
ifFalse: [aTextMorph editor selectPrecedingIdentifier].
pref := String streamContents: [:strm |
aTextMorph selection asString trimBoth do: [:c | c isSeparator ifFalse: [strm nextPut: c]]].
selectorChooser := SelectorChooserMorph popUpPrefix: pref from: aTextMorph.
]
{ #category : #'selector-chooser' }
SmalltalkEditingState >> selectorChooser [
^ selectorChooser
]
{ #category : #'selector-chooser' }
SmalltalkEditingState >> smartQuerySymbolFrom: aTextMorph [
| sel pref caret nextPref |
sel := aTextMorph editor selectionInterval.
aTextMorph editor selectPrecedingIdentifier.
pref := aTextMorph selection asString.
selectorChooser := SelectorChooserMorph popUpPrefix: pref from: aTextMorph.
nextPref := selectorChooser
ifNotNil: [ selectorChooser nextPrefixWith: pref ].
nextPref
ifNil: [aTextMorph editor selectInterval: sel]
ifNotNil: [ selectorChooser prefix: nextPref.
aTextMorph editor selectPrecedingIdentifier.
aTextMorph editor replaceSelectionWith: nextPref.
caret := aTextMorph editor selectionInterval first + nextPref size.
aTextMorph editor selectInterval: (caret to: caret - 1)]
]
{ #category : #'selector-chooser' }
SmalltalkEditingState >> updateSelectorChooserFrom: aTextMorph [
selectorChooser ifNil: [^ self].
self closeSelectorChooser.
self querySymbolFrom: aTextMorph
]