下位スキームでインデントを有効にするにはどうすればよいですか?

デフォルトの下位スキームには字下げがないようです。少なくとも、私が M-x run-scheme を実行すると、結果のreplは自分のコードをインデントしません。

これをどうやって変更できますか?好ましくは、ガイザー(giser)または他のラッパーのようなものは一切使用しない

1
追加された
ビュー: 3

1 答え

問題は、 RET がおそらく字下げを行わない comint-send-input にマップされているということです。

私が行うことは、 comint-send-inputRET をマッピングしたまま Cj改行とインデント 。したがって、改行を入力するには C-j を押し、新しい行をインデントするか、評価のためにフォームを実際に送信するために RET を押します。 (実際には C-j

paredit-newline にマッピングしますが、Pareditを使用していない場合は newline-and-indent

もちろん、それらを逆にして、 comint-send-inputCj改行とインデントコード>。

これらのキーの1つをマッピングする例として、 C-j改行とインデントにマッピングします。

(with-eval-after-load 'cmuscheme
  (define-key inferior-scheme-mode-map (kbd "C-j") #'newline-and-indent))

cmuscheme は歴史的理由から、 inferior-scheme-mode を実装するパッケージの名前、つまりScheme REPLです)。

編集:

私は広範囲にテストしていませんが、これはうまくいくようです。

(defun comint-send-input-indent ()
  (interactive)
  (comint-send-input)
  (unless (save-excursion (forward-char -1)
                          (eq (field-at-pos (point)) 'output))
    (indent-for-tab-command)))

(with-eval-after-load 'cmuscheme
  (define-key inferior-scheme-mode-map (kbd "RET") #'comint-send-input-indent))

この考え方は、 comint-send-input を呼び出して、ポイント(カーソル)がプロンプトの直前にあるかどうかを確認することです。そうでない場合( comint-send-input が改行を入力したため)、行を適切にインデントする indent-for-tab-command を呼び出します。

別の編集:

2番目の考えでは、私はこの定義がおそらくもっと理にかなっていると思う:

(defun comint-send-input-indent ()
  (interactive)
  (let ((parens (or (car (syntax-ppss)) 0)))
    (if (zerop parens)
        (comint-send-input)
      (newline-and-indent))))

詳細については、 C-h f構文-ppss RET を参照してください(さらに、 C-h f parse-partial-sexp RET )。短いバージョンでは、parenのネストがどれほど深いところにあるかを教えてくれるので、これを使って改行とインデントcomint-send-input <�コード>。

2
追加された
@Darklightus、私の悪い、私は例を含める答えを編集しました。代わりに "CET""RET" に置き換えて RET
追加された 著者 Jorriss,
@ワサマサ、それは実際に可能であるように思われる。実際には、(入力を送信するのではなく)既に改行を入力しているのに(私は他のバージョンを使っていませんでした) comest-send-input を使っているEmacs 25 pretestでは、インデントしませんフォームが不完全な場合は新しい行。しかし、ソースをすばやく読んだ後で、それがどのように機能するかはわかりません。私はもっ​​と後でそれを見なければならないでしょう。
追加された 著者 Jorriss,
Emacs Lisp(およびCommon Lisp)では、 progn はSchemeの begin と同等です。しかし、(progn(改行とインデント))(comint-send-input))を使って関数を定義することはできません。もう一方は するのではなく、またはもう一方を実行したいとします。難しい部分はいつ行うべきかを考え出すことです。 (また、関数本体はSchemeのように暗黙の progn であるため、この特定のケースでは実際に progn を使用しないでしょう。関数)
追加された 著者 Jorriss,
私は今これについて Emacsのヘルプメーリングリストで、関連する情報で私の答えを更新します。
追加された 著者 Jorriss,
ここであなたがそれを行う方法です。しかし、私が何かを逃していない限り、私はまだそれがあなたにあなたが望む機能を与えるとは思わない。
追加された 著者 Jorriss,
@Darklightus、私は動作するように見える新しい呪文で答えを編集しました。私はリストから学ぶことでさらに編集します。ありがとう!
追加された 著者 Jorriss,
私は正しいことを実行する単一のコマンドを書く方法を想像することができます。基本的に、サブプロセスに送信できるフォームと残りのインデントを必要とするフォームの違いは、前者が完了している(読み取り:均衡)状態であり、後者が完全ではないということです。
追加された 著者 ICodeForCoffee,
申し訳ありませんが、私はemacsには本当に新しいです。これらのキーはどのようにマップできますか?
追加された 著者 Snakist_へびーん,
デフォルトでは RETcomint-send-input を実行しますが、インデントに加えて改行とインデントcomint-send-input ?次に、2つのキーを使用する代わりに、1つだけを使用できます。どうすればいい?私は他のリスプで begin を使っていましたが、(emacsを壊す以外の)何もしないようです。
追加された 著者 Snakist_へびーん,
私は本当になぜそれをしないのかを理解していない。すでに comint-send-input を行っていますが、その前に改行とインデントしたいと考えています。
追加された 著者 Snakist_へびーん,
私は(progn(newline-and-indent)(comint-send-input))として定義しようとしましたが、何らかの理由で M-x run-scheme
追加された 著者 Snakist_へびーん,
@jbmそうですね、改行は comint-send-input によってその効果が失われます。今度は、うまくインデントされた次の行に、インデントされていない新しい行が続きます。私はメーリングリストからの答えを待つだけだと思う​​。これまでのご協力ありがとうございます!
追加された 著者 Snakist_へびーん,
comint-send-inputnewline-and-indent の間で改行を削除することで少し修正しました。これはほぼ完璧です:唯一の問題は、結果を実際に戻すときに、5の前の改行ではなく(+ 2 3)5 のような改行なしで入力した後に印刷するときです。どのようにこれを修正できるかを見てください。だから誰かがメーリングリストで素敵な答えを送ってくれることを祈っています。これを忘れる前に(何も起こらない場合)私はあなたの答えを受け入れるでしょうが、何か起こった場合に備えて私を更新しておいてください。
追加された 著者 Snakist_へびーん,
@jbm最後のものは、私が望むのとまったく同じように動作するようです。私はまだそれを集中的に使用していませんが、今のところ完全に動作しているようです。どうもありがとうございました!
追加された 著者 Snakist_へびーん,