viml/parser/expressions: Highlight prefix separately from number

Should make accidental octals more visible.
This commit is contained in:
ZyX 2017-10-16 00:30:55 +03:00
parent 5e92ee6565
commit fe81380bf5
2 changed files with 128 additions and 2 deletions

View File

@ -1042,6 +1042,7 @@ void viml_pexpr_free_ast(ExprAST ast)
//
// NVimRegister -> SpecialChar
// NVimNumber -> Number
// NVimNumberPrefix -> SpecialChar
// NVimFloat -> NVimNumber
//
// NVimNestingParenthesis -> NVimParenthesis
@ -1842,6 +1843,14 @@ static const int want_node_to_lexer_flags[] = {
[kENodeArgumentSeparator] = kELFlagForbidScope,
};
/// Number of characters to highlight as NumberPrefix depending on the base
static const uint8_t base_to_prefix_length[] = {
[2] = 2,
[8] = 1,
[10] = 0,
[16] = 2,
};
/// Parse one VimL expression
///
/// @param pstate Parser state.
@ -2632,7 +2641,13 @@ viml_pexpr_parse_figure_brace_closing_error:
} else {
NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
cur_node->data.num.value = cur_token.data.num.val.integer;
HL_CUR_TOKEN(Number);
const uint8_t prefix_length = base_to_prefix_length[
cur_token.data.num.base];
viml_parser_highlight(pstate, cur_token.start, prefix_length,
HL(NumberPrefix));
viml_parser_highlight(
pstate, shifted_pos(cur_token.start, prefix_length),
cur_token.len - prefix_length, HL(Number));
}
want_node = kENodeOperator;
*top_node_p = cur_node;

View File

@ -6858,6 +6858,116 @@ describe('Expressions parser', function()
hl('Number', '2'),
})
end)
itp('highlights numbers with prefix', function()
check_parsing('0xABCDEF', 0, {
-- 01234567
ast = {
'Integer(val=11259375):0:0:0xABCDEF',
},
}, {
hl('NumberPrefix', '0x'),
hl('Number', 'ABCDEF'),
})
check_parsing('0Xabcdef', 0, {
-- 01234567
ast = {
'Integer(val=11259375):0:0:0Xabcdef',
},
}, {
hl('NumberPrefix', '0X'),
hl('Number', 'abcdef'),
})
check_parsing('0XABCDEF', 0, {
-- 01234567
ast = {
'Integer(val=11259375):0:0:0XABCDEF',
},
}, {
hl('NumberPrefix', '0X'),
hl('Number', 'ABCDEF'),
})
check_parsing('0xabcdef', 0, {
-- 01234567
ast = {
'Integer(val=11259375):0:0:0xabcdef',
},
}, {
hl('NumberPrefix', '0x'),
hl('Number', 'abcdef'),
})
check_parsing('0b001', 0, {
-- 01234
ast = {
'Integer(val=1):0:0:0b001',
},
}, {
hl('NumberPrefix', '0b'),
hl('Number', '001'),
})
check_parsing('0B001', 0, {
-- 01234
ast = {
'Integer(val=1):0:0:0B001',
},
}, {
hl('NumberPrefix', '0B'),
hl('Number', '001'),
})
check_parsing('0B00', 0, {
-- 0123
ast = {
'Integer(val=0):0:0:0B00',
},
}, {
hl('NumberPrefix', '0B'),
hl('Number', '00'),
})
check_parsing('00', 0, {
-- 01
ast = {
'Integer(val=0):0:0:00',
},
}, {
hl('NumberPrefix', '0'),
hl('Number', '0'),
})
check_parsing('001', 0, {
-- 012
ast = {
'Integer(val=1):0:0:001',
},
}, {
hl('NumberPrefix', '0'),
hl('Number', '01'),
})
check_parsing('01', 0, {
-- 01
ast = {
'Integer(val=1):0:0:01',
},
}, {
hl('NumberPrefix', '0'),
hl('Number', '1'),
})
check_parsing('1', 0, {
-- 0
ast = {
'Integer(val=1):0:0:1',
},
}, {
hl('Number', '1'),
})
end)
itp('works (KLEE tests)', function()
check_parsing('\0002&A:\000', 0, {
ast = nil,
@ -6879,7 +6989,8 @@ describe('Expressions parser', function()
'Integer(val=0):0:0:00',
},
}, {
hl('Number', '00'),
hl('NumberPrefix', '0'),
hl('Number', '0'),
})
end)
end)