Merge remote-tracking branch 'm-kru/vhdl' into master
This commit is contained in:
commit
def37a6ff4
|
@ -36,10 +36,10 @@ add-highlighter shared/rust/string region %{(?<!')"} (?<!\\)(\\\\)*"
|
||||||
add-highlighter shared/rust/raw_string region -match-capture %{(?<!')r(#*)"} %{"(#*)} fill string
|
add-highlighter shared/rust/raw_string region -match-capture %{(?<!')r(#*)"} %{"(#*)} fill string
|
||||||
|
|
||||||
add-highlighter shared/rust/line_doctest region ^\h*//[!/]\h*```($|should_panic|no_run|ignore|allow_fail|rust|test_harness|compile_fail|E\d{4}|edition201[58]) ^\h*//[!/]\h*```$ regions
|
add-highlighter shared/rust/line_doctest region ^\h*//[!/]\h*```($|should_panic|no_run|ignore|allow_fail|rust|test_harness|compile_fail|E\d{4}|edition201[58]) ^\h*//[!/]\h*```$ regions
|
||||||
add-highlighter shared/rust/line_doctest/marker region ```.* $ group
|
add-highlighter shared/rust/line_doctest/marker region ``` $ group
|
||||||
add-highlighter shared/rust/line_doctest/marker/fence regex ``` 0:meta
|
add-highlighter shared/rust/line_doctest/marker/fence regex ``` 0:meta
|
||||||
add-highlighter shared/rust/line_doctest/marker/keywords regex [\d\w] 0:meta # already matched above, just ignore comma
|
add-highlighter shared/rust/line_doctest/marker/keywords regex [\d\w] 0:meta # already matched above, just ignore comma
|
||||||
add-highlighter shared/rust/line_doctest/inner region '^\h*//[!/]( #(?= )|)' '$| ' group
|
add-highlighter shared/rust/line_doctest/inner region '^\h*//[!/]( #(?= ))?' '$| ' group
|
||||||
add-highlighter shared/rust/line_doctest/inner/comment regex //[!/] 0:documentation
|
add-highlighter shared/rust/line_doctest/inner/comment regex //[!/] 0:documentation
|
||||||
add-highlighter shared/rust/line_doctest/inner/hidden regex '#' 0:meta
|
add-highlighter shared/rust/line_doctest/inner/hidden regex '#' 0:meta
|
||||||
add-highlighter shared/rust/line_doctest/code default-region ref rust
|
add-highlighter shared/rust/line_doctest/code default-region ref rust
|
||||||
|
@ -51,7 +51,7 @@ add-highlighter shared/rust/line_comment1 region // $
|
||||||
add-highlighter shared/rust/block_comment2 region -recurse /\*\*\* /\*\*\* \*/ fill comment
|
add-highlighter shared/rust/block_comment2 region -recurse /\*\*\* /\*\*\* \*/ fill comment
|
||||||
add-highlighter shared/rust/block_doc region -recurse /\*\* /\*\* \*/ regions
|
add-highlighter shared/rust/block_doc region -recurse /\*\* /\*\* \*/ regions
|
||||||
add-highlighter shared/rust/block_doc/doctest region ```($|should_panic|no_run|ignore|allow_fail|rust|test_harness|compile_fail|E\d{4}|edition201[58]) ```$ regions
|
add-highlighter shared/rust/block_doc/doctest region ```($|should_panic|no_run|ignore|allow_fail|rust|test_harness|compile_fail|E\d{4}|edition201[58]) ```$ regions
|
||||||
add-highlighter shared/rust/block_doc/doctest/marker region ```.* $ group
|
add-highlighter shared/rust/block_doc/doctest/marker region ``` $ group
|
||||||
add-highlighter shared/rust/block_doc/doctest/marker/fence regex ``` 0:meta
|
add-highlighter shared/rust/block_doc/doctest/marker/fence regex ``` 0:meta
|
||||||
add-highlighter shared/rust/block_doc/doctest/marker/keywords regex [\d\w] 0:meta # already matched above, just ignore comma
|
add-highlighter shared/rust/block_doc/doctest/marker/keywords regex [\d\w] 0:meta # already matched above, just ignore comma
|
||||||
add-highlighter shared/rust/block_doc/doctest/inner default-region group
|
add-highlighter shared/rust/block_doc/doctest/inner default-region group
|
||||||
|
|
408
rc/filetype/vhdl.kak
Normal file
408
rc/filetype/vhdl.kak
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
# Based on IEEE Std 1076‐2019
|
||||||
|
|
||||||
|
# Detection
|
||||||
|
hook global BufCreate .*[.](vhd[l]?) %[
|
||||||
|
set-option buffer filetype vhdl
|
||||||
|
]
|
||||||
|
|
||||||
|
# Initialization
|
||||||
|
hook global WinSetOption filetype=vhdl %[
|
||||||
|
require-module vhdl
|
||||||
|
set-option window static_words %opt{vhdl_static_words}
|
||||||
|
hook -group vhdl-indent window InsertChar \n vhdl-indent-on-new-line
|
||||||
|
hook -group vhdl-indent window InsertChar \) vhdl-indent-on-closing-parenthesis
|
||||||
|
hook -group vhdl-insert window InsertChar \n vhdl-insert-on-new-line
|
||||||
|
# Cleanup trailing whitespaces on current line insert end.
|
||||||
|
hook -group vhdl-trim-indent window ModeChange pop:insert:.* %[ try %[ execute-keys -draft <semicolon> <a-x> s ^\h+$ <ret> d ] ]
|
||||||
|
hook -once -always window WinSetOption filetype=.* %[ remove-hooks window vhdl-.+ ]
|
||||||
|
]
|
||||||
|
|
||||||
|
hook -group vhdl-highlight global WinSetOption filetype=vhdl %[
|
||||||
|
add-highlighter window/vhdl ref vhdl
|
||||||
|
hook -once -always window WinSetOption filetype=.* %[ remove-highlighter window/vhdl ]
|
||||||
|
]
|
||||||
|
|
||||||
|
provide-module vhdl %§
|
||||||
|
|
||||||
|
# Highlighters & Completion
|
||||||
|
add-highlighter shared/vhdl regions
|
||||||
|
add-highlighter shared/vhdl/code default-region group
|
||||||
|
add-highlighter shared/vhdl/comment_line region '--' $ fill comment
|
||||||
|
add-highlighter shared/vhdl/comment region /\* \*/ fill comment
|
||||||
|
|
||||||
|
# Integer formats
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b0b[01]+l?\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b0x[\da-f]+l?\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b0o?[0-7]+l?\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b([1-9]\d*|0)l?\b' 0:value
|
||||||
|
# Float formats
|
||||||
|
add-highlighter shared/vhdl/code/ regex '\b\d+[eE][+-]?\d+\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(\b\d+)?\.\d+\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '\b\d+\.' 0:value
|
||||||
|
# Imaginary formats
|
||||||
|
add-highlighter shared/vhdl/code/ regex '\b\d+\+\d+[jJ]\b' 0:value
|
||||||
|
|
||||||
|
evaluate-commands %sh[
|
||||||
|
values="true false note warning error failure"
|
||||||
|
|
||||||
|
# LRM 5.2.4.1
|
||||||
|
units="fs ps ns us ms sec min Å nm um mm cm m km"
|
||||||
|
|
||||||
|
# LRM 16.2
|
||||||
|
predefined_attributes="
|
||||||
|
base left right high low ascending length range reverse_range
|
||||||
|
subtype image pos succ pred leftof rightof value val
|
||||||
|
designated_subtype reflect high low index element delayed
|
||||||
|
stable quiet transaction event active last_event last_active
|
||||||
|
last_value driving driving_value simple_name instance_name
|
||||||
|
path_name record signal converse
|
||||||
|
"
|
||||||
|
|
||||||
|
libraries="ieee std"
|
||||||
|
|
||||||
|
packages="
|
||||||
|
math_real math_complex std_logic_1164 std_logic_textio numeric_bit numeric_std
|
||||||
|
numeric_bit_unsigned numeric_std_unsigned fixed_float_types fixed_generic_pkg
|
||||||
|
fixed_pkg float_generic_pkg float_pkg
|
||||||
|
standard textio env
|
||||||
|
"
|
||||||
|
|
||||||
|
# LRM 15.10
|
||||||
|
reserved_words="
|
||||||
|
abs access after alias all and architecture array assert assume assume_guarantee attribute
|
||||||
|
begin block body buffer bus
|
||||||
|
case component configuration constant context cover
|
||||||
|
default disconnect downto
|
||||||
|
else elsif end entity exit
|
||||||
|
fairness file for force function
|
||||||
|
generate generic group guarded
|
||||||
|
if impure in inertial inout is
|
||||||
|
label library linkage literal loop
|
||||||
|
map mod
|
||||||
|
nand new next nor not null
|
||||||
|
of on open or others out
|
||||||
|
package parameter port postponed procedure process property protected pure
|
||||||
|
range record register reject release rem report restrict restrict_guarantee return rol ror
|
||||||
|
select sequence severity signal shared sla sll sra srl strong subtype
|
||||||
|
then to transport type
|
||||||
|
unaffected units until use
|
||||||
|
variable view vpkg vmode vprop vunit
|
||||||
|
wait when while with
|
||||||
|
xnor xor
|
||||||
|
"
|
||||||
|
|
||||||
|
types="
|
||||||
|
bit bit_vector
|
||||||
|
boolean
|
||||||
|
file_open_state file_origin_kind
|
||||||
|
integer natural positive
|
||||||
|
line line_vector
|
||||||
|
std_logic std_logic_vector
|
||||||
|
std_ulogic std_ulogic_vector
|
||||||
|
side
|
||||||
|
signed unsigned
|
||||||
|
string text
|
||||||
|
time
|
||||||
|
"
|
||||||
|
|
||||||
|
functions="
|
||||||
|
find_leftmost find_rightmost divide reciprocal remainder modulo minimum maximum
|
||||||
|
std_match add_carry scalb
|
||||||
|
resize to_ufixed to_sfixed to_unsigned to_signed to_real to_integer to_slv
|
||||||
|
to_std_logic_vector to_stdlogicvector to_sulv to_std_ulogic_vector to_std_ulogicvector
|
||||||
|
to_01 is_x to_x01 to_ux01 to_x01z
|
||||||
|
ufixed_high ufixed_low sfixed_high sfixed_low to_ufix to_sfix ufix_high ufix_low
|
||||||
|
sfix_high sfix_low
|
||||||
|
write read bwrite binary_write bread binary_read owrite oread octal_write octal_read
|
||||||
|
hwrite hread hex_write hex_read to_string to_bstring to_binary_string to_ostring
|
||||||
|
to_octal_string to_hstring to_hex_string from_string from_bstring from_binary_string
|
||||||
|
from_ostring from_octal_string from_hstring from_hex_string
|
||||||
|
rising_edge falling_edge
|
||||||
|
"
|
||||||
|
|
||||||
|
join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; }
|
||||||
|
|
||||||
|
# Add the language's grammar to the static completion list
|
||||||
|
printf %s\\n "declare-option str-list vhdl_static_words $(join "${values} ${units} ${predefined_attributes} ${libraries} ${packages} ${reserved_words} ${types} ${functions}" ' ')"
|
||||||
|
|
||||||
|
# Highlight keywords
|
||||||
|
printf %s "
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${values}" '|'))\b' 0:value
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${units}" '|'))\b' 0:meta
|
||||||
|
add-highlighter shared/vhdl/code/ regex \"'(?i)\b($(join "${predefined_attributes}" '|'))\b\" 0:attribute
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${libraries}" '|'))\b' 0:builtin
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${packages}" '|'))\b' 0:builtin
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${reserved_words}" '|'))\b' 0:keyword
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${functions}" '|'))\b\(' 1:builtin
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)\b($(join "${types}" '|'))\b' 0:type
|
||||||
|
add-highlighter shared/vhdl/code/ regex '^\h*(@[\w_.]+))' 1:attribute
|
||||||
|
"
|
||||||
|
]
|
||||||
|
|
||||||
|
add-highlighter shared/vhdl/code/ regex \(|\)|\;|\.|,|:|\| 0:attribute
|
||||||
|
|
||||||
|
add-highlighter shared/vhdl/code/ regex \?\?|=|/=|<|<=|>|>=|\?=|\?/=|\?<|\?<=|\?>|\?>=|\+|-|&|\*|/|:= 0:operator
|
||||||
|
|
||||||
|
# Meta values highlight.
|
||||||
|
# The values 'U', 'X', 'W', and '–' are metalogical values; they define the behavior of the model itself rather than the behavior of the hardware being synthesized.
|
||||||
|
add-highlighter shared/vhdl/code/ regex "(?i)'[U|X|W|-]'" 0:meta
|
||||||
|
# Highlight other logical values.
|
||||||
|
add-highlighter shared/vhdl/code/ regex "(?i)'[0|1|Z|L|H]'" 0:value
|
||||||
|
|
||||||
|
# String
|
||||||
|
add-highlighter shared/vhdl/code/ regex '"[^"]*"' 0:string
|
||||||
|
|
||||||
|
# Binary vector.
|
||||||
|
add-highlighter shared/vhdl/code/ regex '[bB]"[01_]*"' 0:value
|
||||||
|
|
||||||
|
# Octal vector.
|
||||||
|
add-highlighter shared/vhdl/code/ regex '[oO]"[01234567_]*"' 0:value
|
||||||
|
|
||||||
|
# Hex vector.
|
||||||
|
add-highlighter shared/vhdl/code/ regex '(?i)x"[0123456789abcdef_]*"' 0:value
|
||||||
|
|
||||||
|
define-command -hidden vhdl-insert-on-new-line %[
|
||||||
|
# Handle comment lines.
|
||||||
|
evaluate-commands -itersel %[
|
||||||
|
# Copy '--' comment prefix and following white spaces.
|
||||||
|
try %[
|
||||||
|
# <a-lt> is needed because of "Preserve previous line indent" command.
|
||||||
|
try %[ execute-keys -draft k <a-x> s ^\h*--\h* <ret> y j <a-lt> gh P ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluate-commands -save-regs x %[
|
||||||
|
# Save previous line indent in register x.
|
||||||
|
try %[ execute-keys -draft k<a-x>s^\h+<ret>"xy ] catch %[ reg x '' ]
|
||||||
|
|
||||||
|
# All "wisely add" commands share the same concept.
|
||||||
|
# Only "end if" has extra comments.
|
||||||
|
# Wisely add "end if;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
# Validate previous line and that it is not closed yet.
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)((then|(.*:\h*)?if\b.*\bthen)$)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(else|end|elsif)\b<ret>
|
||||||
|
# Don't add for "if ... generate", it requires "end generate;".
|
||||||
|
execute-keys -draft k<a-x> <a-K>(?i)\bgenerate\b<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>if<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end generate;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i).*\bgenerate$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
# Don't add in case of comment line.
|
||||||
|
execute-keys -draft k<a-x> <a-K>^\h*--<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>generate<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end case;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(case|.*\h*:\h*case)\b<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)end<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>case<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "begin" and "end block;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)((block|.*:\h*block)\b)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>block<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "begin" and "end process;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(.*:\h*)?(postponed\h+)?process\b<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>process<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end loop;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(.*\bloop|.*\h*:\h*(for|loop))$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>loop<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end protected;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(type\b.*\bis\h+protected)$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>protected<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end record;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(type\b.*\bis\h+record\h*)$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>record<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ");" for "type ... is (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(type\b.*\bis\h+\(\h*)$<ret> J}iJ<a-x> <a-K>^<c-r>x(\))<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end entity;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)\h*entity\b.*\bis$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xend<space>entity<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "begin" and "end function;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)(\h*\)?\h*return\b.*\bis$)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>function<semicolon><esc>
|
||||||
|
]
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)(\h*((pure|impure)\h+)?function\b.*\bis$)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>function<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "begin" and "end procedure;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)(\h*procedure\b.*\bis$)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)\b(begin|end)\b<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>procedure<semicolon><esc>
|
||||||
|
]
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)\h*\)\h*\bis$<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)\b(begin|end)\b<ret>
|
||||||
|
# Verify that line with opening parenthesis contains "procedure" keyword.
|
||||||
|
execute-keys -draft k<a-x> s\)<ret> <a-m><semicolon> <a-x><a-k> (?i)\bprocedure\b<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>procedure<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end package;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)(package\b)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(end)<ret>
|
||||||
|
# Make sure it is not package body.
|
||||||
|
execute-keys -draft k<a-x><a-K>(?i)\bbody\b<ret>
|
||||||
|
execute-keys -draft oend<space>package<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "end package body;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)(package\h+body\b)<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(end)<ret>
|
||||||
|
execute-keys -draft oend<space>package<space>body<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add "begin" and "end architecture;".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^(?i)\h*architecture\b<ret> J}iJ<a-x> <a-K>^<c-r>x(?i)(begin|end)<ret>
|
||||||
|
execute-keys -draft o<c-r>xbegin<ret><c-r>xend<space>architecture<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ");" for "port (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)port\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\)\;)<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ");" for "port map (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)port\h+map\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\)\;)<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ");" for "generic (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)generic\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\)\;)<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ")" for "generic map (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)generic\h+map\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\))<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ") return ;" for "[pure|impure] function ... (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)(pure\b|impure\b)?\h*function\b.*\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\)\h*return.*)<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<space>return<space><semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
# Wisely add ");" for "procedure ... (".
|
||||||
|
evaluate-commands %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x> <a-k>^\h*(?i)procedure\b.*\h*\($<ret> J}iJ<a-x> <a-K>^<c-r>x(\)\h*\;)<ret>
|
||||||
|
execute-keys -draft o<c-r>x)<semicolon><esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
define-command -hidden vhdl-indent-on-new-line %{
|
||||||
|
evaluate-commands -itersel %{
|
||||||
|
# Align "then" to previous "if|elsif".
|
||||||
|
evaluate-commands -itersel -save-regs x %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k <a-x> <a-k> (?i)^\h*then$ <ret>
|
||||||
|
try %[ execute-keys -draft <a-/>(?i)\b(if|elsif)\b<ret><a-x>s^\h+<ret>"xy ] catch %[ reg x '' ]
|
||||||
|
try %[ execute-keys -draft k <a-x>s^\h+<ret>d ] catch %[ ]
|
||||||
|
execute-keys -draft kgh i<c-r>x<esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
# Align "generate" to previous "if|for".
|
||||||
|
evaluate-commands -itersel -save-regs x %[
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k <a-x> <a-k> (?i)^\h*generate$ <ret>
|
||||||
|
try %[ execute-keys -draft <a-/>(?i)\b(if|for)\b<ret><a-x>s^\h+<ret>"xy ] catch %[ reg x '' ]
|
||||||
|
try %[ execute-keys -draft k <a-x>s^\h+<ret>d ] catch %[ ]
|
||||||
|
execute-keys -draft kgh i<c-r>x<esc>
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
# Preserve previous line indent.
|
||||||
|
try %[ execute-keys -draft <semicolon> K <a-&> ]
|
||||||
|
|
||||||
|
# Cleanup trailing whitespaces from previous line.
|
||||||
|
try %[ execute-keys -draft k <a-x> s \h+$ <ret> d ]
|
||||||
|
|
||||||
|
# Increase indent after some keywords.
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x><a-k> (?i)\b(begin|block|else|for|generate|if|is|loop|process|protected|record|select|then)$ <ret>
|
||||||
|
# Does not indent if in comment line.
|
||||||
|
execute-keys -draft k<a-x><a-K>(?i)^\h*--<ret>
|
||||||
|
# Handle case line in a bit different way.
|
||||||
|
execute-keys -draft k<a-x><a-K>(?i)^\h*case\b<ret>
|
||||||
|
execute-keys -draft <semicolon> <a-gt>
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add "when " and increase indent after "case ... is".
|
||||||
|
try %[
|
||||||
|
execute-keys -draft k<a-x><a-k> (?i)\h*case\b.*\h+is$ <ret>
|
||||||
|
# Don't indent if in comment line.
|
||||||
|
execute-keys -draft k<a-x><a-K>(?i)^\h*--<ret>
|
||||||
|
execute-keys -draft <semicolon>iwhen<space><esc><a-gt>
|
||||||
|
]
|
||||||
|
|
||||||
|
# Copy the indentation of the matching if.
|
||||||
|
try %{ execute-keys -draft <space> k <a-x> <a-k> ^\h*(elsif\b|else$) <ret> gh [c^\h*(\S*\h*:\h*)?if\b,\bend\sif\b <ret> <a-x> <a-S> 1<a-&> <space> j K <a-&> }
|
||||||
|
|
||||||
|
# Increase indent after some operators.
|
||||||
|
try %[ execute-keys -draft <semicolon> <space> k <a-x> <a-k> (\(|=>|<=|:=)$ <ret> j <a-gt> ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define-command vhdl-indent-on-closing-parenthesis %[
|
||||||
|
evaluate-commands -itersel %[
|
||||||
|
# Decrease indent after ")" at the beginning of line.
|
||||||
|
try %[ execute-keys -draft <a-x> <a-k> (^\h+\)$) <ret> <a-lt> ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
§
|
|
@ -1744,7 +1744,8 @@ void insert_matches(const Buffer& buffer, RegexMatchList& matches, const Regex&
|
||||||
for (auto line = range.begin; line < range.end; ++line)
|
for (auto line = range.begin; line < range.end; ++line)
|
||||||
{
|
{
|
||||||
const StringView l = buffer[line];
|
const StringView l = buffer[line];
|
||||||
for (auto&& m : RegexIterator{l.begin(), l.end(), vm})
|
const auto flags = RegexExecFlags::NotEndOfLine; // buffer line already ends with \n
|
||||||
|
for (auto&& m : RegexIterator{l.begin(), l.end(), vm, flags})
|
||||||
{
|
{
|
||||||
const bool with_capture = capture and m[1].matched and
|
const bool with_capture = capture and m[1].matched and
|
||||||
m[0].second - m[0].first < std::numeric_limits<uint16_t>::max();
|
m[0].second - m[0].first < std::numeric_limits<uint16_t>::max();
|
||||||
|
|
|
@ -261,76 +261,74 @@ InsertCompletion complete_option(const SelectionList& sels,
|
||||||
auto& desc = opt.prefix;
|
auto& desc = opt.prefix;
|
||||||
static const Regex re(R"((\d+)\.(\d+)(?:\+(\d+))?@(\d+))");
|
static const Regex re(R"((\d+)\.(\d+)(?:\+(\d+))?@(\d+))");
|
||||||
MatchResults<String::const_iterator> match;
|
MatchResults<String::const_iterator> match;
|
||||||
if (regex_match(desc.begin(), desc.end(), match, re))
|
if (not regex_match(desc.begin(), desc.end(), match, re))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
BufferCoord coord{str_to_int({match[1].first, match[1].second}) - 1,
|
||||||
|
str_to_int({match[2].first, match[2].second}) - 1};
|
||||||
|
if (not buffer.is_valid(coord))
|
||||||
|
return {};
|
||||||
|
size_t timestamp = (size_t)str_to_int({match[4].first, match[4].second});
|
||||||
|
auto changes = buffer.changes_since(timestamp);
|
||||||
|
if (any_of(changes, [&](auto&& change) { return change.begin < coord; }))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (cursor_pos.line != coord.line or cursor_pos.column < coord.column)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const ColumnCount tabstop = options["tabstop"].get<int>();
|
||||||
|
const ColumnCount column = get_column(buffer, tabstop, cursor_pos);
|
||||||
|
|
||||||
|
struct RankedMatchAndInfo : RankedMatch
|
||||||
{
|
{
|
||||||
BufferCoord coord{ str_to_int({match[1].first, match[1].second}) - 1,
|
using RankedMatch::RankedMatch;
|
||||||
str_to_int({match[2].first, match[2].second}) - 1 };
|
using RankedMatch::operator==;
|
||||||
if (not buffer.is_valid(coord))
|
using RankedMatch::operator<;
|
||||||
return {};
|
|
||||||
size_t timestamp = (size_t)str_to_int({match[4].first, match[4].second});
|
|
||||||
auto changes = buffer.changes_since(timestamp);
|
|
||||||
if (any_of(changes, [&](auto&& change) { return change.begin < coord; }))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (cursor_pos.line == coord.line and cursor_pos.column >= coord.column)
|
StringView on_select;
|
||||||
|
DisplayLine menu_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
StringView query = buffer.substr(coord, cursor_pos);
|
||||||
|
Vector<RankedMatchAndInfo> matches;
|
||||||
|
|
||||||
|
for (auto& candidate : opt.list)
|
||||||
|
{
|
||||||
|
if (RankedMatchAndInfo match{std::get<0>(candidate), query})
|
||||||
{
|
{
|
||||||
StringView query = buffer.substr(coord, cursor_pos);
|
match.on_select = std::get<1>(candidate);
|
||||||
|
auto& menu = std::get<2>(candidate);
|
||||||
|
match.menu_entry = not menu.empty() ?
|
||||||
|
parse_display_line(expand_tabs(menu, tabstop, column), faces)
|
||||||
|
: DisplayLine{String{}, {}};
|
||||||
|
|
||||||
const ColumnCount tabstop = options["tabstop"].get<int>();
|
matches.push_back(std::move(match));
|
||||||
const ColumnCount column = get_column(buffer, tabstop, cursor_pos);
|
|
||||||
|
|
||||||
struct RankedMatchAndInfo : RankedMatch
|
|
||||||
{
|
|
||||||
using RankedMatch::RankedMatch;
|
|
||||||
using RankedMatch::operator==;
|
|
||||||
using RankedMatch::operator<;
|
|
||||||
|
|
||||||
StringView on_select;
|
|
||||||
DisplayLine menu_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector<RankedMatchAndInfo> matches;
|
|
||||||
|
|
||||||
for (auto& candidate : opt.list)
|
|
||||||
{
|
|
||||||
if (RankedMatchAndInfo match{std::get<0>(candidate), query})
|
|
||||||
{
|
|
||||||
match.on_select = std::get<1>(candidate);
|
|
||||||
auto& menu = std::get<2>(candidate);
|
|
||||||
match.menu_entry = not menu.empty() ?
|
|
||||||
parse_display_line(expand_tabs(menu, tabstop, column), faces)
|
|
||||||
: DisplayLine{ expand_tabs(menu, tabstop, column), {} };
|
|
||||||
|
|
||||||
matches.push_back(std::move(match));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t max_count = 100;
|
|
||||||
// Gather best max_count matches
|
|
||||||
auto greater = [](auto& lhs, auto& rhs) { return rhs < lhs; };
|
|
||||||
auto first = matches.begin(), last = matches.end();
|
|
||||||
std::make_heap(first, last, greater);
|
|
||||||
InsertCompletion::CandidateList candidates;
|
|
||||||
candidates.reserve(std::min(matches.size(), max_count));
|
|
||||||
candidates.reserve(matches.size());
|
|
||||||
while (candidates.size() < max_count and first != last)
|
|
||||||
{
|
|
||||||
if (candidates.empty() or candidates.back().completion != first->candidate())
|
|
||||||
candidates.push_back({ first->candidate().str(), first->on_select.str(),
|
|
||||||
std::move(first->menu_entry) });
|
|
||||||
std::pop_heap(first, last--, greater);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end = cursor_pos;
|
|
||||||
if (match[3].matched)
|
|
||||||
{
|
|
||||||
ByteCount len = str_to_int({match[3].first, match[3].second});
|
|
||||||
end = buffer.advance(coord, len);
|
|
||||||
}
|
|
||||||
return { std::move(candidates), coord, end, timestamp };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
|
constexpr size_t max_count = 100;
|
||||||
|
// Gather best max_count matches
|
||||||
|
auto greater = [](auto& lhs, auto& rhs) { return rhs < lhs; };
|
||||||
|
auto first = matches.begin(), last = matches.end();
|
||||||
|
std::make_heap(first, last, greater);
|
||||||
|
InsertCompletion::CandidateList candidates;
|
||||||
|
candidates.reserve(std::min(matches.size(), max_count));
|
||||||
|
candidates.reserve(matches.size());
|
||||||
|
while (candidates.size() < max_count and first != last)
|
||||||
|
{
|
||||||
|
if (candidates.empty() or candidates.back().completion != first->candidate())
|
||||||
|
candidates.push_back({ first->candidate().str(), first->on_select.str(),
|
||||||
|
std::move(first->menu_entry) });
|
||||||
|
std::pop_heap(first, last--, greater);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end = cursor_pos;
|
||||||
|
if (match[3].matched)
|
||||||
|
{
|
||||||
|
ByteCount len = str_to_int({match[3].first, match[3].second});
|
||||||
|
end = buffer.advance(coord, len);
|
||||||
|
}
|
||||||
|
return { std::move(candidates), coord, end, timestamp };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool other_buffers>
|
template<bool other_buffers>
|
||||||
|
|
1
test/regression/3799-incorrect-region-match/cmd
Normal file
1
test/regression/3799-incorrect-region-match/cmd
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
4
test/regression/3799-incorrect-region-match/in
Normal file
4
test/regression/3799-incorrect-region-match/in
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
print << "";
|
||||||
|
part of heredoc
|
||||||
|
|
||||||
|
not part of heredoc
|
2
test/regression/3799-incorrect-region-match/rc
Normal file
2
test/regression/3799-incorrect-region-match/rc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
add-highlighter global/regions regions
|
||||||
|
add-highlighter global/regions/heredoc region -match-capture <<\h*"(\w*)" ^(\w*)$ fill red
|
2
test/regression/3799-incorrect-region-match/script
Normal file
2
test/regression/3799-incorrect-region-match/script
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ui_out '{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }'
|
||||||
|
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "p" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "rint " }, { "face": { "fg": "red", "bg": "default", "attributes": [] }, "contents": "<< \"\";\u000a" }], [{ "face": { "fg": "red", "bg": "default", "attributes": [] }, "contents": "part of heredoc\u000a" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "\u000a" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "not part of heredoc\u000a" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }'
|
Loading…
Reference in New Issue
Block a user