READY: Add lem-tutor interactive tutorial extension#2144
Conversation
|
👌 I love the progression. |
|
❌ Code Contractor Validation: FAILED 📋 Contract Configuration: contract (Source: Repository)version: 2
trigger:
paths:
- "extensions/**"
- "frontends/**/*.lisp"
- "src/**"
- "tests/**"
- "contrib/**"
- "**/*.asd"
head_branches:
exclude:
- 'revert-*'
validation:
limits:
max_total_changed_lines: 400
max_delete_ratio: 0.5
max_files_changed: 10
severity: warning
ai:
system_prompt: |
You are a senior Common Lisp engineer reviewing code for Lem editor.
Lem is a text editor with multiple frontends (ncurses, SDL2, webview).
Focus on maintainability, consistency with existing code, and Lem-specific conventions.
rules:
# === File Structure ===
- name: defpackage_rule
prompt: |
First form must be `defpackage` or `uiop:define-package`.
Package name should match filename (e.g., `foo.lisp` → `:lem-ext/foo` or `:lem-foo`).
Extensions must use `lem-` prefix (e.g., `:lem-python-mode`).
- name: file_structure_rule
prompt: |
File organization (top to bottom):
1. defpackage
2. defvar/defparameter declarations
3. Key bindings (define-key, define-keys)
4. Class/struct definitions
5. Functions and commands
# === Style ===
- name: loop_keywords_rule
prompt: |
Loop keywords must use colons: `(loop :for x :in list :do ...)`
NOT: `(loop for x in list do ...)`
- name: naming_conventions_rule
prompt: |
Naming conventions:
- Functions/variables: kebab-case (e.g., `find-buffer`)
- Special variables: *earmuffs* (e.g., `*global-keymap*`)
- Constants: +plus-signs+ (e.g., `+default-tab-size+`)
- Predicates: -p suffix for functions (e.g., `buffer-modified-p`)
- Do NOT use -p suffix for user-configurable variables
# === Documentation ===
- name: docstring_rule
prompt: |
Required docstrings for:
- Exported functions, methods, classes
- `define-command` (explain what the command does)
- Generic functions (`:documentation` option)
Important functions should explain "why", not just "what".
severity: warning
# === Lem-Specific ===
- name: internal_symbol_rule
prompt: |
Use exported symbols from `lem` or `lem-core` package.
Avoid `lem::internal-symbol` access.
If internal access is necessary, document why.
- name: error_handling_rule
prompt: |
- `error`: Internal/programming errors
- `editor-error`: User-facing errors (displayed in echo area)
Always use `editor-error` for messages shown to users.
- name: frontend_interface_rule
prompt: |
Frontend-specific code must use `lem-if:*` protocol.
Do not call frontend implementation directly from core.
severity: warning
# === Functional Style ===
- name: functional_style_rule
prompt: |
Prefer explicit function arguments over dynamic variables.
Avoid using `defvar` for state passed between functions.
Exception: Well-documented cases like `*current-buffer*`.
- name: dynamic_symbol_call_rule
prompt: |
Avoid `uiop:symbol-call`. Rethink architecture instead.
If unavoidable, document the reason.
# === Libraries ===
- name: alexandria_usage_rule
prompt: |
Alexandria utilities allowed: `if-let`, `when-let`, `with-gensyms`, etc.
Avoid: `alexandria:curry` (use explicit lambdas)
Avoid: `alexandria-2:*` functions not yet used in codebase
# === Macros ===
- name: macro_style_rule
prompt: |
Keep macros small. For complex logic, use `call-with-*` pattern:
```lisp
(defmacro with-foo (() &body body)
`(call-with-foo (lambda () ,@body)))
```
Prefer `list` over backquote outside macros.💬 Feedback Reply to a violation comment with:
📚 About Code ContractorDeclarative Code Standards That Learn and Improve Define domain-specific validation rules in YAML. Want this for your repo? |
|
This PR is ready for review. A working tutorial command that opens an interactive tutorial buffer with progress save/restore across sessions To load and run: Syntax highlighting for the tutorial buffer Suggestions on content, structure, or anything else are very welcome — including from the community on Discord. |
| Two keys that are useful right now: | ||
|
|
||
| C-v Scroll down one screen | ||
| M-v Scroll up one screen |
There was a problem hiding this comment.
is there a reason to keep the M-x notation instead of Alt-x? (here and below) For newcomers, we shouldn't be weird, let's show Alt-… as much as possible.
There was a problem hiding this comment.
Ah, I somehow thought we changed only Alt-x for commands. And leave the M-letter keybindings. I'll change it. As soon as I can.
Witch was just now.
| (merge-pathnames "init.lisp" (lem:lem-home)))) | ||
|
|
||
| (define-keys *global-keymap* | ||
| ("Alt-C-e" 'open-init-file)) |
There was a problem hiding this comment.
we can't use "Alt" in define-keys :S
we'll manage to merge this I have faith.
There was a problem hiding this comment.
It's not faith I'm worried about. My own understanding maybe a bit though. You are right, I have this keybindings myself and it does conflict with some modes out there I noticed. M-C-e that is Will think of one that is unused and makes sense, I am if course open to suggestions.
Closes lem-project#1967 - Alt-x tutorial opens an interactive tutorial buffer - Working copy saved to (lem-home)/lem-tutor-saves/ - Cursor position persisted across sessions - Lesson 1: Movement - Lesson 2: Files and Configuration
…er argument handling
… names, Capitalization, typo fixes
…nch overflow error
8078848 to
16b8be8
Compare
| (:export #:tutorial )) | ||
|
|
||
| (in-package :lem-tutor) | ||
|
|
There was a problem hiding this comment.
Code Contractor: functional_style_rule
Contract: contract
AI check failed: "functional_style_rule"
Reason:
A dynamic variable is introduced and then used by helper functions instead of passing the source directory explicitly as an argument.
💬 Reply /dismiss <reason> to dismiss this violation.
Closes #1967
This PR is ready for review.
What's included:
A working tutorial command that opens an interactive tutorial buffer with progress save/restore across sessions
Lessons 1–4 covering movement, files & configuration, buffers & windows, and editing
Future lessons will be added as separate files
Follows Lem conventions throughout (error handling, lazy-init paths, docstrings)
To load and run:
Since lem-tutor lives inside the Lem source tree, ASDF will find it once the source registry is initialised. In a SLIME REPL inside Lem:
lisp(asdf:initialize-source-registry
'(:source-registry
(:tree "/path/to/lem/")
:inherit-configuration))
(asdf:load-system :lem-tutor)
Then: Alt-x tutorial
Planned follow-up (not blocking merge):
Syntax highlighting for the tutorial buffer
Lesson 5 covering Common Lisp / SLIME
Tests will be added alongside future functionality where applicable
Suggestions on content, structure, or anything else are very welcome — including from the community on Discord.