2019-10-10 12:28:46 -04:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
2019-11-08 16:27:08 -05:00
|
|
|
namespace Aviat\Kilo;
|
2019-10-10 12:28:46 -04:00
|
|
|
|
2021-03-05 12:06:23 -05:00
|
|
|
use Aviat\Kilo\Enum\{Color, Highlight, KeyCode};
|
2019-10-14 16:21:41 -04:00
|
|
|
|
2019-10-24 10:58:38 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ! C function/macro equivalents
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2019-10-22 16:16:28 -04:00
|
|
|
/**
|
|
|
|
* Do bit twiddling to convert a letter into
|
2019-10-24 10:58:38 -04:00
|
|
|
* its Ctrl-letter equivalent ordinal ascii value
|
2019-10-22 16:16:28 -04:00
|
|
|
*
|
|
|
|
* @param string $char
|
|
|
|
* @return int
|
|
|
|
*/
|
2019-10-11 16:32:47 -04:00
|
|
|
function ctrl_key(string $char): int
|
|
|
|
{
|
2019-10-24 10:58:38 -04:00
|
|
|
if ( ! is_ascii($char))
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-10-24 12:00:14 -04:00
|
|
|
// b1,100,001 (a) & b0,011,111 (0x1f) = b0,000,001 (SOH)
|
|
|
|
// b1,100,010 (b) & b0,011,111 (0x1f) = b0,000,010 (STX)
|
|
|
|
// ...and so on
|
2019-10-11 16:32:47 -04:00
|
|
|
return ord($char) & 0x1f;
|
2019-10-22 17:50:35 -04:00
|
|
|
}
|
2019-10-23 13:34:40 -04:00
|
|
|
|
2019-10-24 12:00:14 -04:00
|
|
|
/**
|
|
|
|
* Does the one-character string contain an ascii ordinal value?
|
|
|
|
*
|
|
|
|
* @param string $single_char
|
|
|
|
* @return bool
|
|
|
|
*/
|
2019-10-24 10:58:38 -04:00
|
|
|
function is_ascii(string $single_char): bool
|
2019-10-23 13:34:40 -04:00
|
|
|
{
|
|
|
|
if (strlen($single_char) > 1)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ord($single_char) < 0x80;
|
|
|
|
}
|
|
|
|
|
2019-10-24 12:00:14 -04:00
|
|
|
/**
|
|
|
|
* Does the one-character string contain an ascii control character?
|
|
|
|
*
|
|
|
|
* @param string $char
|
|
|
|
* @return bool
|
|
|
|
*/
|
2020-02-05 14:50:31 -05:00
|
|
|
function is_ctrl(string $char): bool
|
2019-10-23 13:34:40 -04:00
|
|
|
{
|
|
|
|
$c = ord($char);
|
2019-11-19 13:48:12 -05:00
|
|
|
return is_ascii($char) && ( $c === 0x7f || $c < 0x20 );
|
2019-10-23 13:34:40 -04:00
|
|
|
}
|
|
|
|
|
2019-10-24 12:00:14 -04:00
|
|
|
/**
|
|
|
|
* Does the one-character string contain an ascii number?
|
|
|
|
*
|
|
|
|
* @param string $char
|
|
|
|
* @return bool
|
|
|
|
*/
|
2019-10-24 10:58:38 -04:00
|
|
|
function is_digit(string $char): bool
|
2019-10-23 13:34:40 -04:00
|
|
|
{
|
|
|
|
$c = ord($char);
|
2019-10-24 10:58:38 -04:00
|
|
|
return is_ascii($char) && ( $c > 0x2f && $c < 0x3a );
|
|
|
|
}
|
|
|
|
|
2019-10-24 16:22:52 -04:00
|
|
|
/**
|
|
|
|
* Does the one-character string contain ascii whitespace?
|
|
|
|
*
|
|
|
|
* @param string $char
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function is_space(string $char): bool
|
|
|
|
{
|
2021-03-03 16:35:58 -05:00
|
|
|
return match($char) {
|
2020-02-05 14:50:31 -05:00
|
|
|
KeyCode::CARRIAGE_RETURN,
|
|
|
|
KeyCode::FORM_FEED,
|
|
|
|
KeyCode::NEWLINE,
|
|
|
|
KeyCode::SPACE,
|
|
|
|
KeyCode::TAB,
|
2021-03-04 16:41:12 -05:00
|
|
|
KeyCode::VERTICAL_TAB => true,
|
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
default => false,
|
|
|
|
};
|
2019-10-24 16:22:52 -04:00
|
|
|
}
|
|
|
|
|
2019-10-24 10:58:38 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// ! Helper functions
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2019-10-24 16:22:52 -04:00
|
|
|
/**
|
|
|
|
* Does the one-character string contain a character that separates tokens?
|
|
|
|
*
|
|
|
|
* @param string $char
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function is_separator(string $char): bool
|
|
|
|
{
|
|
|
|
if ( ! is_ascii($char))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-02-05 14:50:31 -05:00
|
|
|
$isSep = str_contains(',.()+-/*=~%<>[];', $char);
|
2019-10-24 16:22:52 -04:00
|
|
|
|
2020-02-05 14:50:31 -05:00
|
|
|
return is_space($char) || $char === KeyCode::NULL || $isSep;
|
2019-10-24 16:22:52 -04:00
|
|
|
}
|
|
|
|
|
2019-10-24 12:00:14 -04:00
|
|
|
/**
|
|
|
|
* Replaces a slice of an array with the same value
|
|
|
|
*
|
|
|
|
* @param array $array The array to update
|
|
|
|
* @param int $offset The index of the first location to update
|
|
|
|
* @param int $length The number of indices to update
|
|
|
|
* @param mixed $value The value to replace in the range
|
|
|
|
*/
|
|
|
|
function array_replace_range(array &$array, int $offset, int $length, $value):void
|
|
|
|
{
|
2019-10-30 14:21:10 -04:00
|
|
|
if ($length === 1)
|
|
|
|
{
|
|
|
|
$array[$offset] = $value;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-10-25 15:35:20 -04:00
|
|
|
$replacement = array_fill(0, $length, $value);
|
|
|
|
array_splice($array, $offset, $length, $replacement);
|
2019-10-24 12:00:14 -04:00
|
|
|
}
|
2019-10-24 16:57:27 -04:00
|
|
|
|
2019-11-19 13:48:12 -05:00
|
|
|
/**
|
|
|
|
* Does the string $haystack contain $str, optionally searching from $offset?
|
|
|
|
*
|
|
|
|
* @param string $haystack
|
|
|
|
* @param string $str
|
|
|
|
* @param int|null $offset
|
|
|
|
* @return bool
|
|
|
|
*/
|
2019-11-14 11:12:32 -05:00
|
|
|
function str_contains(string $haystack, string $str, ?int $offset = NULL): bool
|
|
|
|
{
|
2019-11-14 17:11:10 -05:00
|
|
|
if (empty($str))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-11-14 11:12:32 -05:00
|
|
|
return ($offset !== NULL)
|
|
|
|
? strpos($haystack, $str, $offset) !== FALSE
|
2021-03-03 13:14:44 -05:00
|
|
|
: \str_contains($haystack, $str);
|
2019-11-14 11:12:32 -05:00
|
|
|
}
|
|
|
|
|
2019-10-29 17:02:03 -04:00
|
|
|
/**
|
|
|
|
* Get the ASCII color escape number for the specified syntax type
|
|
|
|
*
|
|
|
|
* @param int $hl
|
|
|
|
* @return int
|
|
|
|
*/
|
2019-10-24 16:57:27 -04:00
|
|
|
function syntax_to_color(int $hl): int
|
|
|
|
{
|
2021-03-03 13:14:44 -05:00
|
|
|
return match ($hl)
|
|
|
|
{
|
2019-11-06 16:11:38 -05:00
|
|
|
Highlight::COMMENT => Color::FG_CYAN,
|
|
|
|
Highlight::ML_COMMENT => Color::FG_BRIGHT_BLACK,
|
|
|
|
Highlight::KEYWORD1 => Color::FG_YELLOW,
|
|
|
|
Highlight::KEYWORD2 => Color::FG_GREEN,
|
|
|
|
Highlight::STRING => Color::FG_MAGENTA,
|
2021-03-03 20:23:12 -05:00
|
|
|
Highlight::NUMBER => Color::FG_BRIGHT_RED,
|
2019-11-06 16:11:38 -05:00
|
|
|
Highlight::OPERATOR => Color::FG_BRIGHT_GREEN,
|
|
|
|
Highlight::VARIABLE => Color::FG_BRIGHT_CYAN,
|
|
|
|
Highlight::DELIMITER => Color::FG_BLUE,
|
|
|
|
Highlight::INVALID => Color::BG_BRIGHT_RED,
|
|
|
|
Highlight::MATCH => Color::INVERT,
|
2021-03-03 20:23:12 -05:00
|
|
|
Highlight::IDENTIFIER => Color::FG_BRIGHT_WHITE,
|
2021-03-03 13:14:44 -05:00
|
|
|
default => Color::FG_WHITE,
|
|
|
|
};
|
2019-10-24 16:57:27 -04:00
|
|
|
}
|
2019-10-29 17:02:03 -04:00
|
|
|
|
2019-11-08 16:27:08 -05:00
|
|
|
/**
|
|
|
|
* Replace tabs with the specified number of spaces.
|
|
|
|
*
|
|
|
|
* @param string $str
|
2021-03-04 12:03:51 -05:00
|
|
|
* @param int $number
|
2019-11-08 16:27:08 -05:00
|
|
|
* @return string
|
|
|
|
*/
|
2021-03-04 12:03:51 -05:00
|
|
|
function tabs_to_spaces(string $str, int $number = KILO_TAB_STOP): string
|
2019-11-08 13:28:24 -05:00
|
|
|
{
|
2020-02-05 14:50:31 -05:00
|
|
|
return str_replace(KeyCode::TAB, str_repeat(KeyCode::SPACE, $number), $str);
|
2019-11-08 13:28:24 -05:00
|
|
|
}
|
|
|
|
|
2019-11-08 16:27:08 -05:00
|
|
|
/**
|
|
|
|
* Generate/Get the syntax highlighting objects
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2019-11-08 21:48:46 -05:00
|
|
|
function get_file_syntax_map(): array
|
2019-11-08 16:27:08 -05:00
|
|
|
{
|
|
|
|
static $db = [];
|
|
|
|
|
|
|
|
if (count($db) === 0)
|
|
|
|
{
|
|
|
|
$db = [
|
|
|
|
Syntax::new(
|
|
|
|
'C',
|
|
|
|
['.c', '.h', '.cpp'],
|
|
|
|
[
|
|
|
|
'continue', 'typedef', 'switch', 'return', 'static', 'while', 'break', 'struct',
|
|
|
|
'union', 'class', 'else', 'enum', 'for', 'case', 'if',
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'#include', 'unsigned', '#define', '#ifndef', 'double', 'signed', '#endif',
|
|
|
|
'#ifdef', 'float', '#error', '#undef', 'long', 'char', 'int', 'void', '#if',
|
|
|
|
],
|
|
|
|
'//',
|
|
|
|
'/*',
|
|
|
|
'*/',
|
|
|
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
|
|
|
),
|
|
|
|
Syntax::new(
|
|
|
|
'CSS',
|
|
|
|
['.css', '.less', '.sass', 'scss'],
|
|
|
|
[],
|
|
|
|
[],
|
|
|
|
'',
|
|
|
|
'/*',
|
|
|
|
'*/',
|
|
|
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
|
|
|
),
|
|
|
|
Syntax::new(
|
|
|
|
'JavaScript',
|
|
|
|
['.js', '.jsx', '.ts', '.tsx', '.jsm', '.mjs', '.es'],
|
|
|
|
[
|
2021-03-08 19:48:50 -05:00
|
|
|
'instanceof', 'continue', 'debugger', 'function', 'default', 'extends',
|
|
|
|
'finally', 'delete', 'export', 'import', 'return', 'switch', 'typeof',
|
|
|
|
'break', 'catch', 'class', 'const', 'super', 'throw', 'while', 'yield',
|
|
|
|
'case', 'else', 'this', 'void', 'with', 'from', 'for', 'new', 'try',
|
|
|
|
'var', 'do', 'if', 'in', 'as',
|
2019-11-08 16:27:08 -05:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'=>', 'Number', 'String', 'Object', 'Math', 'JSON', 'Boolean',
|
|
|
|
],
|
|
|
|
'//',
|
|
|
|
'/*',
|
|
|
|
'*/',
|
|
|
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
|
|
|
),
|
|
|
|
Syntax::new(
|
|
|
|
'PHP',
|
|
|
|
['.php', 'kilo'],
|
|
|
|
[
|
2021-03-03 20:23:12 -05:00
|
|
|
'?php', '$this', '__halt_compiler'
|
2019-11-08 16:27:08 -05:00
|
|
|
],
|
|
|
|
[
|
|
|
|
'int', 'float', 'bool', 'string', 'true', 'TRUE', 'false', 'FALSE', 'null', 'NULL',
|
|
|
|
'void', 'iterable', 'object', 'strict_types'
|
|
|
|
],
|
|
|
|
'//',
|
|
|
|
'/*',
|
|
|
|
'*/',
|
|
|
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
|
|
|
),
|
|
|
|
Syntax::new(
|
|
|
|
'Rust',
|
|
|
|
['.rs'],
|
|
|
|
[
|
|
|
|
'continue', 'return', 'static', 'struct', 'unsafe', 'break', 'const', 'crate',
|
|
|
|
'extern', 'match', 'super', 'trait', 'where', 'else', 'enum', 'false', 'impl',
|
|
|
|
'loop', 'move', 'self', 'type', 'while', 'for', 'let', 'mod', 'pub', 'ref', 'true',
|
|
|
|
'use', 'mut', 'as', 'fn', 'if', 'in',
|
|
|
|
],
|
|
|
|
[
|
2021-03-08 19:48:50 -05:00
|
|
|
'DoubleEndedIterator', 'ExactSizeIterator', 'IntoIterator', 'PartialOrd', 'PartialEq',
|
|
|
|
'Iterator', 'ToString', 'Default', 'ToOwned', 'Extend', 'FnOnce', 'Option', 'String',
|
|
|
|
'AsMut', 'AsRef', 'Clone', 'Debug', 'FnMut', 'Sized', 'Unpin', 'array', 'isize',
|
|
|
|
'usize', '&str', 'Copy', 'Drop', 'From', 'Into', 'None', 'Self', 'Send', 'Some',
|
|
|
|
'Sync', 'bool', 'char', 'i128', 'u128', 'Box', 'Err', 'Ord', 'Vec', 'dyn', 'f32',
|
|
|
|
'f64', 'i16', 'i32', 'i64', 'str', 'u16', 'u32', 'u64', 'Eq', 'Fn', 'Ok', 'i8', 'u8',
|
2019-11-08 16:27:08 -05:00
|
|
|
],
|
|
|
|
'//',
|
|
|
|
'/*',
|
|
|
|
'*/',
|
|
|
|
Syntax::HIGHLIGHT_NUMBERS | Syntax::HIGHLIGHT_STRINGS,
|
|
|
|
),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $db;
|
|
|
|
}
|
2021-03-03 16:35:58 -05:00
|
|
|
|
|
|
|
function php_token_to_highlight(int $token): int
|
|
|
|
{
|
|
|
|
return match($token) {
|
|
|
|
// Delimiters
|
|
|
|
T_ARRAY,
|
|
|
|
T_CURLY_OPEN,
|
|
|
|
T_DOLLAR_OPEN_CURLY_BRACES,
|
|
|
|
T_OPEN_TAG,
|
|
|
|
T_OPEN_TAG_WITH_ECHO,
|
|
|
|
T_CLOSE_TAG,
|
|
|
|
T_START_HEREDOC,
|
|
|
|
T_END_HEREDOC => Highlight::DELIMITER,
|
|
|
|
|
|
|
|
// Number literals and magic constants
|
2021-03-03 20:23:12 -05:00
|
|
|
T_CLASS_C,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_DIR,
|
|
|
|
T_DNUMBER,
|
|
|
|
T_LNUMBER,
|
|
|
|
T_FILE,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_FUNC_C,
|
|
|
|
T_LINE,
|
|
|
|
T_METHOD_C,
|
|
|
|
T_NS_C,
|
|
|
|
T_NUM_STRING,
|
|
|
|
T_TRAIT_C => Highlight::NUMBER,
|
2021-03-03 16:35:58 -05:00
|
|
|
|
|
|
|
// String literals
|
|
|
|
T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE => Highlight::STRING,
|
|
|
|
|
|
|
|
// Simple variables
|
|
|
|
T_VARIABLE, T_STRING_VARNAME => Highlight::VARIABLE,
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
T_AS,
|
|
|
|
T_AND_EQUAL,
|
|
|
|
T_BOOLEAN_AND,
|
|
|
|
T_BOOLEAN_OR,
|
|
|
|
T_COALESCE,
|
|
|
|
T_COALESCE_EQUAL,
|
|
|
|
T_CONCAT_EQUAL,
|
|
|
|
T_DEC,
|
|
|
|
T_DIV_EQUAL,
|
|
|
|
T_DOUBLE_ARROW,
|
|
|
|
T_DOUBLE_COLON,
|
|
|
|
T_ELLIPSIS,
|
|
|
|
T_INC,
|
|
|
|
T_INSTANCEOF,
|
|
|
|
T_INSTEADOF,
|
|
|
|
T_IS_EQUAL,
|
|
|
|
T_IS_GREATER_OR_EQUAL,
|
|
|
|
T_IS_IDENTICAL,
|
|
|
|
T_IS_NOT_EQUAL,
|
|
|
|
T_IS_NOT_IDENTICAL,
|
|
|
|
T_IS_SMALLER_OR_EQUAL,
|
|
|
|
T_SPACESHIP,
|
|
|
|
T_LOGICAL_AND,
|
|
|
|
T_LOGICAL_OR,
|
|
|
|
T_LOGICAL_XOR,
|
|
|
|
T_MINUS_EQUAL,
|
|
|
|
T_MOD_EQUAL,
|
|
|
|
T_MUL_EQUAL,
|
|
|
|
T_NS_SEPARATOR,
|
|
|
|
T_NULLSAFE_OBJECT_OPERATOR,
|
|
|
|
T_OBJECT_OPERATOR,
|
|
|
|
T_OR_EQUAL,
|
|
|
|
T_PLUS_EQUAL,
|
|
|
|
T_POW,
|
|
|
|
T_POW_EQUAL,
|
|
|
|
T_SL,
|
|
|
|
T_SL_EQUAL,
|
|
|
|
T_SR,
|
|
|
|
T_SR_EQUAL,
|
|
|
|
T_XOR_EQUAL => Highlight::OPERATOR,
|
|
|
|
|
|
|
|
// Keywords1
|
|
|
|
T_ABSTRACT,
|
|
|
|
T_BREAK,
|
|
|
|
T_CASE,
|
|
|
|
T_CATCH,
|
|
|
|
T_CLASS,
|
|
|
|
T_CLONE,
|
|
|
|
T_CONST,
|
|
|
|
T_CONTINUE,
|
|
|
|
T_DECLARE,
|
|
|
|
T_DEFAULT,
|
|
|
|
T_DO,
|
|
|
|
T_ECHO,
|
|
|
|
T_ELSE,
|
|
|
|
T_ELSEIF,
|
|
|
|
T_EMPTY,
|
|
|
|
T_ENDDECLARE,
|
|
|
|
T_ENDFOR,
|
|
|
|
T_ENDFOREACH,
|
|
|
|
T_ENDIF,
|
|
|
|
T_ENDSWITCH,
|
|
|
|
T_ENDWHILE,
|
|
|
|
T_EVAL,
|
|
|
|
T_EXIT,
|
|
|
|
T_EXTENDS,
|
|
|
|
T_FINAL,
|
|
|
|
T_FINALLY,
|
|
|
|
T_FN,
|
|
|
|
T_FOR,
|
|
|
|
T_FOREACH,
|
|
|
|
T_FUNCTION,
|
|
|
|
T_GLOBAL,
|
|
|
|
T_GOTO,
|
|
|
|
T_HALT_COMPILER,
|
|
|
|
T_IF,
|
|
|
|
T_IMPLEMENTS,
|
|
|
|
T_INCLUDE,
|
|
|
|
T_INCLUDE_ONCE,
|
|
|
|
T_INTERFACE,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_ISSET,
|
|
|
|
T_LIST,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_MATCH,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_NAMESPACE,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_NEW,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_PRINT,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_PRIVATE,
|
|
|
|
T_PUBLIC,
|
|
|
|
T_PROTECTED,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_REQUIRE,
|
|
|
|
T_REQUIRE_ONCE,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_RETURN,
|
|
|
|
T_STATIC,
|
|
|
|
T_SWITCH,
|
|
|
|
T_THROW,
|
|
|
|
T_TRAIT,
|
|
|
|
T_TRY,
|
2021-03-03 20:23:12 -05:00
|
|
|
T_UNSET,
|
2021-03-03 16:35:58 -05:00
|
|
|
T_USE,
|
|
|
|
T_VAR,
|
|
|
|
T_WHILE,
|
|
|
|
T_YIELD,
|
|
|
|
T_YIELD_FROM => Highlight::KEYWORD1,
|
|
|
|
|
|
|
|
// Not string literals, but identifiers, keywords, etc.
|
2021-03-03 20:23:12 -05:00
|
|
|
T_STRING => Highlight::IDENTIFIER,
|
2021-03-03 16:35:58 -05:00
|
|
|
|
|
|
|
// Types and casts
|
|
|
|
T_ARRAY_CAST,
|
|
|
|
T_BOOL_CAST,
|
|
|
|
T_CALLABLE,
|
|
|
|
T_DOUBLE_CAST,
|
|
|
|
T_INT_CAST,
|
|
|
|
T_OBJECT_CAST,
|
|
|
|
T_STRING_CAST,
|
|
|
|
T_UNSET_CAST => Highlight::KEYWORD2,
|
|
|
|
|
|
|
|
// Invalid syntax
|
|
|
|
T_BAD_CHARACTER => Highlight::INVALID,
|
2021-03-04 12:03:51 -05:00
|
|
|
|
2021-03-03 16:35:58 -05:00
|
|
|
default => Highlight::NORMAL,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function php_char_to_highlight(string $char): int
|
|
|
|
{
|
|
|
|
return match ($char) {
|
|
|
|
// Delimiter characters
|
|
|
|
'[', ']', '{', '}', '(', ')', '"', "'" => Highlight::DELIMITER,
|
|
|
|
|
|
|
|
// Single character operators
|
|
|
|
'?', ',', ';', ':', '^', '%', '+', '-',
|
|
|
|
'*', '/', '.', '|', '~', '>', '<', '=', '!' => Highlight::OPERATOR,
|
|
|
|
|
|
|
|
default => Highlight::NORMAL,
|
|
|
|
};
|
|
|
|
}
|