Skip to content

Commit

Permalink
Allow placeholder to wrap and contain newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
jessarcher committed Apr 3, 2024
1 parent 4515c98 commit 3c04832
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/Concerns/TypedValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,20 @@ public function value(): string
/**
* Add a virtual cursor to the value and truncate if necessary.
*/
protected function addCursor(string $value, int $cursorPosition, int $maxWidth): string
protected function addCursor(string $value, int $cursorPosition, ?int $maxWidth = null): string
{
$before = mb_substr($value, 0, $cursorPosition);
$current = mb_substr($value, $cursorPosition, 1);
$after = mb_substr($value, $cursorPosition + 1);

$cursor = mb_strlen($current) && $current !== PHP_EOL ? $current : ' ';

$spaceBefore = $maxWidth < 0 ? mb_strwidth($before) : $maxWidth - mb_strwidth($cursor) - (mb_strwidth($after) > 0 ? 1 : 0);
$spaceBefore = $maxWidth < 0 || $maxWidth === null ? mb_strwidth($before) : $maxWidth - mb_strwidth($cursor) - (mb_strwidth($after) > 0 ? 1 : 0);
[$truncatedBefore, $wasTruncatedBefore] = mb_strwidth($before) > $spaceBefore
? [$this->trimWidthBackwards($before, 0, $spaceBefore - 1), true]
: [$before, false];

$spaceAfter = $maxWidth < 0 ? mb_strwidth($after) : $maxWidth - ($wasTruncatedBefore ? 1 : 0) - mb_strwidth($truncatedBefore) - mb_strwidth($cursor);
$spaceAfter = $maxWidth < 0 || $maxWidth === null ? mb_strwidth($after) : $maxWidth - ($wasTruncatedBefore ? 1 : 0) - mb_strwidth($truncatedBefore) - mb_strwidth($cursor);
[$truncatedAfter, $wasTruncatedAfter] = mb_strwidth($after) > $spaceAfter
? [mb_strimwidth($after, 0, $spaceAfter - 1), true]
: [$after, false];
Expand Down
64 changes: 41 additions & 23 deletions src/TextareaPrompt.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,23 @@ public function __construct(
}

/**
* The currently visible lines.
*
* @return array<int, string>
* Get the formatted value with a virtual cursor.
*/
public function visible(): array
public function valueWithCursor(): string
{
$this->adjustVisibleWindow();
if ($this->value() === '') {
return $this->wrappedPlaceholderWithCursor();
}

$withCursor = $this->valueWithCursor();
return $this->addCursor($this->wrappedValue(), $this->cursorPosition + $this->cursorOffset(), -1);
}

return array_slice(explode(PHP_EOL, $withCursor), $this->firstVisible, $this->scroll, preserve_keys: true);
/**
* The word-wrapped version of the typed value.
*/
public function wrappedValue(): string
{
return $this->mbWordwrap($this->value(), $this->width, PHP_EOL, true);
}

/**
Expand All @@ -78,9 +84,21 @@ public function visible(): array
*/
public function lines(): array
{
$value = $this->mbWordwrap($this->value(), $this->width, PHP_EOL, true);
return explode(PHP_EOL, $this->wrappedValue());
}

/**
* The currently visible lines.
*
* @return array<int, string>
*/
public function visible(): array
{
$this->adjustVisibleWindow();

return explode(PHP_EOL, $value);
$withCursor = $this->valueWithCursor();

return array_slice(explode(PHP_EOL, $withCursor), $this->firstVisible, $this->scroll, preserve_keys: true);
}

/**
Expand Down Expand Up @@ -193,20 +211,6 @@ protected function currentLineIndex(): int
}) ?: 0;
}

/**
* Get the formatted value with a virtual cursor.
*/
public function valueWithCursor(): string
{
$value = implode(PHP_EOL, $this->lines());

if ($this->value() === '') {
return $this->dim($this->addCursor($this->placeholder, 0, PHP_INT_MAX));
}

return $this->addCursor($value, $this->cursorPosition + $this->cursorOffset(), -1);
}

/**
* Calculate the cursor offset considering wrapped words.
*/
Expand All @@ -224,4 +228,18 @@ protected function cursorOffset(): int

return $cursorOffset;
}

/**
* A wrapped version of the placeholder with the virtual cursor.
*/
protected function wrappedPlaceholderWithCursor(): string
{
return implode(PHP_EOL, array_map(
$this->dim(...),
explode(PHP_EOL, $this->addCursor(
$this->mbWordwrap($this->placeholder, $this->width, PHP_EOL, true),
cursorPosition: 0,
))
));
}
}

0 comments on commit 3c04832

Please sign in to comment.