1
1
mirror of https://github.com/mawww/kakoune.git synced 2024-08-17 00:30:26 +03:00

Compare commits

...

21 Commits

Author SHA1 Message Date
nonumeros
3f20539999
Merge b1aa9946f0 into 80fcfebca8 2024-06-26 16:37:05 -05:00
Maxime Coste
80fcfebca8 Fix order of evaluation issue when compiling regex alternations
The previous implementation was relying on the left hand side of the
assignement's side effects to be sequenced before the right hand side
evaluation (so --split_pos was expected to have taken place)

This is actually counter to C++17 which guarantees evaluation of the
right hand side of the assignement first. For some reason this is
not the case with GCC on linux.
2024-06-26 22:38:01 +10:00
Maxime Coste
cbdd200e73 Fix corner case in passin arguments to grep and make 2024-06-26 20:35:34 +10:00
Maxime Coste
374a7a8c99 Remove some selection copies in pipe and throw early if read only
Throwing early avoids losing selections in this case.
2024-06-24 21:18:17 +10:00
Maxime Coste
6674fe7587 Merge remote-tracking branch 'stacyharper/elixir-heex' 2024-06-23 11:14:34 +10:00
Maxime Coste
4a00a6edea Fix trailing whitespaces 2024-06-23 11:03:50 +10:00
Tobias Pisani
6493ddad42 Allow individual show-whitespace options to be turned off
This is especially useful to use the indent guides without the  other
parameters, but in general it can be a useful option.

It could be worth considering cleaning up these options to default off instead, but
the default also seems useful, so i consider this ok, as it might be the more advanced
usecase.
2024-06-23 11:03:03 +10:00
Maxime Coste
880ad98a30 Add a -script switch to the fifo to cater for grep/make use cases
Avoid the brittle `exit; %arg{@}` trick
2024-06-22 17:02:54 +10:00
Willow Barraco
0bb355557e
elixir: detect heex additionaly to leex 2024-06-19 12:45:20 +02:00
Maxime Coste
ba504431dc Small code style tweak 2024-06-15 16:09:14 +10:00
Maxime Coste
c4684d0d84 Store instruction pointers directly in ThreadedRegexVM::Thread
The previous tradeoff of having a very small Thread struct is not
necessary anymore as we do not memcpy Threads on swap_next since
d708b77186.

This requires offsets to be used instead of indices for jump/split
ops.
2024-06-15 14:36:33 +10:00
Maxime Coste
c84942c2ac Add perf-annotate highlighting to perf.kak 2024-06-15 11:45:19 +10:00
Maxime Coste
700265b25d Bump cirrus CI linux_gcc memory to avoid OOM 2024-06-12 22:39:45 +10:00
Maxime Coste
8045712595 Bump cirrus CI freebsd to 13.3 2024-06-12 22:31:41 +10:00
Maxime Coste
966deb514e Add some static_asserts in SSO code 2024-06-12 20:18:00 +10:00
Maxime Coste
fe8f0f3371 Merge remote-tracking branch 'Icantjuddle/master' 2024-06-12 19:55:34 +10:00
Ben Judd
faf83b10e2 Switch to bitfield. 2024-06-11 08:33:35 -07:00
Ben Judd
9c185249a2 Fix build by moving include. 2024-06-07 17:54:06 -07:00
Ben Judd
2754e27cf2 Increase SSO from 22 to 23 chars. 2024-06-07 17:48:07 -07:00
ce
b1aa9946f0 highlighting missing,modified 2024-04-27 18:40:55 -04:00
ce
014f8ee55e mkiv lmtx syntax highlighting 2024-04-27 18:40:55 -04:00
20 changed files with 304 additions and 121 deletions

View File

@ -1,6 +1,6 @@
freebsd_task:
freebsd_instance:
image_family: freebsd-13-2
image_family: freebsd-13-3
matrix:
- name: freebsd_clang
env:
@ -27,6 +27,7 @@ linux_task:
- name: linux_gcc
container:
image: gcc:10
memory: 8G
env:
CXX: g++
test_script: make CXX=$CXX -j$(nproc) test

View File

@ -41,22 +41,27 @@ highlighter is replaced with the new one.
using the `Whitespace` face, with the following *options*:
*-lf* <separator>:::
a one character long separator that will replace line feeds
a one character long separator that will replace line feeds,
or an empty string to ignore them.
*-spc* <separator>:::
a one character long separator that will replace spaces
a one character long separator that will replace spaces,
or an empty string to ignore them.
*-nbsp* <separator>:::
a one character long separator that will replace non-breakable spaces
a one character long separator that will replace non-breakable spaces,
or an empty string to ignore them.
*-tab* <separator>:::
a one character long separator that will replace tabulations
a one character long separator that will replace tabulations,
or an empty string to ignore them.
*-tabpad* <separator>:::
a one character long separator that will be appended to tabulations to honor the *tabstop* option
*-indent* <separator>:::
a one character long separator that will replace the first space in indentation according to the *indentwidth* option
a one character long separator that will replace the first space in indentation
according to the *indentwidth* option, or an empty string to ignore them.
This will use the `WhitespaceIndent` face.
*-only-trailing*:::

90
rc/filetype/context.kak Normal file
View File

