Skip to content

fix markdown-preview#2225

Merged
vindarel merged 4 commits into
lem-project:mainfrom
MasterCsquare:fix-markdown-preview
Jun 9, 2026
Merged

fix markdown-preview#2225
vindarel merged 4 commits into
lem-project:mainfrom
MasterCsquare:fix-markdown-preview

Conversation

@MasterCsquare

@MasterCsquare MasterCsquare commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

the markdown-preview not open a external browser on ncurses.
add a new command markdown-preview-external-browser to do it.
the trivial-open-browser use format to compose the path-name, that's why it reported error.
use M-x markdown-preview-external-browser to open the previewed markdown on browser.

the markdown-preview not open a external browser on ncurses.
add a new command markdown-preview-external-browser to do it.
the trivial-open-browser use format to compose the path-name,
that's why it reported error.
@code-contractor-app

code-contractor-app Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

✅ Code Contractor Validation: PASSED

=== Contract: contract ===

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

📋 Contract Source: Repository

📊 Statistics:
  Files Changed:    2
  Lines Added:      8
  Lines Deleted:    1
  Total Changed:    9
  Delete Ratio:     0.11 (11%)

Status: PASSED ✅

🤖 AI Providers:
  - codex — model: gpt-5.4

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 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

      # === 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 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

@code-contractor-app code-contractor-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Contractor validation passed ✅ — see the sticky comment for full results.

@vindarel

vindarel commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Can you explain why you replace trivial-open-browser, did you capture the error message? (nothing against the move) open-browser seems to also just be xdg-open. (I don't see a single usage of format in this little library.) Thanks.

@vindarel

vindarel commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

You can also use the opportunity to add docstrings to both functions, markdown-preview[-external-browser]. Thanks.

@MasterCsquare

MasterCsquare commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author
Subprocess with command "xdg-open #A((25) BASE-CHAR . \"/tmp/tmpKKGYNQX1-tmp.html\")"
 exited with error code 1
Backtrace for: #<SB-THREAD:THREAD tid=3092 "editor" RUNNING {12052697D3}>
0: ((LAMBDA NIL :IN UIOP/IMAGE:PRINT-BACKTRACE))
1: ((FLET "THUNK" :IN UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX))
2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<FUNCTION (FLET "THUNK" :IN UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX) {7FB125135ACB}>)
3: (UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX #<FUNCTION (LAMBDA NIL :IN UIOP/IMAGE:PRINT-BACKTRACE) {1206CDC96B}> :PACKAGE :CL)
4: (LEM-CORE:POP-UP-BACKTRACE #<UIOP/RUN-PROGRAM:SUBPROCESS-ERROR {1206CDC783}>)
5: ((LAMBDA (CONDITION) :IN LEM-CORE:COMMAND-LOOP) #<UIOP/RUN-PROGRAM:SUBPROCESS-ERROR {1206CDC783}>)
6: (SB-KERNEL::%SIGNAL #<UIOP/RUN-PROGRAM:SUBPROCESS-ERROR {1206CDC783}>)
7: (CERROR "IGNORE-ERROR-STATUS" UIOP/RUN-PROGRAM:SUBPROCESS-ERROR :COMMAND "xdg-open #A((25) BASE-CHAR . \"/tmp/tmpKKGYNQX1-tmp.html\")" :CODE 1 :PROCESS NIL)
8: (UIOP/RUN-PROGRAM::%CHECK-RESULT 1 :COMMAND "xdg-open #A((25) BASE-CHAR . \"/tmp/tmpKKGYNQX1-tmp.html\")" :PROCESS NIL :IGNORE-ERROR-STATUS NIL)
9: (UIOP/RUN-PROGRAM::%USE-SYSTEM "xdg-open #A((25) BASE-CHAR . \"/tmp/tmpKKGYNQX1-tmp.html\")")
10: ((:METHOD LEM-CORE:EXECUTE :AROUND (LEM-MARKDOWN-MODE:MARKDOWN-MODE T T)) #<COMMON-LISP-USER::|%ACTIVE-MODES-CLASS-example.md| {1206CA8153}> #<LEM-MARKDOWN-MODE/PREVIEW/PREVIEW::MARKDOWN-PREVIEW-EXTERNAL-BROWSER {1202804DD3}> NIL) [fast-method]
11: (LEM-CORE:CALL-COMMAND #<LEM-MARKDOWN-MODE/PREVIEW/PREVIEW::MARKDOWN-PREVIEW-EXTERNAL-BROWSER {1202804DD3}> NIL)
12: ((:METHOD LEM-CORE:EXECUTE :AROUND (LEM-MARKDOWN-MODE:MARKDOWN-MODE T T)) #<COMMON-LISP-USER::|%ACTIVE-MODES-CLASS-example.md| {1206CA8153}> #<LEM-CORE/COMMANDS/OTHER:EXECUTE-COMMAND {1206E4DB13}> NIL) [fast-method]
13: (LEM-CORE:CALL-COMMAND LEM-CORE/COMMANDS/OTHER:EXECUTE-COMMAND NIL)
14: (LEM-CORE::COMMAND-LOOP-BODY)
15: (LEM-CORE:COMMAND-LOOP)
16: (LEM-CORE::TOPLEVEL-COMMAND-LOOP #<FUNCTION (LAMBDA NIL :IN LEM-CORE::RUN-EDITOR-THREAD) {12065CBFCB}>)
17: ((LAMBDA NIL :IN LEM-CORE::RUN-EDITOR-THREAD))
18: ((LAMBDA NIL :IN LEM-CORE::RUN-EDITOR-THREAD))
19: ((FLET BT2::RUN-FUNCTION :IN BT2::ESTABLISH-DYNAMIC-ENV))
20: ((LABELS BT2::%ESTABLISH-DYNAMIC-ENV-WRAPPER :IN BT2::ESTABLISH-DYNAMIC-ENV))
21: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
22: ((FLET "WITHOUT-INTERRUPTS-BODY-" :IN SB-THREAD::RUN))
23: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
24: ((FLET "WITHOUT-INTERRUPTS-BODY-" :IN SB-THREAD::RUN))
25: (SB-THREAD::RUN)
26: ("foreign function: call_into_lisp_")

It would reported the error liked that using trivial-open-browser, which called (format nil "xdg-open ~S" pathname) on linux.
because it's ~S not ~A, it would add somethings like #A((25) BASE-CHAR ..

@vindarel

vindarel commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Is your preview updated on the fly by wesockets? (mine isn't)

@MasterCsquare

Copy link
Copy Markdown
Contributor Author

It's updated on webwiew within html-buffer, but not with external-browser. the method lem-markdown-mode/internal:on-change is not implement yet.

…editor

xdg-open should be fire-and-forget — run-program waits for the process
to exit, which can block the editor on some desktop configurations.
launch-program returns immediately.
@MasterCsquare

MasterCsquare commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

I have implemented on-change,which is just the same as on-save. it updates the preview on-the-fly now on SDL2 and ncurses.
However, it's not working on webview and i don't know why, although we can preview it in the buffer to make everything work.
By the way, I replaced uiop:run-program with uiop:launch-program to avoid blocking the editor.

@vindarel vindarel merged commit e65b67d into lem-project:main Jun 9, 2026
10 checks passed
@vindarel

vindarel commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Excellent, thanks.

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