Skip to content

Commit 733a6ad

Browse files
Compact directories
1 parent b92ba1f commit 733a6ad

File tree

28 files changed

+415
-78
lines changed

28 files changed

+415
-78
lines changed

README.md

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,45 @@
11
# JFileTreePrettyPrint
22

3-
A lightweight Java library for printing directory structures in a clean, tree-like format (think Unix `tree` command).
3+
A lightweight Java library for printing directory structures in a clean, tree-like format.
44

55
- Print folder trees like Unix `tree`
6-
- Choose ASCII or Unicode styles for tree rendering
7-
- Emoji support 🎉
8-
- Limit displayed children statically or dynamically
6+
- Customizable:
7+
- ASCII or Unicode styles for tree rendering
8+
- Emoji support 🎉
9+
- Limit displayed children statically or dynamically
10+
- Compact directory chains
11+
12+
**ℹ️ Was developed just for fun, has not been thoroughly tested! May not be suitable for production code 😊**
13+
14+
```java
15+
// Example: BasicUsage.java
16+
var printer = FileTreePrettyPrinter.createDefault();
17+
var tree = printer.prettyPrint("src/example/resources/base");
18+
System.out.println(tree);
19+
```
20+
21+
Result:
22+
```
23+
base/
24+
├─ businessPlan.pdf
25+
├─ businessProject.pdf
26+
├─ cars/
27+
│ ├─ Ferrari.doc
28+
│ └─ Porsche.doc
29+
├─ diyIdeas.docx
30+
├─ giftIdeas.txt
31+
└─ images/
32+
├─ funnyCat.gif
33+
├─ holidays/
34+
│ ├─ meAtTheBeach.jpeg
35+
│ └─ meAtTheZoo.jpeg
36+
└─ landscape.jpeg
37+
```
938

10-
ℹ️ Was developed just for fun!
1139

12-
* [Import dependency](#import-dependency)
1340
* [Usage](#usage)
41+
* [Import dependency](#import-dependency)
1442
* [Options](#options)
15-
* [Tree format](#tree-format)
16-
* [Emojis ❤️](#emojis-%EF%B8%8F)
17-
* [Children limit](#children-limit)
1843
* [Changelog](#changelog)
1944
* [Roadmap](#roadmap)
2045
* [License](#license)
@@ -39,34 +64,14 @@ For Gradle:
3964
implementation "com.github.computerdaddyguy:jfiletreeprettyprinter:0.1.0"
4065
```
4166

42-
# Usage
43-
```java
44-
// Example: BasicUsage.java
45-
var printer = FileTreePrettyPrinter.createDefault();
46-
var tree = printer.prettyPrint("src/example/resources/base");
47-
System.out.println(tree);
48-
```
49-
50-
Result:
51-
```
52-
base/
53-
├─ businessPlan.pdf
54-
├─ businessProject.pdf
55-
├─ cars/
56-
│ ├─ Ferrari.doc
57-
│ └─ Porsche.doc
58-
├─ diyIdeas.docx
59-
├─ giftIdeas.txt
60-
└─ images/
61-
├─ funnyCat.gif
62-
├─ holidays/
63-
│ ├─ meAtTheBeach.jpeg
64-
│ └─ meAtTheZoo.jpeg
65-
└─ landscape.jpeg
66-
```
6767

6868
# Options
6969

70+
* [Tree format](#tree-format)
71+
* [Emojis ❤️](#emojis-%EF%B8%8F)
72+
* [Children limit](#children-limit)
73+
* [Compact directories](#compact-directories)
74+
7075
## Tree format
7176
Choose between different tree formats.
7277
The default is `UNICODE_BOX_DRAWING`, supported by all terminals, but you can also switch to use `CLASSIC_ASCII`.
@@ -163,7 +168,8 @@ static_children_limit/
163168
164169
```
165170

166-
Or you can also set a limitation function, to dynamically choose the number of children displayed in each directory (for, say, avoid cluttering the whole console with known large folders like `node_modules` but continue to pretty print normally other folders).
171+
Or you can also set a limitation function, to dynamically choose the number of children displayed in each directory.
172+
It avoids cluttering the whole console with known large folders (e.g. `node_modules`) but continue to pretty print normally other folders.
167173

168174
The `PathPredicates` class contains several ready-to-use predicates to help you.
169175

@@ -187,6 +193,27 @@ children_limit_dynamic/
187193
└─ ... (9 files skipped)
188194
```
189195

196+
💡 *Idea for a future version: helper for custom basic functions (by name, prefix, regex, etc.)*
197+
198+
## Compact directories
199+
Directories chain with single directory child are fully expanded by default, but you can compact them into a single tree entry.
200+
201+
```java
202+
// Example: CompactDirectories.java
203+
var prettyPrinter = FileTreePrettyPrinter.builder()
204+
.customizeOptions(options -> options.withCompactDirectories(true))
205+
.build();
206+
```
207+
```
208+
single_directory_child/
209+
├─ file1
210+
├─ file2
211+
└─ this/is/single/directory/child/
212+
├─ file1
213+
├─ file2
214+
└─ file3
215+
```
216+
190217
# Changelog
191218
See [CHANGELOG.md](CHANGELOG.md) for released versions.
192219

ROADMAP.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
- [x] Pre-defined Path predicates
1010
- [x] Add examples & README
1111
- [x] Implement emojis for files
12+
- [x] Unify dir-in-a-row into a single entry option
1213
- [ ] Max depth options
13-
- [ ] Unify dir-in-a-row into a single entry option
14+
- [ ] Refactor unit tests (custom assert?)
1415
- [ ] Publish on Maven Central!
1516

1617
## Other ideas
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.github.computerdaddyguy.jfiletreeprettyprinter.example;
2+
3+
import io.github.computerdaddyguy.jfiletreeprettyprinter.FileTreePrettyPrinter;
4+
5+
public class CompactDirectories {
6+
7+
public static void main(String[] args) {
8+
var prettyPrinter = FileTreePrettyPrinter.builder()
9+
.customizeOptions(options -> options.withCompactDirectories(true))
10+
.build();
11+
var tree = prettyPrinter.prettyPrint("src/example/resources/single_directory_child");
12+
System.out.println(tree);
13+
}
14+
15+
}

src/example/resources/single_directory_child/file1

Whitespace-only changes.

src/example/resources/single_directory_child/file2

Whitespace-only changes.

src/example/resources/single_directory_child/this/is/single/directory/child/file1

Whitespace-only changes.

src/example/resources/single_directory_child/this/is/single/directory/child/file2

Whitespace-only changes.

src/example/resources/single_directory_child/this/is/single/directory/child/file3

Whitespace-only changes.

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/PrettyPrintOptions.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class PrettyPrintOptions implements VisitingOptions, RenderingOptions {
1414

1515
private TreeFormat treeFormat = TreeFormat.UNICODE_BOX_DRAWING;
1616
private boolean useEmojis = false;
17+
private boolean compactDirectories = false;
1718

1819
public PrettyPrintOptions() {
1920
super();
@@ -91,4 +92,22 @@ public PrettyPrintOptions withEmojis(boolean useEmojis) {
9192
return this;
9293
}
9394

95+
// ----------------------------------------------
96+
97+
@Override
98+
public boolean areCompactDirectoriesUsed() {
99+
return compactDirectories;
100+
}
101+
102+
/**
103+
* Whether or not compact directories chain into a single entry in the rendered tree.
104+
* Default is {@code false}.
105+
*
106+
* @param compact {@code true} to compact, {@code false} otherwise.
107+
*/
108+
public PrettyPrintOptions withCompactDirectories(boolean compact) {
109+
this.compactDirectories = compact;
110+
return this;
111+
}
112+
94113
}

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/visitor/ChildVisitRegister.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,20 @@ public boolean hasSomeNotVisitedChildren() {
7171
return records.isEmpty() ? false : records.getLast().notVisited().size() > 0;
7272
}
7373

74+
public boolean hasSingleDirectoryChild() {
75+
return records.isEmpty() ? false : records.getLast().hasSingleDirectoryChild();
76+
}
77+
7478
private class ChildVisitCounterRecord {
7579

7680
private final int maxChildVisitCount;
81+
private LinkedHashSet<Path> allChildren;
7782
private LinkedHashSet<Path> notVisited;
7883
private LinkedHashSet<Path> alreadyVisited;
7984

8085
ChildVisitCounterRecord(int maxChildVisitCount, LinkedHashSet<Path> childrenInDir) {
8186
this.maxChildVisitCount = maxChildVisitCount;
87+
this.allChildren = childrenInDir;
8288
this.notVisited = childrenInDir;
8389
this.alreadyVisited = new LinkedHashSet<Path>();
8490
}
@@ -99,6 +105,10 @@ Set<Path> notVisited() {
99105
return notVisited;
100106
}
101107

108+
boolean hasSingleDirectoryChild() {
109+
return allChildren.size() == 1 && allChildren.getFirst().toFile().isDirectory();
110+
}
111+
102112
}
103113

104114
}

0 commit comments

Comments
 (0)