screen: make better use of the available space in the titlebar
When the terminal is very narrow, there is little point in showing only part of the version string -- and chewing off one or two digits from the version number might even give someone a wrong idea. The user is better served with always showing the full filename, as long as it fits in the available screen width. This fixes https://savannah.gnu.org/bugs/?47703.master
parent
338807a327
commit
577f7fafa9
211
src/winio.c
211
src/winio.c
|
@ -1915,27 +1915,18 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
|
||||||
* of path on the titlebar. */
|
* of path on the titlebar. */
|
||||||
void titlebar(const char *path)
|
void titlebar(const char *path)
|
||||||
{
|
{
|
||||||
int space = COLS;
|
size_t verlen, prefixlen, pathlen, statelen;
|
||||||
/* The space we have available for display. */
|
/* The width of the different titlebar elements, in columns. */
|
||||||
size_t verlen = strlenpt(BRANDING);
|
size_t pluglen = 0;
|
||||||
/* The length of the version message in columns. */
|
/* The width that "Modified" would take up. */
|
||||||
const char *prefix;
|
size_t offset = 0;
|
||||||
/* "DIR:", "File:", or "New Buffer". Goes before filename. */
|
/* The position at which the center part of the titlebar starts. */
|
||||||
size_t prefixlen;
|
const char *prefix = "";
|
||||||
/* The length of the prefix in columns, plus one for padding. */
|
/* What is shown before the path -- "File:", "DIR:", or "". */
|
||||||
const char *state;
|
const char *state = "";
|
||||||
/* "Modified", "View", or "". Shows the state of this
|
/* The state of the current buffer -- "Modified", "View", or "". */
|
||||||
* buffer. */
|
char *fragment;
|
||||||
size_t statelen = 0;
|
/* The tail part of the pathname when dottified. */
|
||||||
/* The length of the state in columns, or the length of
|
|
||||||
* "Modified" if the state is blank and we're not in the file
|
|
||||||
* browser. */
|
|
||||||
char *exppath = NULL;
|
|
||||||
/* The filename, expanded for display. */
|
|
||||||
bool newfie = FALSE;
|
|
||||||
/* Do we say "New Buffer"? */
|
|
||||||
bool dots = FALSE;
|
|
||||||
/* Do we put an ellipsis before the path? */
|
|
||||||
|
|
||||||
assert(path != NULL || openfile->filename != NULL);
|
assert(path != NULL || openfile->filename != NULL);
|
||||||
|
|
||||||
|
@ -1945,123 +1936,89 @@ void titlebar(const char *path)
|
||||||
|
|
||||||
blank_titlebar();
|
blank_titlebar();
|
||||||
|
|
||||||
/* Limit the length of the version message to a third of the width of
|
/* Do as Pico: if there is not enough width available for all items,
|
||||||
* the screen, minus three columns for spaces. */
|
* first sacrifice the version string, then eat up the side spaces,
|
||||||
if (verlen > (COLS / 3) - 3)
|
* then sacrifice the prefix, and only then start dottifying. */
|
||||||
verlen = (COLS / 3) - 3;
|
|
||||||
|
|
||||||
/* Leave two spaces before the version message, and account also
|
|
||||||
* for the space after it. */
|
|
||||||
mvwaddnstr(topwin, 0, 2, BRANDING, actual_x(BRANDING, verlen));
|
|
||||||
verlen += 3;
|
|
||||||
|
|
||||||
/* Account for the full length of the version message. */
|
|
||||||
space -= verlen;
|
|
||||||
|
|
||||||
|
/* Figure out the path, prefix and state strings. */
|
||||||
#ifndef DISABLE_BROWSER
|
#ifndef DISABLE_BROWSER
|
||||||
/* Don't display the state if we're in the file browser. */
|
|
||||||
if (path != NULL)
|
|
||||||
state = "";
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
state = openfile->modified ? _("Modified") : ISSET(VIEW_MODE) ?
|
|
||||||
_("View") : "";
|
|
||||||
|
|
||||||
statelen = strlenpt((*state == '\0' && path == NULL) ?
|
|
||||||
_("Modified") : state);
|
|
||||||
|
|
||||||
/* If possible, add a space before state. */
|
|
||||||
if (space > 0 && statelen < space)
|
|
||||||
statelen++;
|
|
||||||
else
|
|
||||||
goto the_end;
|
|
||||||
|
|
||||||
#ifndef DISABLE_BROWSER
|
|
||||||
/* path should be a directory if we're in the file browser. */
|
|
||||||
if (path != NULL)
|
if (path != NULL)
|
||||||
prefix = _("DIR:");
|
prefix = _("DIR:");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (openfile->filename[0] == '\0') {
|
{
|
||||||
prefix = _("New Buffer");
|
if (openfile->filename[0] == '\0')
|
||||||
newfie = TRUE;
|
path = _("New Buffer");
|
||||||
} else
|
|
||||||
prefix = _("File:");
|
|
||||||
|
|
||||||
prefixlen = strnlenpt(prefix, space - statelen) + 1;
|
|
||||||
|
|
||||||
/* If newfie is FALSE, add a space after prefix. */
|
|
||||||
if (!newfie && prefixlen + statelen < space)
|
|
||||||
prefixlen++;
|
|
||||||
|
|
||||||
/* If we're not in the file browser, set path to the current
|
|
||||||
* filename. */
|
|
||||||
if (path == NULL)
|
|
||||||
path = openfile->filename;
|
|
||||||
|
|
||||||
/* Account for the full lengths of the prefix and the state. */
|
|
||||||
if (space >= prefixlen + statelen)
|
|
||||||
space -= prefixlen + statelen;
|
|
||||||
else
|
|
||||||
space = 0;
|
|
||||||
/* space is now the room we have for the filename. */
|
|
||||||
|
|
||||||
if (!newfie) {
|
|
||||||
size_t lenpt = strlenpt(path), start_col;
|
|
||||||
|
|
||||||
/* Don't set dots to TRUE if we have fewer than eight columns
|
|
||||||
* (i.e. one column for padding, plus seven columns for a
|
|
||||||
* filename). */
|
|
||||||
dots = (space >= 8 && lenpt >= space);
|
|
||||||
|
|
||||||
if (dots) {
|
|
||||||
start_col = lenpt - space + 3;
|
|
||||||
space -= 3;
|
|
||||||
} else
|
|
||||||
start_col = 0;
|
|
||||||
|
|
||||||
exppath = display_string(path, start_col, space, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If dots is TRUE, we will display something like "File:
|
|
||||||
* ...ename". */
|
|
||||||
if (dots) {
|
|
||||||
mvwaddnstr(topwin, 0, verlen - 1, prefix, actual_x(prefix,
|
|
||||||
prefixlen));
|
|
||||||
if (space <= -3 || newfie)
|
|
||||||
goto the_end;
|
|
||||||
waddch(topwin, ' ');
|
|
||||||
waddnstr(topwin, "...", space + 3);
|
|
||||||
if (space <= 0)
|
|
||||||
goto the_end;
|
|
||||||
waddstr(topwin, exppath);
|
|
||||||
} else {
|
|
||||||
size_t exppathlen = newfie ? 0 : strlenpt(exppath);
|
|
||||||
/* The length of the expanded filename. */
|
|
||||||
|
|
||||||
/* There is room for the whole filename, so we center it. */
|
|
||||||
mvwaddnstr(topwin, 0, verlen + ((space - exppathlen) / 3),
|
|
||||||
prefix, actual_x(prefix, prefixlen));
|
|
||||||
if (!newfie) {
|
|
||||||
waddch(topwin, ' ');
|
|
||||||
waddstr(topwin, exppath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
the_end:
|
|
||||||
free(exppath);
|
|
||||||
|
|
||||||
if (state[0] != '\0') {
|
|
||||||
if (statelen >= COLS - 1)
|
|
||||||
mvwaddnstr(topwin, 0, 0, state, actual_x(state, COLS));
|
|
||||||
else {
|
else {
|
||||||
assert(COLS - statelen - 1 >= 0);
|
path = openfile->filename;
|
||||||
|
prefix = _("File:");
|
||||||
|
}
|
||||||
|
|
||||||
mvwaddnstr(topwin, 0, COLS - statelen - 1, state,
|
if (openfile->modified)
|
||||||
actual_x(state, statelen));
|
state = _("Modified");
|
||||||
|
else if (ISSET(VIEW_MODE))
|
||||||
|
state = _("View");
|
||||||
|
|
||||||
|
pluglen = strlenpt(_("Modified")) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the widths of the four elements, including their padding. */
|
||||||
|
verlen = strlenpt(BRANDING) + 3;
|
||||||
|
prefixlen = strlenpt(prefix);
|
||||||
|
if (prefixlen > 0)
|
||||||
|
prefixlen++;
|
||||||
|
pathlen= strlenpt(path);
|
||||||
|
statelen = strlenpt(state) + 2;
|
||||||
|
if (statelen > 2) {
|
||||||
|
pathlen++;
|
||||||
|
pluglen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only print the version message when there is room for it. */
|
||||||
|
if (verlen + prefixlen + pathlen + pluglen + statelen <= COLS)
|
||||||
|
mvwaddstr(topwin, 0, 2, BRANDING);
|
||||||
|
else {
|
||||||
|
verlen = 2;
|
||||||
|
/* If things don't fit yet, give up the placeholder. */
|
||||||
|
if (verlen + prefixlen + pathlen + pluglen + statelen > COLS)
|
||||||
|
pluglen = 0;
|
||||||
|
/* If things still don't fit, give up the side spaces. */
|
||||||
|
if (verlen + prefixlen + pathlen + pluglen + statelen > COLS) {
|
||||||
|
verlen = 0;
|
||||||
|
statelen -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have side spaces left, center the path name. */
|
||||||
|
if (verlen > 0)
|
||||||
|
offset = verlen + (COLS - (verlen + pluglen + statelen) -
|
||||||
|
(prefixlen + pathlen)) / 2;
|
||||||
|
|
||||||
|
/* Only print the prefix when there is room for it. */
|
||||||
|
if (verlen + prefixlen + pathlen + pluglen + statelen <= COLS) {
|
||||||
|
mvwaddstr(topwin, 0, offset, prefix);
|
||||||
|
if (prefixlen > 0)
|
||||||
|
waddstr(topwin, " ");
|
||||||
|
} else
|
||||||
|
wmove(topwin, 0, offset);
|
||||||
|
|
||||||
|
/* Print the full path if there's room; otherwise, dottify it. */
|
||||||
|
if (pathlen + pluglen + statelen <= COLS)
|
||||||
|
waddstr(topwin, path);
|
||||||
|
else if (5 + statelen <= COLS) {
|
||||||
|
waddstr(topwin, "...");
|
||||||
|
fragment = display_string(path, 3 + pathlen - COLS + statelen,
|
||||||
|
COLS - statelen, FALSE);
|
||||||
|
waddstr(topwin, fragment);
|
||||||
|
free(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right-align the state if there's room; otherwise, trim it. */
|
||||||
|
if (statelen > 0 && statelen <= COLS)
|
||||||
|
mvwaddstr(topwin, 0, COLS - statelen, state);
|
||||||
|
else if (statelen > 0)
|
||||||
|
mvwaddnstr(topwin, 0, 0, state, actual_x(state, COLS));
|
||||||
|
|
||||||
wattroff(topwin, A_BOLD);
|
wattroff(topwin, A_BOLD);
|
||||||
wattroff(topwin, interface_color_pair[TITLE_BAR].pairnum);
|
wattroff(topwin, interface_color_pair[TITLE_BAR].pairnum);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue