// Helper functions for working with wcstring. #ifndef FISH_WCSTRINGUTIL_H #define FISH_WCSTRINGUTIL_H #include #include #include #include "common.h" /// @typedef wcstring_range represents a range in a wcstring. /// The first element is the location, the second is the count. typedef std::pair wcstring_range; /// wcstring equivalent of wcstok(). Supports NUL. For convenience and wcstok() compatibility, the /// first character of each token separator is replaced with NUL. /// @return Returns a pair of (pos, count). /// This will be (npos, npos) when it's done. In the form of (pos, npos) /// when the token is already known to be the final token. /// @note The final token may not necessarily return (pos, npos). wcstring_range wcstring_tok(wcstring& str, const wcstring& needle, wcstring_range last = wcstring_range(0, 0)); /// Given iterators into a string (forward or reverse), splits the haystack iterators /// about the needle sequence, up to max times. Inserts splits into the output array. /// If the iterators are forward, this does the normal thing. /// If the iterators are backward, this returns reversed strings, in reversed order! /// If the needle is empty, split on individual elements (characters). template void split_about(ITER haystack_start, ITER haystack_end, ITER needle_start, ITER needle_end, wcstring_list_t* output, long max, bool no_empty = false) { long remaining = max; ITER haystack_cursor = haystack_start; while (remaining > 0 && haystack_cursor != haystack_end) { ITER split_point; if (needle_start == needle_end) { // empty needle, we split on individual elements split_point = haystack_cursor + 1; } else { split_point = std::search(haystack_cursor, haystack_end, needle_start, needle_end); } if (split_point == haystack_end) { // not found break; } wcstring result = wcstring(haystack_cursor, split_point); if (!no_empty || result.size() > 0) { output->push_back(std::move(result)); } remaining--; // Need to skip over the needle for the next search note that the needle may be empty. haystack_cursor = split_point + std::distance(needle_start, needle_end); } // Trailing component, possibly empty. output->push_back(wcstring(haystack_cursor, haystack_end)); } enum class ellipsis_type { None, //Prefer niceness over minimalness Prettiest, //Make every character count ($ instead of ...) Shortest, }; wcstring truncate(const wcstring &input, int max_len, ellipsis_type etype = ellipsis_type::Prettiest); wcstring trim(const wcstring &input, const wchar_t *any_of); #endif