Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions content/develop/clients/hiredis/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ a string key using [`SET`]({{< relref "/commands/set" >}}) and
[`GET`]({{< relref "/commands/get" >}}), and then finally closes the
connection. An explanation of the code follows the example.

{{< clients-example set="landing" step="connect" lang_filter="C" description="Foundational: Connect to a Redis server, set and retrieve string values using SET and GET, then close the connection" difficulty="beginner" >}}
{{< /clients-example >}}
{{< jupyter-example set="landing" step="connect" lang_filter="C" description="Foundational: Connect to a Redis server, set and retrieve string values using SET and GET, then close the connection" difficulty="beginner" />}}

For a real project, you would build your code with a makefile, but for
this simple test, you can just place it in a file called `main.c` and
Expand Down
83 changes: 82 additions & 1 deletion layouts/_default/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
{{ partial "ai-metadata.html" . }}

{{ partial "fonts.html" . }}

{{ if hugo.IsProduction -}}
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
Expand Down Expand Up @@ -1627,6 +1627,84 @@
}, 120000);
}

// Same workaround as JS/Ruby above, applied to C cells.
// CodeMirror 5 ships C support inside the "clike" mode, exposed under MIME "text/x-csrc".
const CM_CLIKE_MODE_URL = 'https://unpkg.com/codemirror@5.65.16/mode/clike/clike.js';

function loadCodeMirrorCMode(CM) {
if (!CM || typeof CM.defineMode !== 'function') return Promise.resolve(false);
if (CM.modes && CM.modes.clike) return Promise.resolve(true);
if (window.__cmCModePromise) return window.__cmCModePromise;

window.__cmCModePromise = new Promise(function(resolve) {
const hadPrev = Object.prototype.hasOwnProperty.call(window, 'CodeMirror');
const prev = window.CodeMirror;
window.CodeMirror = CM;
const script = document.createElement('script');
script.src = CM_CLIKE_MODE_URL;
const restore = function() {
if (hadPrev) { window.CodeMirror = prev; } else { try { delete window.CodeMirror; } catch (e) { window.CodeMirror = undefined; } }
};
script.onload = function() {
restore();
resolve(!!(CM.modes && CM.modes.clike));
};
script.onerror = function() {
restore();
console.warn('[Thebe] Failed to load CodeMirror C mode from', CM_CLIKE_MODE_URL);
window.__cmCModePromise = null;
resolve(false);
};
document.head.appendChild(script);
});
return window.__cmCModePromise;
}

function findCCmInstances() {
const out = [];
document.querySelectorAll('.thebe-cell .CodeMirror').forEach(function(cmEl) {
const cm = cmEl.CodeMirror;
if (!cm) return;
const mode = cm.getOption('mode');
const modeName = (typeof mode === 'string') ? mode : (mode && mode.name);
if (modeName === 'text/x-csrc') out.push(cm);
});
return out;
}

function applyCModeToCells() {
findCCmInstances().forEach(function(cm) {
cm.setOption('mode', null);
cm.setOption('mode', 'text/x-csrc');
});
}

let __cHighlightDone = false;
let __cHighlightObserver = null;
function __tryRegisterCMode() {
if (__cHighlightDone) return;
const cCms = findCCmInstances();
if (cCms.length === 0) return;
__cHighlightDone = true;
if (__cHighlightObserver) { __cHighlightObserver.disconnect(); __cHighlightObserver = null; }
const CM = cCms[0].constructor;
loadCodeMirrorCMode(CM).then(function(ok) {
if (ok) applyCModeToCells();
});
}
function ensureCHighlightingForActivatedCells() {
__tryRegisterCMode();
if (__cHighlightDone || __cHighlightObserver) return;
if (typeof MutationObserver !== 'function') return;
__cHighlightObserver = new MutationObserver(function() { __tryRegisterCMode(); });
__cHighlightObserver.observe(document.body, { childList: true, subtree: true });
// Safety net: stop observing after 2 minutes even if no C cells ever appear.
setTimeout(function() {
if (__cHighlightObserver) { __cHighlightObserver.disconnect(); __cHighlightObserver = null; }
}, 120000);
}
Comment thread
paoloredis marked this conversation as resolved.


// Function to handle kernel expiration/disconnection
function handleKernelExpired() {
// Clear localStorage session so fresh start on reload
Expand Down Expand Up @@ -1676,6 +1754,7 @@
// as Thebe creates the editors (covers both fresh click and auto-reconnect).
ensureJsHighlightingForActivatedCells();
ensureRubyHighlightingForActivatedCells();
ensureCHighlightingForActivatedCells();

// NOTE: Loading state is now managed by individual click handlers (lines 1189-1190)
// This prevents all blocks from showing "Starting kernel..." when only one is clicked
Expand Down Expand Up @@ -1741,6 +1820,8 @@
// Thebe's bundled CodeMirror lacks the JavaScript mode; lazy-load it
// so Node.js cells keep syntax highlighting after activation.
ensureJsHighlightingForActivatedCells();
// Same workaround for C cells (clike mode under MIME text/x-csrc).
ensureCHighlightingForActivatedCells();
// Note: Removed focus() call that was causing scroll jump on page refresh
// Users can click into any editor to focus when they want to edit
}
Expand Down
11 changes: 5 additions & 6 deletions layouts/shortcodes/jupyter-example.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,10 @@
{{ else }}
{{/* Regular line - add to full file */}}
{{ if $inAnyStep }}
{{/* Skip comment-only lines in steps */}}
{{ if or (eq $trimmed "") (not (hasPrefix $trimmed $commentPrefix)) }}
{{ $currentSection = $currentSection | append . }}
{{ if $inCurrentStep }}
{{ $currentStepLines = $currentStepLines | append . }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Comment filter removal unintentionally changes all existing examples

Medium Severity

Removing the comment-only line filter here is a global change that affects all languages using this shortcode, not just C. For instance, the Python landing.py steps set_get_string and hash_operations contain comment-only lines like # True, # bar, and # {'surname': 'Smith', ...} that were intentionally stripped before rendering. These will now appear in the displayed step code on the live redis-py landing page. The fix could be scoped more narrowly (e.g., only preserving lines matching the //% directive pattern) rather than removing all comment filtering.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fc03082. Configure here.

{{ end }}
{{/* Preserve all lines verbatim, comments included. */}}
{{ $currentSection = $currentSection | append . }}
{{ if $inCurrentStep }}
{{ $currentStepLines = $currentStepLines | append . }}
{{ end }}
{{ else }}
{{/* Context lines (outside any step) - include empty lines for consistent spacing */}}
Expand Down Expand Up @@ -324,6 +322,7 @@
{{/* Map internal language identifier to a CodeMirror mode name for data-language */}}
{{ $cmLanguage := $language }}
{{ if eq $language "node.js" }}{{ $cmLanguage = "javascript" }}{{ end }}
{{ if eq $language "c" }}{{ $cmLanguage = "text/x-csrc" }}{{ end }}
<div class="step-code-view">
<div data-executable="true" data-language="{{ $cmLanguage }}" class="thebe-cell">
{{- highlight $stepCode $language "" -}}
Expand Down
3 changes: 3 additions & 0 deletions local_examples/client-specific/c/landing.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// EXAMPLE: landing
// BINDER_ID c-landing
// KERNEL_NAME c
// STEP_START connect
// The following comment is required to make the example interactive.
//%cflags:-lhiredis
Comment thread
cursor[bot] marked this conversation as resolved.
Comment thread
paoloredis marked this conversation as resolved.
#include <stdio.h>
#include <stdlib.h>

Expand Down
Loading