@@ -51,13 +51,25 @@ public function linesBefore(int $linesBefore): self
5151 {
5252 $ this ->linesBefore = $ linesBefore ;
5353
54+ if (is_int ($ this ->linesAfter ) && is_int ($ this ->linesBefore )) {
55+ $ range = range ($ this ->surroundingLines [0 ], $ this ->surroundingLines [count ($ this ->surroundingLines [0 ]) - 1 ]);
56+
57+ $ this ->snippetLineCount = ($ this ->linesAfter + $ this ->linesBefore ) + count ($ range );
58+ }
59+
5460 return $ this ;
5561 }
5662
5763 public function linesAfter (int $ linesAfter ): self
5864 {
5965 $ this ->linesAfter = $ linesAfter ;
6066
67+ if (is_int ($ this ->linesAfter ) && is_int ($ this ->linesBefore )) {
68+ $ range = range ($ this ->surroundingLines [0 ], $ this ->surroundingLines [count ($ this ->surroundingLines ) - 1 ]);
69+
70+ $ this ->snippetLineCount = ($ this ->linesAfter + $ this ->linesBefore ) + count ($ range );
71+ }
72+
6173 return $ this ;
6274 }
6375
@@ -138,23 +150,73 @@ protected function isSurroundedLineNumber(int $lineNumber): bool
138150 return in_array ($ lineNumber , $ this ->surroundingLines , true );
139151 }
140152
153+ protected function getBounds (int $ surroundingLine , int $ totalNumberOfLineInFile ): array
154+ {
155+ $ startLine = max ($ surroundingLine - floor ($ this ->snippetLineCount / 2 ), 1 );
156+
157+ $ endLine = $ startLine + ($ this ->snippetLineCount - 1 );
158+
159+ if ($ endLine > $ totalNumberOfLineInFile ) {
160+ $ endLine = $ totalNumberOfLineInFile ;
161+ $ startLine = max ($ endLine - ($ this ->snippetLineCount - 1 ), 1 );
162+ }
163+
164+ return [$ startLine , $ endLine ];
165+ }
166+
141167 protected function getBoundsMulti (int $ totalNumberOfLineInFile ): array
142168 {
143- $ firstLine = max ($ this ->surroundingLines [0 ] - floor ($ this ->snippetLineCount / 2 ), 1 );
144- $ lastLine = max ($ this ->surroundingLines [count ($ this ->surroundingLines ) - 1 ] - floor ($ this ->snippetLineCount / 2 ), 1 );
145- $ endLine = $ lastLine + ($ this ->snippetLineCount - 1 );
146- $ startLine = $ firstLine - ($ this ->snippetLineCount - 1 );
169+ $ firstLineNum = $ this ->surroundingLines [0 ];
170+ $ lastLineNum = $ this ->surroundingLines [count ($ this ->surroundingLines ) - 1 ];
147171
148- if (is_int ($ this ->linesAfter ) && is_int ($ this ->linesBefore )) {
149- $ firstLine = max ($ this ->surroundingLines [0 ], 1 );
150- $ lastLine = max ($ this ->surroundingLines [count ($ this ->surroundingLines ) - 1 ], 1 );
172+ if (! is_int ($ this ->linesAfter ) || ! is_int ($ this ->linesBefore )) {
173+ $ startBounds = $ this ->getBounds ($ firstLineNum , $ totalNumberOfLineInFile );
174+ $ endBounds = $ this ->getBounds ($ lastLineNum , $ totalNumberOfLineInFile );
175+
176+ $ bounds = array_merge ($ startBounds , $ endBounds );
177+ sort ($ bounds , SORT_NUMERIC );
151178
152- $ startLine = max ($ firstLine - $ this ->linesBefore , 1 );
153- $ endLine = max ($ lastLine + $ this ->linesAfter , 1 );
179+ $ startLine = $ bounds [0 ];
180+ $ endLine = $ bounds [count ($ bounds ) - 1 ];
181+
182+ [$ startLine , $ endLine ] = $ this ->ensureBoundsAreWithinLimits ($ startLine , $ endLine , $ totalNumberOfLineInFile );
183+ [$ startLine , $ endLine ] = $ this ->trimSnippetSize ($ startLine , $ endLine );
154184
155185 $ this ->snippetLineCount = ($ endLine - $ startLine ) + 1 ;
186+
187+ return [$ startLine , $ endLine ];
156188 }
157189
190+ $ startLine = $ firstLineNum - $ this ->linesBefore ;
191+ $ endLine = $ lastLineNum + $ this ->linesAfter ;
192+
193+ $ this ->snippetLineCount = ($ endLine - $ startLine ) + 1 ;
194+
195+ [$ startLine , $ endLine ] = $ this ->ensureBoundsAreWithinLimits ($ startLine , $ endLine , $ totalNumberOfLineInFile );
196+ [$ startLine , $ endLine ] = $ this ->trimSnippetSize ($ startLine , $ endLine );
197+
198+ return [$ startLine , $ endLine ];
199+ }
200+
201+ protected function trimSnippetSize (int $ startLine , int $ endLine ): array
202+ {
203+ if (count (range ($ startLine , $ endLine )) > $ this ->snippetLineCount ) {
204+ if (! in_array ($ endLine , $ this ->surroundingLines , true )) {
205+ $ endLine --;
206+ }
207+ }
208+
209+ if (count (range ($ startLine , $ endLine )) > $ this ->snippetLineCount ) {
210+ if (! in_array ($ startLine , $ this ->surroundingLines , true )) {
211+ $ startLine ++;
212+ }
213+ }
214+
215+ return [$ startLine , $ endLine ];
216+ }
217+
218+ protected function ensureBoundsAreWithinLimits (int $ startLine , int $ endLine , int $ totalNumberOfLineInFile ): array
219+ {
158220 if ($ startLine <= 0 ) {
159221 $ startLine = 1 ;
160222 }
0 commit comments