history.h:

some typedefs -> using declarations
make the documentation comments work
This commit is contained in:
Aaron Gyes
2021-12-12 13:36:14 -08:00
parent 549fae1400
commit 04a4693b5b

View File

@@ -26,42 +26,43 @@ class env_stack_t;
class environment_t;
class operation_context_t;
// Fish supports multiple shells writing to history at once. Here is its strategy:
//
// 1. All history files are append-only. Data, once written, is never modified.
//
// 2. A history file may be re-written ("vacuumed"). This involves reading in the file and writing a
// new one, while performing maintenance tasks: discarding items in an LRU fashion until we reach
// the desired maximum count, removing duplicates, and sorting them by timestamp (eventually, not
// implemented yet). The new file is atomically moved into place via rename().
//
// 3. History files are mapped in via mmap(). Before the file is mapped, the file takes a fcntl read
// lock. The purpose of this lock is to avoid seeing a transient state where partial data has been
// written to the file.
//
// 4. History is appended to under a fcntl write lock.
//
// 5. The chaos_mode boolean can be set to true to do things like lower buffer sizes which can
// trigger race conditions. This is useful for testing.
/**
Fish supports multiple shells writing to history at once. Here is its strategy:
typedef std::vector<wcstring> path_list_t;
1. All history files are append-only. Data, once written, is never modified.
2. A history file may be re-written ("vacuumed"). This involves reading in the file and writing a
new one, while performing maintenance tasks: discarding items in an LRU fashion until we reach
the desired maximum count, removing duplicates, and sorting them by timestamp (eventually, not
implemented yet). The new file is atomically moved into place via rename().
3. History files are mapped in via mmap(). Before the file is mapped, the file takes a fcntl read
lock. The purpose of this lock is to avoid seeing a transient state where partial data has been
written to the file.
4. History is appended to under a fcntl write lock.
5. The chaos_mode boolean can be set to true to do things like lower buffer sizes which can
trigger race conditions. This is useful for testing.
*/
using path_list_t = std::vector<wcstring>;
enum class history_search_type_t {
// Search for commands exactly matching the given string.
/// Search for commands exactly matching the given string.
exact,
// Search for commands containing the given string.
/// Search for commands containing the given string.
contains,
// Search for commands starting with the given string.
/// Search for commands starting with the given string.
prefix,
// Search for commands containing the given glob pattern.
/// Search for commands containing the given glob pattern.
contains_glob,
// Search for commands starting with the given glob pattern.
/// Search for commands starting with the given glob pattern.
prefix_glob,
// Matches everything.
/// Matches everything.
match_everything,
};
typedef uint64_t history_identifier_t;
using history_identifier_t = uint64_t;
/// Ways that a history item may be written to disk (or omitted).
enum class history_persistence_mode_t : uint8_t {
@@ -73,7 +74,7 @@ enum class history_persistence_mode_t : uint8_t {
class history_item_t {
public:
/// Construct from a text, timestamp, and optional identifier.
/// If \p no_persist is set, then do not write this item to disk.
/// If \p persist_mode is ::ephemeral, then do not write this item to disk.
explicit history_item_t(
wcstring str = {}, time_t when = 0, history_identifier_t ident = 0,
history_persistence_mode_t persist_mode = history_persistence_mode_t::disk);
@@ -84,7 +85,7 @@ class history_item_t {
/// \return whether the text is empty.
bool empty() const { return contents.empty(); }
// \return wehther our contents matches a search term.
/// \return wehther our contents matches a search term.
bool matches_search(const wcstring &term, enum history_search_type_t type,
bool case_sensitive) const;
@@ -100,22 +101,22 @@ class history_item_t {
void set_required_paths(path_list_t paths) { required_paths = std::move(paths); }
private:
// Attempts to merge two compatible history items together.
/// Attempts to merge two compatible history items together.
bool merge(const history_item_t &item);
// The actual contents of the entry.
/// The actual contents of the entry.
wcstring contents;
// Original creation time for the entry.
/// Original creation time for the entry.
time_t creation_timestamp;
// Paths that we require to be valid for this item to be autosuggested.
/// Paths that we require to be valid for this item to be autosuggested.
path_list_t required_paths;
// Sometimes unique identifier used for hinting.
/// Sometimes unique identifier used for hinting.
history_identifier_t identifier;
// If set, do not write this item to disk.
/// If set, do not write this item to disk.
history_persistence_mode_t persist_mode;
friend class history_t;
@@ -124,7 +125,7 @@ class history_item_t {
friend class history_tests_t;
};
typedef std::deque<history_item_t> history_item_list_t;
using history_item_list_t = std::deque<history_item_t>;
struct history_impl_t;
@@ -136,98 +137,98 @@ class history_t : noncopyable_t, nonmovable_t {
acquired_lock<history_impl_t> impl();
acquired_lock<const history_impl_t> impl() const;
// Privately add an item. If pending, the item will not be returned by history searches until a
// call to resolve_pending. Any trailing ephemeral items are dropped.
/// Privately add an item. If pending, the item will not be returned by history searches until a
/// call to resolve_pending. Any trailing ephemeral items are dropped.
void add(history_item_t &&item, bool pending = false);
// Add a new history item with text \p str to the end of history.
/// Add a new history item with text \p str to the end of history.
void add(wcstring str);
public:
explicit history_t(wcstring name);
~history_t();
// Whether we're in maximum chaos mode, useful for testing.
// This causes things like locks to fail.
/// Whether we're in maximum chaos mode, useful for testing.
/// This causes things like locks to fail.
static bool chaos_mode;
// Whether to force the read path instead of mmap. This is useful for testing.
/// Whether to force the read path instead of mmap. This is useful for testing.
static bool never_mmap;
// Returns history with the given name, creating it if necessary.
/// Returns history with the given name, creating it if necessary.
static std::shared_ptr<history_t> with_name(const wcstring &name);
/// Returns whether this is using the default name.
bool is_default() const;
// Determines whether the history is empty. Unfortunately this cannot be const, since it may
// require populating the history.
/// Determines whether the history is empty. Unfortunately this cannot be const, since it may
/// require populating the history.
bool is_empty();
// Remove a history item.
/// Remove a history item.
void remove(const wcstring &str);
/// Remove any trailing ephemeral items.
void remove_ephemeral_items();
// Add a new pending history item to the end, and then begin file detection on the items to
// determine which arguments are paths. Arguments may be expanded (e.g. with PWD and variables)
// using the given \p vars. The item has the given \p persist_mode.
/// Add a new pending history item to the end, and then begin file detection on the items to
/// determine which arguments are paths. Arguments may be expanded (e.g. with PWD and variables)
/// using the given \p vars. The item has the given \p persist_mode.
static void add_pending_with_file_detection(
const std::shared_ptr<history_t> &self, const wcstring &str,
const std::shared_ptr<environment_t> &vars,
history_persistence_mode_t persist_mode = history_persistence_mode_t::disk);
// Resolves any pending history items, so that they may be returned in history searches.
/// Resolves any pending history items, so that they may be returned in history searches.
void resolve_pending();
// Saves history.
/// Saves history.
void save();
// Searches history.
/// Searches history.
bool search(history_search_type_t search_type, const wcstring_list_t &search_args,
const wchar_t *show_time_format, size_t max_items, bool case_sensitive,
bool null_terminate, bool reverse, const cancel_checker_t &cancel_check,
io_streams_t &streams);
// Irreversibly clears history.
/// Irreversibly clears history.
void clear();
// Irreversibly clears history for the current session.
/// Irreversibly clears history for the current session.
void clear_session();
// Populates from older location (in config path, rather than data path).
/// Populates from older location (in config path, rather than data path).
void populate_from_config_path();
// Populates from a bash history file.
/// Populates from a bash history file.
void populate_from_bash(FILE *f);
// Incorporates the history of other shells into this history.
/// Incorporates the history of other shells into this history.
void incorporate_external_changes();
// Gets all the history into a list. This is intended for the $history environment variable.
// This may be long!
/// Gets all the history into a list. This is intended for the $history environment variable.
/// This may be long!
void get_history(wcstring_list_t &result);
// Let indexes be a list of one-based indexes into the history, matching the interpretation of
// $history. That is, $history[1] is the most recently executed command. Values less than one
// are skipped. Return a mapping from index to history item text.
/// Let indexes be a list of one-based indexes into the history, matching the interpretation of
/// $history. That is, $history[1] is the most recently executed command. Values less than one
/// are skipped. Return a mapping from index to history item text.
std::unordered_map<long, wcstring> items_at_indexes(const std::vector<long> &idxs);
// Return the specified history at the specified index. 0 is the index of the current
// commandline. (So the most recent item is at index 1.)
/// Return the specified history at the specified index. 0 is the index of the current
/// commandline. (So the most recent item is at index 1.)
history_item_t item_at_index(size_t idx);
// Return the number of history entries.
/// Return the number of history entries.
size_t size();
};
/// Flags for history searching.
enum {
// If set, ignore case.
/// If set, ignore case.
history_search_ignore_case = 1 << 0,
// If set, do not deduplicate, which can help performance.
/// If set, do not deduplicate, which can help performance.
history_search_no_dedup = 1 << 1
};
using history_search_flags_t = uint32_t;
@@ -236,52 +237,52 @@ using history_search_flags_t = uint32_t;
/// Note this does NOT de-duplicate; it is the caller's responsibility to do so.
class history_search_t {
private:
// The history in which we are searching.
// TODO: this should be a shared_ptr.
/// The history in which we are searching.
/// TODO: this should be a shared_ptr.
history_t *history_;
// The original search term.
/// The original search term.
wcstring orig_term_;
// The (possibly lowercased) search term.
/// The (possibly lowercased) search term.
wcstring canon_term_;
// Our search type.
/// Our search type.
enum history_search_type_t search_type_ { history_search_type_t::contains };
// Our flags.
/// Our flags.
history_search_flags_t flags_{0};
// The current history item.
/// The current history item.
maybe_t<history_item_t> current_item_;
// Index of the current history item.
/// Index of the current history item.
size_t current_index_{0};
// If deduping, the items we've seen.
/// If deduping, the items we've seen.
std::unordered_set<wcstring> deduper_;
// return whether we are case insensitive.
/// return whether we are case insensitive.
bool ignores_case() const { return flags_ & history_search_ignore_case; }
// return whether we deduplicate items.
/// return whether we deduplicate items.
bool dedup() const { return !(flags_ & history_search_no_dedup); }
public:
// Gets the original search term.
/// Gets the original search term.
const wcstring &original_term() const { return orig_term_; }
// Finds the previous search result (backwards in time). Returns true if one was found.
/// Finds the previous search result (backwards in time). Returns true if one was found.
bool go_backwards();
// Returns the current search result item. asserts if there is no current item.
/// Returns the current search result item. asserts if there is no current item.
const history_item_t &current_item() const;
// Returns the current search result item contents. asserts if there is no current item.
/// Returns the current search result item contents. asserts if there is no current item.
const wcstring &current_string() const;
// Construct from a history pointer; the caller is responsible for ensuring the history stays
// alive.
/// Construct from a history pointer; the caller is responsible for ensuring the history stays
/// alive.
history_search_t(history_t *hist, const wcstring &str,
enum history_search_type_t type = history_search_type_t::contains,
history_search_flags_t flags = 0)
@@ -291,39 +292,43 @@ class history_search_t {
}
}
// Construct from a shared_ptr. TODO: this should be the only constructor.
/// Construct from a shared_ptr. TODO: this should be the only constructor.
history_search_t(const std::shared_ptr<history_t> &hist, const wcstring &str,
enum history_search_type_t type = history_search_type_t::contains,
history_search_flags_t flags = 0)
: history_search_t(hist.get(), str, type, flags) {}
// Default constructor.
/** Default constructor. */
history_search_t() = default;
};
/// Saves the new history to disk.
/** Saves the new history to disk. */
void history_save_all();
/// Return the prefix for the files to be used for command and read history.
/** Return the prefix for the files to be used for command and read history. */
wcstring history_session_id(const environment_t &vars);
/// Given a list of proposed paths and a context, perform variable and home directory expansion,
/// and detect if the result expands to a value which is also the path to a file.
/// Wildcard expansions are suppressed - see implementation comments for why.
/// This is used for autosuggestion hinting. If we add an item to history, and one of its arguments
/// refers to a file, then we only want to suggest it if there is a valid file there.
/// This does disk I/O and may only be called in a background thread.
/**
Given a list of proposed paths and a context, perform variable and home directory expansion,
and detect if the result expands to a value which is also the path to a file.
Wildcard expansions are suppressed - see implementation comments for why.
This is used for autosuggestion hinting. If we add an item to history, and one of its arguments
refers to a file, then we only want to suggest it if there is a valid file there.
This does disk I/O and may only be called in a background thread.
*/
path_list_t expand_and_detect_paths(const path_list_t &paths, const environment_t &vars);
/// Given a list of proposed paths and a context, expand each one and see if it refers to a file.
/// Wildcard expansions are suppressed.
/// \return true if \p paths is empty or every path is valid.
/**
Given a list of proposed paths and a context, expand each one and see if it refers to a file.
Wildcard expansions are suppressed.
\return true if \p paths is empty or every path is valid.
*/
bool all_paths_are_valid(const path_list_t &paths, const operation_context_t &ctx);
/// Sets private mode on. Once in private mode, it cannot be turned off.
/** Sets private mode on. Once in private mode, it cannot be turned off. */
void start_private_mode(env_stack_t &vars);
/// Queries private mode status.
/** Queries private mode status. */
bool in_private_mode(const environment_t &vars);
#endif