19

ここでemacs初心者を完了します。

私はUbuntuでemacs23.1.1とemacsスターターキットを使用しています。私は主にlua-mode(でインストールされています)で作業しますpackage-install lua-mode

インデントがどのように機能するかを調整する必要があるので、コーディングガイドラインと一致します。

ガイドラインは次のとおりです。

  • タブからスペースへ;
  • インデントごとに2つのスペース。
  • 末尾のスペースなしで、1行あたり最大80文字。

例:

ローカルfoo=function()
  print( "Hello、world!")
終わり

自動インデントで戦おうとしない場合、emacsで得られるもの:

ローカルfoo=function()
               print( "Hello、world")
終わり

アップデート:

(これはコメントに属しますが、追加のフォーマットが必要なため、ここに配置する必要があります。)

トーマスによる解決策を試してみると、次のようになります。

ローカルfoo=function()
               print( "Hello、world")
        終わり

タブと4つのスペースendでインデントされていることに注意してください。うまくいきません...

アップデート2:

このことも間違った方法でインデントされます:

ローカルバー=foo(
    "1"、
    "2"、
   baz()、-3つのスペースに注意してください
   「クォー」
)。  

そのはず:

ローカルバー=foo(
    "1"、
    "2"、
    baz()、
    「クォー」
  )。

アップデート3:

間違ったインデントの3番目のケース:

ローカルバー=foo(
    "1"、
    "2"
  )。

  local t=5-この行はインデントしないでください。
              -ローカルとtの間のタブにも注意してください。

アップデート4:

トーマスの現在のバージョンで得られるものは次のとおりです。

ローカルfoo=function()
               print( "Hello、world")
        終わり

            ローカルバー=5--Emacsは\tを5の前に置きます

            local zzz = foo(-Emacsはfooの前に\tを置きます
                「1つ」、-ここでTABを2回押しました
                "2"、
               三()、
               "四"
            )。

明示的に記載されている場合を除き、インデントについては何もせず、コードを入力してRETURN各行の最後で押すだけでした。私は実際にコメントを入力しませんでした。

次のようになります。

ローカルfoo=function()
  print( "Hello、world")
終わり

ローカルバー=5

ローカルzzz=foo(
    "1"、
    "2"、
    三()、
    "四"
  )。

アップデート5:

もう1つの間違ったインデントの場合:

