-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
History API rewrite (discussion after #680) #735
Comments
@stormasm what do you mean exactly by that? Given you currently can disable API and completer by simply not providing them when |
@ClementNerma true, good point ! Think about it then from the point of view of having a History / Menu / Completer (HMC) crate system where developers can come along and have the ability to implement any one of the three components given our fundamental Reedline API into these systems... In other words vastly loosening the Engine API to be able to accept those components (as Traits)... Or something to that effect... From the History API point of view imagine you wanted to use a different persistence database / something different than SQLite (for example)... |
Sorry, I don't really get what you're suggesting. Aren't these three components traits already? PR #680 was about making it more flexible and easier to use, but it was already a trait before. IIRC I've already implemented a custom completer, and in the current git tree it seems you can make custom menus? |
@ClementNerma going back to your previous PR --- one thing you mentioned in there was to leave the File format of the History API alone ---- that seems critical to me... The current file format of the History API would remain "untouched". I really like the way it works for many different reasons... |
@ClementNerma lets just focus on the History API for now... |
Seems fine to me. For the SQLite database I feel like it could still be useful for programs who'd like to take advantage of it, so I'd like to keep the ID inside. The migration is instant for previous database and 100% compatible with the previous one (the only change to the schema is one new column).
Well initially I started the PR to create a path for myself while building my own shell. But now I'd like to think this could help other people as Reedline is the 'de facto' library for this kind of task in Rust. So why not improve it in multiple ways? I now have a good understanding of how the history API works so that's where I can be the more proficient for now, but I'm absolutely not against helping on other parts if help is required :) |
@ClementNerma sounds good to me ! again, thanks for showing an interest in improving the History API... |
I updated the PR, I feel like it should mergeable in its current state. What do you think? This could be the first brick of a larger API overhaul, but greatly improving the History API and making it entirely implementable for everyone is a major upside IMO. I think a later step could be to introduce a third builtin history type, which would use all the features from the history. Like SQLite, but using a more performant and compact system like |
@ClementNerma I don't see any new commits in the PR, can you please paste a link to the PR here, if we are talking #680 --- the last commit I see is from awhile ago... |
Indeed it doesn't show up in the PR 🤔 |
@ClementNerma we are doing a nushell release on Feb 6 so it probably makes sense to hold off on submitting the PR to next week... Prior to submitting the PR I would recommend NOT changing anything in the Schema file for the SQlite... I don't think we are going to want to have to run a Migrate script on developers databases... So I would recommend no changes to the text file or the database file... Also I would recommend running your ideas by @Hofer-Julian prior to doing any more work on this concept... They are pretty familiar with the inner workings of how Reedline interacts and works with the History / Database... And may have some insights on how you can move forward with your intentions of improving History. Thanks ! |
Ok so I'll remove the new SQLite schema and wait for people to review it. |
@ClementNerma since the old PR is already closed and it has lots of old stuff in there... can you please open a new PR so we start from a clean slate... thanks ! |
To remove duplicates from the command history in nushell, I have created the PR The code snippets are from the version I've looked at f244736. save /// save a history item to the database
/// if given id is None, a new id is created and set in the return value
/// if given id is Some, the existing entry is updated
fn save(&mut self, h: HistoryItem) -> Result<HistoryItem>; I don't think that a new history item must be generated if no id is given. count and search /// count the results of a query
fn count(&self, query: SearchQuery) -> Result<i64>;
/// return the total number of history items
fn count_all(&self) -> Result<i64> {
self.count(SearchQuery::everything(SearchDirection::Forward, None))
}
/// return the results of a query
fn search(&self, query: SearchQuery) -> Result<Vec<HistoryItem>>; Search should probably return an iterator and not a It might even make sense to combine File-based historyThis is an append-only log with just the commands synchronized between It probably shouldn't contain duplicates. I would change the format to include a
Without changing the file format, one could also simply not save entries that |
This is a very ambiguous scenario that's not obvious at first glance ; hence why I'm recommending different methods for creating and updating items. History backends also being responsible for ID generation also to always ensure consistency within the code and always be sure we can identify a given
Allocating a 1M-elements vector doesn't take more than milliseconds, probably even less. Also, the
These are actually two very different things ; for instance in a database it would require two data fetching. In a file, even more.
Besides what I already said at the beginning of my comment, including a timestamp would break the existing text-based format. One thing I would consider (and I think it would be a very good addition IMO) would be to deprecate the old file format and create a new one with all the bells and whistles of the
I also don't think this is a good idea, requiring to update old entries would require additional writes to the file that wouldn't be needed otherwise. It also prevents the file from being append-only. |
fn main() {
let mut vec = Vec::new();
for i in 0..1_000_000 {
let str = format!("{}{}{}", &i, &i, &i);
if str.contains("111") {
vec.push((i, str));
}
}
println!("{}", vec.len());
} ~80ms on my desktop and ~310ms on my laptop. Still a history of a million commands is unrealistic, so yeah, fast enough.
After further thinking, I agree with keeping them separate. You don't always need the count and the additional aggregation it will cost.
It would be the same amount of writes. Instead of writing a duplicate at the end, some bytes in the middle are altered. Since a fixed amount of bytes is reserved, the file's content mustn't be moved at all.
I'd love to remove typos from my history when they clutter my searches. |
I was talking about an instant allocation, not 1 million of allocations, which is immensely slower :) |
This issue is aimed to track all discussions for the rewrite of the history, menu and completer (HMC) API, followed existing decisions and trials in #680 (history only).
Opening message from @stormasm : #680 (comment)
The text was updated successfully, but these errors were encountered: