Skip to content

prompt-window: add docs on the tail to show what it is - #2370

Open
MasterCsquare wants to merge 7 commits into
lem-project:mainfrom
MasterCsquare:naming
Open

MasterCsquare wants to merge 7 commits into
lem-project:mainfrom
MasterCsquare:naming

Conversation

@MasterCsquare

@MasterCsquare MasterCsquare commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

When M-x, the docs about what the command do would be showed

Image

@code-contractor-app

code-contractor-app Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

⏳ Commit 34b6e3f has not been validated yet. The results below are for a previous commit. Comment /rerun (keeps dismissed violations dismissed) or @code-contractor-app to re-validate.

✅ Code Contractor Validation: PASSED

📌 Result for commit 58b4ed7

=== Contract: contract ===

✓ Code Contractor Validation Result
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📋 Contract Source: Repository

📊 Statistics:
  Files Changed:    1
  Lines Added:      33
  Lines Deleted:    2
  Total Changed:    35
  Delete Ratio:     0.06 (6%)

Status: PASSED ✅

🤖 AI Providers:
  - codex — profile: bedrock-gpt61-terra

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 No violations detected. Great job!
📋 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.

          Exception: In major-mode files (e.g., *-mode.lisp), flexible ordering is acceptable when it follows established patterns from similar modes (e.g., clojure-mode, python-mode).

      # === 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*`, constants, and configuration variables (not meant to be modified at runtime).

      - name: dynamic_symbol_call_rule
        prompt: |
          Avoid `uiop:symbol-call`. Rethink architecture instead.
          Exception: Acceptable in extensions when following patterns established in other major-mode extensions (e.g., for optional dependency loading or plugin systems).
          If used, 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.

          Exception: In major-mode files, macro patterns that are standard in other major-modes (e.g., clojure-mode, python-mode) are acceptable.
📚 About Code Contractor

Declarative Code Standards That Learn and Improve

Define domain-specific validation rules in YAML.
Your contracts document team knowledge and evolve into more accurate AI enforcement.

Want this for your repo?
→ Install Code Contractor

(keybindings (collect-command-all-keybindings buffer command)))
(format nil "~{~A~^ ~}"
(remove-if #'alexandria:emptyp
(ecase *command-completion-detail-order*

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If *command-completion-detail-order* holds anything other than the two expected keywords (say a user sets :docs-first or nil in init.lisp), ecase signals an error. It fires inside prompt-command-completion for every command, so M-x completion stops working. A user config variable should not be able to break M-x. Use case with a fallback to the default order, or check the value once and report it with editor-error.

Comment thread src/ext/prompt-window.lisp Resolved
Comment thread src/ext/prompt-window.lisp Resolved
Comment thread src/ext/prompt-window.lisp Resolved
Comment thread src/ext/prompt-window.lisp Resolved
Comment thread src/prompt.lisp Resolved
M-x completion runs on every keystroke and used to rebuild the detail
string (docstring summary + keybindings) for every registered command
before filtering, even though only the matching items are displayed.

Improvements:

* Cache the derived summary per command name in
  *command-docstring-summary-cache*.  Each entry stores the docstring the
  summary was computed from together with the summary, so a redefined
  command (fresh documentation string) is detected by identity check and
  recomputed, while unchanged commands are served from the hash table.
  This avoids trimming, splitting and width-measuring the full docstring
  of every command on every completion refresh.

* Compute the completion detail lazily: filter the command names first and
  create completion items only for the matching names.  Previously items
  for all commands were built, including keybinding collection and detail
  formatting, and only then filtered, so most of that work was discarded
  as soon as the user typed a prefix.

* In completion, hoist the explode-string of the search name out of
  test-with-separator.  The hyphenated matching path re-split the input
  for every candidate element; now it is split once per call.

  No behavior change: candidate-first ordering, alphabetical ordering,
  deduplication and the rendered detail strings are unchanged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants