Установка языка с помощью #lang в REPL
Вопрос
Я хотел бы установить язык в REPL на лету, с помощью #lang
, без использования аргумента командной строки «-I».Но это дает мне ошибку «прочитайте:#lang не включен в текущем контексте».
Есть ли переключатель командной строки, которого мне не хватает?Или, может быть, я могу использовать метакоманду?Причина, по которой мне это нужно, заключается в том, что я хотел бы иметь возможность отправлять буфер Emacs в Racket REPL, но это не сработает, если файл начинается с #lang
.
Решение
[Редактировать]
я не могу получить C-x C-b
работать с #lang
или.
Но буфер, содержащий #lang
можно отправить в REPL, запущенный из Geiser, с помощью C-c C-a
.Это Переключитесь на REPL и войдите в модуль из раскрывающегося меню Гейзера.Если у меня есть буфер для bugsy.rkt:
;; bugsy.rkt
#lang racket
(define k 6)
(define j 7)
(define (f lhs rhs)
(+ lhs rhs))
Ввод текста C-c C-a
дает мне это в REPL:
racket@> ,enter "<filepath>/bugsy.rkt"
racket@bugsy.rkt>
Затем я могу получить доступ к модулю в REPL:
racket@bugsy.rkt> k
6
racket@bugsy.rkt> (f 3 4)
7
Если я хочу переключиться на другой модуль [или буфер файла], я могу использовать ,enter
команда в REPL:
racket@bugsy.rkt> ,enter "clyde.rkt"
racket@clyde.rkt> ,enter "bonny.rkt"
racket@bonny.rkt>
Есть пример того ,enter
команда в документации. Посмотрите выше динозавра.
[Оригинал]
Согласно документации Racket #lang
имеет очень простой синтаксис, читатель по существу загружает синтаксис языка из всего, что следует за символом пробела после #lang
.Это означает в некотором смысле, что #lang
не соответствует синтаксису Racket [или любого другого языка].Вместо этого это особенность реализации ридера, которая является частью более широкой экосистемы разработки «Racket».
Гейзер [и, предположительно, Шарлатан и режим рэкета] справляются с этим, анализируя #lang
в elsip перед передачей кода в Racket REPL.В Гейзере работа выполняется в geiser-racket.el.
Функция синтаксического анализа находится в строке 132:
(defun geiser-racket--language ()
(or (cdr (geiser-racket--explicit-module))
(save-excursion
(goto-char (point-min))
(if (re-search-forward "^#lang +\\([^ ]+\\)" nil t)
(geiser-syntax--form-from-string (match-string-no-properties 1))))
"#f"))
И это называется geiser-racket--geiser-procedure
в строке 166.
(defun geiser-racket--geiser-procedure (proc &rest args)
(case proc
((eval compile)
(format ",geiser-eval %s %s %s"
(or (car args) "#f")
(geiser-racket--language)
(mapconcat 'identity (cdr args) " ")))
((load-file compile-file)
(format ",geiser-load %S" (geiser-racket--find-module)))
((no-values) ",geiser-no-values")
(t (format ",apply geiser:%s (%s)" proc (mapconcat 'identity args " ")))))
Это может дать вам отправную точку для разработки собственного кода, если один из существующих режимов Emacs не соответствует вашим потребностям.
Другие советы
; foo.rkt
#lang whatever
"hi"
это в основном то же самое, что и
(module foo whatever
"hi")
Таким образом, в качестве быстрого взлома вы, вероятно, могли бы отрезать #lang
строку, извлеките из нее lang и поместите остальную часть буфера внутрь (module ...)
форма перед comint-send-input
-включаю его.
Еще проще, если вы не возражаете сохранить буфер на диск, сначала:Просто пришлите сюда ,enter /path/to/file.rkt
в буфер REPL, или если вы не используете XREPL, (enter! "/path/to/file.rkt")
.
Кроме того, стоит упомянуть несколько режимов, связанных с ракеткой:
- Гейзер
- Шарлатан
- режим ракетки (Я виноват в этом)
Возможно, один из них уже делает то, что вы хотите, или вы могли бы заглянуть в то, как они работают (у каждого из них несколько иной подход к этому).
У меня было очень трудно упаковывать голову вокруг этого, используя ракетку и гаесер, чтобы пройти через SICP с #lang sicp
.Наконец понял его.Основываясь на всех хороших ответах выше, это комментарии, чтобы напомнить себе о том, что делать и почему:
#lang sicp
;;C-c C-a loads #lang module into REPL (save before loading)
;;C-u C-c C-z is faster than C-c C-a
;;https://docs.racket-lang.org/sicp-manual/index.html
;;https://stackoverflow.com/questions/21008623/setting-language-with-lang-in-the-repl
(#%require sicp-pict)
(paint einstein)
.
Ракетка и Geiser - две удивительные компоненты программного обеспечения, почти сдавались, но это стоило усилия, чтобы получить эту работу.Благодаря всем за хорошую работу и помогая нам учиться.