Repository navigation
Don't fold on tab by default - #2297
Conversation
✅ Code Contractor Validation: PASSED 📌 Result for commit 📋 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
Only flag violations when elements appear OUT OF ORDER (e.g., key bindings AFTER functions, or defvar AFTER functions).
Key bindings appearing BEFORE functions is correct and expected.
# === 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.📚 About Code ContractorDeclarative Code Standards That Learn and Improve Define domain-specific validation rules in YAML. Want this for your repo? |
|
youre probably right, its supposed to fold only when the cursor is on the first line of a defun, but since i dont use completion much i may not have noticed the friction it caused |
Actually maybe its also particularly problematic for me because the folding behavior seems to occur in places where I wanted different behaviors as well. For example, if I am defining a function, and I want to tab complete a symbol like (defun foo () (lem:def))
;; CURSOR HERE ^Another thing I like to do when working on code is using (defun bar ()
(let ((asdf
1))
(print asdf)))I think if these problems were fixed, I think the folding behavior would be less disruptive. But as it is, it seems to break these tasks |
|
oh indeed. Can we bind folding to another key? |
What is the preferred approach @vindarel @mahmoodsh36 ? Should I disable tab folding by default or change the default folding key so it doesn't conflict with the other tab actions? I think given the problems that the current implementation of the tab folding has that it might be better to use a different key like |
|
Hey shall you bind folding to I'm annoyed by folding when the cursor is at the end of line too^^ (right before the last paren, where I want code completion) |
|
Hi, ping. |
Sorry I've been busy, I'll see about getting this done |
|
Okay @vindarel |
|
That's a bummer, we need the same behaviour in ncurses. What about |
|
Okay I swapped it to |
|
thank you! |
Folding function definitions by default whenever you press tab is a new behavior that was just added in this commit about 2 months ago.
While some people might like this behavior, I found it very confusing and it caused friction when trying to use tab for symbol completion and code indentation.
Because the folding behavior is bound to such a fundamental key (
Tab) which is already used for several other tasks, I think it would be better for this to be an opt-in feature, rather than enabled by default.