-
-
Notifications
You must be signed in to change notification settings - Fork 475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(search-output-formatter): initialize search output formatter #3258
feat(search-output-formatter): initialize search output formatter #3258
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
let source = SourceFile::new(source_code); | ||
|
||
let start = source.location(span.start())?; | ||
let end = source.location(span.end())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this makes me realize we need to calculate line numbers for every match, which can potentially be a bit expensive. No big deal either way, but a good reminder that I may want to see if the Grit engine can already report the line numbers for us. At least it tracks them for some purposes already (though not everywhere), so I may be able to pull those out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you like me to add a TODO to keep track of this possibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be appreciated!
} else if is_last_line { | ||
let start_index = current_text | ||
.text_len() | ||
.checked_sub(current_text.trim_start().text_len()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I’d just use saturated_sub()
for the extra safety. It shouldn’t happen either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! Quick note, with that function being available on u32
I would need to add a bunch of into()
-s, and later transform it back to TextSize
. Is this ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just pushed the changes which show what I am referring to, I am happy to revert them in case 👍
for (i, char) in iter { | ||
let should_highlight = i >= marker.start().into() && i < marker.end().into(); | ||
if should_highlight { | ||
fmt.write_markup(markup! { <Emphasis><Info>{char}</Info></Emphasis> })?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we create subslices of adjacent characters that need highlighting, instead of adding the markup per character?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely! I have just pushed the changes, let me know if you have any feedback :)
@@ -783,10 +801,25 @@ impl Workspace for WorkspaceServer { | |||
} | |||
|
|||
fn search_pattern(&self, params: SearchPatternParams) -> Result<SearchResults, WorkspaceError> { | |||
let SearchPatternParams { | |||
path, | |||
pattern: _pattern, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use ..
if you want to ignore additional fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this PR doesn't add anything to the user (there's no command search
yet), I think the changelog change should be reverted.
I also left some feedback and questions
@@ -103,6 +103,10 @@ pub(crate) struct UnhandledDiagnostic; | |||
#[diagnostic(category = "parse", message = "Skipped file with syntax errors")] | |||
pub(crate) struct SkippedDiagnostic; | |||
|
|||
#[derive(Debug, Diagnostic)] | |||
#[diagnostic(category = "search", tags(SEARCH))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason why you added a SEARCH
tag? Tags are meant to add additional information to the current diagnostic, and you can assign multiple tags. I'm not sure this tag fits in here, unless there's a reason I don't see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for my understanding, you think the category
should be enough to right, and no tags would be needed here? If so, I guess that makes sense :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason why you added a
SEARCH
tag? Tags are meant to add additional information to the current diagnostic, and you can assign multiple tags. I'm not sure this tag fits in here, unless there's a reason I don't see
Yes, this is the reason why I went with it:
- I think a
SearchDiagnostic
should have aHint
severity- The
DiagnosticPrinter
will deem a diagnostic skippable if its severity is below its diagnostic_level -- in our case, anything belowInformation
is deemed skippable
- The
- For
fn should_skip_diagnostic
to print a search diagnostic despite its low severity, I figured I needed to have aSEARCH
tag attached to thediagnostic_tags
(seetraverse.rs::should_skip_diagnostic
)
With your previous comments, I realized I am able to get this info out of the printer execution
if needed: so, if there are no better ways, I could change my code to query the execution if you'd want me to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a particular reason why you added a
SEARCH
tag? Tags are meant to add additional information to the current diagnostic, and you can assign multiple tags. I'm not sure this tag fits in here, unless there's a reason I don't seeYes, this is the reason why I went with it:
I think a
SearchDiagnostic
should have aHint
severity
- The
DiagnosticPrinter
will deem a diagnostic skippable if its severity is below its diagnostic_level -- in our case, anything belowInformation
is deemed skippableFor
fn should_skip_diagnostic
to print a search diagnostic despite its low severity, I figured I needed to have aSEARCH
tag attached to thediagnostic_tags
(seetraverse.rs::should_skip_diagnostic
)With your previous comments, I realized I am able to get this info out of the printer
execution
if needed: so, if there are no better ways, I could change my code to query the execution if you'd want me to
I apologize for this confusion: after checking thoroughly, I realized this behavior was not happening the way I was imagining it.
I have now proceeded to remove the SEARCH
tag and its associated checks altogether 👍
.guard() | ||
.search_pattern(pattern) | ||
.with_file_path_and_code( | ||
workspace_file.path.display().to_string(), | ||
category!("search"), | ||
)?; | ||
|
||
let input = workspace_file.input()?; | ||
let file_name = workspace_file.path.display().to_string(); | ||
|
||
// FIXME: We need to report some real results here... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the FIXME
still relevant after this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess so, since the formatting is ready for the engine that provides real results is :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess so, since the formatting is ready for the engine that provides real results is :)
Sorry for my last out-of-sync reply: I actually went ahead and removed this one, in favor of keeping the other TODO
inside the function which is actually supposed to return the matches
.map(|mat| { | ||
SearchDiagnostic | ||
.with_file_span(mat) | ||
.with_severity(Severity::Hint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the severity of SearchDiagnostic
doesn't depend on external factors (for example, the configuration), then the severity can be set directly in the definition of SearchDiagnostic
:
#[derive(Debug, Diagnostic)]
#[diagnostic(category = "search", tags(SEARCH), severity = Hint)]
struct SearchDiagnostic;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Severity::Information
is also more appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so too!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! I will go ahead and change the severity to Information
then
@@ -783,10 +801,22 @@ impl Workspace for WorkspaceServer { | |||
} | |||
|
|||
fn search_pattern(&self, params: SearchPatternParams) -> Result<SearchResults, WorkspaceError> { | |||
let SearchPatternParams { path, .. } = params; | |||
|
|||
// FIXME: Let's implement some real matching here... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the FIXME
still applicable? I see there's some new code, maybe the FIXME
should become a TODO or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A TODO
definitely sounds better, thanks! 👍
Thanks @BackupMiles ! |
Summary
This PR aims to provide the infrastructure for the future search command output.
TextRange
inside a fileAims to resolve #2462
Test Plan
Since this PR only introduces an infrastructure for a command output, I have not provided any tests yet -- I would be glad to add them if deemed necessary.
Running
cargo test
still yields a positive result.