mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 20:33:08 +00:00
Rewrite parser_t::current_line() to respect new parser
This commit is contained in:
parent
2c19ca0dbf
commit
1305c02579
3 changed files with 50 additions and 121 deletions
|
@ -1590,3 +1590,17 @@ int parse_execution_context_t::get_current_line_number()
|
|||
}
|
||||
return line_number;
|
||||
}
|
||||
|
||||
int parse_execution_context_t::get_current_source_offset() const
|
||||
{
|
||||
int result = -1;
|
||||
if (executing_node_idx != NODE_OFFSET_INVALID)
|
||||
{
|
||||
const parse_node_t &node = tree.at(executing_node_idx);
|
||||
if (node.has_source())
|
||||
{
|
||||
result = static_cast<int>(node.source_start);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,12 @@ public:
|
|||
/* Returns the current line number, indexed from 1. Not const since it touches cached_lineno_offset */
|
||||
int get_current_line_number();
|
||||
|
||||
/* Returns the source offset, or -1 */
|
||||
int get_current_source_offset() const;
|
||||
|
||||
/* Returns the source string */
|
||||
const wcstring &get_source() const { return src; }
|
||||
|
||||
/* Start executing at the given node offset. Returns 0 if there was no error, 1 if there was an error */
|
||||
parse_execution_result_t eval_node_at_offset(node_offset_t offset, const block_t *associated_block, const io_chain_t &io);
|
||||
|
||||
|
|
151
parser.cpp
151
parser.cpp
|
@ -823,149 +823,58 @@ const wchar_t *parser_t::current_filename() const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculates the on-screen width of the specified substring of the
|
||||
specified string. This function takes into account the width and
|
||||
alignment of the tab character, but other wise behaves like
|
||||
repeatedly calling wcwidth.
|
||||
*/
|
||||
static int printed_width(const wchar_t *str, int len)
|
||||
{
|
||||
int res=0;
|
||||
int i;
|
||||
|
||||
CHECK(str, 0);
|
||||
|
||||
for (i=0; str[i] && i<len; i++)
|
||||
{
|
||||
if (str[i] == L'\t')
|
||||
{
|
||||
res=(res+8)&~7;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += fish_wcwidth(str[i]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
wcstring parser_t::current_line()
|
||||
{
|
||||
wcstring lineinfo;
|
||||
|
||||
int lineno=1;
|
||||
|
||||
const wchar_t *file;
|
||||
const wchar_t *whole_str;
|
||||
const wchar_t *line;
|
||||
const wchar_t *line_end;
|
||||
int i;
|
||||
int offset;
|
||||
int current_line_width;
|
||||
const wchar_t *function_name=0;
|
||||
int current_line_start=0;
|
||||
|
||||
if (!current_tokenizer)
|
||||
if (execution_contexts.empty())
|
||||
{
|
||||
return L"";
|
||||
return wcstring();
|
||||
}
|
||||
const parse_execution_context_t *context = execution_contexts.back();
|
||||
assert(context != NULL);
|
||||
|
||||
int source_offset = context->get_current_source_offset();
|
||||
if (source_offset < 0)
|
||||
{
|
||||
return wcstring();
|
||||
}
|
||||
|
||||
file = parser_t::current_filename();
|
||||
whole_str = tok_string(current_tokenizer);
|
||||
line = whole_str;
|
||||
const int lineno = this->get_lineno();
|
||||
const wchar_t *file = this->current_filename();
|
||||
|
||||
if (!line)
|
||||
return L"";
|
||||
wcstring prefix;
|
||||
|
||||
|
||||
/*
|
||||
Calculate line number, line offset, etc.
|
||||
*/
|
||||
for (i=0; i<current_tokenizer_pos && whole_str[i]; i++)
|
||||
{
|
||||
if (whole_str[i] == L'\n')
|
||||
{
|
||||
lineno++;
|
||||
current_line_start=i+1;
|
||||
line = &whole_str[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
// lineno = current_tokenizer_pos;
|
||||
|
||||
|
||||
current_line_width=printed_width(whole_str+current_line_start,
|
||||
current_tokenizer_pos-current_line_start);
|
||||
|
||||
if ((function_name = is_function()))
|
||||
{
|
||||
lineno += function_get_definition_offset(function_name);
|
||||
}
|
||||
|
||||
/*
|
||||
Copy current line from whole string
|
||||
*/
|
||||
line_end = wcschr(line, L'\n');
|
||||
if (!line_end)
|
||||
line_end = line+wcslen(line);
|
||||
|
||||
line = wcsndup(line, line_end-line);
|
||||
|
||||
/**
|
||||
If we are not going to print a stack trace, at least print the line number and filename
|
||||
*/
|
||||
/* If we are not going to print a stack trace, at least print the line number and filename */
|
||||
if (!get_is_interactive() || is_function())
|
||||
{
|
||||
int prev_width = my_wcswidth(lineinfo.c_str());
|
||||
if (file)
|
||||
{
|
||||
append_format(lineinfo, _(L"%ls (line %d): "), file, lineno);
|
||||
append_format(prefix, _(L"%ls (line %d): "), user_presentable_path(file).c_str(), lineno);
|
||||
}
|
||||
else if (is_within_fish_initialization)
|
||||
{
|
||||
append_format(lineinfo, L"%ls: ", _(L"Startup"), lineno);
|
||||
append_format(prefix, L"%ls: ", _(L"Startup"), lineno);
|
||||
}
|
||||
else
|
||||
{
|
||||
append_format(lineinfo, L"%ls: ", _(L"Standard input"), lineno);
|
||||
append_format(prefix, L"%ls: ", _(L"Standard input"), lineno);
|
||||
}
|
||||
offset = my_wcswidth(lineinfo.c_str()) - prev_width;
|
||||
}
|
||||
else
|
||||
|
||||
bool skip_caret = get_is_interactive() && ! is_function();
|
||||
|
||||
/* Use an error with empty text */
|
||||
assert(source_offset >= 0);
|
||||
parse_error_t empty_error = {};
|
||||
empty_error.source_start = source_offset;
|
||||
|
||||
wcstring line_info = empty_error.describe_with_prefix(context->get_source(), prefix, skip_caret);
|
||||
if (! line_info.empty())
|
||||
{
|
||||
offset=0;
|
||||
line_info.push_back(L'\n');
|
||||
}
|
||||
|
||||
// debug( 1, L"Current pos %d, line pos %d, file_length %d, is_interactive %d, offset %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive, offset);
|
||||
/*
|
||||
Skip printing character position if we are in interactive mode
|
||||
and the error was on the first character of the line.
|
||||
*/
|
||||
if (!get_is_interactive() || is_function() || (current_line_width!=0))
|
||||
{
|
||||
// Workaround since it seems impossible to print 0 copies of a character using %*lc
|
||||
if (offset+current_line_width)
|
||||
{
|
||||
append_format(lineinfo,
|
||||
L"%ls\n%*lc^\n",
|
||||
line,
|
||||
offset+current_line_width,
|
||||
L' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
append_format(lineinfo,
|
||||
L"%ls\n^\n",
|
||||
line);
|
||||
}
|
||||
}
|
||||
|
||||
free((void *)line);
|
||||
parser_t::stack_trace(0, lineinfo);
|
||||
|
||||
return lineinfo;
|
||||
parser_t::stack_trace(0, line_info);
|
||||
return line_info;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue