-
Notifications
You must be signed in to change notification settings - Fork 0
/
path.hpp
145 lines (118 loc) · 3.79 KB
/
path.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* This file implements the path gestion.
*/
#ifndef PATH_HPP
#define PATH_HPP
#include "config.hpp"
#include "log.hpp"
#include <cctype>
#include <filesystem>
#include <map>
#include <set>
#include <string>
#include <ncurses.h>
#include "libft-detect.hpp"
/// Maximum number of entries in a directory to take into account
#define MAX_LINES 10000
namespace fs = std::filesystem;
struct Entry {
fs::path path;
lft::filetype *filetype;
bool isDisplayed = false;
bool isVirtual = false;
~Entry();
};
/**
* Custom sort function.
* It is not case sensitive and handle numbers as expected (lower go first)
*/
static auto entrySort = [](Entry *a, Entry *b) {
lft::generalFT af = ft_finder->getFiletype(a->path)->general;
lft::generalFT bf = ft_finder->getFiletype(b->path)->general;
if (af != bf) {
for (auto &ft : config->filetype_order) {
if (af == ft)
return true;
if (bf == ft)
return false;
}
}
std::string as = a->path.filename();
std::string bs = b->path.filename();
// Sort string filename
for (auto &c : as)
c = std::tolower(c);
for (auto &c : bs)
c = std::tolower(c);
// Sort int filename (e.g. /proc/PID)
auto to_int = [](std::string &s, int &i) {
for (auto &c : s) {
if (!isdigit(c))
return false;
}
i = std::stoi(s);
return true;
};
int ai, bi;
if (to_int(as, ai) && to_int(bs, bi))
return ai < bi;
return as < bs;
};
/**
* The content of a directory
* Uses `std::set` to automatically sort the entries alphabetically
*/
class Content {
public:
~Content();
std::set<Entry *, decltype(entrySort)> entries;
inline unsigned int numOfEntries() { return entries.size(); }
void addVirtual(std::string text);
void makeVirtual(std::string text);
lft::filetype *getFileType(unsigned int n);
Entry *getFileByLine(unsigned int line);
inline void setSavedLine(unsigned int cl) { savedLine = cl; }
inline unsigned int getSavedLine() { return savedLine; }
private:
Entry *getNthElement(std::set<Entry *, decltype(entrySort)> &s, unsigned int n);
unsigned int savedLine; // the line is saved the restore the state latter
};
class Window; // in miller.hpp
/**
* The class representing the status of the path
*/
class Path {
public:
Path(fs::path start_path);
~Path();
bool goUp();
void goDown();
void previewChild(Window *win);
int find(Content *content, fs::path p);
inline fs::path path() { return currentPath; }
inline void setPath(const fs::path p) { currentPath = p; }
/// Get the corresponding content
inline Content *&parent() { return parentContent; }
inline Content *¤t() { return currentContent; }
inline Content *&child() { return childContent; }
/// Get the corresponding content with an aditionnal pointer
//inline Content **parentp() { return &parentContent; }
//inline Content **currentp() { return ¤tContent; }
//inline Content **childp() { return &childContent; }
/// Set the corresponding content
inline void setParent(Content *c) { parentContent = c; }
inline void setCurrent(Content *c) { currentContent = c; }
inline void setChild(Content *c) { childContent = c; }
void updateCache(int parentLine, int currentLine, int childLine, fs::path childPath);
void restoreCache();
private:
Content *parentContent, *currentContent, *childContent;
fs::path currentPath;
std::map<std::string, Content *> contentCache;
int loadContent(Content *&content, fs::path path);
int getIndex(const std::set<Entry *, decltype(entrySort)> &s, fs::path p);
};
namespace path {
fs::path simplify(fs::path p);
}
#endif // PATH_HPP