Smalltalk electric snippets: make iterator variable naming logic more configurable
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 04 Mar 2015 09:51:20 +0000
changeset 444 a47f43af21d6
parent 423 60c930c93819
child 445 783f2a4af9c2
Smalltalk electric snippets: make iterator variable naming logic more configurable * UserPreferences current smallSenseSmalltalkIterationVariableNamePrefixWithEach: If set, then variable name is prefixed with "each", i.e., `eachPerson`. Defaults to `false`. Thanks Alexander Zottnick for suggestion. * UserPreferences current smallSenseSmalltalkIterationVariableNameMaxLength: Length limit for generated variable name, if the name is longer than this limit, fall back to generic `each` to make the code more concise. Defaults to 14 (subject to change). These preferences are "hidden" for now, i.e., there is no configuration UI for them. One has to add the setting to her/his user startup file.
SmallSense__EditSupportTests.st
SmallSense__SmalltalkEditSupport.st
SmallSense__SmalltalkEditSupportTests.st
extensions.st
stx_goodies_smallsense.st
--- a/SmallSense__EditSupportTests.st	Sat Feb 21 22:54:44 2015 +0000
+++ b/SmallSense__EditSupportTests.st	Wed Mar 04 09:51:20 2015 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
 stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
 Copyright (C) 2013-2015 Jan Vrany
@@ -63,6 +65,8 @@
 setUp
     | topView |
 
+    super setUp.
+
     Smalltalk loadPackage: 'stx:goodies/sunitext/ui'.
 
     topView := StandardSystemView new.
@@ -81,7 +85,7 @@
     topView waitUntilVisible.
 
     "Created: / 23-07-2014 / 07:15:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 11-08-2014 / 14:35:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 04-03-2015 / 09:42:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 tearDown
@@ -90,6 +94,16 @@
     editSupport := nil.
     codeView topView destroy.
 
+    super tearDown
+
     "Created: / 23-07-2014 / 07:17:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 09:43:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!EditSupportTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- a/SmallSense__SmalltalkEditSupport.st	Sat Feb 21 22:54:44 2015 +0000