ローカルfoo=
{{
バー(); -ここでTABを押しましたが、中括弧を閉じるとそれが殺されました
バズ;
}

する必要があります:

ローカルfoo=
{{
  バー();
  バズ;
}

アップデート6:

完全を期すために、Thomasの構成調整なしで、luaモードの現在のGitHEADで得られるものを次に示します。

ローカルfoo=function()
               print( "Hello、world!")
            終わり

ローカルバー=5

ローカルfoo=bar(
バー、
   baz()、
   quo()、
aaa
)。

ローカルt=
{{
"1"、
2()、
}

チューニングあり:

ローカルfoo=function()
           print( "Hello、world!")
            終わり

            ローカルバー=5

            ローカルfoo=bar(
            バー、
               baz()、
               quo()、
               aaa
            )。

            ローカルt=
            {{
            "1"、
            2()、
         }

私のコーディングガイドラインに一致させるには、次のようになります。

ローカルfoo=function()
  print( "Hello、world!")
終わり

ローカルバー=5

ローカルfoo=bar(
    バー、
    baz()、
    quo()、
    aaa
  )。

ローカルt=
{{
  "1"、
  2()、
}
4

7 に答える 7

9

さて、これをもう一度試してみましょう... lua-modeのソースコードを閲覧した後、私は次のアプローチを思いつきました。

明らかに奇妙なデフォルトのインデントの理由は、現在の行をインデントする列を計算する「lua-calculate-indentation」と呼ばれる関数です。残念ながら、返される値は目的の仕様と一致しません。

たとえば、次のような新しい.luaファイルに1行入力すると、次のようになります。

local foo = function()

Enterキーを押してポイントを2行目に移動するには、。と入力して上記の関数を呼び出すことができますM-: (lua-calculate-indentation)。結果は15です。これは、lua-modeが列15の2番目をインデントすることを意味します。これが、元の質問で説明および例示した非正統的なインデントの理由です。

さて、これを修正するために、関数「lua-calculate-indentation」を再定義して、必要なインデントを返すようにすることをお勧めします。このためには、次のコードを空のファイルに入れ、「lua-mode.el」と同じディレクトリに「my-lua.el」という名前で保存します。

;; use an indentation width of two spaces
(setq lua-indent-level 2)

;; Add dangling '(', remove '='
(setq lua-cont-eol-regexp
      (eval-when-compile
        (concat
         "\\((\\|\\_<"
         (regexp-opt '("and" "or" "not" "in" "for" "while"
                       "local" "function") t)
         "\\_>\\|"
         "\\(^\\|[^" lua-operator-class "]\\)"
         (regexp-opt '("+" "-" "*" "/" "^" ".." "==" "<" ">" "<=" ">=" "~=") t)
         "\\)"
         "\\s *\\=")))

(defun lua-calculate-indentation (&optional parse-start)
  "Overwrites the default lua-mode function that calculates the
column to which the current line should be indented to."
  (save-excursion
    (when parse-start
      (goto-char parse-start))

    ;; We calculate the indentation column depending on the previous
    ;; non-blank, non-comment code line. Also, when the current line
    ;; is a continuation of that previous line, we add one additional
    ;; unit of indentation.
    (+ (if (lua-is-continuing-statement-p) lua-indent-level 0)
       (if (lua-goto-nonblank-previous-line)
           (+ (current-indentation) (lua-calculate-indentation-right-shift-next))
         0))))

(defun lua-calculate-indentation-right-shift-next (&optional parse-start)
  "Assuming that the next code line is not a block ending line,
this function returns the column offset that line should be
indented to with respect to the current line."
  (let ((eol)
        (token)
        (token-info)
        (shift 0))
    (save-excursion
      (when parse-start
        (goto-char parse-start))

      ; count the balance of block-opening and block-closing tokens
      ; from the beginning to the end of this line.
      (setq eol (line-end-position))
      (beginning-of-line)
      (while (and (lua-find-regexp 'forward lua-indentation-modifier-regexp)
                  (<= (point) eol)
                  (setq token (match-string 0))
                  (setq token-info (assoc token lua-block-token-alist)))
        ; we found a token. Now, is it an opening or closing token?
        (if (eq (nth 2 token-info) 'open)
            (setq shift (+ shift lua-indent-level))
          (when (or (> shift 0)
                    (string= token ")"))
            (setq shift (- shift lua-indent-level))))))
    shift))

このコードは、インデントレベルを(3ではなく)2つのスペースに設定し、ステートメントが複数行にまたがっているかどうかを検出する正規表現を変更し、最後に補助を使用してインデント関数を再定義します。

あとは、このコードが実際にロードされていることを確認するだけです。これは、元のlua-modeがロードされた後に発生する必要があります。そうしないと、そのコードによって元のインデント関数が再インストールされます。

ここでそれを行う方法は少しハックです。バッファがメジャーモードをluaモードに変更するたびに呼び出されるコールバック関数をインストールします。次に、前述の補助関数が定義されているかどうかを確認します。定義されていない場合は、「my-lua.el」をロードします。これは少し壊れやすいですが、luaのソースコードをいじらない限り、問題はないはずです。

〜/ emacs.d / agladysh.elファイルに次の行を追加します(「agladysh」がユーザー名であると想定)。

(add-hook 'lua-mode-hook 
          (lambda () (unless (fboundp 'lua-calculate-indentation-right-shift-next)
                       (load-file (locate-file "my-lua.el" load-path)))))

lua-modeがロードパス上にあると仮定します。これは、lua-modeのインストール手順に従った場合のはずです。

今回はうまくいくことを願っていますが、そうでない場合はお知らせください。

于 2011-01-10T22:04:16.127 に答える
4

これが尋ねられてからしばらく経ちましたが、Emacsパッケージシステムを介してインストールされたlua-modeでは、これがまだ問題であることを指摘したいと思います。

ただし、 GitHubの最新バージョンは非常にうまく機能し、インデントの奇妙さには気づきませんでした。Luaスタイルガイドに準拠するために必要なのは、とに設定indent-tabs-modeすることだけです。nillua-indent-level2

于 2013-06-09T10:45:08.773 に答える
2

ホームディレクトリのファイルに次のコードを入力する.emacsと、lua-mode(およびlua-modeのみ)が次のように動作します。

  • Enterキーを押すと、改行が挿入され、デフォルトでは次の行が前の行と同じようにインデントされます。
  • Tabキーを押して行をインデントするたびに、ポイントは行の最初の非空白文字にジャンプするか、行が空の場合はポイントがすでにその文字にある場合は、2つのスペースが挿入されます。

特に後者はあなたが望むものではないかもしれませんが、おそらくそれは最初の近似です。

(defvar my-lua-indent 2
  "The number of spaces to insert for indentation")

(defun my-lua-enter ()
  "Inserts a newline and indents the line like the previous
non-empty line."
  (interactive)
  (newline)
  (indent-relative-maybe))

(defun my-lua-indent ()
  "Moves point to the first non-whitespace character of the
line if it is left of it. If point is already at that
position, or if it is at the beginning of an empty line,
inserts two spaces at point."
  (interactive)
  (when (looking-back "^\\s *")
    (if (looking-at "[\t ]")
        (progn (back-to-indentation)
               (when (looking-at "$")
                 (kill-line 0)
                 (indent-relative-maybe)
                 (insert (make-string my-lua-indent ? ))))
      (insert (make-string my-lua-indent ? )))))

(defun my-lua-setup ()
  "Binds ENTER to my-lua-enter and configures indentation the way
I want it. Makes sure spaces are used for indentation, not tabs."
  (setq indent-tabs-mode nil)
  (local-set-key "\r" 'my-lua-enter)
  (setq indent-line-function 'my-lua-indent))

;; add `my-lua-setup' as a call-back that is invoked whenever lua-mode
;; is activated.
(add-hook 'lua-mode-hook 'my-lua-setup)

これらの変更を有効にするには、Emacsを再起動します。

于 2011-01-10T10:02:47.173 に答える
1

これを行うためのよりクリーンな方法が、2つの変数の形式で2019年に追加されました。lua-indent-これでほぼそこに到達しますが、それでも何らかの理由でネストされたブロックを二重インデントします。ちょっとしたアドバイスハックを追加すると、仕事は終わりです。

(setq lua-indent-nested-block-content-align nil)
(setq lua-indent-close-paren-align nil)

(defun lua-at-most-one-indent (old-function &rest arguments)
  (let ((old-res (apply old-function arguments)))
    (if (> old-res lua-indent-level) lua-indent-level old-res)))

(advice-add #'lua-calculate-indentation-block-modifier
            :around #'lua-at-most-one-indent)
于 2021-04-20T10:18:38.013 に答える
0

私は今、あまり助けられません-私は2日で締め切りがあります8-(-しかし、これが私の.emacsでlua-modeを使用できるようにするために使用するものです...

(setq lua-indent-level 2)
(setq lua-electric-flag nil)
(defun lua-abbrev-mode-off () (abbrev-mode 0))
(add-hook 'lua-mode-hook 'lua-abbrev-mode-off)
(setq save-abbrevs nil)   ;; is this still needed?

私は自分のコードを通常とは異なる方法でインデントします-以下の例を参照してください-したがって、lua-modeが上の行から正しいインデントを正しく推測できる場合にのみTabキーを押すように訓練しました...

map = function (f, A, n)
    local B = {}                 -- TAB here doesn't work
    for i=1,(n or #A) do         -- TAB here works
      table.insert(B, f(A[i]))   -- TAB here works
    end                          -- TAB here works
    return B                     -- TAB here works
  end                            -- TAB here works
于 2011-01-10T14:27:57.630 に答える
0

私はlua-mode.elのメンテナーです(著者ではありません)。私はこのスレッドの他の寄稿者よりもEmacsLispに精通していないので、パッチを歓迎します。デフォルトのルールについては、奇妙なことや間違っていることは何もないことを指摘したいと思います。私が見る限り、匿名関数を使用している場合、インデントはfunctionキーワードを左マージン。これは、関数パラメーターなど、他の場所で関数式を使用することを検討する場合に意味があります。

したがって、1つの簡単な回避策は書くことではありません

ローカルf=関数..。

しかし

ローカル関数f..。

「ローカル関数」構文よりも前のバージョンのLuaを使用している場合を除きます。

そうは言っても、インデントを変えたい理由がわかります。この場合、構成変数lua-indent-function-from-function-keyword(より良い名前、誰か?)を持つことは合理的であるように思われ、それを実装したパッチを喜んで受け入れます。

于 2011-01-11T15:08:48.797 に答える
-1

あなたが探しているものの多くは、一般的なインデントエンジンの説明に該当するカスタムCインデント定義に関するemacsマニュアルにあると思います。

あなたはそれをあなたが想像できることを何でもするようにすることができます、それはあなたが想像することをただするよりも強く好ましいでしょう。

于 2011-01-10T02:59:46.070 に答える