Skip to content

Instantly share code, notes, and snippets.

@wouterj
Created May 12, 2014 20:24
Show Gist options
  • Select an option

  • Save wouterj/57f12c1852ac57fd853d to your computer and use it in GitHub Desktop.

Select an option

Save wouterj/57f12c1852ac57fd853d to your computer and use it in GitHub Desktop.
<?php
interface LineNumber
{
function getLineNumber($currentLineNumber);
}
class RelativeLineNumber implements LineNumber
{
private $linesDelta;
public function __construct($linesDelta)
{
$this->linesDelta = intval($linesDelta);
}
public function getLineNumber($currentLineNumber)
{
return $currentLineNumber + $this->linesDelta;
}
}
class AbsoluteLineNumber implements LineNumber
{
private $lineNumber;
public function __construct($lineNumber)
{
$this->lineNumber = $lineNumber;
}
public function getLineNumber($currentLineNumber)
{
return $this->lineNumber;
}
}
class LineMatch
{
/** @var Expression */
private $expression;
public function __construct(Expression $expression)
{
$this->expression = $expression;
}
public function getRegex()
{
return (string) $this->expression;
}
}
class Expression
{
private $regex;
private function __construct($regex)
{
$this->regex = $regex;
}
public static function regex($regex)
{
return new self($regex);
}
public static function exact($string)
{
return new self('{'.preg_quote($string).'}');
}
public static function glob($string)
{
return new self('{'.str_replace('\*', '.*?', preg_quote($string)).'}');
}
public function __toString()
{
return $this->regex;
}
}
class Lines
{
public static function down($lines)
{
return new RelativeLineNumber($lines);
}
public static function up($lines)
{
return new RelativeLineNumber(-$lines);
}
public static function exact($line)
{
return new AbsoluteLineNumber($line);
}
public static function match(Expression $expression)
{
return new LineMatch($expression);
}
}
class LineNumberSearchStrategy implements SearchStrategy
{
public function has(File $file, $pattern)
{
return count($file->readlines()) >= $pattern->getLineNumber($this->getCurrentLineNumber()) - 1;
}
public function findNext(File $file, $pattern)
{
return $pattern->getLineNumber($file->getCurrentLineNumber());
}
public function findPrev(File $file, $pattern)
{
return $pattern->getLineNumber($file->getCurrentLineNumber());
}
public function supports($pattern)
{
return is_object($pattern) && $pattern instanceof LineNumber;
}
}
class LineSearchStrategy implements SearchStrategy
{
public function has(File $file, $pattern)
{
try {
$this->getLine($file->readlines(), $pattern->getRegex());
return true;
} catch (PatternNotFoundException $e) {
return false;
}
}
public function findNext(File $file, $pattern)
{
return $this->getLine(array_slice($file->readlines(), $file->getCurrentLineNumber()), $pattern->getRegex());
}
public function findPrev(File $file, $pattern)
{
return $this->getLine(array_reverse(array_slice($file->readlines(), 0, $file->getCurrentLineNumber())), $pattern->getRegex());
}
private function getLine($lines, $regex)
{
foreach ($lines as $number => $line) {
if (preg_match($regex, $line)) {
return $number;
}
}
throw new PatternNotFoundException(...);
}
public function supports($pattern)
{
return is_object($pattern) && $pattern instanceof LineMatch;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment