Flatten nested paths with only one child
Diff
flake.nix | 1 -
src/git.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
grammar/fortran/highlights.scm | 197 --------------------------------------------------------------------------------
grammar/html/highlights.scm | 20 --------------------
grammar/html/injections.scm | 10 ----------
templates/repo/tree.html | 6 +++++-
src/methods/repo/tree.rs | 1 +
7 files changed, 50 insertions(+), 247 deletions(-)
@@ -54,7 +54,6 @@
./src
./statics
./templates
./grammar
./themes
./build.rs
];
@@ -1,15 +1,3 @@
use std::{
borrow::Cow,
collections::{BTreeMap, VecDeque},
ffi::OsStr,
fmt::{self, Arguments, Write},
io::ErrorKind,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
time::Duration,
};
use anyhow::{anyhow, Context, Result};
use axum::response::IntoResponse;
use bytes::{buf::Writer, BufMut, Bytes, BytesMut};
@@ -26,7 +14,19 @@
url::Scheme,
ObjectId, ThreadSafeRepository, Url,
};
use itertools::Itertools;
use moka::future::Cache;
use std::borrow::Cow;
use std::{
collections::{BTreeMap, VecDeque},
ffi::OsStr,
fmt::{self, Arguments, Write},
io::ErrorKind,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
time::Duration,
};
use tar::Builder;
use time::{OffsetDateTime, UtcOffset};
use tracing::{error, instrument, warn};
@@ -198,7 +198,7 @@
| EntryKind::Blob
| EntryKind::BlobExecutable
| EntryKind::Link => {
let object = item
let mut object = item
.object()
.context("Expected item in tree to be object but it wasn't")?;
@@ -206,14 +206,39 @@
Kind::Blob => TreeItem::File(File {
mode: item.mode().0,
size: object.into_blob().data.len(),
path,
name: item.filename().to_string(),
}),
Kind::Tree => TreeItem::Tree(Tree {
mode: item.mode().0,
path,
name: item.filename().to_string(),
}),
Kind::Tree => {
let mut children = PathBuf::new();
while let Ok(Some(Ok(item))) = object
.try_into_tree()
.iter()
.map(gix::Tree::iter)
.flatten()
.at_most_one()
{
let nested_object = item.object().context(
"Expected item in tree to be object but it wasn't",
)?;
if nested_object.kind != Kind::Tree {
break;
}
object = nested_object;
children.push(item.filename().to_path_lossy());
}
TreeItem::Tree(Tree {
mode: item.mode().0,
path,
children,
name: item.filename().to_string(),
})
}
_ => continue,
});
}
@@ -602,6 +627,7 @@
pub struct Tree {
pub mode: u16,
pub name: String,
pub children: PathBuf,
pub path: PathBuf,
}
@@ -1,197 +1,0 @@
(identifier) @variable
(string_literal) @string
(number_literal) @number
(boolean_literal) @boolean
(comment) @comment
[
(intrinsic_type)
"allocatable"
"attributes"
"device"
"dimension"
"endtype"
"global"
"grid_global"
"host"
"import"
"in"
"inout"
"intent"
"optional"
"out"
"pointer"
"type"
"value"
] @type
[
"contains"
"private"
"public"
] @include
[
(none)
"implicit"
] @attribute
[
"endfunction"
"endprogram"
"endsubroutine"
"function"
"procedure"
"subroutine"
] @keyword.function
[
(default)
(procedure_qualifier)
"abstract"
"bind"
"call"
"class"
"continue"
"cycle"
"endenum"
"endinterface"
"endmodule"
"endprocedure"
"endprogram"
"endsubmodule"
"enum"
"enumerator"
"equivalence"
"exit"
"extends"
"format"
"goto"
"include"
"interface"
"intrinsic"
"non_intrinsic"
"module"
"namelist"
"only"
"parameter"
"print"
"procedure"
"program"
"read"
"stop"
"submodule"
"use"
"write"
] @keyword
"return" @keyword.return
[
"else"
"elseif"
"elsewhere"
"endif"
"endwhere"
"if"
"then"
"where"
] @conditional
[
"do"
"enddo"
"forall"
"while"
] @repeat
[
"*"
"+"
"-"
"/"
"="
"<"
">"
"<="
">="
"=="
"/="
] @operator
[
"\\.and\\."
"\\.or\\."
"\\.lt\\."
"\\.gt\\."
"\\.ge\\."
"\\.le\\."
"\\.eq\\."
"\\.eqv\\."
"\\.neqv\\."
] @keyword.operator
[
"("
")"
"["
"]"
"<<<"
">>>"
] @punctuation.bracket
[
"::"
","
"%"
] @punctuation.delimiter
(parameters
(identifier) @parameter)
(program_statement
(name) @namespace)
(module_statement
(name) @namespace)
(submodule_statement
(module_name) (name) @namespace)
(function_statement
(name) @function)
(subroutine_statement
(name) @function)
(module_procedure_statement
(name) @function)
(end_program_statement
(name) @namespace)
(end_module_statement
(name) @namespace)
(end_submodule_statement
(name) @namespace)
(end_function_statement
(name) @function)
(end_subroutine_statement
(name) @function)
(end_module_procedure_statement
(name) @function)
(subroutine_call
(identifier) @function)
(keyword_argument
name: (identifier) @keyword)
(derived_type_member_expression
(type_member) @property)
@@ -1,20 +1,0 @@
(tag_name) @tag
(erroneous_end_tag_name) @tag.error
(doctype) @constant
(attribute_name) @attribute
(comment) @comment
[
"\""
(attribute_value)
] @string
[
"<"
">"
"</"
"/>"
"<!"
] @punctuation.bracket
"=" @punctuation.delimiter
@@ -1,10 +1,0 @@
((comment) @injection.content
(#set! injection.language "comment"))
((script_element
(raw_text) @injection.content)
(#set! injection.language "javascript"))
((style_element
(raw_text) @injection.content)
(#set! injection.language "css"))
@@ -19,7 +19,11 @@
{% match item -%}
{%- when crate::git::TreeItem::Tree with (tree) -%}
<td><pre>{{ tree.mode|file_perms }}</pre></td>
<td><pre><a class="nested-tree" href="/{{ repo.display() }}/tree/{{ tree.path.display() }}{{ query }}">{{ tree.name }}</a></pre></td>
<td><pre><a class="nested-tree" href="/{{ repo.display() }}/tree/{{ tree.path.display() }}{{ query }}">{{ tree.name }}</a>
{%- for child in tree.children.ancestors().collect_vec().into_iter().rev() -%}
{%- if let Some(file_name) = child.file_name() %} / <a class="nested-tree" href="/{{ repo.display() }}/tree/{{ tree.path.display() }}/{{ child.display() }}{{ query }}">{{ file_name.to_string_lossy() }}</a>{%- endif -%}
{%- endfor -%}
</pre></td>
<td></td>
<td></td>
@@ -5,6 +5,7 @@
use askama::Template;
use axum::{extract::Query, response::IntoResponse, Extension};
use itertools::Itertools;
use serde::Deserialize;
use crate::{