diff --git a/doc/cp.txt b/doc/cp.txt index d379012..62577da 100644 --- a/doc/cp.txt +++ b/doc/cp.txt @@ -437,7 +437,10 @@ Test cases use competitive programming terminology with color highlighting: Highlight Groups ~ *cp-highlights* -cp.nvim defines the following highlight groups for status indicators: +cp.nvim defines comprehensive highlight groups for test status, ANSI colors, +and diff visualization. + +Test Status Groups ~ CpTestAC Green foreground for AC status CpTestWA Red foreground for WA status @@ -445,14 +448,193 @@ cp.nvim defines the following highlight groups for status indicators: CpTestRTE Purple foreground for RTE status CpTestPending Gray foreground for pending tests -You can customize these colors by linking to other highlight groups in your -colorscheme or by redefining them: >lua - vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' }) - vim.api.nvim_set_hl(0, 'CpTestWA', { fg = '#ff0000' }) +ANSI Color Support ~ + *cp-ansi-colors* +cp.nvim preserves ANSI colors from compiler output and program stderr using +a sophisticated parsing system. Colors are automatically mapped to your +terminal colorscheme via vim.g.terminal_color_* variables. + +ANSI Highlight Groups: + + CpAnsiBold Bold text formatting + CpAnsiItalic Italic text formatting + CpAnsiBoldItalic Combined bold and italic formatting + +Color combinations (16 standard terminal colors): + CpAnsiRed Standard red (terminal_color_1) + CpAnsiBoldRed Bold red combination + CpAnsiItalicRed Italic red combination + CpAnsiBoldItalicRed Bold italic red combination + + CpAnsiGreen Standard green (terminal_color_2) + CpAnsiYellow Standard yellow (terminal_color_3) + CpAnsiBlue Standard blue (terminal_color_4) + CpAnsiMagenta Standard magenta (terminal_color_5) + CpAnsiCyan Standard cyan (terminal_color_6) + CpAnsiWhite Standard white (terminal_color_7) + CpAnsiBlack Standard black (terminal_color_0) + +Bright color variants: + CpAnsiBrightRed Bright red (terminal_color_9) + CpAnsiBrightGreen Bright green (terminal_color_10) + CpAnsiBrightYellow Bright yellow (terminal_color_11) + CpAnsiBrightBlue Bright blue (terminal_color_12) + CpAnsiBrightMagenta Bright magenta (terminal_color_13) + CpAnsiBrightCyan Bright cyan (terminal_color_14) + CpAnsiBrightWhite Bright white (terminal_color_15) + CpAnsiBrightBlack Bright black (terminal_color_8) + +Each color supports Bold, Italic, and BoldItalic variants automatically. + +Diff Highlight Groups ~ + + CpDiffAdded Green background for added text in diffs + CpDiffRemoved Red background for removed text in diffs + +Terminal Color Integration ~ + *cp-terminal-colors* +ANSI colors automatically use your terminal's color palette through Neovim's +vim.g.terminal_color_* variables. This ensures compiler colors match your +colorscheme without manual configuration. + +If your colorscheme doesn't set terminal colors, cp.nvim falls back to +sensible defaults. You can override terminal colors in your configuration: >vim + let g:terminal_color_1 = '#ff6b6b' " Custom red + let g:terminal_color_2 = '#51cf66' " Custom green < -Keymaps ~ - *cp-test-keys* +Highlight Customization ~ + *cp-highlight-custom* +You can customize any highlight group by linking to existing groups or +defining custom colors: >lua + -- Link to existing colorscheme groups + vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' }) + vim.api.nvim_set_hl(0, 'CpTestWA', { link = 'DiagnosticError' }) + + -- Define custom colors + vim.api.nvim_set_hl(0, 'CpTestTLE', { fg = '#ffa500', bold = true }) + vim.api.nvim_set_hl(0, 'CpDiffAdded', { fg = '#10b981', bg = '#1e293b' }) + + -- Customize ANSI colors while preserving terminal integration + vim.api.nvim_set_hl(0, 'CpAnsiRed', { + fg = vim.g.terminal_color_1 or '#ef4444' + }) +< + +Place customizations in your init.lua or after the colorscheme loads to +prevent them from being overridden: >lua + vim.api.nvim_create_autocmd('ColorScheme', { + callback = function() + -- Your cp.nvim highlight customizations here + vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'String' }) + end + }) +< + +============================================================================== +ANSI COLORS AND HIGHLIGHTING *cp-ansi* + +cp.nvim provides comprehensive ANSI color support and highlighting for +compiler output, program stderr, and diff visualization. + +============================================================================== +HIGHLIGHT GROUPS *cp-highlights* + +Test Status Groups ~ + +Test cases use competitive programming terminology with color highlighting: + + CpTestAC Green foreground for AC status + CpTestWA Red foreground for WA status + CpTestTLE Orange foreground for TLE status + CpTestRTE Purple foreground for RTE status + CpTestPending Gray foreground for pending tests + +ANSI Color Groups ~ + +cp.nvim preserves ANSI colors from compiler output and program stderr using +a sophisticated parsing system. Colors are automatically mapped to your +terminal colorscheme via vim.g.terminal_color_* variables. + +Basic formatting groups: + CpAnsiBold Bold text formatting + CpAnsiItalic Italic text formatting + CpAnsiBoldItalic Combined bold and italic formatting + +Standard terminal colors (each supports Bold, Italic, BoldItalic variants): + CpAnsiRed Standard red (terminal_color_1) + CpAnsiGreen Standard green (terminal_color_2) + CpAnsiYellow Standard yellow (terminal_color_3) + CpAnsiBlue Standard blue (terminal_color_4) + CpAnsiMagenta Standard magenta (terminal_color_5) + CpAnsiCyan Standard cyan (terminal_color_6) + CpAnsiWhite Standard white (terminal_color_7) + CpAnsiBlack Standard black (terminal_color_0) + +Bright color variants: + CpAnsiBrightRed Bright red (terminal_color_9) + CpAnsiBrightGreen Bright green (terminal_color_10) + CpAnsiBrightYellow Bright yellow (terminal_color_11) + CpAnsiBrightBlue Bright blue (terminal_color_12) + CpAnsiBrightMagenta Bright magenta (terminal_color_13) + CpAnsiBrightCyan Bright cyan (terminal_color_14) + CpAnsiBrightWhite Bright white (terminal_color_15) + CpAnsiBrightBlack Bright black (terminal_color_8) + +Example combinations: + CpAnsiBoldRed Bold red combination + CpAnsiItalicGreen Italic green combination + CpAnsiBoldItalicYellow Bold italic yellow combination + +Diff Highlight Groups ~ + + CpDiffAdded Green background for added text in diffs + CpDiffRemoved Red background for removed text in diffs + +============================================================================== +TERMINAL COLOR INTEGRATION *cp-terminal-colors* + +ANSI colors automatically use your terminal's color palette through Neovim's +vim.g.terminal_color_* variables. This ensures compiler colors match your +colorscheme without manual configuration. + +If your colorscheme doesn't set terminal colors, cp.nvim falls back to +sensible defaults. You can override terminal colors in your configuration: >vim + let g:terminal_color_1 = '#ff6b6b' " Custom red + let g:terminal_color_2 = '#51cf66' " Custom green +< + +============================================================================== +HIGHLIGHT CUSTOMIZATION *cp-highlight-custom* + +You can customize any highlight group by linking to existing groups or +defining custom colors: >lua + -- Link to existing colorscheme groups + vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'DiffAdd' }) + vim.api.nvim_set_hl(0, 'CpTestWA', { link = 'DiagnosticError' }) + + -- Define custom colors + vim.api.nvim_set_hl(0, 'CpTestTLE', { fg = '#ffa500', bold = true }) + vim.api.nvim_set_hl(0, 'CpDiffAdded', { fg = '#10b981', bg = '#1e293b' }) + + -- Customize ANSI colors while preserving terminal integration + vim.api.nvim_set_hl(0, 'CpAnsiRed', { + fg = vim.g.terminal_color_1 or '#ef4444' + }) +< + +Place customizations in your init.lua or after the colorscheme loads to +prevent them from being overridden: >lua + vim.api.nvim_create_autocmd('ColorScheme', { + callback = function() + -- Your cp.nvim highlight customizations here + vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'String' }) + end + }) +< + +============================================================================== +RUN PANEL KEYMAPS *cp-test-keys* Navigate to next test case (configurable via run_panel.next_test_key) Navigate to previous test case (configurable via diff --git a/spec/execute_spec.lua b/spec/execute_spec.lua index 3b2a650..e8a223a 100644 --- a/spec/execute_spec.lua +++ b/spec/execute_spec.lua @@ -395,50 +395,24 @@ describe('cp.execute', function() end) describe('integration tests', function() - local function compile_and_run_fixture(fixture_name) - local source_file = string.format('spec/fixtures/%s.cpp', fixture_name) - local binary_file = string.format('build/%s', fixture_name) - - local language_config = { - compile = { 'g++', '-o', '{binary}', '{source}' }, - test = { '{binary}' }, - } - local substitutions = { - source = source_file, - binary = binary_file, - } - - local compile_result = execute.compile_generic(language_config, substitutions) - - if compile_result.code ~= 0 then - return compile_result - end - + it('captures interleaved stderr/stdout with ANSI colors', function() local start_time = vim.uv.hrtime() - local redirected_cmd = { 'sh', '-c', binary_file .. ' 2>&1' } - local result = vim.system(redirected_cmd, { timeout = 2000, text = false }):wait() + local python_cmd = { + 'sh', + '-c', + "python3 -c \"import sys; print('\\033[32mstdout: \\033[1mSuccess\\033[0m'); print('\\033[31mstderr: \\033[1mWarning\\033[0m', file=sys.stderr); print('plain stdout')\" 2>&1", + } + local result = vim.system(python_cmd, { timeout = 2000, text = false }):wait() local execution_time = (vim.uv.hrtime() - start_time) / 1000000 local ansi = require('cp.ansi') - return { - stdout = ansi.bytes_to_string(result.stdout or ''), - stderr = ansi.bytes_to_string(result.stderr or ''), - code = result.code or 0, - time_ms = execution_time, - } - end - - it('captures interleaved stderr/stdout with ANSI colors', function() - local result = compile_and_run_fixture('interleaved') + local combined_output = ansi.bytes_to_string(result.stdout or '') assert.equals(0, result.code) - - local combined_output = result.stdout assert.is_not_nil(string.find(combined_output, 'stdout:')) assert.is_not_nil(string.find(combined_output, 'stderr:')) assert.is_not_nil(string.find(combined_output, 'plain stdout')) - local ansi = require('cp.ansi') local parsed = ansi.parse_ansi_text(combined_output) local clean_text = table.concat(parsed.lines, '\n') @@ -466,19 +440,24 @@ describe('cp.execute', function() assert.is_true(has_bold, 'Should have bold highlights') end) - it('handles compilation failures with combined output', function() - local result = compile_and_run_fixture('syntax_error') + it('handles script failures with combined output', function() + local python_cmd = { + 'sh', + '-c', + "python3 -c \"import sys; print('Starting...'); print('ERROR: Something failed', file=sys.stderr); sys.exit(1)\" 2>&1", + } + local result = vim.system(python_cmd, { timeout = 2000, text = false }):wait() assert.is_not_equals(0, result.code) - local compile_output = result.stdout - assert.is_not_nil(string.find(compile_output, 'error')) - local ansi = require('cp.ansi') - local parsed = ansi.parse_ansi_text(compile_output) - local clean_text = table.concat(parsed.lines, '\n') + local combined_output = ansi.bytes_to_string(result.stdout or '') + assert.is_not_nil(string.find(combined_output, 'Starting')) + assert.is_not_nil(string.find(combined_output, 'ERROR')) - assert.is_not_nil(string.find(clean_text, 'syntax_error.cpp')) + local parsed = ansi.parse_ansi_text(combined_output) + local clean_text = table.concat(parsed.lines, '\n') + assert.is_not_nil(string.find(clean_text, 'Something failed')) end) end) end) diff --git a/spec/fixtures/interleaved.cpp b/spec/fixtures/interleaved.cpp deleted file mode 100644 index 857c113..0000000 --- a/spec/fixtures/interleaved.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main() { - std::cout << "\033[32mstdout: \033[1mSuccess\033[0m" << std::endl; - std::cerr << "\033[31mstderr: \033[1mWarning\033[0m" << std::endl; - std::cout << "plain stdout" << std::endl; - return 0; -} \ No newline at end of file diff --git a/spec/fixtures/syntax_error.cpp b/spec/fixtures/syntax_error.cpp deleted file mode 100644 index 877829f..0000000 --- a/spec/fixtures/syntax_error.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int main() { - std::cout << "this will never compile" << std::endl - // missing semicolon above - undefined_function(); - return 0 - // missing semicolon again \ No newline at end of file