6

ポイントで検索タグが失敗した場合、通常の検索タグにフォールバックするように、etags-select 関数を拡張しようとしています。私が試したコードは次のとおりです。

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (unless (etags-select-find-tag-at-point)
    (etags-select-find-tag)))

(global-set-key (kbd "C-f") 'my-etags-find-tag)

ただし、ポイントが有効なタグにない場合、これは失敗します。代わりに、etags-select-find-tag-at-point によってエラーがスローされます。

etags-select-find-tag-at-point: Wrong type argument: char-or-string-p, nil

この場合、etags-select-find-tag-at-pointによって行われたテストを繰り返すだけです:

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (if (find-tag-default)
      (etags-select-find-tag-at-point)
    (etags-select-find-tag)))

しかし、それは少し冗長に思えます。例外をトラップして、elisp で代替処理を行うことは可能ですか?

4

2 に答える 2

12

試してみてくださいignore-errors。例えば、

(unless (ignore-errors (etags-select-find-tag-at-point))
  (etags-select-find-tag))

通常、(ignore-errors body)返されるものは何でもbody返します。エラーの場合は を返しますnil

condition-caseより一般的な条件処理についても参照してください。

Elisp info manual がインストールされている場合は、 から詳細を取得できます C-hSignore-errors

編集:

関数が成功時に nil を返す可能性を考慮していませんでした。だから私たちはおそらく必要です

(unless (ignore-errors (or (etags-select-find-tag-at-point) t))
  (etags-select-find-tag))
于 2012-07-20T13:49:01.760 に答える
4

の元のソース コードを変更せずにetags-select.el、 を 2 回呼び出す場合でも、より合理的なオプションだと思いますfind-tag-default。次のような方法でメモ化することにより、呼び出しの繰り返しを避けるために、呼び出し内の動的環境をごまかすことができます。

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (let ((ftd (find-tag-default)))
    (flet ((find-tag-default () ftd))
      (if (find-tag-default)
          (etags-select-find-tag-at-point)
        (etags-select-find-tag)))))

編集:OK、あなたの要求に従って、コードの説明。まず、このコードが両方の質問を達成することに注意してください。

  1. 失敗しない
  2. あなたが示すコードよりも効率的です(冗長であるとあなたが言うもの)。

なぜより効率的なのですか?冗長コードの問題は、find-tag-defaultそれが であるかどうかを確認するためにを呼び出しnil、そうである場合は を呼び出すことですetags-select-find-tag-at-point。この関数はfind-tag-default、デフォルト値を取得するために を再度呼び出します。私のコードは、find-tag-default計算した値だけで関数を再定義して値をキャッシュすることです。はfletそれを行うので、 をetags-select-find-tag-at-point呼び出すfind-tag-defaultと、計算された値がそれ以上処理されずに返されます。

于 2012-07-20T12:12:03.160 に答える