Files
lix/lix/libutil/terminal.hh
T
Jade Lovelace 61955d0a40 libexpr: hyperlink attr names to their definition locations
Concept: what if you could, in your fancy terminal, in the year of our
lord 2025, just click on the attrs you're looking at to go to where
they're defined. Currently we only expose this info as
builtins.unsafeGetAttrPos, which is inconvenient as it's not
discoverable to users.

By putting it in this more visible yet invisible spot, it's more likely
to be more useful to more people.

In the current state, this is not the most useful ever due to stuff like
https://github.com/neovim/neovim/discussions/35097. However, it can be
expanded by perhaps adding something like the url format setting ripgrep
has.

Change-Id: I3947f97d5c2056d59099af468d7b855486438227
2025-08-20 20:55:54 +00:00

92 lines
2.9 KiB
C++

#pragma once
///@file
#include <limits>
#include <optional>
#include <string>
namespace nix {
enum class StandardOutputStream {
Stdout = 1,
Stderr = 2,
};
/**
* Determine whether the output is a real terminal (i.e. not dumb, not a pipe).
*
* This is probably not what you want, you may want shouldANSI() or something
* more specific. Think about how the output should work with a pager or
* entirely non-interactive scripting use.
*
* The user may be redirecting the Lix output to a pager, but have stderr
* connected to a terminal. Think about where you are outputting the text when
* deciding whether to use STDERR_FILENO or STDOUT_FILENO.
*
* \param fileno file descriptor number to check if it is a tty
*/
bool isOutputARealTerminal(StandardOutputStream fileno);
/**
* Determine whether ANSI escape sequences are appropriate for the
* present output.
*
* This follows the rules described on https://bixense.com/clicolors/
* with CLICOLOR defaulted to enabled (and thus ignored).
*
* That is to say, the following procedure is followed in order:
* - NO_COLOR or NOCOLOR set -> always disable colour
* - CLICOLOR_FORCE or FORCE_COLOR set -> enable colour
* - The output is a tty; TERM != "dumb" -> enable colour
* - Otherwise -> disable colour
*
* \param fileno which file descriptor number to consider. Use the one you are outputting to
*/
bool shouldANSI(StandardOutputStream fileno = StandardOutputStream::Stderr);
/**
* Truncate a string to 'width' printable characters. If 'filterAll'
* is true, all ANSI escape sequences are filtered out. Otherwise,
* some escape sequences (such as colour setting) are copied but not
* included in the character count. Also, tabs are expanded to
* spaces.
*/
std::string filterANSIEscapes(std::string_view s,
bool filterAll = false,
unsigned int width = std::numeric_limits<unsigned int>::max(),
bool eatTabs = true);
/**
* Recalculate the window size, updating a global variable. Used in the
* `SIGWINCH` signal handler.
*/
void updateWindowSize();
/**
* @return the number of rows and columns of the terminal.
*
* The value is cached so this is quick. The cached result is computed
* by `updateWindowSize()`.
*/
std::pair<unsigned short, unsigned short> getWindowSize();
/**
* Makes a terminal hyperlink using OSC 8.
*
* If the link target is too long (700 bytes is the current limit), the link is
* skipped and the link text is emitted as-is. This limits the maximum amount
* of context required to a manageable amount that doesn't break any terminals.
*
* See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
*
* @see makeHyperlinkLocalPath
*/
std::string makeHyperlink(std::string_view linkText, std::string_view target);
/**
* Creates an OSC 8 compliant `file://` path for a given filesystem path.
*/
std::string
makeHyperlinkLocalPath(std::string_view path, std::optional<unsigned> lineNumber = std::nullopt);
}