2012-06-21 27 views

答えて

23

あなたはCUA選択モード有効にする場合:あなたの初期化ファイル内

M-Xcua-selection-modeRET

または恒久的に:

(cua-selection-mode 1) 

をあなたは、その先進的な長方形の編集機能を使用することができます。

(またはあなたがcua-modeユーザーなら、あなたはそれを行う必要はありません。)

  • C-RETコーナーをマークする
  • 反対側の角に移動します。
  • M-r to do a regexpは、マークされた矩形内に置き換えます。
  • C-RETとマークを外す/終了する矩形編集。ドキュメントについて

、のMxに解説して見出し "CUA矩形のサポート" を探しfind-libraryRETcua-baseRET

あなたはのためのCUA矩形施設を使用しない場合何らかの理由で(おそらく実際にreplace-stringが必要な場合)、apply-on-rectangleを使用しているカスタム関数はかなり簡単にまとめられます。

編集:実際には、もう少し私が予想していたよりも複雑であるが、コードのほとんどはインタラクティブ仕様と「区切り」プレフィックス引数の動作のサポート(両方replace-stringに基づく)です。

編集2:私は、これはより完全な機能を備えた方法でやって価値があったことを決めた:

以下はCxのRM-%CxのRCMを提供 - %、期待通りに行動します。

(require 'rect) 

(defun my-search-replace-in-rectangle 
    (start end search-pattern replacement search-function literal) 
    "Replace all instances of SEARCH-PATTERN (as found by SEARCH-FUNCTION) 
with REPLACEMENT, in each line of the rectangle established by the START 
and END buffer positions. 

SEARCH-FUNCTION should take the same BOUND and NOERROR arguments as 
`search-forward' and `re-search-forward'. 

The LITERAL argument is passed to `replace-match' during replacement. 

If `case-replace' is nil, do not alter case of replacement text." 
    (apply-on-rectangle 
    (lambda (start-col end-col search-function search-pattern replacement) 
    (move-to-column start-col) 
    (let ((bound (min (+ (point) (- end-col start-col)) 
         (line-end-position))) 
      (fixedcase (not case-replace))) 
     (while (funcall search-function search-pattern bound t) 
     (replace-match replacement fixedcase literal)))) 
    start end search-function search-pattern replacement)) 

(defun my-replace-regexp-rectangle-read-args (regexp-flag) 
    "Interactively read arguments for `my-replace-regexp-rectangle' 
or `my-replace-string-rectangle' (depending upon REGEXP-FLAG)." 
    (let ((args (query-replace-read-args 
       (concat "Replace" 
         (if current-prefix-arg " word" "") 
         (if regexp-flag " regexp" " string")) 
       regexp-flag))) 
    (list (region-beginning) (region-end) 
      (nth 0 args) (nth 1 args) (nth 2 args)))) 

(defun my-replace-regexp-rectangle 
    (start end regexp to-string &optional delimited) 
    "Perform a regexp search and replace on each line of a rectangle 
established by START and END (interactively, the marked region), 
similar to `replace-regexp'. 

Optional arg DELIMITED (prefix arg if interactive), if non-nil, means 
replace only matches surrounded by word boundaries. 

If `case-replace' is nil, do not alter case of replacement text." 
    (interactive (my-replace-regexp-rectangle-read-args t)) 
    (when delimited 
    (setq regexp (concat "\\b" regexp "\\b"))) 
    (my-search-replace-in-rectangle 
    start end regexp to-string 're-search-forward nil)) 

(defun my-replace-string-rectangle 
    (start end from-string to-string &optional delimited) 
    "Perform a string search and replace on each line of a rectangle 
established by START and END (interactively, the marked region), 
similar to `replace-string'. 

Optional arg DELIMITED (prefix arg if interactive), if non-nil, means 
replace only matches surrounded by word boundaries. 

If `case-replace' is nil, do not alter case of replacement text." 
    (interactive (my-replace-regexp-rectangle-read-args nil)) 
    (let ((search-function 'search-forward)) 
    (when delimited 
     (setq search-function 're-search-forward 
      from-string (concat "\\b" (regexp-quote from-string) "\\b"))) 
    (my-search-replace-in-rectangle 
    start end from-string to-string search-function t))) 

(global-set-key (kbd "C-x r M-%") 'my-replace-string-rectangle) 
(global-set-key (kbd "C-x r C-M-%") 'my-replace-regexp-rectangle) 
+0

ありがとうございます!残念ながら、emacsのGUIでは 'C-RET'という角をマークするだけで、端末モードではマークできません。 – user545424

+0

端末がそのシーケンスを送信していないことが原因です。 xtermが成功しているかもしれません(http://stackoverflow.com/questions/4337837/send-c-to-emacs-in-vt100-xterm-terminal-mac-os-xs-terminalも参照してください)。また、非CUAのアプローチのために、より完全な機能を備えたコードで私の答えを更新しました。 – phils

+0

機能要求:長方形を検索します。私は巨大なコラムを持っています。それに他のものがあるのか​​どうかを確認する必要があります。私はいくつかの複雑な正規表現を使用しています - もし列が本当に大きければ、正規表現のスタックオーバーフローが発生します。 – Adobe

0

CUAモードでは、 'M-r'にバインドされたcua-replace-in-rectangleを使用できます。

+0

しかし、これは最初のものだけを置き換えます(デフォルトのvim replace-regexpの動作)。 – Adobe

0

私のパッケージevil-visual-replaceを使用すると、邪悪なビジュアルブロック内にquery-replacereplace-regexpが得られます。最近のEmacsで

3

(例えばEmacsの25)あなたはM-%query-replace)またはC-M-%query-replace-regexp)を使用して、箱から出して、これを行うことができます。

M-x rectangle-mark-modeを使用して矩形領域を作成します。必要に応じてC-x C-xを使用して、マークの前にポイントを挿入します。次に、単にクエリを置き換えます。

しかし、彼らはreplace-stringのEmacs 25で同じ変更をしませんでした。もしあなたが好きなのであれば、と同じ方法で、引数region-noncontiguous-pを追加するだけで、これを行うことができます。コードは単純です:

(defun replace-string (from-string to-string &optional delimited start end backward 
         region-noncontiguous-p) 
    "..." 
    (declare (interactive-only 
      "use `search-forward' and `replace-match' instead.")) 
    (interactive 
    (let ((common 
      (query-replace-read-args 
      (concat "Replace" 
        (if current-prefix-arg 
         (if (eq current-prefix-arg '-) " backward" " word") 
        "") 
        " string" 
        (if (use-region-p) " in region" "")) 
      nil))) 
    (list (nth 0 common) (nth 1 common) (nth 2 common) 
      (if (use-region-p) (region-beginning)) 
      (if (use-region-p) (region-end)) 
      (nth 3 common) 
      (if (use-region-p) (region-noncontiguous-p))))) 
    (perform-replace 
    from-string to-string nil nil delimited nil nil start end backward region-noncontiguous-p)) 

また、あなただけのライブラリreplace+.elをダウンロードして、そこからreplace-stringのバージョンを使用することができます。それはあなたが望むことをします。

FWIW、私はこの機能をreplace-stringに追加するためにEmacs bug#27897と同じライブラリのいくつかの他のコマンドreplace.elを提出しました。

+0

これに関連するanzuバグ(あなたの 'query-replace'のバージョンを置き換えるかもしれません)もあります:https://github.com/syohex/emacs-anzu/issues/69 –

関連する問題