I gave a shot to Claude Opal 4.1 (did not test as on a road trip).
Two artefacts were created.
First one
detectLineTerminationConvention: aFilename
���Detect the line termination convention used in a text file.
Returns #cr, #lf, #crlf, or #unknown���
```
| fileReference contents crCount lfCount crlfCount index |
"Create file reference and check if file exists"
fileReference := aFilename asFileReference.
fileReference exists ifFalse: [
^ self error: 'File does not exist: ', aFilename
].
"Read file contents as binary to preserve line endings"
contents := fileReference binaryReadStream contents.
contents isEmpty ifTrue: [ ^ #unknown ].
"Initialize counters"
crCount := 0.
lfCount := 0.
crlfCount := 0.
index := 1.
"Scan through the content looking for line terminators"
[ index <= contents size ] whileTrue: [
| currentByte nextByte |
currentByte := contents at: index.
"Check for CR (13) followed by LF (10)"
(currentByte = 13 and: [ index < contents size ]) ifTrue: [
nextByte := contents at: index + 1.
nextByte = 10
ifTrue: [
"Found CRLF"
crlfCount := crlfCount + 1.
index := index + 2 ]
ifFalse: [
"Found standalone CR"
crCount := crCount + 1.
index := index + 1 ]
] ifFalse: [
"Check for standalone LF (10)"
currentByte = 10 ifTrue: [
lfCount := lfCount + 1 ].
index := index + 1
]
].
"Determine the predominant line ending convention"
(crlfCount > 0 and: [ crlfCount >= crCount and: [ crlfCount >= lfCount ] ])
ifTrue: [ ^ #crlf ].
(lfCount > 0 and: [ lfCount >= crCount ])
ifTrue: [ ^ #lf ].
crCount > 0
ifTrue: [ ^ #cr ].
^ #unknown
```
Second one :
���FileLineEndingDetector - A utility class for detecting and converting line endings���
Object subclass: #FileLineEndingDetector
instanceVariableNames: ������
classVariableNames: ������
package: ���FileUtilities���
���Class-side methods���
FileLineEndingDetector class >> detectLineEndingIn: aFilename
���Main method to detect line ending convention in a file���
```
| fileReference contents |
fileReference := aFilename asFileReference.
fileReference exists ifFalse: [
^ self error: 'File does not exist: ', aFilename
].
contents := fileReference binaryReadStream contents.
^ self detectLineEndingInBytes: contents
```
FileLineEndingDetector class >> detectLineEndingInBytes: aByteArray
���Detect line ending convention in a byte array���
```
| crCount lfCount crlfCount index result |
aByteArray isEmpty ifTrue: [ ^ #unknown ].
crCount := 0.
lfCount := 0.
crlfCount := 0.
index := 1.
[ index <= aByteArray size ] whileTrue: [
| currentByte |
currentByte := aByteArray at: index.
"Check for CRLF sequence"
(currentByte = 13 and: [ index < aByteArray size and: [ (aByteArray at: index + 1) = 10 ] ])
ifTrue: [
crlfCount := crlfCount + 1.
index := index + 2 ]
ifFalse: [
"Check for standalone CR or LF"
currentByte = 13 ifTrue: [ crCount := crCount + 1 ].
currentByte = 10 ifTrue: [ lfCount := lfCount + 1 ].
index := index + 1 ]
].
"Determine the predominant convention"
result := self determineConvention: crCount lf: lfCount crlf: crlfCount.
^ result
```
FileLineEndingDetector class >> determineConvention: crCount lf: lfCount crlf: crlfCount
���Determine the line ending convention based on counts���
```
| total |
total := crCount + lfCount + crlfCount.
total = 0 ifTrue: [ ^ #unknown ].
"If CRLF is present and dominant, it's Windows"
(crlfCount > 0 and: [ crlfCount >= (total * 0.8) ])
ifTrue: [ ^ #crlf ].
"If LF is dominant, it's Unix/Linux"
(lfCount > 0 and: [ lfCount >= (total * 0.8) ])
ifTrue: [ ^ #lf ].
"If CR is dominant, it's old Mac"
(crCount > 0 and: [ crCount >= (total * 0.8) ])
ifTrue: [ ^ #cr ].
"Mixed line endings detected"
^ #mixed
```
FileLineEndingDetector class >> getLineEndingInfo: aFilename
���Get detailed information about line endings in a file���
```
| fileReference contents info |
fileReference := aFilename asFileReference.
fileReference exists ifFalse: [
^ Dictionary new
at: #error put: 'File does not exist';
yourself
].
contents := fileReference binaryReadStream contents.
info := self analyzeLineEndings: contents.
info at: #filename put: aFilename.
info at: #size put: fileReference size.
^ info
```
FileLineEndingDetector class >> analyzeLineEndings: aByteArray
���Analyze and return detailed information about line endings���
```
| crCount lfCount crlfCount index info |
crCount := 0.
lfCount := 0.
crlfCount := 0.
index := 1.
[ index <= aByteArray size ] whileTrue: [
| currentByte |
currentByte := aByteArray at: index.
(currentByte = 13 and: [ index < aByteArray size and: [ (aByteArray at: index + 1) = 10 ] ])
ifTrue: [
crlfCount := crlfCount + 1.
index := index + 2 ]
ifFalse: [
currentByte = 13 ifTrue: [ crCount := crCount + 1 ].
currentByte = 10 ifTrue: [ lfCount := lfCount + 1 ].
index := index + 1 ]
].
info := Dictionary new.
info at: #cr put: crCount.
info at: #lf put: lfCount.
info at: #crlf put: crlfCount.
info at: #total put: (crCount + lfCount + crlfCount).
info at: #convention put: (self determineConvention: crCount lf: lfCount crlf: crlfCount).
^ info
```
FileLineEndingDetector class >> convertFile: aFilename to: aConvention
���Convert a file to use a specific line ending convention���
```
| fileReference contents convertedContents |
fileReference := aFilename asFileReference.
fileReference exists ifFalse: [
^ self error: 'File does not exist: ', aFilename
].
contents := fileReference contents.
convertedContents := self convertString: contents to: aConvention.
fileReference writeStreamDo: [ :stream |
stream nextPutAll: convertedContents
].
^ true
```
FileLineEndingDetector class >> convertString: aString to: aConvention
���Convert a string to use a specific line ending convention���
```
| normalized newLineString |
"First normalize to LF only"
normalized := aString copyReplaceAll: String crlf with: String lf.
normalized := normalized copyReplaceAll: String cr with: String lf.
"Then convert to target convention"
aConvention = #lf ifTrue: [ ^ normalized ].
aConvention = #crlf ifTrue: [
newLineString := String crlf.
^ normalized copyReplaceAll: String lf with: newLineString
].
aConvention = #cr ifTrue: [
newLineString := String cr.
^ normalized copyReplaceAll: String lf with: newLineString
].
^ normalized
```
���Extension methods for FileReference���
FileReference >> detectLineEnding
���Detect the line ending convention of this file���
^ FileLineEndingDetector detectLineEndingIn: self fullName
FileReference >> lineEndingInfo
���Get detailed line ending information for this file���
^ FileLineEndingDetector getLineEndingInfo: self fullName
FileReference >> convertLineEndingTo: aConvention
���Convert this file to use a specific line ending convention���
^ FileLineEndingDetector convertFile: self fullName to: aConvention
���Usage examples:���
���
������Basic detection������
FileLineEndingDetector detectLineEndingIn: ���/path/to/file.txt���.
```
""Using FileReference extension""
'/path/to/file.txt' asFileReference detectLineEnding.
""Get detailed information""
FileLineEndingDetector getLineEndingInfo: '/path/to/file.txt'.
""Convert file to Unix line endings""
'/path/to/file.txt' asFileReference convertLineEndingTo: #lf.
""Convert file to Windows line endings""
FileLineEndingDetector convertFile: '/path/to/file.txt' to: #crlf.
```
This was given with some explanations. Seems not so bad to me. It uses ByteArray. Questiona le ?
Something, I���d like to do is using Claude Code (I used the chat here- the terminal mode hase more memory and agentic feature) with is quite mind blowing to me. Ideally, I���d like to make him ingest some good quality code or why not all the mini image code (or the VM ?).
I think there must be ways to use Claude Code efficiently (.claude stuffs, etc) that would make the writing ���personalized���.
My 2 cents.
Cedrick.