@particle-academy/fancy-code 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.cjs +403 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +403 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,10 +201,12 @@ function RunButton() {
|
|
|
201
201
|
| TypeScript | `ts`, `typescript`, `tsx` |
|
|
202
202
|
| HTML | `html`, `htm` |
|
|
203
203
|
| PHP | `php` |
|
|
204
|
+
| Python | `py`, `python` |
|
|
205
|
+
| Go | `go`, `golang` |
|
|
204
206
|
|
|
205
207
|
## Custom Language Registration
|
|
206
208
|
|
|
207
|
-
Add languages beyond the
|
|
209
|
+
Add languages beyond the built-ins using `registerLanguage`:
|
|
208
210
|
|
|
209
211
|
```tsx
|
|
210
212
|
import { registerLanguage } from "@particle-academy/fancy-code";
|
package/dist/index.cjs
CHANGED
|
@@ -110,10 +110,11 @@ function CodeEditorPanel({ className }) {
|
|
|
110
110
|
"textarea",
|
|
111
111
|
{
|
|
112
112
|
ref: textareaRef,
|
|
113
|
-
className: "relative m-0 block w-full resize-none
|
|
113
|
+
className: "relative m-0 block w-full resize-none border-none bg-transparent p-2.5 text-[13px] leading-[1.5] text-transparent outline-none",
|
|
114
114
|
style: {
|
|
115
115
|
caretColor: themeColors.cursorColor,
|
|
116
116
|
minHeight: _minHeight ? _minHeight - 40 : 80,
|
|
117
|
+
overflow: "hidden",
|
|
117
118
|
whiteSpace: wordWrap ? "pre-wrap" : "pre",
|
|
118
119
|
overflowWrap: wordWrap ? "break-word" : "normal"
|
|
119
120
|
},
|
|
@@ -662,6 +663,377 @@ var tokenizePhp = (source) => {
|
|
|
662
663
|
return tokens;
|
|
663
664
|
};
|
|
664
665
|
|
|
666
|
+
// src/engine/tokenizers/python.ts
|
|
667
|
+
var KEYWORDS2 = /* @__PURE__ */ new Set([
|
|
668
|
+
"and",
|
|
669
|
+
"as",
|
|
670
|
+
"assert",
|
|
671
|
+
"async",
|
|
672
|
+
"await",
|
|
673
|
+
"break",
|
|
674
|
+
"class",
|
|
675
|
+
"continue",
|
|
676
|
+
"def",
|
|
677
|
+
"del",
|
|
678
|
+
"elif",
|
|
679
|
+
"else",
|
|
680
|
+
"except",
|
|
681
|
+
"finally",
|
|
682
|
+
"for",
|
|
683
|
+
"from",
|
|
684
|
+
"global",
|
|
685
|
+
"if",
|
|
686
|
+
"import",
|
|
687
|
+
"in",
|
|
688
|
+
"is",
|
|
689
|
+
"lambda",
|
|
690
|
+
"nonlocal",
|
|
691
|
+
"not",
|
|
692
|
+
"or",
|
|
693
|
+
"pass",
|
|
694
|
+
"raise",
|
|
695
|
+
"return",
|
|
696
|
+
"try",
|
|
697
|
+
"while",
|
|
698
|
+
"with",
|
|
699
|
+
"yield",
|
|
700
|
+
"True",
|
|
701
|
+
"False",
|
|
702
|
+
"None"
|
|
703
|
+
]);
|
|
704
|
+
var TYPES = /* @__PURE__ */ new Set([
|
|
705
|
+
"int",
|
|
706
|
+
"str",
|
|
707
|
+
"float",
|
|
708
|
+
"bool",
|
|
709
|
+
"list",
|
|
710
|
+
"dict",
|
|
711
|
+
"tuple",
|
|
712
|
+
"set",
|
|
713
|
+
"bytes",
|
|
714
|
+
"bytearray",
|
|
715
|
+
"memoryview",
|
|
716
|
+
"range",
|
|
717
|
+
"frozenset",
|
|
718
|
+
"complex",
|
|
719
|
+
"type",
|
|
720
|
+
"object",
|
|
721
|
+
"property",
|
|
722
|
+
"classmethod",
|
|
723
|
+
"staticmethod",
|
|
724
|
+
"Any",
|
|
725
|
+
"Optional",
|
|
726
|
+
"Union",
|
|
727
|
+
"Callable",
|
|
728
|
+
"List",
|
|
729
|
+
"Dict",
|
|
730
|
+
"Tuple",
|
|
731
|
+
"Set",
|
|
732
|
+
"Sequence",
|
|
733
|
+
"Mapping",
|
|
734
|
+
"Iterator",
|
|
735
|
+
"Generator",
|
|
736
|
+
"Coroutine"
|
|
737
|
+
]);
|
|
738
|
+
var tokenizePython = (source) => {
|
|
739
|
+
const tokens = [];
|
|
740
|
+
const len = source.length;
|
|
741
|
+
let i = 0;
|
|
742
|
+
while (i < len) {
|
|
743
|
+
const ch = source[i];
|
|
744
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
|
|
745
|
+
i++;
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
if (ch === "#") {
|
|
749
|
+
const pos = i;
|
|
750
|
+
i++;
|
|
751
|
+
while (i < len && source[i] !== "\n") i++;
|
|
752
|
+
tokens.push({ type: "comment", start: pos, end: i });
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
if (ch === "@" && i + 1 < len && /[a-zA-Z_]/.test(source[i + 1])) {
|
|
756
|
+
const pos = i;
|
|
757
|
+
i++;
|
|
758
|
+
while (i < len && /[a-zA-Z0-9_.]/.test(source[i])) i++;
|
|
759
|
+
tokens.push({ type: "keyword", start: pos, end: i });
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (ch === '"' || ch === "'" || (ch === "f" || ch === "r" || ch === "b" || ch === "F" || ch === "R" || ch === "B") && (source[i + 1] === '"' || source[i + 1] === "'")) {
|
|
763
|
+
const pos = i;
|
|
764
|
+
if (ch !== '"' && ch !== "'") i++;
|
|
765
|
+
const quote = source[i];
|
|
766
|
+
if (source[i + 1] === quote && source[i + 2] === quote) {
|
|
767
|
+
const triple = quote + quote + quote;
|
|
768
|
+
i += 3;
|
|
769
|
+
while (i < len && source.slice(i, i + 3) !== triple) {
|
|
770
|
+
if (source[i] === "\\") i++;
|
|
771
|
+
i++;
|
|
772
|
+
}
|
|
773
|
+
i += 3;
|
|
774
|
+
tokens.push({ type: "string", start: pos, end: i });
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
i++;
|
|
778
|
+
while (i < len && source[i] !== quote && source[i] !== "\n") {
|
|
779
|
+
if (source[i] === "\\") i++;
|
|
780
|
+
i++;
|
|
781
|
+
}
|
|
782
|
+
if (i < len && source[i] === quote) i++;
|
|
783
|
+
tokens.push({ type: "string", start: pos, end: i });
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
if (ch >= "0" && ch <= "9" || ch === "." && i + 1 < len && source[i + 1] >= "0" && source[i + 1] <= "9") {
|
|
787
|
+
const pos = i;
|
|
788
|
+
if (ch === "0" && (source[i + 1] === "x" || source[i + 1] === "X")) {
|
|
789
|
+
i += 2;
|
|
790
|
+
while (i < len && /[0-9a-fA-F_]/.test(source[i])) i++;
|
|
791
|
+
} else if (ch === "0" && (source[i + 1] === "b" || source[i + 1] === "B")) {
|
|
792
|
+
i += 2;
|
|
793
|
+
while (i < len && /[01_]/.test(source[i])) i++;
|
|
794
|
+
} else if (ch === "0" && (source[i + 1] === "o" || source[i + 1] === "O")) {
|
|
795
|
+
i += 2;
|
|
796
|
+
while (i < len && /[0-7_]/.test(source[i])) i++;
|
|
797
|
+
} else {
|
|
798
|
+
while (i < len && /[0-9_.]/.test(source[i])) i++;
|
|
799
|
+
if (i < len && (source[i] === "e" || source[i] === "E")) {
|
|
800
|
+
i++;
|
|
801
|
+
if (i < len && (source[i] === "+" || source[i] === "-")) i++;
|
|
802
|
+
while (i < len && source[i] >= "0" && source[i] <= "9") i++;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
if (i < len && source[i] === "j") i++;
|
|
806
|
+
tokens.push({ type: "number", start: pos, end: i });
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
if (/[a-zA-Z_]/.test(ch)) {
|
|
810
|
+
const pos = i;
|
|
811
|
+
i++;
|
|
812
|
+
while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
|
|
813
|
+
const word = source.slice(pos, i);
|
|
814
|
+
let j = i;
|
|
815
|
+
while (j < len && (source[j] === " " || source[j] === " ")) j++;
|
|
816
|
+
if (KEYWORDS2.has(word)) {
|
|
817
|
+
tokens.push({ type: "keyword", start: pos, end: i });
|
|
818
|
+
} else if (TYPES.has(word)) {
|
|
819
|
+
tokens.push({ type: "type", start: pos, end: i });
|
|
820
|
+
} else if (source[j] === "(") {
|
|
821
|
+
tokens.push({ type: "function", start: pos, end: i });
|
|
822
|
+
} else if (word[0] >= "A" && word[0] <= "Z") {
|
|
823
|
+
tokens.push({ type: "type", start: pos, end: i });
|
|
824
|
+
} else {
|
|
825
|
+
tokens.push({ type: "variable", start: pos, end: i });
|
|
826
|
+
}
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
if ("+-*/%=<>!&|^~:@".includes(ch)) {
|
|
830
|
+
const pos = i;
|
|
831
|
+
i++;
|
|
832
|
+
while (i < len && "+-*/%=<>!&|^~:".includes(source[i])) i++;
|
|
833
|
+
tokens.push({ type: "operator", start: pos, end: i });
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
if ("()[]{},.;\\".includes(ch)) {
|
|
837
|
+
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
838
|
+
i++;
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
tokens.push({ type: "plain", start: i, end: i + 1 });
|
|
842
|
+
i++;
|
|
843
|
+
}
|
|
844
|
+
return tokens;
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
// src/engine/tokenizers/go.ts
|
|
848
|
+
var KEYWORDS3 = /* @__PURE__ */ new Set([
|
|
849
|
+
"break",
|
|
850
|
+
"case",
|
|
851
|
+
"chan",
|
|
852
|
+
"const",
|
|
853
|
+
"continue",
|
|
854
|
+
"default",
|
|
855
|
+
"defer",
|
|
856
|
+
"else",
|
|
857
|
+
"fallthrough",
|
|
858
|
+
"for",
|
|
859
|
+
"func",
|
|
860
|
+
"go",
|
|
861
|
+
"goto",
|
|
862
|
+
"if",
|
|
863
|
+
"import",
|
|
864
|
+
"interface",
|
|
865
|
+
"map",
|
|
866
|
+
"package",
|
|
867
|
+
"range",
|
|
868
|
+
"return",
|
|
869
|
+
"select",
|
|
870
|
+
"struct",
|
|
871
|
+
"switch",
|
|
872
|
+
"type",
|
|
873
|
+
"var",
|
|
874
|
+
"nil",
|
|
875
|
+
"true",
|
|
876
|
+
"false",
|
|
877
|
+
"iota"
|
|
878
|
+
]);
|
|
879
|
+
var TYPES2 = /* @__PURE__ */ new Set([
|
|
880
|
+
"bool",
|
|
881
|
+
"byte",
|
|
882
|
+
"complex64",
|
|
883
|
+
"complex128",
|
|
884
|
+
"error",
|
|
885
|
+
"float32",
|
|
886
|
+
"float64",
|
|
887
|
+
"int",
|
|
888
|
+
"int8",
|
|
889
|
+
"int16",
|
|
890
|
+
"int32",
|
|
891
|
+
"int64",
|
|
892
|
+
"rune",
|
|
893
|
+
"string",
|
|
894
|
+
"uint",
|
|
895
|
+
"uint8",
|
|
896
|
+
"uint16",
|
|
897
|
+
"uint32",
|
|
898
|
+
"uint64",
|
|
899
|
+
"uintptr",
|
|
900
|
+
"any"
|
|
901
|
+
]);
|
|
902
|
+
var BUILTINS = /* @__PURE__ */ new Set([
|
|
903
|
+
"make",
|
|
904
|
+
"len",
|
|
905
|
+
"cap",
|
|
906
|
+
"new",
|
|
907
|
+
"append",
|
|
908
|
+
"copy",
|
|
909
|
+
"close",
|
|
910
|
+
"delete",
|
|
911
|
+
"complex",
|
|
912
|
+
"real",
|
|
913
|
+
"imag",
|
|
914
|
+
"panic",
|
|
915
|
+
"recover",
|
|
916
|
+
"print",
|
|
917
|
+
"println"
|
|
918
|
+
]);
|
|
919
|
+
var tokenizeGo = (source) => {
|
|
920
|
+
const tokens = [];
|
|
921
|
+
const len = source.length;
|
|
922
|
+
let i = 0;
|
|
923
|
+
while (i < len) {
|
|
924
|
+
const ch = source[i];
|
|
925
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
|
|
926
|
+
i++;
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
if (ch === "/" && source[i + 1] === "/") {
|
|
930
|
+
const pos = i;
|
|
931
|
+
i += 2;
|
|
932
|
+
while (i < len && source[i] !== "\n") i++;
|
|
933
|
+
tokens.push({ type: "comment", start: pos, end: i });
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (ch === "/" && source[i + 1] === "*") {
|
|
937
|
+
const pos = i;
|
|
938
|
+
i += 2;
|
|
939
|
+
while (i < len && !(source[i] === "*" && source[i + 1] === "/")) i++;
|
|
940
|
+
i += 2;
|
|
941
|
+
tokens.push({ type: "comment", start: pos, end: i });
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
if (ch === "`") {
|
|
945
|
+
const pos = i;
|
|
946
|
+
i++;
|
|
947
|
+
while (i < len && source[i] !== "`") i++;
|
|
948
|
+
i++;
|
|
949
|
+
tokens.push({ type: "string", start: pos, end: i });
|
|
950
|
+
continue;
|
|
951
|
+
}
|
|
952
|
+
if (ch === '"') {
|
|
953
|
+
const pos = i;
|
|
954
|
+
i++;
|
|
955
|
+
while (i < len && source[i] !== '"' && source[i] !== "\n") {
|
|
956
|
+
if (source[i] === "\\") i++;
|
|
957
|
+
i++;
|
|
958
|
+
}
|
|
959
|
+
if (i < len && source[i] === '"') i++;
|
|
960
|
+
tokens.push({ type: "string", start: pos, end: i });
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (ch === "'") {
|
|
964
|
+
const pos = i;
|
|
965
|
+
i++;
|
|
966
|
+
while (i < len && source[i] !== "'" && source[i] !== "\n") {
|
|
967
|
+
if (source[i] === "\\") i++;
|
|
968
|
+
i++;
|
|
969
|
+
}
|
|
970
|
+
if (i < len && source[i] === "'") i++;
|
|
971
|
+
tokens.push({ type: "string", start: pos, end: i });
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
if (ch >= "0" && ch <= "9" || ch === "." && i + 1 < len && source[i + 1] >= "0" && source[i + 1] <= "9") {
|
|
975
|
+
const pos = i;
|
|
976
|
+
if (ch === "0" && (source[i + 1] === "x" || source[i + 1] === "X")) {
|
|
977
|
+
i += 2;
|
|
978
|
+
while (i < len && /[0-9a-fA-F_]/.test(source[i])) i++;
|
|
979
|
+
} else if (ch === "0" && (source[i + 1] === "b" || source[i + 1] === "B")) {
|
|
980
|
+
i += 2;
|
|
981
|
+
while (i < len && /[01_]/.test(source[i])) i++;
|
|
982
|
+
} else if (ch === "0" && (source[i + 1] === "o" || source[i + 1] === "O")) {
|
|
983
|
+
i += 2;
|
|
984
|
+
while (i < len && /[0-7_]/.test(source[i])) i++;
|
|
985
|
+
} else {
|
|
986
|
+
while (i < len && /[0-9_.]/.test(source[i])) i++;
|
|
987
|
+
if (i < len && (source[i] === "e" || source[i] === "E")) {
|
|
988
|
+
i++;
|
|
989
|
+
if (i < len && (source[i] === "+" || source[i] === "-")) i++;
|
|
990
|
+
while (i < len && source[i] >= "0" && source[i] <= "9") i++;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
if (i < len && source[i] === "i") i++;
|
|
994
|
+
tokens.push({ type: "number", start: pos, end: i });
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
if (/[a-zA-Z_]/.test(ch)) {
|
|
998
|
+
const pos = i;
|
|
999
|
+
i++;
|
|
1000
|
+
while (i < len && /[a-zA-Z0-9_]/.test(source[i])) i++;
|
|
1001
|
+
const word = source.slice(pos, i);
|
|
1002
|
+
let j = i;
|
|
1003
|
+
while (j < len && (source[j] === " " || source[j] === " ")) j++;
|
|
1004
|
+
if (KEYWORDS3.has(word)) {
|
|
1005
|
+
tokens.push({ type: "keyword", start: pos, end: i });
|
|
1006
|
+
} else if (TYPES2.has(word)) {
|
|
1007
|
+
tokens.push({ type: "type", start: pos, end: i });
|
|
1008
|
+
} else if (BUILTINS.has(word) && source[j] === "(") {
|
|
1009
|
+
tokens.push({ type: "function", start: pos, end: i });
|
|
1010
|
+
} else if (source[j] === "(") {
|
|
1011
|
+
tokens.push({ type: "function", start: pos, end: i });
|
|
1012
|
+
} else if (word[0] >= "A" && word[0] <= "Z") {
|
|
1013
|
+
tokens.push({ type: "type", start: pos, end: i });
|
|
1014
|
+
} else {
|
|
1015
|
+
tokens.push({ type: "variable", start: pos, end: i });
|
|
1016
|
+
}
|
|
1017
|
+
continue;
|
|
1018
|
+
}
|
|
1019
|
+
if ("+-*/%=<>!&|^~:".includes(ch)) {
|
|
1020
|
+
const pos = i;
|
|
1021
|
+
i++;
|
|
1022
|
+
while (i < len && "+-*/%=<>!&|^~:".includes(source[i])) i++;
|
|
1023
|
+
tokens.push({ type: "operator", start: pos, end: i });
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
if ("(){}[];,.".includes(ch)) {
|
|
1027
|
+
tokens.push({ type: "punctuation", start: i, end: i + 1 });
|
|
1028
|
+
i++;
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
tokens.push({ type: "plain", start: i, end: i + 1 });
|
|
1032
|
+
i++;
|
|
1033
|
+
}
|
|
1034
|
+
return tokens;
|
|
1035
|
+
};
|
|
1036
|
+
|
|
665
1037
|
// src/languages/builtin.ts
|
|
666
1038
|
registerLanguage({
|
|
667
1039
|
name: "JavaScript",
|
|
@@ -684,6 +1056,16 @@ registerLanguage({
|
|
|
684
1056
|
aliases: ["php"],
|
|
685
1057
|
tokenize: tokenizePhp
|
|
686
1058
|
});
|
|
1059
|
+
registerLanguage({
|
|
1060
|
+
name: "Python",
|
|
1061
|
+
aliases: ["py", "python"],
|
|
1062
|
+
tokenize: tokenizePython
|
|
1063
|
+
});
|
|
1064
|
+
registerLanguage({
|
|
1065
|
+
name: "Go",
|
|
1066
|
+
aliases: ["go", "golang"],
|
|
1067
|
+
tokenize: tokenizeGo
|
|
1068
|
+
});
|
|
687
1069
|
var iconBtnClass = "inline-flex items-center justify-center rounded-md p-1 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200";
|
|
688
1070
|
function LanguageSelector() {
|
|
689
1071
|
const { language, setLanguage } = useCodeEditor();
|
|
@@ -946,14 +1328,23 @@ function useEditorEngine({
|
|
|
946
1328
|
}
|
|
947
1329
|
return count;
|
|
948
1330
|
}, [value]);
|
|
1331
|
+
const autoResize = react.useCallback(() => {
|
|
1332
|
+
const ta = textareaRef.current;
|
|
1333
|
+
if (!ta) return;
|
|
1334
|
+
ta.style.height = "auto";
|
|
1335
|
+
ta.style.height = ta.scrollHeight + "px";
|
|
1336
|
+
}, []);
|
|
949
1337
|
react.useEffect(() => {
|
|
950
1338
|
const ta = textareaRef.current;
|
|
951
|
-
if (!ta
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1339
|
+
if (!ta) return;
|
|
1340
|
+
if (ta.value !== value) {
|
|
1341
|
+
const { selectionStart, selectionEnd } = ta;
|
|
1342
|
+
ta.value = value;
|
|
1343
|
+
ta.selectionStart = selectionStart;
|
|
1344
|
+
ta.selectionEnd = selectionEnd;
|
|
1345
|
+
}
|
|
1346
|
+
autoResize();
|
|
1347
|
+
}, [value, autoResize]);
|
|
957
1348
|
const updateCursorInfo = react.useCallback(() => {
|
|
958
1349
|
const ta = textareaRef.current;
|
|
959
1350
|
if (!ta) return;
|
|
@@ -970,8 +1361,9 @@ function useEditorEngine({
|
|
|
970
1361
|
const ta = textareaRef.current;
|
|
971
1362
|
if (!ta) return;
|
|
972
1363
|
onChangeRef.current?.(ta.value);
|
|
1364
|
+
autoResize();
|
|
973
1365
|
updateCursorInfo();
|
|
974
|
-
}, [updateCursorInfo]);
|
|
1366
|
+
}, [autoResize, updateCursorInfo]);
|
|
975
1367
|
const handleSelect = react.useCallback(() => {
|
|
976
1368
|
updateCursorInfo();
|
|
977
1369
|
}, [updateCursorInfo]);
|
|
@@ -1031,6 +1423,7 @@ function useEditorEngine({
|
|
|
1031
1423
|
ta.selectionStart = ta.selectionEnd = start + tabSize;
|
|
1032
1424
|
onChangeRef.current?.(ta.value);
|
|
1033
1425
|
}
|
|
1426
|
+
autoResize();
|
|
1034
1427
|
updateCursorInfo();
|
|
1035
1428
|
return;
|
|
1036
1429
|
}
|
|
@@ -1049,11 +1442,12 @@ function useEditorEngine({
|
|
|
1049
1442
|
ta.value = before + insertion + after;
|
|
1050
1443
|
ta.selectionStart = ta.selectionEnd = start + insertion.length;
|
|
1051
1444
|
onChangeRef.current?.(ta.value);
|
|
1445
|
+
autoResize();
|
|
1052
1446
|
updateCursorInfo();
|
|
1053
1447
|
return;
|
|
1054
1448
|
}
|
|
1055
1449
|
},
|
|
1056
|
-
[readOnly, tabSize, updateCursorInfo]
|
|
1450
|
+
[readOnly, tabSize, autoResize, updateCursorInfo]
|
|
1057
1451
|
);
|
|
1058
1452
|
return {
|
|
1059
1453
|
textareaRef,
|