+++ b/SmallSense__SmalltalkEditSupport.st	Wed Mar 04 09:51:20 2015 +0000
@@ -196,22 +196,15 @@
                     (#( #do #select #reject #detect #contains #allSatisfy #anySatisfy )
                         includes:lastValue0)
                             ifTrue:[
-                                | collectionName  eachName  space  part1  part2 |
+                                | collectionName iterationVariableName space part1 part2 |
 
-                                space := RBFormatter spaceAfterKeywordSelector ifTrue:[
-                                        ' '
-                                    ] ifFalse:[ '' ].
-                                eachName := 'each'.
+                                space := RBFormatter spaceAfterKeywordSelector ifTrue:[' '] ifFalse:[ '' ].
+                                iterationVariableName := 'each'.
                                 tokens size > 4 ifTrue:[
-                                    ((collectionName := tokens at:tokens size - 6) last = $s) ifTrue:[
-                                        (collectionName endsWith:'ses') ifTrue:[
-                                            eachName := collectionName copyButLast:2
-                                        ] ifFalse:[
-                                            eachName := collectionName copyButLast:1
-                                        ].
-                                    ].
+                                    collectionName := tokens at:tokens size - 6.
+                                    iterationVariableName := self iterationVariableNameForCollectionNamed: collectionName.
                                 ].
-                                part1 := ':' , space , '[:' , eachName , ' | '.
+                                part1 := ':' , space , '[:' , iterationVariableName , ' | '.
                                 part2 := ' ]'.
                                 self electricInsert:part1 , part2 advanceCursorBy:part1 size.
                                 ^ true.
@@ -225,7 +218,7 @@
     ^ false.
 
     "Created: / 22-10-2013 / 03:05:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 12-02-2015 / 00:02:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 04-03-2015 / 07:54:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 electricInsertSnippetAfterSpace
@@ -565,6 +558,28 @@
 
 !SmalltalkEditSupport methodsFor:'private'!
 
+iterationVariableNameForCollectionNamed: collectionName
+    | eachName |
+
+    eachName := 'each'.
+    ((collectionName) last = $s) ifTrue:[
+        (collectionName endsWith:'ses') ifTrue:[
+            eachName := collectionName copyButLast:2
+        ] ifFalse:[
+            eachName := collectionName copyButLast:1
+        ].
+        UserPreferences current smallSenseSmalltalkIterationVariableNamePrefixWithEach ifTrue:[ 
+            eachName := 'each' , eachName capitalized.
+        ].
+        eachName size > UserPreferences current smallSenseSmalltalkIterationVariableNameMaxLength ifTrue:[ 
+            eachName := 'each'.
+        ].
+    ].
+    ^ eachName
+
+    "Created: / 04-03-2015 / 07:52:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 tokensAtCursorLine
     | line scanner token |
 
--- a/SmallSense__SmalltalkEditSupportTests.st	Sat Feb 21 22:54:44 2015 +0000
+++ b/SmallSense__SmalltalkEditSupportTests.st	Wed Mar 04 09:51:20 2015 +0000
@@ -118,6 +118,38 @@
     self assert: (codeView list at: 2) = '    thisValue'.
 
     "Created: / 11-08-2014 / 15:01:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_03
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    UserPreferences current smallSenseSmalltalkIterationVariableNamePrefixWithEach: true.
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:eachSnippet |  ]'.
+
+    "Created: / 04-03-2015 / 08:13:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_04
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    UserPreferences current smallSenseSmalltalkIterationVariableNameMaxLength: 5.
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:each |  ]'.
+
+    "Created: / 04-03-2015 / 08:14:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !SmalltalkEditSupportTests methodsFor:'tests - indent-on-paste'!
--- a/extensions.st	Sat Feb 21 22:54:44 2015 +0000
+++ b/extensions.st	Wed Mar 04 09:51:20 2015 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "{ Package: 'stx:goodies/smallsense' }"!
 
 !AssignmentNode methodsFor:'enumeration'!
@@ -1090,6 +1092,51 @@
     "Created: / 19-07-2014 / 00:11:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNameMaxLength
+    "Maximum length for iteration variable name. If variable name computed from
+     collection name exeeds the max length, 'each' is used instead."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNameMaxLength ifAbsent:[15"Magic number"]
+
+    "Created: / 04-03-2015 / 08:01:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 09:39:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNameMaxLength: anInteger
+    "Sets the maximum length for iteration variable name. If variable name computed from
+     collection name exeeds the max length, 'each' is used instead."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNameMaxLength put: anInteger
+
+    "Created: / 04-03-2015 / 08:01:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNamePrefixWithEach
+    "If true, then iteration variable names are prefixed with 'each', i.e.,
+     persons -> eachPerson."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNamePrefixWithEach ifAbsent:[false]
+
+    "Created: / 04-03-2015 / 07:57:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNamePrefixWithEach: aBoolean
+    "If true, then iteration variable names are prefixed with 'each', i.e.,
+     persons -> eachPerson."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNamePrefixWithEach put: aBoolean.
+
+    "Created: / 04-03-2015 / 07:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !VariableNode methodsFor:'queries'!
 
 isGlobalOrPrivateClass
--- a/stx_goodies_smallsense.st	Sat Feb 21 22:54:44 2015 +0000
+++ b/stx_goodies_smallsense.st	Wed Mar 04 09:51:20 2015 +0000
@@ -99,6 +99,7 @@
         #'stx:goodies/refactoryBrowser/lint'    "RBBasicLintRule - extended"
         #'stx:goodies/refactoryBrowser/parser'    "RBBlockNode - extended"
         #'stx:goodies/regex'    "Regex::RxCharSetParser - superclass of SmallSense::TokenPatternParser::TokenSpecParser"