@ -0,0 +1,90 @@
# https://wiki.contextgarden.net/Main_Page
#
# Detection
# ‾‾‾‾‾‾‾‾‾
hook global BufCreate .*\.(mkiv) %{
set-option buffer filetype context
}
# Initialization
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook global WinSetOption filetype=context %(
require-module context
hook window InsertChar \n -group context-indent context-indent-on-new-line
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window context-indent }
)
hook -group context-highlight global WinSetOption filetype=context %{
add-highlighter window/context ref context
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/context }
}
provide-module context %{
# Highlighters
#‾‾‾‾‾‾‾‾‾‾‾‾
#
add-highlighter shared/context group
#add-highlighter shared/context default-region group
#
# Commands and control sequences for typesetting
# ‾‾‾‾‾‾‾‾‾‾‾‾
#add-highlighter shared/context/ regex '(\[\w+?=?\w+\])' 1:cyan 2:magenta 3:yellow
#add-highlighter shared/context/ regex '(\[?\w-*\w+\]|\[\w*-|\W)' 1:yellow 2:magenta 3:cyan
add-highlighter shared/context/ regex '(\[?\w*-*\w+\]|\[\w*-|\W?)' 1:yellow 2:magenta 3:cyan
#add-highlighter shared/context/ regex '(\[\w*\W?\w+\])' 1:yellow 2:magenta 3:cyan
#add-highlighter shared/context/ regex '(\w*|\W?\[?\W)' 1:cyan 2:yellow 3:magenta
add-highlighter shared/context/ regex '(\[file?:\w+\])' 1:value
add-highlighter shared/context/ regex '(\{\\em.*?\})' 1:+i
add-highlighter shared/context/ regex '(\{\\bf.*?\})' 1:+b
add-highlighter shared/context/ regex '(\{\\it.*?\})' 1:+i
add-highlighter shared/context/ regex '(\{\\bi.*?\})' 1:+ib
add-highlighter shared/context/ regex '(\{\\bs.*?\})' 1:+ib
add-highlighter shared/context/ regex '(\\overstrikes\{.*?\})' 1:+s
#for more information about the commands availability and/or implementation please read the ConTeXt documentation
#
add-highlighter shared/context/ regex '(\h*\\start*?\w-*|FLOATtext|FLOWcell|FLOWchart|FORMULAformula|JScode|JSpreamble|LUA|MP|MPclip|MPcode|MPdefinitions|MPenvironment|MPextensions|MPinclusions|MPinitializations|MPpage|MPpositiongraphic|MPpositionmethod|MPrun|PARSEDXML|TEX|TEXpage|XML|align|alignment|allmodes|appendices|asciimode|aside|attachment|attention|backgrounds|backmatter|bar|bbordermatrix|bitmapimage|blockquote|bodymatter|boxedcolumns|btxlabeltext|btxrenderingdefinitions|buffer|but|cases|catcodetable|centeraligned|chapter|characteralign|checkedfences|chemical|chemicaltext|collect|collecting|color|colorintent|coloronly|colorset|columns|columnset|columnsetspan|combination|comment|component|concept|contextcode|contextdefinitioncode|ctxfunction|ctxfunctiondefinition|currentcolor|currentlistentrywrapper|delimited|delimitedtext|displaymath|document|effect|element|embeddedxtable|endnote|enumerate|environment|exceptions|expanded|expandedcollect|extendedcatcodetable|externalfigurecollection|facingfloat|fact|figure|figuretext|fittingpage|fixed|floatcombination|font|fontclass|fontsolution|footnote|formula|formulas|framed|framedcell|framedcontent|framedrow|framedtable|framedtext|frontmatter|goto|graphictext|gridsnapping|hanging|hboxestohbox|hbregister|head|headtext|headtext|help|helptext|hiding|highlight|hyphenation|imath|indentedtext|interaction|interactionmenu|interface|intermezzotext|intertext|item|itemgroup|itemgroupcolumns|itemize|itemize|knockout|labeltext|language|layout|leftaligned|legend|linealignment|linecorrection|linefiller|linenote|linenumbering|lines|linetable|linetablebody|linetablecell|linetablehead|localfootnotes|localfootnotes|localheadsetup|locallinecorrection|localnotes|localsetups|luacode|luaparameterset|makeup|marginblock|marginrule|markedcontent|markedpages|math|mathalignment|mathcases|mathlabeltext|mathmatrix|mathmode|mathstyle|matrices|matrix|maxaligned|mdformula|midaligned|middlealigned|middlemakeup|mixedcolumns|mode|modeset|module|moduletestsection|mpformula|multicolumns|namedsection|namedsubformulas|narrow|narrower|negative|nicelyfilledbox|nointerference|notallmodes|note|notext|notmode|operatortext|opposite|outputstream|overlay|overprint|packed|pagecolumns|pagecomment|pagefigure|pagelayout|pagemakeup|par|paragraph|paragraphs|parbuilder|part|placechemical|placefigure|placefloat|placeformula|placegraphic|placeintermezzo|placelegend|placepairedbox|placetable|positioning|positionoverlay|postponing|prefixtext|processcommacommand|processcommalist|processesassignmentcommand|processesassignmentlist|product|project|protectedcolors|publication|quotation|quote|randomized|rawsetups|readingfile|regime|register|remark|reusableMPgraphic|reusableMPgraphic|rightaligned|ruby|script|sdformula|section|sectionblock|sectionblockenvironment|sectionlevel|setups|shift|sidebar|simplecolumns|specialitem|speech|splitformula|splittext|spread|standardmakeup|staticMPfigure|staticMPgraphic|strictinspectnextcharacter|structurepageregister|style|subformulas|subject|subjectlevel|subsection|subsentence|substack|subsubject|subsubsection|subsubsubject|subsubsubsection|suffixtext|symbolset|table|tabletext|tabulate|tabulatehead|tabulatetail|taglabeltext|texcode|texdefinition|text|textbackgrounds|textcolor|textcolorintent|textflow|textmakeup|textrule|textrule|thematrix|title|tokenlist|tokens|transparent|typescript|typescriptcollection|typing|uniqueMPgraphic|unittext|unpacked|usableMPgraphic|useMPgraphic|usemathstyleparameter|userdata|usingbtxspecification|vboxregister|vboxtohbox|vboxtohboxseparator|viewerlayer|vtopregister|xcell|xcolumn|xgroup|xmldisplayverbatim|xmlinlineverbatim|xmlraw|xmlsetups|xrow|xrowgroup|xtable|xtablebody|xtablefoot|xtablehead|xtablenext)' 1:meta
#add-highlighter shared/context/ regex '(\h*\\stop*?\w+)' 1:meta
add-highlighter shared/context/ regex '(\h*\\stop*?\w-*|FLOATtext|FLOWcell|FLOWchart|FORMULAformula|JScode|JSpreamble|LUA|MP|MPclip|MPcode|MPdefinitions|MPenvironment|MPextensions|MPinclusions|MPinitializations|MPpage|MPpositiongraphic|MPpositionmethod|MPrun|PARSEDXML|TEX|TEXpage|XML|align|alignment|allmodes|appendices|asciimode|aside|attachment|attention|backgrounds|backmatter|bar|bbordermatrix|bitmapimage|blockquote|bodymatter|boxedcolumns|btxlabeltext|btxrenderingdefinitions|buffer|but|cases|catcodetable|centeraligned|chapter|characteralign|checkedfences|chemical|chemicaltext|collect|collecting|color|colorintent|coloronly|colorset|columns|columnset|columnsetspan|combination|comment|component|concept|contextcode|contextdefinitioncode|ctxfunction|ctxfunctiondefinition|currentcolor|currentlistentrywrapper|delimited|delimitedtext|displaymath|document|effect|element|embeddedxtable|endnote|enumerate|environment|exceptions|expanded|expandedcollect|extendedcatcodetable|externalfigurecollection|facingfloat|fact|figure|figuretext|fittingpage|fixed|floatcombination|font|fontclass|fontsolution|footnote|formula|formulas|framed|framedcell|framedcontent|framedrow|framedtable|framedtext|frontmatter|goto|graphictext|gridsnapping|hanging|hboxestohbox|hbregister|head|headtext|headtext|help|helptext|hiding|highlight|hyphenation|imath|indentedtext|interaction|interactionmenu|interface|intermezzotext|intertext|item|itemgroup|itemgroupcolumns|itemize|itemize|knockout|labeltext|language|layout|leftaligned|legend|linealignment|linecorrection|linefiller|linenote|linenumbering|lines|linetable|linetablebody|linetablecell|linetablehead|localfootnotes|localfootnotes|localheadsetup|locallinecorrection|localnotes|localsetups|luacode|luaparameterset|makeup|marginblock|marginrule|markedcontent|markedpages|math|mathalignment|mathcases|mathlabeltext|mathmatrix|mathmode|mathstyle|matrices|matrix|maxaligned|mdformula|midaligned|middlealigned|middlemakeup|mixedcolumns|mode|modeset|module|moduletestsection|mpformula|multicolumns|namedsection|namedsubformulas|narrow|narrower|negative|nicelyfilledbox|nointerference|notallmodes|note|notext|notmode|operatortext|opposite|outputstream|overlay|overprint|packed|pagecolumns|pagecomment|pagefigure|pagelayout|pagemakeup|par|paragraph|paragraphs|parbuilder|part|placechemical|placefigure|placefloat|placeformula|placegraphic|placeintermezzo|placelegend|placepairedbox|placetable|positioning|positionoverlay|postponing|prefixtext|processcommacommand|processcommalist|processesassignmentcommand|processesassignmentlist|product|project|protectedcolors|publication|quotation|quote|randomized|rawsetups|readingfile|regime|register|remark|reusableMPgraphic|reusableMPgraphic|rightaligned|ruby|script|sdformula|section|sectionblock|sectionblockenvironment|sectionlevel|setups|shift|sidebar|simplecolumns|specialitem|speech|splitformula|splittext|spread|standardmakeup|staticMPfigure|staticMPgraphic|strictinspectnextcharacter|structurepageregister|style|subformulas|subject|subjectlevel|subsection|subsentence|substack|subsubject|subsubsection|subsubsubject|subsubsubsection|suffixtext|symbolset|table|tabletext|tabulate|tabulatehead|tabulatetail|taglabeltext|texcode|texdefinition|text|textbackgrounds|textcolor|textcolorintent|textflow|textmakeup|textrule|textrule|thematrix|title|tokenlist|tokens|transparent|typescript|typescriptcollection|typing|uniqueMPgraphic|unittext|unpacked|usableMPgraphic|useMPgraphic|usemathstyleparameter|userdata|usingbtxspecification|vboxregister|vboxtohbox|vboxtohboxseparator|viewerlayer|vtopregister|xcell|xcolumn|xgroup|xmldisplayverbatim|xmlinlineverbatim|xmlraw|xmlsetups|xrow|xrowgroup|xtable|xtablebody|xtablefoot|xtablehead|xtablenext)' 1:meta
add-highlighter shared/context/ regex '(\h*\\define*?\w-*|accent|activecharacter|alternativestyle|anchor|attachment|attribute|background|bar|block|bodyfont|bodyfontenvironment|bodyfontswitch|bodyfont|breakpoint|breakpoints|btx|btxdataset|btxregister|btxrendering|buffer|button|capitals|character|characterkerning|characterspacing|chemical|chemicals|chemicalsymbol|collector|color|colorgroup|color|columnbreak|columnset|columnsetarea|columnsetspan|combination|combinedlist|command|comment|complexorsimple|complexorsimpleempty|complexorsimpleempty|complexorsimple|conversion|conversionset|conversion|counter|dataset|date|delimitedtext|description|dfont|document|effect|enumeration|expandable|expansion|externalfigure|face|facingfloat|fallbackfamily|fallbackfamily|field|fieldbody|fieldbodyset|fieldcategory|fieldstack|figuresymbol|fileconstant|filefallback|filesynonym|filler|firstline|fittingpage|float|float|font|fontalternative|fontfallback|fontfamily|fontfamilypreset|fontfamily|fontfamilypreset|fontfamily|fontfeature|fontfile|fontsize|fontsolution|fontstyle|fontsynonym|font|formula|formulaalternative|formulaframed|framed|framedcontent|framedtable|framedtext|frozenfont|globalcolor|color|globalcolor|graphictypesynonym|gridsnapping|hbox|head|headalternative|help|high|highlight|hspace|hyphenationfeatures|indentedtext|indenting|initial|insertion|interaction|interactionbar|interactionmenu|interfaceconstant|interfaceelement|interfacevariable|interlinespace|intermediatecolor|itemgroup|items|label|labelclass|layer|layerpreset|layerpreset|layout|linefiller|linenote|linenumbering|lines|list|listalternative|listextra|low|lowhigh|lowmidhigh|MPinstance|makeup|marginblock|margindata|marker|marking|mathaccent|mathalignment|mathcases|mathcommand|mathdouble|mathdoubleextensible|mathematics|mathextensible|mathfence|mathfraction|mathframed|mathmatrix|mathornament|mathover|mathoverextensible|mathovertextextensible|mathradical|mathstackers|mathstyle|mathtriplet|mathunder|mathunderextensible|mathundertextextensible|mathunstacked|measure|messageconstant|mixedcolumns|mode|multicolumns|multitonecolor|color|spotcolor|namedcolor|color|namedcolor|namespace|narrower|note|orientation|ornament|ornament|outputroutine|outputroutinecommand|overlay|page|pagebreak|pagechecker|pagecolumns|pageinjection|pageinjectionalternative|pageshift|pagestate|pairedbox|palet|palet|papersize|papersize|paragraph|paragraphs|parallel|parbuilder|periodkerning|placeholder|placement|positioning|prefixset|processcolor|color|processor|profile|program|pushbutton|pushsymbol|reference|referenceformat|register|renderingwindow|resetset|ruby|scale|script|section|sectionblock|sectionlevels|selector|separatorset|shift|sidebar|sort|sorting|spotcolor|startstop|style|styleinstance|subfield|subformula|symbol|synonym|synonyms|systemattribute|systemconstant|systemvariable|TABLEsetup|tabletemplate|tabulate|text|textbackground|textflow|textnote|tokenlist|tooltip|transparency|transparency|transparency|twopasslist|type|typeface|typescriptprefix|typescriptsynonym|typesetting|typing|unit|userdata|userdataalternative|viewerlayer|vspace|vspacing|vspacingamount|xtable|color|gridsnapping|bodyfontenvironment)' 1:meta
add-highlighter shared/context/ regex '(\h*\\setup*?\w-*|MPinstance|TABLE|align|attachment|background|backgroundOPT|bar|blackrules|bleeding|block|bodyfont|bookmark|btx|btxdataset|btxregister|btxrendering|buffer|button|capitals|caption|characteralign|characterkerning|chemical|clipping|collector|columnset|columnsetarea|columnsetspan|combination|combinedlist|combinedlistOPT|comment|counter|dataset|delimitedtext|description|document|effect|enumeration|expansion|externalfigure|facingfloat|fieldbody|fieldcategory|fieldcontentframed|fieldlabelframed|fieldtotalframed|filler|fillinlines|fillinrules|firstline|fittingpage|fittingpageOPT|float|floatsplitting|fontsolution|formula|formulaframed|framed|framedcontent|framedtext|head|headalternative|help|high|highlight|indentedtext|indenting|initial|insertion|interaction|interactionbar|interactionbarOPT|interactionmenu|interlinespace|itemgroup|items|label|language|layer|layerOPT|layeredtext|layout|linefiller|linenote|linenumbering|lines|linetable|list|listalternative|listextra|low|lowhigh|lowmidhigh|makeup|marginblock|margindata|marginframed|marginrule|marginruleOPT|marking|mathalignment|mathcases|mathematics|mathfence|mathfraction|mathframed|mathmatrix|mathmatrixOPT|mathornament|mathradical|mathstackers|mixedcolumns|mixedcolumnsOPT|multicolumns|multicolumnsOPT|narrower|notation|note|offset|offsetbox|orientation|outputroutine|pagechecker|pagecolumns|pagecolumnsOPT|pageinjection|pageinjectionalternative|pagestate|pairedbox|papersize|paragraph|paragraphs|parallel|periodkerning|periods|placeholder|placement|positionbar|positioning|processor|profile|referenceformat|register|renderingwindow|rotate|ruby|scale|script|sectionblock|selector|shift|sidebar|sorting|startstop|stretched|style|subformula|synonyms|tables|tabulate|textbackground|textflow|textnote|thinrules|tolerance|tooltip|type|typing|unit|userdata|userdataalternative|viewerlayer|xtable|xtableOPT)' 1:meta
add-highlighter shared/context/ regex '(\h*\\use*?\w-*|typescript)' 1:meta
#add-highlighter shared/context/ regex '(^\\start\.*|chapter|section|subsection|subsubsection|paragraph|tabulate|itemize|enumerate|formula|columns|table|quotation|textbackgrounds|backgrounds)' 1:green
#
#add-highlighter shared/context/ regex '(^\\stop\.*|chapter|section|subsection|subsubsection|paragraph|tabulate|itemize|enumerate|formula|columns|table|quotation|textbackgrounds|backgrounds)' 1:green
#detection of any % comment string including followed by a command
add-highlighter shared/context/ regex '(\B\h*%.*?$)' 1:comment
#indentation
#
define-command -hidden context-indent-on-new-line %{
evaluate-commands -draft -itersel %{
try %{ execute-keys -draft <semicolon>K<a-&> }
try %{ execute-keys -draft kxs(\[.*\])<esc>"ay}
try %{ execute-keys -draft Z kx <a-k>(^\h*([^\n]+)\])<ret> z i<tab> <esc> <c-r><a><c-r><a><esc>}
#The following was the tricky part,without additional registers or an if then clause regex, for the simple reason that unlike TeX derivatives such as LaTeX in which groups are defined within \{ and \} respectively and its optional arguments' counterparts are enclosed within \[ and \], in ConTeXt however, brackets are used for both optional and mandatory arguments. So the key element here is to reverse the order, for the selection to reflect it, and it doesn't matter really whether \stop precedes \start or whether the input will attempt to modify it.
try %{ execute-keys -draft Z jxs (^\h*\\start)<ret> d <esc> i \stop <esc>}
# No need to close define group. It inherits most arguments from setup. if setup is needed then presumably the same method applies as here save the arguments that follow as it applies to the rest
try %{ execute-keys -draft Z jxs (^\h*\\define\.*[^\[.*\]\n]+)<ret> d<esc>}
try %{ execute-keys -draft Z jxs (^\h*\\setup\.*[^\[.*\]\n]+)<ret> d<esc>}
# removing trailing \[ \] after the groups/environments so is not processed by the engine
try %{ execute-keys -draft Z jxs (\h*\[.*\])<ret> d <esc> i <esc>}
}
}
}

