4

コードの一部を強調表示し、タブまたは使用しているスペースをインデントまたはインデント解除できるのは、ほとんどの最新のエディターの標準です。これをemacsでどのように行うのですか?

たとえば、崇高なテキストを開いて、次のコードを強調表示しました。

variation1 person phoneMap carrierMap addressMap =
    case M.lookup person phoneMap of
      Nothing -> Nothing
      Just number ->
          case M.lookup number carrierMap of
            Nothing -> Nothing
            Just carrier -> M.lookup carrier addressMap

次にタブを押して取得しました

  variation1 person phoneMap carrierMap addressMap =
      case M.lookup person phoneMap of
        Nothing -> Nothing
        Just number ->
            case M.lookup number carrierMap of
              Nothing -> Nothing
              Just carrier -> M.lookup carrier addressMap

そのコードの1つのシフトタブが元の場所に戻り、シフトタブを押し続けると、最終的に次のようになります:

variation1 person phoneMap carrierMap addressMap =
case M.lookup person phoneMap of
Nothing -> Nothing
Just number ->
case M.lookup number carrierMap of
Nothing -> Nothing
Just carrier -> M.lookup carrier addressMap

別の回答からの引用:

emacs 言語モードには、実際には「このブロックを 1 タブ分インデントする」という概念はありません。代わりに、彼らは非常に独断的で、「これが正しいインデントだ」という考えを持っています。これは、言語モードでタブを押すと得られるものです。

次のコードでそれを行う場合を除いて(haskellモードとghc modが有効になっています):

import Monad
import System
import IO
import Random
import Control.Monad.State

type RandomState a = State StdGen a
data CountedRandom = CountedRandom {
      crGen :: StdGen
    , crCount :: Int
    }

type CRState = State CountedRandom