+        #'stx:goodies/sunit'    "TestAsserter - superclass of SmallSense::AbstractTestCase"
         #'stx:libbasic'    "Autoload - superclass of SmallSense::AbstractJavaCompletionEngineTests"
         #'stx:libcomp'    "AbstractSyntaxHighlighter - superclass of SmallSense::SmalltalkParser"
         #'stx:libhtml'    "HTMLDocumentFrame - extended"
@@ -150,6 +151,7 @@
         "<className> or (<className> attributes...) in load order"
         #'SmallSense::AbstractDIalog'
         #'SmallSense::AbstractSearchProcessor'
+        (#'SmallSense::AbstractTestCase' autoload)
         #'SmallSense::CodeHighlightingService'
         #'SmallSense::CodeNavigationService'
         #'SmallSense::CompletionContext'
@@ -193,6 +195,7 @@
         #'SmallSense::ClassType'
         #'SmallSense::CompositeProcessor'
         #'SmallSense::ConstantPO'
+        (#'SmallSense::EditSupportTests' autoload)
         #'SmallSense::GenericEditSupport'
         #'SmallSense::ImplementorSearchProcessor'
         #'SmallSense::JavaEditSupport'
@@ -219,6 +222,7 @@
         #'SmallSense::JavaCompletionEngine'
         #'SmallSense::JavaConstructorPO'
         #'SmallSense::MethodKeywordRestPO'
+        (#'SmallSense::SmalltalkEditSupportTests' autoload)
         #'SmallSense::ClassSearchDialog'
         #'SmallSense::JavaCompletionEngineSimple'
         #'SmallSense::MethodSearchDialog'
@@ -226,12 +230,9 @@
         #'SmallSense::PackageSelectDialog'
         #'SmallSense::ProtocolSelectDialog'
         #'SmallSense::GroovyCompletionEngineSimple'
-        (#'SmallSense::AbstractTestCase' autoload)
+        (#'SmallSense::AbstractJavaCompletionEngineTests' autoload)
+        (#'SmallSense::BaseTestClass' autoload)
         (#'SmallSense::CompletionEngineTests' autoload)
-        (#'SmallSense::AbstractJavaCompletionEngineTests' autoload)   
-        (#'SmallSense::BaseTestClass' autoload)
-        (#'SmallSense::TestCase' autoload)
-        (#'SmallSense::EditSupportTests' autoload)
         (#'SmallSense::FinderTests' autoload)
         (#'SmallSense::GroovyCompletionEngineSimpleTests' autoload)
         (#'SmallSense::JavaCompletionEngineEnvironmentResource' autoload)
@@ -239,12 +240,10 @@
         (#'SmallSense::JavaEditSupportTests' autoload)
         (#'SmallSense::RecognizerTests' autoload)
         (#'SmallSense::SmalltalkCompletionEngineTests' autoload)
-        (#'SmallSense::SmalltalkEditSupportTests' autoload)
         (#'SmallSense::SmalltalkParserTests' autoload)
+        (#'SmallSense::TestCase' autoload)
         (#'SmallSense::TokenPatternMatcherTests' autoload)
     )
-
-    "Modified: / 21-02-2015 / 22:50:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 extensionMethodNames
@@ -322,6 +321,10 @@
         #'Tools::Inspector2' processShortcut:
         WorkspaceApplication processShortcut:
         #'Tools::NewSystemBrowser' processShortcut:
+        UserPreferences smallSenseSmalltalkIterationVariableNameMaxLength
+        UserPreferences smallSenseSmalltalkIterationVariableNameMaxLength:
+        UserPreferences smallSenseSmalltalkIterationVariableNamePrefixWithEach
+        UserPreferences smallSenseSmalltalkIterationVariableNamePrefixWithEach:
     )
 ! !