practicode
Advanced tools
@@ -18,3 +18,3 @@ { | ||
| "hint_list": "up/down move | Enter open | Esc close", | ||
| "hint_output": "Esc code | / command | ? help", | ||
| "hint_output": "Esc/click edit | / command | ? help", | ||
| "hint_code": "Esc then / command", | ||
@@ -27,2 +27,3 @@ "hint_idle": "/ command | ? help", | ||
| "cmd_run": "Judge the current submission", | ||
| "cmd_code": "Return to the code editor", | ||
| "cmd_edit": "Return to the code editor", | ||
@@ -55,3 +56,5 @@ "cmd_next": "Open the next problem", | ||
| "generating_next": "Generating next problem", | ||
| "already_busy": "Already busy." | ||
| "already_busy": "Already busy.", | ||
| "run_pass_next": "Next: /next", | ||
| "run_fail_next": "Fix: press Esc or click this pane to edit, then /run" | ||
| } |
@@ -18,3 +18,3 @@ { | ||
| "hint_list": "arriba/abajo mover | Enter abrir | Esc cerrar", | ||
| "hint_output": "Esc codigo | / comando | ? ayuda", | ||
| "hint_output": "Esc/clic editar | / comando | ? ayuda", | ||
| "hint_code": "Esc y luego / comando", | ||
@@ -27,2 +27,3 @@ "hint_idle": "/ comando | ? ayuda", | ||
| "cmd_run": "Evalua la solucion actual", | ||
| "cmd_code": "Volver al editor de codigo", | ||
| "cmd_edit": "Volver al editor de codigo", | ||
@@ -55,3 +56,5 @@ "cmd_next": "Abrir el siguiente problema", | ||
| "generating_next": "Generando el siguiente problema", | ||
| "already_busy": "Ya hay una tarea en curso." | ||
| "already_busy": "Ya hay una tarea en curso.", | ||
| "run_pass_next": "Siguiente: /next", | ||
| "run_fail_next": "Corrige: pulsa Esc o haz clic en este panel para editar, luego /run" | ||
| } |
@@ -18,3 +18,3 @@ { | ||
| "hint_list": "上下 移動 | Enter 開く | Esc 閉じる", | ||
| "hint_output": "Esc コード | / コマンド | ? ヘルプ", | ||
| "hint_output": "Esc/クリック 編集 | / コマンド | ? ヘルプ", | ||
| "hint_code": "Esc の後 / コマンド", | ||
@@ -27,2 +27,3 @@ "hint_idle": "/ コマンド | ? ヘルプ", | ||
| "cmd_run": "現在の提出を判定", | ||
| "cmd_code": "コードエディタに戻る", | ||
| "cmd_edit": "コードエディタに戻る", | ||
@@ -55,3 +56,5 @@ "cmd_next": "次の問題を開く", | ||
| "generating_next": "次の問題を生成中", | ||
| "already_busy": "すでに処理中です。" | ||
| "already_busy": "すでに処理中です。", | ||
| "run_pass_next": "次: /next", | ||
| "run_fail_next": "修正: Esc またはこのペインをクリックして編集し、/run" | ||
| } |
@@ -18,3 +18,3 @@ { | ||
| "hint_list": "위/아래 이동 | Enter 열기 | Esc 닫기", | ||
| "hint_output": "Esc 코드 | / 명령 | ? 도움말", | ||
| "hint_output": "Esc/클릭 편집 | / 명령 | ? 도움말", | ||
| "hint_code": "Esc 후 / 명령", | ||
@@ -27,2 +27,3 @@ "hint_idle": "/ 명령 | ? 도움말", | ||
| "cmd_run": "현재 제출을 채점", | ||
| "cmd_code": "코드 편집기로 돌아가기", | ||
| "cmd_edit": "코드 편집기로 돌아가기", | ||
@@ -55,3 +56,5 @@ "cmd_next": "다음 문제 열기", | ||
| "generating_next": "다음 문제 생성 중", | ||
| "already_busy": "이미 작업 중입니다." | ||
| "already_busy": "이미 작업 중입니다.", | ||
| "run_pass_next": "다음: /next", | ||
| "run_fail_next": "수정: Esc를 누르거나 이 창을 클릭해 편집한 뒤 /run" | ||
| } |
@@ -18,3 +18,3 @@ { | ||
| "hint_list": "上下 移动 | Enter 打开 | Esc 关闭", | ||
| "hint_output": "Esc 代码 | / 命令 | ? 帮助", | ||
| "hint_output": "Esc/点击 编辑 | / 命令 | ? 帮助", | ||
| "hint_code": "Esc 后输入 / 命令", | ||
@@ -27,2 +27,3 @@ "hint_idle": "/ 命令 | ? 帮助", | ||
| "cmd_run": "评测当前提交", | ||
| "cmd_code": "回到代码编辑器", | ||
| "cmd_edit": "回到代码编辑器", | ||
@@ -55,3 +56,5 @@ "cmd_next": "打开下一题", | ||
| "generating_next": "正在生成下一题", | ||
| "already_busy": "已有任务正在运行。" | ||
| "already_busy": "已有任务正在运行。", | ||
| "run_pass_next": "下一步: /next", | ||
| "run_fail_next": "修复: 按 Esc 或点击此面板编辑,然后 /run" | ||
| } |
+1
-1
@@ -360,3 +360,3 @@ # This file is automatically @generated by Cargo. | ||
| name = "practicode" | ||
| version = "0.1.4" | ||
| version = "0.1.5" | ||
| dependencies = [ | ||
@@ -363,0 +363,0 @@ "anyhow", |
+1
-1
| [package] | ||
| name = "practicode" | ||
| version = "0.1.4" | ||
| version = "0.1.5" | ||
| edition = "2024" | ||
@@ -5,0 +5,0 @@ description = "Local-first coding-test practice in a Rust terminal UI with optional AI help." |
+1
-1
| { | ||
| "name": "practicode", | ||
| "version": "0.1.4", | ||
| "version": "0.1.5", | ||
| "description": "Local-first coding-test practice in a Rust terminal UI with optional AI help.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
+1
-2
@@ -66,2 +66,3 @@ # practicode | ||
| | `/run` | Judge the current submission | | ||
| | `/code` | Return to the code editor | | ||
| | `/next` | Open the next local problem, or ask AI to create one | | ||
@@ -82,3 +83,2 @@ | `/next easy string problem` | Ask AI for a custom next problem | | ||
| | `/theme dark` | Set theme: `dark` or `light` | | ||
| | `/source ai` | Prefer AI for next-problem generation | | ||
| | `/update` | Show update instructions when a newer version is available | | ||
@@ -111,3 +111,2 @@ | `/exit` | Quit | | ||
| /model sonnet | ||
| /source ai | ||
| ``` | ||
@@ -114,0 +113,0 @@ |
+20
-18
@@ -604,4 +604,4 @@ use crate::process::{CommandSpec, run_capture, which}; | ||
| Err(error) => { | ||
| lines.push(format!("case {}: FAIL", index + 1)); | ||
| lines.push(error.to_string()); | ||
| lines.push(format!("Case {}: FAIL", index + 1)); | ||
| push_labeled_block(&mut lines, "Error", &error.to_string()); | ||
| break; | ||
@@ -614,24 +614,16 @@ } | ||
| passed += 1; | ||
| lines.push(format!("case {}: PASS", index + 1)); | ||
| lines.push(format!("Case {}: PASS", index + 1)); | ||
| if !run.stderr.trim().is_empty() { | ||
| lines.push("stderr:".to_string()); | ||
| lines.push(run.stderr.trim_end().to_string()); | ||
| push_labeled_block(&mut lines, "Stderr", run.stderr.trim_end()); | ||
| } | ||
| } else { | ||
| lines.push(format!("case {}: FAIL", index + 1)); | ||
| lines.push(format!("Case {}: FAIL", index + 1)); | ||
| if run.timed_out { | ||
| lines.push("timeout: 5s".to_string()); | ||
| push_labeled_block(&mut lines, "Error", "timeout: 5s"); | ||
| } | ||
| lines.push(format!("input: {:?}", case.input)); | ||
| lines.push(format!("expected: {:?}", expected)); | ||
| lines.push(format!("got: {:?}", got)); | ||
| lines.push("stdout:".to_string()); | ||
| lines.push(if run.stdout.trim_end().is_empty() { | ||
| "<empty>".to_string() | ||
| } else { | ||
| run.stdout.trim_end().to_string() | ||
| }); | ||
| push_labeled_block(&mut lines, "Input", case.input.trim_end()); | ||
| push_labeled_block(&mut lines, "Expected", expected); | ||
| push_labeled_block(&mut lines, "Got", run.stdout.trim_end()); | ||
| if !run.stderr.trim().is_empty() { | ||
| lines.push("stderr:".to_string()); | ||
| lines.push(run.stderr.trim_end().to_string()); | ||
| push_labeled_block(&mut lines, "Stderr", run.stderr.trim_end()); | ||
| } | ||
@@ -650,2 +642,12 @@ break; | ||
| fn push_labeled_block(lines: &mut Vec<String>, label: &str, body: &str) { | ||
| lines.push(String::new()); | ||
| lines.push(label.to_string()); | ||
| if body.is_empty() { | ||
| lines.push(" <empty>".to_string()); | ||
| } else { | ||
| lines.extend(body.lines().map(|line| format!(" {line}"))); | ||
| } | ||
| } | ||
| pub fn command_for(root: &Path, path: &Path, language: &str) -> Result<Option<CommandSpec>> { | ||
@@ -652,0 +654,0 @@ match language { |
+11
-3
| use anyhow::{Context, Result}; | ||
| use crossterm::{cursor::SetCursorStyle, execute}; | ||
| use crossterm::{ | ||
| cursor::SetCursorStyle, | ||
| event::{DisableMouseCapture, EnableMouseCapture}, | ||
| execute, | ||
| }; | ||
| use std::{env, io::stdout}; | ||
@@ -28,7 +32,11 @@ | ||
| let mut terminal = ratatui::init(); | ||
| let _ = execute!(stdout(), SetCursorStyle::SteadyBar); | ||
| let _ = execute!(stdout(), SetCursorStyle::SteadyBar, EnableMouseCapture); | ||
| let result = app.run(&mut terminal); | ||
| ratatui::restore(); | ||
| let _ = execute!(stdout(), SetCursorStyle::DefaultUserShape); | ||
| let _ = execute!( | ||
| stdout(), | ||
| SetCursorStyle::DefaultUserShape, | ||
| DisableMouseCapture | ||
| ); | ||
| result | ||
| } |
Sorry, the diff of this file is too big to display
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
178749
2.65%335
4.69%145
-0.68%4
33.33%