getRandom :: Random a => RandomState a
getRandom =
  get >>= \gen ->
  let (val, gen') = random gen in
  put gen' >>
  return val  

私は以下を取得します:

import Monad
  import System
  import IO
  import Random
  import Control.Monad.State

type RandomState a = State StdGen a
data CountedRandom = CountedRandom {
  crGen :: StdGen
  , crCount :: Int
  }

type CRState = State CountedRandom

               getRandom :: Random a => RandomState a
               getRandom =
  get >>= \gen ->
  let (val, gen') = random gen in
  put gen' >>
  return val  

欲しかったとき

import Monad
import System
import IO
import Random
import Control.Monad.State

type RandomState a = State StdGen a
data CountedRandom = CountedRandom {
      crGen :: StdGen
    , crCount :: Int
    }

type CRState = State CountedRandom

getRandom :: Random a => RandomState a
getRandom =
  get >>= \gen ->
    let (val, gen') = random gen in
    put gen' >>
    return val  

ataylorからの解決策に十分近い:

(defcustom tab-shift-width 4
  "Sets selected text shift width on tab"
  :type 'integer)
(make-variable-buffer-local 'tab-shift-width)

(global-set-key 
 (kbd "<tab>")
 (lambda (start end)
   (interactive "r")
   (if (use-region-p)
       (save-excursion
     (let ((deactivate-mark nil))
       (indent-rigidly start end tab-shift-width)))
     (indent-for-tab-command))))

(global-set-key 
 (kbd "S-<tab>")
 (lambda (start end)
   (interactive "r")
   (if (use-region-p)
       (save-excursion
     (let ((deactivate-mark nil))
       (indent-rigidly start end (- tab-shift-width))))
     (indent-for-tab-command))))

emacs がインデント検出 (つまり、変数の値を取得するだけ) をサポートしていればいいのですが。これに最も近いのは dtrt indent というプラグインですが、Haskell では機能しません。

4

4 に答える 4

2

indent-region現在のモードに従ってテキストのブロックを再インデントします。

インデント レベルを強制的に追加するstring-rectangleには、文字列の入力を求める を使用できます。ここで、インデント レベルの文字列を指定できます (例: タブ、4 つのスペースなど)。文字列は、現在選択されているリージョンの各行の現在の列に挿入され、効果的にインデントされます。または、 から同様の効果を得ることができますopen-rectangle。これは、ポイントとマークによって定義された角を持つ長方形に空白を挿入します。

インデントを強制するもう 1 つの方法は、indent-rigidly( C-x TAB) を呼び出すことです。これは、モード固有のインデント ルールを上書きし、固定量だけインデントします。数値引数はインデントする量を指定し、負の引数はインデントを解除します。これをリージョンが選択されたときのデフォルトの動作にしたい場合は、次のようにすることができます:

(global-set-key 
 (kbd "<tab>")
 (lambda (start end)
   (interactive "r")
   (if (use-region-p)
       (save-excursion
     (let ((deactivate-mark nil))
       (indent-rigidly start end 4)))
     (indent-for-tab-command))))
于 2012-05-07T19:32:32.373 に答える
2

Haskell コードを正しくインデントするのは非常に困難です。これは、1 つのコードに「正しい」インデントが複数あるためです。

haskell-modeには、従うことを期待する非常に具体的な行形式があり (適切な場所で改行を作成する必要があるため)、その行形式に一致するコードをフォーマットするためのいくつかのインデント規則があります。これらの規則は、自動インデントの結果の一貫性を高めるために存在します。ルールはおおよそ次のとおりです。

  • ブロックを導入するすべてのキーワードの後に​​、改行を作成するか、ブロック全体がレイアウトに収まるようにする必要があります。getRandomそれ以外の場合は、例のようにぶら下がっているブロックがたくさんあります
  • すべてのブロックは、ちょうど 2 つのスペースでインデントされます。これにはモジュール ブロックが含まれます。module Bla whereすると、その行以降の部分全体がインデントされます。これは、インデント順序が機能するように、デフォルトの Haskell モジュール ファイル形式を維持する必要があることを意味します。
  • 行のインデントは、できるだけ明確にする必要があります。行がそのインデントに応じて異なることを意味する可能性がある場合haskell-mode、コンテキストで意味があると考えられる位置にインデントされることにつながります。これを修正することは、場合によっては不可能です。

の要件を満たすように Haskell コードを構造化することは不可能であるため、haskell-modeこのように Haskell コード ファイルをインデントすることはできません。自動インデントはローカルでのみ使用する必要があります。これは、いくつかの方法で行うことができます。

  • 行にいるとき、 を押すと、現在の行を前の行に対して最も「正しい」位置にインデントできますTAB。もう一度押すTABと、行が「次の」インデント レベルに移動し、可能なすべての論理インデント ステップを連続的に循環します。
  • ローカルで見つかった一連のブロック (関数の本体など) を選択して を使用するM-x indent-regionと、ほとんどの場合正しい結果が得られます。

このような状況で私が通常行うことは、「間違った」インデントがある行から開始し、 1 回押して、行ごとに下に移動し、その行のインデントが完了するまで各行を 1 回または複数回TAB押します。TAB正しい。現在の行の現在の「論理的なインデント位置」は、前のコード コンテキストから計算されるため、インデントを上から修正すると、ほとんどの場合正しい結果が得られます。

于 2012-05-08T00:10:54.567 に答える
0

emacs 言語モードには、実際には「このブロックを 1 タブ分インデントする」という概念はありません。代わりに、彼らは非常に独断的で、「これが正しいインデントだ」という考えを持っています。これは、言語モードでタブを押すと得られるものです。

慣れてくると、何かが変に思えてきます。Haskell コードでは、これらの case ステートメントには有効なインデントが 1 つしかありません。それ以外は、中かっことセミコロンを追加しない限り、構文エラーになります。emacs が「正しい」インデントと見なすものを本当にカスタマイズしたい場合は、モードのカスタマイズ方法を参照してください。多くの言語モードは c-mode 変数を再利用するので、おそらくここから始めるのが良いでしょう (Haskell モードが何をするのかはよくわかりませんが、カスタマイズする必要があるとは思いませんでした)。

編集: あなたの問題は、Haskell モードがインストールされていないことが原因であることがコメントでわかりました。それを取得するためにgithub ページにアクセスしました。

于 2012-05-07T19:32:25.187 に答える
0

その領域を強調表示して を叩きC-M-\ます。複数行インデントのページではindent-region、さらに多くの楽しみを見つけることができます。

于 2012-05-07T19:23:30.287 に答える