Skip to content

Commit db40888

Browse files
committed
Show some context on hover for search results
Closes #123
1 parent 2b86643 commit db40888

File tree

6 files changed

+255
-141
lines changed

6 files changed

+255
-141
lines changed

src/file_controller/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ impl Cache {
267267
}
268268

269269
fn make_line_result(&self, file_path: &Path, span: &Span) -> Result<LineResult, String> {
270-
let (text, context) = match self.get_highlighted(file_path) {
270+
let (text, pre, post) = match self.get_highlighted(file_path) {
271271
Ok(lines) => {
272272
let line = span.range.row_start.0 as i32;
273273
let text = lines[line as usize].clone();
@@ -280,13 +280,14 @@ impl Cache {
280280
if ctx_end >= lines.len() as i32 {
281281
ctx_end = lines.len() as i32 - 1;
282282
}
283-
let context = lines[ctx_start as usize..=ctx_end as usize].join("\n");
283+
let pre = lines[ctx_start as usize..line as usize].join("\n");
284+
let post = lines[line as usize + 1..=ctx_end as usize].join("\n");
284285

285-
(text, context)
286+
(text, pre, post)
286287
}
287288
Err(_) => return Err(format!("Error finding text for {:?}", span)),
288289
};
289-
Ok(LineResult::new(span, text, context))
290+
Ok(LineResult::new(span, text, pre, post))
290291
}
291292

292293
// Sorts a set of search results into buckets by file.

src/file_controller/results.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,19 @@ pub struct LineResult {
3535
pub column_start: u32,
3636
pub column_end: u32,
3737
pub line: String,
38-
pub context: String,
38+
pub pre_context: String,
39+
pub post_context: String,
3940
}
4041

4142
impl LineResult {
42-
pub fn new(span: &Span, line: String, context: String) -> LineResult {
43+
pub fn new(span: &Span, line: String, pre_context: String, post_context: String) -> LineResult {
4344
LineResult {
4445
line_start: span.range.row_start.one_indexed().0,
4546
column_start: span.range.col_start.one_indexed().0,
4647
column_end: span.range.col_end.one_indexed().0,
4748
line,
48-
context,
49+
pre_context,
50+
post_context,
4951
}
5052
}
5153
}

static/rustw.css

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ span#measure {
384384
.div_search_results {
385385
padding-top: 0.25em;
386386
padding-bottom: 1.5em;
387+
height: 100%;
387388
}
388389
.div_search_group {
389390
border-top: solid black 1px;
@@ -513,6 +514,7 @@ span#measure {
513514

514515
.div_sidebar_main {
515516
padding: 10px;
517+
height: 100%;
516518
overflow: scroll;
517519
display: none;
518520
}
@@ -521,13 +523,46 @@ span#measure {
521523
display: block;
522524
}
523525

524-
#search_box{
526+
#search_box {
525527
width:100%;
526528
height: 20px;
527529
box-sizing: border-box;
528530

529531
}
530532

533+
.div_search_context_box {
534+
display: block;
535+
position: absolute;
536+
width: 100%;
537+
height: auto;
538+
border: 3px black;
539+
border-style: solid none solid none;
540+
white-space: pre;
541+
background-color: white;
542+
opacity: 1;
543+
z-index: 10;
544+
overflow: hidden;
545+
546+
animation-duration: 0.5s;
547+
animation-name: search_context_open;
548+
animation-timing-function: linear;
549+
}
550+
551+
@keyframes search_context_open {
552+
from {
553+
max-height: 0;
554+
}
555+
to {
556+
max-height: 14em;
557+
}
558+
}
559+
560+
.search_context_highlight {
561+
background-color: lightgrey;
562+
display: inline-block;
563+
width: 100%;
564+
}
565+
531566
.selected {
532567
background-color: lightgrey;
533568
}

static/rustw.out.js

Lines changed: 123 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6924,89 +6924,129 @@ var ResultSet = function (_React$Component) {
69246924
return ResultSet;
69256925
}(_react2.default.Component);
69266926

6927-
function FileResult(props) {
6928-
var lines = props.lines,
6929-
file_name = props.file_name,
6930-
kind = props.kind,
6931-
count = props.count;
6932-
6933-
var divLines = lines.map(function (l) {
6934-
var lineId = 'snippet_line_number_' + kind + '_' + count + '_' + l.line_start;
6935-
var snippetId = 'snippet_line_' + kind + '_' + count + '_' + l.line_start;
6936-
6937-
// Squash the indent down by a factor of four.
6938-
var text = l.line;
6939-
var trimmed = text.trimLeft();
6940-
var newIndent = (text.length - trimmed.length) / 4;
6941-
var diffIndent = text.length - trimmed.length - newIndent;
6942-
trimmed = trimmed.padStart(trimmed.length + newIndent);
6943-
6944-
var lineClick = function lineClick(e) {
6945-
var highlight = {
6946-
"line_start": l.line_start,
6947-
"line_end": l.line_start,
6948-
"column_start": 0,
6949-
"column_end": 0
6950-
};
6951-
props.app.loadSource(file_name, highlight);
6952-
e.preventDefault();
6953-
e.stopPropagation();
6954-
};
6955-
var snippetClick = function snippetClick(e) {
6956-
var highlight = {
6957-
"line_start": l.line_start,
6958-
"line_end": l.line_end,
6959-
"column_start": l.column_start,
6960-
"column_end": l.column_end
6961-
};
6962-
props.app.loadSource(file_name, highlight);
6963-
e.preventDefault();
6964-
e.stopPropagation();
6965-
};
6927+
var FileResult = function (_React$Component2) {
6928+
_inherits(FileResult, _React$Component2);
69666929

6967-
return _react2.default.createElement(
6968-
'div',
6969-
{ key: kind + '-' + count + '-' + l.line_start },
6970-
_react2.default.createElement(
6971-
'span',
6972-
{ className: 'div_span_src_number' },
6930+
function FileResult(props) {
6931+
_classCallCheck(this, FileResult);
6932+
6933+
var _this2 = _possibleConstructorReturn(this, (FileResult.__proto__ || Object.getPrototypeOf(FileResult)).call(this, props));
6934+
6935+
_this2.state = { peekContext: null };
6936+
return _this2;
6937+
}
6938+
6939+
_createClass(FileResult, [{
6940+
key: 'render',
6941+
value: function render() {
6942+
var _this3 = this;
6943+
6944+
var _props2 = this.props,
6945+
lines = _props2.lines,
6946+
file_name = _props2.file_name,
6947+
kind = _props2.kind,
6948+
count = _props2.count,
6949+
app = _props2.app;
6950+
6951+
var self = this;
6952+
var divLines = lines.map(function (l) {
6953+
var lineId = 'snippet_line_number_' + kind + '_' + count + '_' + l.line_start;
6954+
var snippetId = 'snippet_line_' + kind + '_' + count + '_' + l.line_start;
6955+
6956+
// Squash the indent down by a factor of four.
6957+
var text = l.line;
6958+
var trimmed = text.trimLeft();
6959+
var newIndent = (text.length - trimmed.length) / 4;
6960+
var diffIndent = text.length - trimmed.length - newIndent;
6961+
trimmed = trimmed.padStart(trimmed.length + newIndent);
6962+
6963+
var lineClick = function lineClick(e) {
6964+
var highlight = {
6965+
"line_start": l.line_start,
6966+
"line_end": l.line_start,
6967+
"column_start": 0,
6968+
"column_end": 0
6969+
};
6970+
app.loadSource(file_name, highlight);
6971+
e.preventDefault();
6972+
e.stopPropagation();
6973+
};
6974+
var snippetClick = function snippetClick(e) {
6975+
var highlight = {
6976+
"line_start": l.line_start,
6977+
"line_end": l.line_end,
6978+
"column_start": l.column_start,
6979+
"column_end": l.column_end
6980+
};
6981+
app.loadSource(file_name, highlight);
6982+
e.preventDefault();
6983+
e.stopPropagation();
6984+
};
6985+
6986+
var onMouseOver = function onMouseOver(e) {
6987+
self.setState({ peekContext: { pre: l.pre_context, post: l.post_context } });
6988+
e.preventDefault();
6989+
e.stopPropagation();
6990+
};
6991+
var onMouseOut = function onMouseOut(e) {
6992+
self.setState({ peekContext: null });
6993+
e.preventDefault();
6994+
e.stopPropagation();
6995+
};
6996+
6997+
var context = null;
6998+
if (_this3.state.peekContext) {
6999+
context = _react2.default.createElement(SearchContext, { line: l.line, preContext: _this3.state.peekContext.pre, postContext: _this3.state.peekContext.post });
7000+
}
7001+
7002+
return _react2.default.createElement(
7003+
'div',
7004+
{ key: kind + '-' + count + '-' + l.line_start },
7005+
_react2.default.createElement(
7006+
'span',
7007+
{ className: 'div_span_src_number' },
7008+
_react2.default.createElement(
7009+
'div',
7010+
{ className: 'span_src_number', id: lineId, onClick: lineClick },
7011+
l.line_start
7012+
)
7013+
),
7014+
_react2.default.createElement(
7015+
'span',
7016+
{ className: 'div_span_src' },
7017+
_react2.default.createElement('div', { className: 'span_src', id: snippetId, onClick: snippetClick, onMouseOver: onMouseOver, onMouseOut: onMouseOut, dangerouslySetInnerHTML: { __html: trimmed }, 'data-adjust': diffIndent })
7018+
),
7019+
context,
7020+
_react2.default.createElement('br', null)
7021+
);
7022+
});
7023+
var onClick = function onClick(e) {
7024+
props.app.loadSource(file_name);
7025+
e.preventDefault();
7026+
e.stopPropagation();
7027+
};
7028+
return _react2.default.createElement(
7029+
'div',
7030+
null,
69737031
_react2.default.createElement(
69747032
'div',
6975-
{ className: 'span_src_number', id: lineId, onClick: lineClick },
6976-
l.line_start
7033+
{ className: 'div_search_file_link', onClick: onClick },
7034+
file_name
7035+
),
7036+
_react2.default.createElement(
7037+
'div',
7038+
{ className: 'div_all_span_src' },
7039+
divLines
69777040
)
6978-
),
6979-
_react2.default.createElement(
6980-
'span',
6981-
{ className: 'div_span_src' },
6982-
_react2.default.createElement('div', { className: 'span_src', id: snippetId, onClick: snippetClick, dangerouslySetInnerHTML: { __html: trimmed }, 'data-adjust': diffIndent })
6983-
),
6984-
_react2.default.createElement('br', null)
6985-
);
6986-
});
6987-
var onClick = function onClick(e) {
6988-
props.app.loadSource(file_name);
6989-
e.preventDefault();
6990-
e.stopPropagation();
6991-
};
6992-
return _react2.default.createElement(
6993-
'div',
6994-
null,
6995-
_react2.default.createElement(
6996-
'div',
6997-
{ className: 'div_search_file_link', onClick: onClick },
6998-
file_name
6999-
),
7000-
_react2.default.createElement(
7001-
'div',
7002-
{ className: 'div_all_span_src' },
7003-
divLines
7004-
)
7005-
);
7006-
}
7041+
);
7042+
}
7043+
}]);
70077044

7008-
var StructuredResultSet = function (_React$Component2) {
7009-
_inherits(StructuredResultSet, _React$Component2);
7045+
return FileResult;
7046+
}(_react2.default.Component);
7047+
7048+
var StructuredResultSet = function (_React$Component3) {
7049+
_inherits(StructuredResultSet, _React$Component3);
70107050

70117051
function StructuredResultSet() {
70127052
_classCallCheck(this, StructuredResultSet);
@@ -7109,6 +7149,11 @@ function highlight_needle(results, tag) {
71097149
});
71107150
}
71117151

7152+
function SearchContext(props) {
7153+
var text = props.preContext + '\n<span class="search_context_highlight">' + props.line + '</span>\n' + props.postContext;
7154+
return _react2.default.createElement('div', { className: 'div_search_context_box', dangerouslySetInnerHTML: { __html: text } });
7155+
}
7156+
71127157
/***/ }),
71137158
/* 148 */
71147159
/***/ (function(module, exports, __webpack_require__) {

static/rustw.out.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)