View File

@ -8,7 +8,7 @@ hook global BufCreate .*[.](ex|exs) %{
set-option buffer filetype elixir
}
hook global BufCreate .*[.]html[.]l?eex %{
hook global BufCreate .*[.]html[.][lh]?eex %{
set-option buffer filetype eex
}
@ -64,6 +64,7 @@ add-highlighter shared/elixir/single_string region "'" "(?<!\\)(?:\\\\)*'" fill
add-highlighter shared/elixir/comment region '#' '$' fill comment
add-highlighter shared/elixir/leex region -match-capture '~L("""|")' '(?<!\\)(?:\\\\)*("""|")' ref eex
add-highlighter shared/elixir/heex region -match-capture '~H("""|")' '(?<!\\)(?:\\\\)*("""|")' ref eex
add-highlighter shared/elixir/double_string/base default-region fill string
add-highlighter shared/elixir/double_string/interpolation region -recurse \{ \Q#{ \} fill builtin

View File

@ -16,3 +16,17 @@ hook -group perf-report-highlight global WinSetOption filetype=perf-report %{
map window normal <ret> ': perf-report-focus<ret>'
}
provide-module perf-annotate %{
require-module gas
add-highlighter shared/perf-annotate group
add-highlighter shared/perf-annotate/gas ref gas
add-highlighter shared/perf-annotate/above_threshold regex '^\h+([1-9]|\d{2})\.\d+\b' 0:red
add-highlighter shared/perf-annotate/below_threshold regex '^\h+0\.\d+\b' 0:green
}
hook -group perf-annotate-highlight global WinSetOption filetype=perf-annotate %{
require-module perf-annotate
add-highlighter window/perf-annotate ref perf-annotate
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/perf-annotate }
}

View File

@ -1,12 +1,14 @@
provide-module fifo %{
define-command -params .. -docstring %{
fifo [-name <buffer-name>] [-scroll] [--] <command>...: run command in a fifo buffer
fifo [-name <name>] [-scroll] [-script <script>] [--] <args>...: run command in a fifo buffer
if <script> is used, eval it with <args> as '$@', else pass arguments directly to the shell
} fifo %{ evaluate-commands %sh{
name='*fifo*'
while true; do
case "$1" in
"-scroll") scroll="-scroll"; shift ;;
"-script") script="$2"; shift 2 ;;
"-name") name="$2"; shift 2 ;;
"--") shift; break ;;
*) break ;;
@ -14,7 +16,11 @@ define-command -params .. -docstring %{
done
output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-fifo.XXXXXXXX)/fifo
mkfifo ${output}
( eval "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
if [ -n "$script" ]; then
( eval "$script" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
else
( "$@" > ${output} 2>&1 & ) > /dev/null 2>&1 < /dev/null
fi
printf %s\\n "
edit! -fifo ${output} ${scroll} ${name}

View File

@ -12,8 +12,7 @@ define-command -params .. -docstring %{
Passing no argument will perform a literal-string grep for the current selection
} grep %{
evaluate-commands -try-client %opt{toolsclient} %{
fifo -name *grep* %{
shift 2
fifo -name *grep* -script %{
trap - INT QUIT
if [ $# -eq 0 ]; then
case "$kak_opt_grepcmd" in
@ -29,7 +28,7 @@ define-command -params .. -docstring %{
esac
fi
$kak_opt_grepcmd "$@" 2>&1 | tr -d '\r'
} 'exit;' %arg{@} # pass arguments for "$@" above, exit to avoid evaluating them
} -- %arg{@}
set-option buffer filetype grep
set-option buffer jump_current_line 0
}

View File

@ -13,11 +13,10 @@ define-command -params .. -docstring %{
All the optional arguments are forwarded to the make utility
} make %{
evaluate-commands -try-client %opt{toolsclient} %{
fifo -scroll -name *make* %{
shift 2
fifo -scroll -name *make* -script %{
trap - INT QUIT
$kak_opt_makecmd "$@"
} 'exit;' %arg{@} # pass arguments for "$@" above, exit to avoid evaluating them
} -- %arg{@}
set-option buffer filetype make
set-option buffer jump_current_line 0
}

View File

@ -424,7 +424,7 @@ StringView Context::main_sel_register_value(StringView reg) const
return RegisterManager::instance()[reg].get_main(*this, index);
}
void Context::set_name(String name) {
void Context::set_name(String name) {
String old_name = std::exchange(m_name, std::move(name));
hooks().run_hook(Hook::ClientRenamed, format("{}:{}", old_name, m_name), *this);
}

View File

@ -239,7 +239,7 @@ struct HashMap
constexpr bool contains(const KeyType& key) const { return find_index(key) >= 0; }
template<typename KeyType> requires IsHashCompatible<Key, std::remove_cvref_t<KeyType>>
constexpr EffectiveValue& operator[](KeyType&& key)
constexpr EffectiveValue& operator[](KeyType&& key)
{
const auto hash = hash_value(key);
auto index = find_index(key, hash);

View File

@ -981,18 +981,14 @@ struct ShowWhitespacesHighlighter : Highlighter
bool only_trailing = (bool) parser.get_switch("only-trailing");
auto get_param = [&](StringView param, StringView fallback) {
StringView value = parser.get_switch(param).value_or(fallback);
if (value.char_length() != 1)
throw runtime_error{format("-{} expects a single character parameter", param)};
if (value.char_length() > 1)
throw runtime_error{format("-{} expects a single character or empty parameter", param)};
return value.str();
};
String indent = parser.get_switch("indent").value_or("").str();
if (indent.char_length() > 1)
throw runtime_error{format("-indent expects a single character or empty parameter")};
return std::make_unique<ShowWhitespacesHighlighter>(
get_param("tab", ""), get_param("tabpad", " "), get_param("spc", "·"),
get_param("lf", "¬"), get_param("nbsp", ""), indent, only_trailing);
get_param("lf", "¬"), get_param("nbsp", ""), get_param("indent", ""), only_trailing);
}
private:
@ -1043,28 +1039,28 @@ private:
if (it != end)
atom_it = line.split(atom_it, it.coord());
if (cp == '\t')
if (cp == '\t' and not m_tab.empty() and not m_tabpad.empty())
{
const ColumnCount column = get_column(buffer, tabstop, coord);
const ColumnCount count = tabstop - (column % tabstop);
atom_it->replace(m_tab + String(m_tabpad[(CharCount)0], count - m_tab.column_length()));
}
else if (cp == ' ') {
if (m_indent.empty() or indentwidth == 0 or not is_indentation) {
else if (cp == ' ' and is_indentation and indentwidth > 0 and not m_indent.empty()) {
const ColumnCount column = get_column(buffer, tabstop, coord);
if (column % indentwidth == 0 and column != 0) {
atom_it->replace(m_indent);
face = indentface;
}
else {
atom_it->replace(m_spc);
} else {
const ColumnCount column = get_column(buffer, tabstop, coord);
if (column % indentwidth == 0 and column != 0) {
atom_it->replace(m_indent);
face = indentface;
} else {
atom_it->replace(m_spc);
}
}
}
else if (cp == '\n')
else if (cp == ' ' and not m_spc.empty()) {
atom_it->replace(m_spc);
}
else if (cp == '\n' and not m_lf.empty())
atom_it->replace(m_lf);
else if (cp == 0xA0 or cp == 0x202F)
else if ((cp == 0xA0 or cp == 0x202F) and not m_nbsp.empty())
atom_it->replace(m_nbsp);
atom_it->face = merge_faces(atom_it->face, face);
break;

View File

@ -589,13 +589,13 @@ void pipe(Context& context, NormalParams params)
return;
Buffer& buffer = context.buffer();
SelectionList selections = context.selections();
if (replace)
{
buffer.throw_if_read_only();
ScopedEdition edition(context);
ForwardChangesTracker changes_tracker;
size_t timestamp = buffer.timestamp();
Vector<Selection> new_sels;
SelectionList selections = context.selections();
for (auto& sel : selections)
{
const auto beg = changes_tracker.get_new_coord_tolerant(sel.min());
@ -614,20 +614,27 @@ void pipe(Context& context, NormalParams params)
auto new_end = apply_diff(buffer, beg, in, out);
if (new_end != beg)
new_sels.push_back(keep_direction({beg, buffer.char_prev(new_end), std::move(sel.captures())}, sel));
{
auto& min = sel.min();
auto& max = sel.max();
min = beg;
max = buffer.char_prev(new_end);
}
else
{
if (new_end != BufferCoord{})
new_end = buffer.char_prev(new_end);
new_sels.push_back({new_end, new_end, std::move(sel.captures())});
sel.set(new_end);
}
changes_tracker.update(buffer, timestamp);
}
context.selections_write_only().set(std::move(new_sels), selections.main_index());
selections.force_timestamp(timestamp);
context.selections_write_only() = std::move(selections);
}
else
{
SelectionList& selections = context.selections();
const auto old_main = selections.main_index();
for (int i = 0; i < selections.size(); ++i)
{

View File

@ -706,7 +706,7 @@ private:
{
auto& node = get_node(index);
const uint32_t start_pos = (uint32_t)m_program.instructions.size();
const OpIndex start_pos = op_count();
const bool ignore_case = node.ignore_case;
const bool save = (node.op == ParsedRegex::Alternation or node.op == ParsedRegex::Sequence) and
@ -746,14 +746,17 @@ private:
if (child != index+1)
push_inst(CompiledRegex::Split);
}
auto split_pos = m_program.instructions.size();
auto split_pos = op_count();
const auto end = node.children_end;
for (auto child : Children<>{m_parsed_regex, index})
{
auto node = compile_node<direction>(child);
if (child != index+1)
m_program.instructions[--split_pos].param.split = CompiledRegex::Param::Split{.target = node, .prioritize_parent = true};
{
--split_pos;
m_program.instructions[split_pos].param.split = {.offset = offset(node, split_pos), .prioritize_parent = true};
}
if (get_node(child).children_end != end)
{
auto jump = push_inst(CompiledRegex::Jump);
@ -801,8 +804,8 @@ private:
break;
}
for (auto& offset : goto_inner_end_offsets)
m_program.instructions[offset].param.jump_target = m_program.instructions.size();
for (auto& index : goto_inner_end_offsets)
m_program.instructions[index].param.jump_offset = offset(op_count(), index);
if (save)
push_inst(CompiledRegex::Save, {.save_index=int16_t(node.value * 2 + (forward ? 1 : 0))});
@ -810,19 +813,29 @@ private:
return start_pos;
}
OpIndex op_count() const
{
return static_cast<OpIndex>(m_program.instructions.size());
}
static OpIndex offset(OpIndex to, OpIndex from)
{
return static_cast<OpIndex>(to - from);
}
template<RegexMode direction>
OpIndex compile_node(ParsedRegex::NodeIndex index)
{
auto& node = get_node(index);
const OpIndex start_pos = (OpIndex)m_program.instructions.size();
const OpIndex start_pos = op_count();
Vector<OpIndex> goto_ends;
auto& quantifier = node.quantifier;
if (quantifier.allows_none())
{
auto split_pos = push_inst(CompiledRegex::Split, {.split={.target=0, .prioritize_parent=quantifier.greedy}});
auto split_pos = push_inst(CompiledRegex::Split, {.split={.offset=0, .prioritize_parent=quantifier.greedy}});
goto_ends.push_back(split_pos);
}
@ -832,18 +845,18 @@ private:
inner_pos = compile_node_inner<direction>(index);
if (quantifier.allows_infinite_repeat())
push_inst(CompiledRegex::Split, {.split = {.target=inner_pos, .prioritize_parent=not quantifier.greedy}});
push_inst(CompiledRegex::Split, {.split = {.offset=offset(inner_pos, op_count()), .prioritize_parent=not quantifier.greedy}});
// Write the node as an optional match for the min -> max counts
else for (int i = std::max((int16_t)1, quantifier.min); // STILL UGLY !
i < quantifier.max; ++i)
{
auto split_pos = push_inst(CompiledRegex::Split, {.split={.target=0, .prioritize_parent=quantifier.greedy}});
auto split_pos = push_inst(CompiledRegex::Split, {.split={.offset=0, .prioritize_parent=quantifier.greedy}});
goto_ends.push_back(split_pos);
compile_node_inner<direction>(index);
}
for (auto offset : goto_ends)
m_program.instructions[offset].param.split.target = m_program.instructions.size();
for (auto index : goto_ends)
m_program.instructions[index].param.split.offset = offset(op_count(), index);
return start_pos;
}
@ -851,7 +864,7 @@ private:
OpIndex push_inst(CompiledRegex::Op op, CompiledRegex::Param param = {})
{
constexpr auto max_instructions = std::numeric_limits<OpIndex>::max();
const auto res = m_program.instructions.size();
const auto res = op_count();
if (res >= max_instructions)
throw regex_error(format("regex compiled to more than {} instructions", max_instructions));
m_program.instructions.push_back({ op, 0, param });
@ -1031,7 +1044,7 @@ private:
{
auto& inst = m_program.instructions[i];
if (is_jump(inst.op))
m_program.instructions[inst.param.jump_target].last_step = 0xffff; // tag as jump target
m_program.instructions[i + inst.param.jump_offset].last_step = 0xffff; // tag as jump target
}
for (auto block_begin = begin; block_begin < end; )
@ -1071,11 +1084,11 @@ private:
String dump_regex(const CompiledRegex& program)
{
String res;
int count = 0;
int index = 0;
for (auto& inst : program.instructions)
{
char buf[20];
format_to(buf, " {:03} ", count++);
format_to(buf, " {:03} ", index);
res += buf;
switch (inst.op)
{
@ -1095,13 +1108,13 @@ String dump_regex(const CompiledRegex& program)
res += format("character type {}\n", to_underlying(inst.param.character_type));
break;
case CompiledRegex::Jump:
res += format("jump {}\n", inst.param.jump_target);
res += format("jump {} ({:03})\n", inst.param.jump_offset, index + inst.param.jump_offset);
break;
case CompiledRegex::Split:
{
res += format("split (prioritize {}) {}\n",
res += format("split (prioritize {}) {} ({:03})\n",
(inst.param.split.prioritize_parent) ? "parent" : "child",
inst.param.split.target);
inst.param.split.offset, index + inst.param.split.offset);
break;
}
case CompiledRegex::Save:
@ -1135,6 +1148,7 @@ String dump_regex(const CompiledRegex& program)
case CompiledRegex::Match:
res += "match\n";
}
++index;
}
auto dump_start_desc = [&](const CompiledRegex::StartDesc& desc, StringView name) {
res += name + " start desc: [";

View File

@ -54,11 +54,11 @@ struct CharacterClass
if (ignore_case)
cp = to_lower(cp);
for (auto& range : ranges)
for (auto& [min, max] : ranges)
{
if (cp < range.min)
if (cp < min)
break;
else if (cp <= range.max)
else if (cp <= max)
return not negative;
}
@ -106,11 +106,11 @@ struct CompiledRegex : UseMemoryDomain<MemoryDomain::Regex>
} literal;
int16_t character_class_index;
CharacterType character_type;
int16_t jump_target;
int16_t jump_offset;
int16_t save_index;
struct Split
{
int16_t target;
int16_t offset;
bool prioritize_parent : 1;
} split;
bool line_start;
@ -351,10 +351,10 @@ private:
--saves.refcount;
};
struct alignas(int32_t) Thread
struct Thread
{
int16_t inst;
int16_t saves;
const CompiledRegex::Instruction* inst;
int saves;
};
using StartDesc = CompiledRegex::StartDesc;
@ -370,8 +370,7 @@ private:
// Steps a thread until it consumes the current character, matches or fail
[[gnu::always_inline]]
void step_thread(const CompiledRegex::Instruction* instructions, const Iterator& pos, Codepoint cp,
uint16_t current_step, Thread thread, const ExecConfig& config)
void step_thread(const Iterator& pos, Codepoint cp, uint16_t current_step, Thread thread, const ExecConfig& config)
{
auto failed = [this, &thread]() {
release_saves(thread.saves);
@ -382,7 +381,7 @@ private:
while (true)
{
auto& inst = instructions[thread.inst++];
auto& inst = *thread.inst++;
// if this instruction was already executed for this step in another thread,
// then this thread is redundant and can be dropped
if (inst.last_step == current_step)
@ -416,19 +415,20 @@ private:
return consumed();
return failed();
case CompiledRegex::CharClass:
if (pos == config.end)
return failed();
return m_program.character_classes[inst.param.character_class_index].matches(cp) ? consumed() : failed();
if (pos != config.end and
m_program.character_classes[inst.param.character_class_index].matches(cp))
return consumed();
return failed();
case CompiledRegex::CharType:
if (pos == config.end)
return failed();
return is_ctype(inst.param.character_type, cp) ? consumed() : failed();
if (pos != config.end and is_ctype(inst.param.character_type, cp))
return consumed();
return failed();
case CompiledRegex::Jump:
thread.inst = inst.param.jump_target;
thread.inst = &inst + inst.param.jump_offset;
break;
case CompiledRegex::Split:
if (auto target = inst.param.split.target;
instructions[target].last_step != current_step)
if (auto* target = &inst + inst.param.split.offset;
target->last_step != current_step)
{
if (thread.saves >= 0)
++m_saves[thread.saves].refcount;
@ -478,7 +478,8 @@ private:
m_captures = -1;
m_threads.ensure_initial_capacity();
const int16_t first_inst = forward ? 0 : m_program.first_backward_inst;
ConstArrayView<CompiledRegex::Instruction> insts{m_program.instructions};
const auto* first_inst = insts.begin() + (forward ? 0 : m_program.first_backward_inst);
m_threads.push_current({first_inst, -1});
const auto* start_desc = (forward ? m_program.forward_start_desc : m_program.backward_start_desc).get();
@ -486,7 +487,6 @@ private:
constexpr bool search = mode & RegexMode::Search;
constexpr bool any_match = mode & RegexMode::AnyMatch;
ConstArrayView<CompiledRegex::Instruction> insts{m_program.instructions};
uint16_t current_step = -1;
m_found_match = false;
while (true) // Iterate on all codepoints and once at the end
@ -506,7 +506,7 @@ private:
Codepoint cp = codepoint(next, config);
while (not m_threads.current_is_empty())
step_thread(insts.pointer(), pos, cp, current_step, m_threads.pop_current(), config);
step_thread(pos, cp, current_step, m_threads.pop_current(), config);
if (pos == config.end or
(m_threads.next_is_empty() and (not search or m_found_match)) or

View File

@ -40,7 +40,7 @@ void HistoryRegister::set(Context& context, ConstArrayView<String> values, bool
return;
}
for (auto&& entry : values | reverse())
for (auto&& entry : values | reverse())
{
m_content.erase(std::remove(m_content.begin(), m_content.end(), entry), m_content.end());
m_content.insert(m_content.begin(), entry);

View File

@ -1,22 +1,27 @@
#include "string.hh"
#include <cstdio>
#include <cstring>
#include "assert.hh"
#include "unit_tests.hh"
namespace Kakoune
{
namespace
{
// Avoid including all of <algorithm> just for this.
constexpr auto max(auto lhs, auto rhs) { return lhs > rhs ? lhs : rhs;}
constexpr auto min(auto lhs, auto rhs) { return lhs < rhs ? lhs : rhs;}
}
String::Data::Data(const char* data, size_t size, size_t capacity)
{
if (capacity > Short::capacity)
{
if (capacity & 1)
++capacity;
kak_assert(capacity < Long::max_capacity);
kak_assert(capacity <= Long::max_capacity);
u.l.ptr = Alloc{}.allocate(capacity+1);
u.l.size = size;
u.l.capacity = capacity;
u.l.capacity = (capacity & Long::max_capacity);
u.l.mode = Long::active_mask;
if (data != nullptr)
memcpy(u.l.ptr, data, size);
@ -60,26 +65,28 @@ String::Data& String::Data::operator=(Data&& other) noexcept
template<bool copy>
void String::Data::reserve(size_t new_capacity)
{
if (capacity() != 0 and new_capacity <= capacity())
auto const current_capacity = capacity();
if (current_capacity != 0 and new_capacity <= current_capacity)
return;
if (is_long())
new_capacity = std::max(u.l.capacity * 2, new_capacity);
if (!is_long() and new_capacity <= Short::capacity)
return;
if (new_capacity & 1)
++new_capacity;
kak_assert(new_capacity <= Long::max_capacity);
new_capacity = max(new_capacity, // Do not upgrade new_capacity to be over limit.
min(current_capacity * 2, Long::max_capacity));
kak_assert(new_capacity < Long::max_capacity);
char* new_ptr = Alloc{}.allocate(new_capacity+1);
if (copy)
{
memcpy(new_ptr, data(), size()+1);
u.l.size = size();
}
release();
u.l.size = size();
u.l.ptr = new_ptr;
u.l.capacity = new_capacity;
u.l.capacity = (new_capacity & Long::max_capacity);
u.l.mode = Long::active_mask;
}
template void String::Data::reserve<true>(size_t);
@ -89,6 +96,7 @@ void String::Data::force_size(size_t new_size)
{
reserve<false>(new_size);
set_size(new_size);
data()[new_size] = 0;
}
void String::Data::append(const char* str, size_t len)
@ -131,17 +139,47 @@ void String::Data::set_size(size_t size)
if (is_long())
u.l.size = size;
else
u.s.size = (size << 1) | 1;
u.s.remaining_size = Short::capacity - size;
}
void String::Data::set_short(const char* data, size_t size)
{
u.s.size = (size << 1) | 1;
kak_assert(size <= Short::capacity);
u.s.remaining_size = Short::capacity - size;
if (data != nullptr)
memcpy(u.s.string, data, size);
u.s.string[size] = 0;
}
UnitTest test_data{[]{
using Data = String::Data;
{ // Basic data usage.
Data data;
kak_assert(data.size() == 0);
kak_assert(not data.is_long());
kak_assert(data.capacity() == 23);
// Should be SSO-ed.
data.append("test", 4);
kak_assert(data.size() == 4);
kak_assert(data.capacity() == 23);
kak_assert(not data.is_long());
kak_assert(data.data() == StringView("test"));
}
{
char large_buf[2048];
memset(large_buf, 'x', 2048);
Data data(large_buf, 2048);
kak_assert(data.size() == 2048);
kak_assert(data.capacity() >= 2048);
data.clear();
kak_assert(data.size() == 0);
kak_assert(not data.is_long());
kak_assert(data.capacity() == 23);
}
}};
const String String::ms_empty;
}

View File

@ -1,12 +1,13 @@
#ifndef string_hh_INCLUDED
#define string_hh_INCLUDED
#include <climits>
#include <cstddef>
#include "memory.hh"
#include "hash.hh"
#include "units.hh"
#include "utf8.hh"
#include <climits>
namespace Kakoune
{
@ -156,17 +157,22 @@ public:
// String data storage using small string optimization.
//
// the LSB of the last byte is used to flag if we are using the small buffer
// or an allocated one. On big endian systems that means the allocated
// capacity must be pair, on little endian systems that means the allocated
// capacity cannot use its most significant byte, so we effectively limit
// capacity to 2^24 on 32bit arch, and 2^60 on 64.
// The MSB of the last byte is used to flag if we are using the allocated buffer
// (1) or in-situ storage, the small one (0). That means the allocated capacity
// cannot use its most significant byte, so we effectively limit capacity to
// 2^24 on 32bit arch, and 2^56 on 64bit.
//
// There is also a special NoCopy mode in which the data referred to is un-owned.
// It is indicated by being in Long mode with capacity == 0.
struct Data
{
using Alloc = Allocator<char, MemoryDomain::String>;
Data() { set_empty(); }
Data(NoCopy, const char* data, size_t size) : u{Long{const_cast<char*>(data), size, 0}} {}
Data(NoCopy, const char* data, size_t size) : u{Long{const_cast<char*>(data),
size,
/*capacity=*/0,
/*mode=*/Long::active_mask}} {}
Data(const char* data, size_t size, size_t capacity);
Data(const char* data, size_t size) : Data(data, size, size) {}
@ -177,8 +183,8 @@ public:
Data& operator=(const Data& other);
Data& operator=(Data&& other) noexcept;
bool is_long() const { return (u.s.size & 1) == 0; }
size_t size() const { return is_long() ? u.l.size : (u.s.size >> 1); }
bool is_long() const { return (u.l.mode& Long::active_mask) > 0; }
size_t size() const { return is_long() ? u.l.size : (Short::capacity - u.s.remaining_size); }
size_t capacity() const { return is_long() ? u.l.capacity : Short::capacity; }
const char* data() const { return is_long() ? u.l.ptr : u.s.string; }
@ -194,20 +200,27 @@ public:
private:
struct Long
{
static constexpr size_t max_capacity =
(size_t)1 << 8 * (sizeof(size_t) - 1);
static constexpr size_t capacity_bits = CHAR_BIT * (sizeof(size_t) - 1);
static constexpr size_t max_capacity = ((size_t)1 << capacity_bits) - 1;
char* ptr;
size_t size;
size_t capacity;
size_t capacity : capacity_bits;
unsigned char mode;
static constexpr unsigned char active_mask = 0b1000'0000;
};
static_assert(sizeof(Long) == sizeof(char*) * 3);
struct Short
{
static constexpr size_t capacity = sizeof(Long) - 2;
char string[capacity+1];
unsigned char size;
static constexpr size_t capacity = sizeof(Long) - 1;
char string[capacity];
// When string is full remaining_size will be 0 and be the null terminator.
// When string is empty remaining size will be 23 (0b00010111)
// and not collide with Long::active_mask.
unsigned char remaining_size;
};
static_assert(offsetof(Long, mode) == offsetof(Short, remaining_size));
union
{
@ -217,11 +230,11 @@ public:
void release()
{
if (is_long() and u.l.capacity != 0)
if (is_long() and (u.l.capacity != 0))
Alloc{}.deallocate(u.l.ptr, u.l.capacity+1);
}
void set_empty() { u.s.size = 1; u.s.string[0] = 0; }
void set_empty() { u.s.remaining_size = Short::capacity; u.s.string[0] = '\0'; }
void set_short(const char* data, size_t size);
};

View File

@ -202,7 +202,7 @@ InplaceString<23> to_string(Grouped val)
InplaceString<23> res;
for (int pos = 0, len = ungrouped.m_length; pos != len; ++pos)
{
if (res.m_length and ((len - pos) % 3) == 0)
if (res.m_length and ((len - pos) % 3) == 0)
res.m_data[res.m_length++] = ',';
res.m_data[res.m_length++] = ungrouped.m_data[pos];
}

View File

@ -144,10 +144,10 @@ decltype(auto) to_string(const StronglyTypedNumber<RealType, ValueType>& val)
namespace detail
{
template<typename T> requires std::is_convertible_v<T, StringView>
template<typename T> requires std::is_convertible_v<T, StringView>
StringView format_param(const T& val) { return val; }
template<typename T> requires (not std::is_convertible_v<T, StringView>)
template<typename T> requires (not std::is_convertible_v<T, StringView>)
decltype(auto) format_param(const T& val) { return to_string(val); }
}

View File

@ -377,7 +377,7 @@ void TerminalUI::Screen::output(bool force, bool synchronized, Writer& writer)
{
for (int line = 0; line < (int)size.line; ++line)
{
auto hash = hash_line(lines[line]);
auto hash = hash_line(lines[line]);
if (hash == hashes[line])
continue;
hashes[line] = hash;