mirror of
https://github.com/neovim/neovim.git
synced 2026-03-30 20:32:08 +00:00
feat(ux): sexy intro #38378
Problem: Intro is not sexy. Solution: Make it sexy. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9986360065
commit
9595f07425
@@ -26,6 +26,7 @@
|
||||
#include "nvim/grid_defs.h"
|
||||
#include "nvim/highlight.h"
|
||||
#include "nvim/highlight_defs.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/lua/executor.h"
|
||||
#include "nvim/mbyte.h"
|
||||
#include "nvim/memory.h"
|
||||
@@ -4188,20 +4189,24 @@ bool may_show_intro(void)
|
||||
void intro_message(bool colon)
|
||||
{
|
||||
static char *(lines[]) = {
|
||||
N_(NVIM_VERSION_LONG),
|
||||
"│ ╲ ││",
|
||||
"││╲╲││",
|
||||
"││ ╲ │",
|
||||
"",
|
||||
N_(NVIM_VERSION_LONG),
|
||||
"────────────────────────────────────────────",
|
||||
N_("Nvim is open source and freely distributable"),
|
||||
"https://neovim.io/#chat",
|
||||
"",
|
||||
N_("type :help nvim<Enter> if you are new! "),
|
||||
N_("type :checkhealth<Enter> to optimize Nvim"),
|
||||
N_("type :q<Enter> to exit "),
|
||||
N_("type :help<Enter> for help "),
|
||||
"",
|
||||
N_("type :help news<Enter> to see changes in v%s.%s"),
|
||||
"",
|
||||
"────────────────────────────────────────────",
|
||||
N_("type :help nvim<Enter> if you are new! "),
|
||||
N_("type :checkhealth<Enter> to optimize Nvim"),
|
||||
N_("type :q<Enter> to exit "),
|
||||
N_("type :help<Enter> for help "),
|
||||
"────────────────────────────────────────────",
|
||||
N_("type :help news<Enter> for v%s.%s notes "),
|
||||
"────────────────────────────────────────────",
|
||||
N_("Help poor children in Uganda!"),
|
||||
N_("type :help Kuwasha<Enter> for information "),
|
||||
N_("type :help Kuwasha<Enter> for information "),
|
||||
};
|
||||
|
||||
// blanklines = screen height - # message lines
|
||||
@@ -4247,7 +4252,7 @@ void intro_message(bool colon)
|
||||
}
|
||||
|
||||
if (*mesg != NUL) {
|
||||
do_intro_line(row, mesg, colon);
|
||||
do_intro_line(row, mesg, colon, i < 3);
|
||||
}
|
||||
row++;
|
||||
|
||||
@@ -4258,22 +4263,64 @@ void intro_message(bool colon)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_intro_line(int row, char *mesg, bool colon)
|
||||
/// Adds extra highlighting.
|
||||
static void do_intro_line(int row, char *mesg, bool colon, bool is_logo)
|
||||
{
|
||||
int l;
|
||||
|
||||
// Center the message horizontally.
|
||||
int col = vim_strsize(mesg);
|
||||
|
||||
col = (Columns - col) / 2;
|
||||
|
||||
if (col < 0) {
|
||||
col = 0;
|
||||
}
|
||||
|
||||
grid_line_start((!colon && ui_has(kUIMultigrid)) ? &firstwin->w_grid : &default_gridview, row);
|
||||
|
||||
// Split up in parts to highlight <> items differently.
|
||||
// Compute special highlighting attributes
|
||||
int id_attr = syn_id2attr(syn_name2id("Identifier"));
|
||||
int nontext_attr = syn_id2attr(syn_name2id("NonText"));
|
||||
int special_attr = syn_id2attr(syn_name2id("Special"));
|
||||
int string_attr = syn_id2attr(syn_name2id("String"));
|
||||
|
||||
// Handle logo lines
|
||||
if (is_logo) {
|
||||
bool seen_diagonal = false;
|
||||
|
||||
for (char *p = mesg; *p != NUL;) {
|
||||
int clen = utfc_ptr2len(p);
|
||||
int attr = 0;
|
||||
// Multi-byte (box-drawing) character.
|
||||
if ((uint8_t)(*p) >= 0x80) {
|
||||
// Found "╲" diagonal logo part.
|
||||
seen_diagonal = seen_diagonal || (clen == 3 && utf_ptr2char(p) == 0x2572);
|
||||
attr = seen_diagonal ? string_attr : special_attr;
|
||||
}
|
||||
col += grid_line_puts(col, p, clen, attr);
|
||||
p += clen;
|
||||
}
|
||||
|
||||
grid_line_flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try highlighting full line:
|
||||
// - Version starts with "NVIM".
|
||||
// - Separator line consists from ─ (UTF-8: E2 94 80).
|
||||
bool is_version = mesg[0] == 'N' && mesg[1] == 'V' && mesg[2] == 'I' && mesg[3] == 'M';
|
||||
bool is_sep = utfc_ptr2len(mesg) == 3 && utf_ptr2char(mesg) == 0x2500;
|
||||
if (is_version || is_sep) {
|
||||
int clen = is_sep ? 3 : 1;
|
||||
int attr = is_sep ? nontext_attr : string_attr;
|
||||
|
||||
for (char *p = mesg; *p != NUL;) {
|
||||
col += grid_line_puts(col, p, clen, attr);
|
||||
p += clen;
|
||||
}
|
||||
grid_line_flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// Highlight `:...<Enter>` differently.
|
||||
for (char *p = mesg; *p != NUL; p += l) {
|
||||
for (l = 0;
|
||||
p[l] != NUL && (l == 0 || (p[l] != '<' && p[l - 1] != '>'));
|
||||
@@ -4281,7 +4328,25 @@ static void do_intro_line(int row, char *mesg, bool colon)
|
||||
l += utfc_ptr2len(p + l) - 1;
|
||||
}
|
||||
assert(row <= INT_MAX && col <= INT_MAX);
|
||||
col += grid_line_puts(col, p, l, *p == '<' ? HL_ATTR(HLF_8) : 0);
|
||||
|
||||
if (*p == '<') {
|
||||
col += grid_line_puts(col, p, l, HL_ATTR(HLF_8));
|
||||
} else {
|
||||
// Check for ":command" pattern before a <key> segment.
|
||||
char *colon_pos = memchr(p, ':', (size_t)l);
|
||||
if (colon_pos != NULL && p[l] == '<') {
|
||||
// No highlight for "type ".
|
||||
int prefix_len = (int)(colon_pos - p);
|
||||
col += grid_line_puts(col, p, prefix_len, 0);
|
||||
// Highlight ":".
|
||||
col += grid_line_puts(col, colon_pos, 1, HL_ATTR(HLF_8));
|
||||
// Highlight "command" (after the ":").
|
||||
int cmd_len = l - prefix_len - 1;
|
||||
col += grid_line_puts(col, colon_pos + 1, cmd_len, id_attr);
|
||||
} else {
|
||||
col += grid_line_puts(col, p, l, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
grid_line_flush();
|
||||
}
|
||||
|
||||
@@ -2150,22 +2150,26 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim
|
||||
command('set cmdheight=0')
|
||||
feed(':intro<CR>')
|
||||
screen:expect([[
|
||||
|*5
|
||||
{MATCH:.*}|
|
||||
|*3
|
||||
{16:│} {26:╲} {26:││} |
|
||||
{16:││}{26:╲╲││} |
|
||||
{16:││} {26:╲} {26:│} |
|
||||
|
|
||||
{MATCH:.*}|
|
||||
{1:────────────────────────────────────────────} |
|
||||
Nvim is open source and freely distributable |
|
||||
https://neovim.io/#chat |
|
||||
|
|
||||
type :help nvim{18:<Enter>} if you are new! |
|
||||
type :checkhealth{18:<Enter>} to optimize Nvim |
|
||||
type :q{18:<Enter>} to exit |
|
||||
type :help{18:<Enter>} for help |
|
||||
|
|
||||
{MATCH: +}type :help news{18:<Enter>} to see changes in v{MATCH:%d+%.%d+ +}|
|
||||
|
|
||||
{1:────────────────────────────────────────────} |
|
||||
type {18::}{25:help nvim}{18:<Enter>} if you are new! |
|
||||
type {18::}{25:checkhealth}{18:<Enter>} to optimize Nvim |
|
||||
type {18::}{25:q}{18:<Enter>} to exit |
|
||||
type {18::}{25:help}{18:<Enter>} for help |
|
||||
{1:────────────────────────────────────────────} |
|
||||
type {18::}{25:help news}{18:<Enter>} for v{MATCH:%d+%.%d+} notes{MATCH: *}|
|
||||
{1:────────────────────────────────────────────} |
|
||||
Help poor children in Uganda! |
|
||||
type :help Kuwasha{18:<Enter>} for information |
|
||||
|*4
|
||||
type {18::}{25:help Kuwasha}{18:<Enter>} for information |
|
||||
|*2
|
||||
^ |
|
||||
]])
|
||||
feed('<CR>')
|
||||
@@ -2208,22 +2212,26 @@ describe('ui/ext_messages', function()
|
||||
-- Note parts of it depends on version or is indeterministic. We ignore those parts.
|
||||
local introscreen = [[
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
{MATCH:.*}|
|
||||
{1:~ }|*2
|
||||
{1:~ }{16:│} {26:╲} {26:││}{1: }|
|
||||
{1:~ }{16:││}{26:╲╲││}{1: }|
|
||||
{1:~ }{16:││} {26:╲} {26:│}{1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}{26:NVIM {MATCH:%S+}}{1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Nvim is open source and freely distributable{1: }|
|
||||
{1:~ }https://neovim.io/#chat{1: }|
|
||||
{1:~ }|
|
||||
{1:~ }type :help nvim{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type :checkhealth{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type :q{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type :help{18:<Enter>} for help {1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}type :help news{18:<Enter>} to see changes in v{MATCH:%d+%.%d+}{1:{MATCH: +}}|
|
||||
{1:~ }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help nvim}{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type {18::}{25:checkhealth}{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type {18::}{25:q}{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type {18::}{25:help}{18:<Enter>} for help {1: }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help news}{18:<Enter>} for v{MATCH:%d+%.%d+} notes {1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Help poor children in Uganda!{1: }|
|
||||
{1:~ }type :help Kuwasha{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*5
|
||||
{1:~ }type {18::}{25:help Kuwasha}{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*3
|
||||
]]
|
||||
local showmode = { { '-- INSERT --', 5, 'ModeMsg' } }
|
||||
screen:expect(introscreen)
|
||||
@@ -2244,22 +2252,26 @@ describe('ui/ext_messages', function()
|
||||
grid = [[
|
||||
^ |
|
||||
{1:~ }{4: }{1: }|
|
||||
{1:~ }|*3
|
||||
{MATCH:.*}|
|
||||
{1:~ }|
|
||||
{1:~ }{16:│} {26:╲} {26:││}{1: }|
|
||||
{1:~ }{16:││}{26:╲╲││}{1: }|
|
||||
{1:~ }{16:││} {26:╲} {26:│}{1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}{26:NVIM {MATCH:%S+}}{1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Nvim is open source and freely distributable{1: }|
|
||||
{1:~ }https://neovim.io/#chat{1: }|
|
||||
{1:~ }|
|
||||
{1:~ }type :help nvim{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type :checkhealth{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type :q{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type :help{18:<Enter>} for help {1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}type :help news{18:<Enter>} to see changes in v{MATCH:%d+%.%d+}{1:{MATCH: +}}|
|
||||
{1:~ }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help nvim}{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type {18::}{25:checkhealth}{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type {18::}{25:q}{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type {18::}{25:help}{18:<Enter>} for help {1: }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help news}{18:<Enter>} for v{MATCH:%d+%.%d+} notes {1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Help poor children in Uganda!{1: }|
|
||||
{1:~ }type :help Kuwasha{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*5
|
||||
{1:~ }type {18::}{25:help Kuwasha}{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*3
|
||||
]],
|
||||
showmode = showmode,
|
||||
}
|
||||
@@ -2281,22 +2293,26 @@ describe('ui/ext_messages', function()
|
||||
screen:expect {
|
||||
grid = [[
|
||||
^ |
|
||||
|*4
|
||||
{MATCH:.*}|
|
||||
|*2
|
||||
{16:│} {26:╲} {26:││} |
|
||||
{16:││}{26:╲╲││} |
|
||||
{16:││} {26:╲} {26:│} |
|
||||
|
|
||||
{MATCH: +}{26:NVIM {MATCH:%S+}}{MATCH: +}|
|
||||
{1:────────────────────────────────────────────} |
|
||||
Nvim is open source and freely distributable |
|
||||
https://neovim.io/#chat |
|
||||
|
|
||||
type :help nvim{18:<Enter>} if you are new! |
|
||||
type :checkhealth{18:<Enter>} to optimize Nvim |
|
||||
type :q{18:<Enter>} to exit |
|
||||
type :help{18:<Enter>} for help |
|
||||
|
|
||||
{MATCH: +}type :help news{18:<Enter>} to see changes in v{MATCH:%d+%.%d+ +}|
|
||||
|
|
||||
{1:────────────────────────────────────────────} |
|
||||
type {18::}{25:help nvim}{18:<Enter>} if you are new! |
|
||||
type {18::}{25:checkhealth}{18:<Enter>} to optimize Nvim |
|
||||
type {18::}{25:q}{18:<Enter>} to exit |
|
||||
type {18::}{25:help}{18:<Enter>} for help |
|
||||
{1:────────────────────────────────────────────} |
|
||||
type {18::}{25:help news}{18:<Enter>} for v{MATCH:%d+%.%d+} notes {MATCH: +}|
|
||||
{1:────────────────────────────────────────────} |
|
||||
Help poor children in Uganda! |
|
||||
type :help Kuwasha{18:<Enter>} for information |
|
||||
|*5
|
||||
type {18::}{25:help Kuwasha}{18:<Enter>} for information |
|
||||
|*3
|
||||
]],
|
||||
}
|
||||
|
||||
@@ -2411,22 +2427,26 @@ it('ui/ext_multigrid supports intro screen', function()
|
||||
[3:--------------------------------------------------------------------------------]|
|
||||
## grid 2
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
{MATCH:.*}|
|
||||
{1:~ }|*2
|
||||
{1:~ }{16:│} {26:╲} {26:││}{1: }|
|
||||
{1:~ }{16:││}{26:╲╲││}{1: }|
|
||||
{1:~ }{16:││} {26:╲} {26:│}{1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}{26:NVIM {MATCH:%S+}}{1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Nvim is open source and freely distributable{1: }|
|
||||
{1:~ }https://neovim.io/#chat{1: }|
|
||||
{1:~ }|
|
||||
{1:~ }type :help nvim{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type :checkhealth{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type :q{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type :help{18:<Enter>} for help {1: }|
|
||||
{1:~ }|
|
||||
{1:~{MATCH: +}}type :help news{18:<Enter>} to see changes in v{MATCH:%d+%.%d+}{1:{MATCH: +}}|
|
||||
{1:~ }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help nvim}{18:<Enter>} if you are new! {1: }|
|
||||
{1:~ }type {18::}{25:checkhealth}{18:<Enter>} to optimize Nvim{1: }|
|
||||
{1:~ }type {18::}{25:q}{18:<Enter>} to exit {1: }|
|
||||
{1:~ }type {18::}{25:help}{18:<Enter>} for help {1: }|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }type {18::}{25:help news}{18:<Enter>} for v{MATCH:%d+%.%d+} notes {1:{MATCH: +}}|
|
||||
{1:~ ──────────────────────────────────────────── }|
|
||||
{1:~ }Help poor children in Uganda!{1: }|
|
||||
{1:~ }type :help Kuwasha{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*4
|
||||
{1:~ }type {18::}{25:help Kuwasha}{18:<Enter>} for information {1: }|
|
||||
{1:~ }|*2
|
||||
## grid 3
|
||||
|
|
||||
]],
|
||||
|
||||
Reference in New Issue
Block a user