From 808ea834e7cf593ab94fc8934a9d948c4ae606a4 Mon Sep 17 00:00:00 2001 From: Daniil159x Date: Sun, 22 Dec 2024 03:06:28 +0300 Subject: [PATCH 1/3] intro query --- elixir/query.py | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/elixir/query.py b/elixir/query.py index ff14d4b1..0838cb04 100755 --- a/elixir/query.py +++ b/elixir/query.py @@ -259,9 +259,12 @@ def query(self, cmd, *args): # DT bindings compatible strings are handled differently if family == 'B': - return self.get_idents_comps(version, ident) + defs, refs, docs = self.get_idents_comps(version, ident) else: - return self.get_idents_defs(version, ident, family) + defs, refs, docs = self.get_idents_defs(version, ident, family) + + peeks = self.get_peeks_of_syms(version, defs, refs) + return defs, refs, docs, peeks else: return 'Unknown subcommand: ' + cmd + '\n' @@ -402,10 +405,37 @@ def get_idents_defs(self, version, ident, family): symbol_doccomments.append(SymbolInstance(path, docline)) return symbol_definitions, symbol_references, symbol_doccomments + + def get_peeks_of_syms(self, version, symbol_definitions, symbol_references): + + peeks = {} + + def request_peeks(syms): + if len(syms) > 100: + return + for sym in syms: + if sym.path not in peeks: + peeks[sym.path] = {} + + content = self.scriptLines('get-file', version, "/" + sym.path) + + if type(sym.line) is int: + lines = (sym.line,) + else: + lines = map(int, sym.line.split(',')) + + for num in lines: + index = num - 1 + if index >= 0 and index < len(content): + peeks[sym.path][num] = decode(content[index]).strip() + + request_peeks(symbol_definitions) + request_peeks(symbol_references) + return peeks def cmd_ident(q, version, ident, family, **kwargs): - symbol_definitions, symbol_references, symbol_doccomments = q.query("ident", version, ident, family) + symbol_definitions, symbol_references, symbol_doccomments, peeks = q.query("ident", version, ident, family) print("Symbol Definitions:") for symbol_definition in symbol_definitions: print(symbol_definition) @@ -418,6 +448,11 @@ def cmd_ident(q, version, ident, family, **kwargs): for symbol_doccomment in symbol_doccomments: print(symbol_doccomment) + print("\nSymbol peeks:") + for file, content in peeks.items(): + for num, line in content.items(): + print(f"{file}:{num}: {line}") + def cmd_file(q, version, path, **kwargs): code = q.query("file", version, path) print(code) From 66d8e1d19d51435b87a058c66397cd142fc4de13 Mon Sep 17 00:00:00 2001 From: Daniil159x Date: Sun, 22 Dec 2024 03:11:11 +0300 Subject: [PATCH 2/3] use peeks in dynamic ref --- elixir/api.py | 5 +++-- static/dynamic-references.js | 31 +++++++++++++++++++++++-------- static/style.css | 11 +++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/elixir/api.py b/elixir/api.py index 99aba6a4..f4e3beb8 100755 --- a/elixir/api.py +++ b/elixir/api.py @@ -46,14 +46,15 @@ def on_get(self, req, resp, project, ident): if version == 'latest': version = query.query('latest') - symbol_definitions, symbol_references, symbol_doccomments = query.query('ident', version, ident, family) + symbol_definitions, symbol_references, symbol_doccomments, peaks = query.query('ident', version, ident, family) resp.status = falcon.HTTP_200 resp.content_type = falcon.MEDIA_JSON resp.media = { 'definitions': [sym.__dict__ for sym in symbol_definitions], 'references': [sym.__dict__ for sym in symbol_references], - 'documentations': [sym.__dict__ for sym in symbol_doccomments] + 'documentations': [sym.__dict__ for sym in symbol_doccomments], + 'peeks': peaks } query.close() diff --git a/static/dynamic-references.js b/static/dynamic-references.js index c2816bac..4ea94464 100644 --- a/static/dynamic-references.js +++ b/static/dynamic-references.js @@ -28,7 +28,7 @@ function identUrl(project, ident, version, family) { ] */ -function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) { +function generateSymbolDefinitionsHTML(symbolDefinitions, peeks, project, version) { let result = ""; let typesCount = {}; let previous_type = ""; @@ -55,7 +55,7 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) { previous_type = sd.type; } let ln = sd.line.toString().split(','); - if (ln.length == 1) { + if (ln.length == 1 && !peeks) { let n = ln[0]; result += `
  • ${sd.path}, line ${n} (as a ${sd.type})`; } else { @@ -66,7 +66,14 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) { result += `
  • ${sd.path} (as a ${sd.type})`; result += ''; } @@ -77,7 +84,7 @@ function generateSymbolDefinitionsHTML(symbolDefinitions, project, version) { return result; } -function generateSymbolReferencesHTML(symbolReferences, project, version) { +function generateSymbolReferencesHTML(symbolReferences, peeks, project, version) { let result = ""; if(symbolReferences.length == 0) { @@ -88,7 +95,7 @@ function generateSymbolReferencesHTML(symbolReferences, project, version) { result += '
      '; for (let sr of symbolReferences) { let ln = sr.line.split(','); - if (ln.length == 1) { + if (ln.length == 1 && !peeks) { let n = ln[0]; result += `
    • ${sr.path}, line ${n}`; } else { @@ -99,7 +106,14 @@ function generateSymbolReferencesHTML(symbolReferences, project, version) { result += `
    • ${sr.path}`; result += '' } @@ -143,10 +157,11 @@ function generateReferencesHTML(data, project, version) { let symbolDefinitions = data["definitions"]; let symbolReferences = data["references"]; let symbolDocumentations = data["documentations"]; + let peeks = data["peeks"]; return '
      ' + generateDocCommentsHTML(symbolDocumentations, project, version) + - generateSymbolDefinitionsHTML(symbolDefinitions, project, version) + - generateSymbolReferencesHTML(symbolReferences, project, version) + + generateSymbolDefinitionsHTML(symbolDefinitions, peeks, project, version) + + generateSymbolReferencesHTML(symbolReferences, peeks, project, version) + '
      '; } diff --git a/static/style.css b/static/style.css index 127878fa..c8b838a6 100644 --- a/static/style.css +++ b/static/style.css @@ -693,6 +693,12 @@ h2 { font-weight: 400; color: #000; } + +.lxrident a span { + width: 8em; + display: inline-block; +} + .lxrident li li::before { color: #444; } @@ -714,6 +720,11 @@ h2 { content: '└╴'; } +.lxrident li pre { + display: inline-block; + margin: auto; +} + /* tree */ From a270c3cd122c9c3849adf05ead172de4e0e99d3c Mon Sep 17 00:00:00 2001 From: Daniil159x Date: Sun, 22 Dec 2024 03:12:34 +0300 Subject: [PATCH 3/3] use peeks in jinja --- elixir/web.py | 22 +++++++++++++--------- templates/ident.html | 10 +++++++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/elixir/web.py b/elixir/web.py index 2a0cbbbb..262fc1e8 100755 --- a/elixir/web.py +++ b/elixir/web.py @@ -635,11 +635,12 @@ def generate_source_page(ctx, q, project, version, path): # type: type of the symbol # path: path of the file that contains the symbol # line: list of LineWithURL -SymbolEntry = namedtuple('SymbolEntry', 'type, path, lines') +# peeks: map of code line previews for this path +SymbolEntry = namedtuple('SymbolEntry', 'type, path, lines, peeks') # Converts SymbolInstance into SymbolEntry # path of SymbolInstance will be appended to base_url -def symbol_instance_to_entry(base_url, symbol): +def symbol_instance_to_entry(base_url, symbol, peeks): # TODO this should be a responsibility of Query if type(symbol.line) is str: line_numbers = symbol.line.split(',') @@ -647,11 +648,13 @@ def symbol_instance_to_entry(base_url, symbol): line_numbers = [symbol.line] lines = [ - LineWithURL(l, f'{ base_url }/{ symbol.path }#L{ l }') + LineWithURL(int(l), f'{ base_url }/{ symbol.path }#L{ l }') for l in line_numbers ] - return SymbolEntry(symbol.type, symbol.path, lines) + current_peeks = peeks.get(symbol.path, {}) + + return SymbolEntry(symbol.type, symbol.path, lines, current_peeks) # Generates response (status code and optionally HTML) of the `ident` route # ctx: RequestContext @@ -662,15 +665,16 @@ def generate_ident_page(ctx, q, project, version, family, ident): source_base_url = get_source_base_url(project, version) - symbol_definitions, symbol_references, symbol_doccomments = q.query('ident', version, ident, family) + symbol_definitions, symbol_references, symbol_doccomments, peeks = q.query('ident', version, ident, family) symbol_sections = [] + empty_peeks = {} if len(symbol_definitions) or len(symbol_references): if len(symbol_doccomments): symbol_sections.append({ 'title': 'Documented', - 'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym) for sym in symbol_doccomments]}, + 'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym, empty_peeks) for sym in symbol_doccomments]}, }) if len(symbol_definitions): @@ -679,9 +683,9 @@ def generate_ident_page(ctx, q, project, version, family, ident): # TODO this should be a responsibility of Query for sym in symbol_definitions: if sym.type not in defs_by_type: - defs_by_type[sym.type] = [symbol_instance_to_entry(source_base_url, sym)] + defs_by_type[sym.type] = [symbol_instance_to_entry(source_base_url, sym, peeks)] else: - defs_by_type[sym.type].append(symbol_instance_to_entry(source_base_url, sym)) + defs_by_type[sym.type].append(symbol_instance_to_entry(source_base_url, sym, peeks)) symbol_sections.append({ 'title': 'Defined', @@ -695,7 +699,7 @@ def generate_ident_page(ctx, q, project, version, family, ident): if len(symbol_references): symbol_sections.append({ 'title': 'Referenced', - 'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym) for sym in symbol_references]}, + 'symbols': {'_unknown': [symbol_instance_to_entry(source_base_url, sym, peeks) for sym in symbol_references]}, }) else: symbol_sections.append({ diff --git a/templates/ident.html b/templates/ident.html index 7781494d..67f426df 100644 --- a/templates/ident.html +++ b/templates/ident.html @@ -33,7 +33,7 @@

      {{ section['title'] }} in {{ symbols|length }} files
    • {{ symbol.path }} - {%- if symbol.lines|length == 1 %}, + {%- if symbol.lines|length == 1 and symbol.peeks|length == 0 %}, line {{ symbol.lines[0].lineno }} {%- elif symbols|length > 100 %}, {{ symbol.lines|length }} times @@ -42,10 +42,14 @@

      {{ section['title'] }} in {{ symbols|length }} files (as a {{ symbol.type }}) {% endif %} - {% if symbol.lines|length > 1 and symbols|length <= 100 %} + {% if (symbol.lines|length > 1 or symbol.peeks|length > 0) and symbols|length <= 100 %} {% endif %}