編 集

Last modified: "2019/01/04 21:13:32"

Table of contents


知っていると便利な辺り

テキスト折り返し(詰め込み)桁数の指定

テキストを指定した桁数で折り返す(指定した桁数あたりに改行を挿入する:詰め込み)は、 M-q (fill-paragraph) で実行されるが、折り返す桁数を指定するには、 折り返したいカラムまでカーソルを移動して C-x f (set-fill-column) する。 もしくは、ESC 桁数 C-x f する。 C-x f は、実行したバッファのみで有効になる。 [xyzzy:00698](亀井さん)より。

折り返し桁数の既定値は、72 。これを変更したい場合は、.xyzzy とかに、

(setq-default fill-column 62)

とかしておく。

喜多さんの flex-fill.l を使うと、とっても便利。


ソート(並べ替え)する。

filter-region, filter-buffer で外部コマンド sort を実行している。

リージョンをソート --- C-x | sort

バッファ全体をソート --- C-x # sort


カーソル周辺のスペースを削除

M-\ (delete-horizontal-spaces) で、カーソルの前後にある連続したスペースを削除する。 [xyzzy:08467]より。


よく使う辺り

カーソルが行頭にある場合は、いっきに行削除

どこからかいただいたもの。

(defun my-kill-line (&optional arg)
  (interactive "*p")
  (cond ((bolp)
         (let ((point (point))
               (lines (cond ((or (null arg)
                                 (<= arg 1))
                             0)
                            (t
                             (- arg 1)))))
           (kill-region point
                        (progn
                          (forward-line lines)
                          (goto-eol)
                          (forward-char)
                          (point)))))
        (t
         (kill-line arg))))
(define-key *global-keymap* #\C-k 'my-kill-line)

後ろ向きに行を削除

カーソルの前の文字から、行頭までを削除する。私がもっとも便利に思っているコマンドのひとつ。 C-BackSpace に割り当てている。
須田さんのぺーじより。

キーバインドを C-BackSpace に割り当てると、IME の「確定取消し」と衝突するので、 私の場合、使用する頻度のずっと低いIME の「確定取消し」を C-S-BackSpace に変更している。

(defun backward-kill-line ()
  (interactive)
  (kill-region (point) (progn (goto-bol) (point))))
(set-extended-key-translate-table exkey-C-backspace #\F13)
(global-set-key #\F13 'backward-kill-line)

カーソル行を上下に移動

Toy さんのぺーじより。これもとっても便利。(x680x0 ???)

カーソル行を下に移動する。S-M-Down にしてみた。

(defun transpose-lines-down (&optional (n 1))
  (interactive "*p")
  (when (save-excursion (forward-line n))
    (let ((column (current-column))
          (beg (progn (goto-bol) (point)))
          (end (progn
                 (or (forward-line 1)
                     (progn (goto-eol) (insert #\LFD)))
                 (point))))
      (insert (prog1
                  (buffer-substring beg end)
                (delete-region beg end)
                (forward-line n)))
      (forward-line -1)
      (goto-column column))))
(global-set-key #\S-M-Down 'transpose-lines-down)

カーソル行を上に移動する。S-M-Up にしてみた。

(defun transpose-lines-up (&optional (n 1))
  (interactive "*p")
  (transpose-lines-down (- n)))
(global-set-key #\S-M-Up 'transpose-lines-up)

セレクションを上書きして貼り付け

通常の C-y (yank) では、セレクションがあっても無視され、 カーソル位置に貼り付けられるが、この関数を使うとセレクションを上書きしてくれる。 セレクションを多用する人にはうれしい機能。

Toy さんのぺーじより。

(defun yank-overwrite (prefix &optional (arg 0))
  (interactive "*P\np")
  (when (pre-selection-p)
    (delete-region (selection-mark) (selection-point))
    (stop-selection))
  (setq *this-command* 'yank)
  (yank prefix arg))
(global-set-key #\C-y 'yank-overwrite)

yank-select メニュウ

キルリングの履歴を一覧から選択して貼り付けることができる。

須田さんのぺーじを参考につくったものを clipselect.l につけてみた。


コピー&ペースト

カーソル位置の単語をクリップボードへコピー

[xyzzy:06776](松田 里都さん)を参考に。

(defun copy-current-word ()
  (interactive)
  (save-excursion
    (copy-to-clipboard
     (buffer-substring (progn
                         (or (looking-at "\\<")
                             (backward-word 1))
                         (point))
                       (progn
                         (forward-word)
                         (point))))))

クリップボードから引用符付貼付け

(defun my-paste-with-quote ()
  (interactive "*")
  (unless (clipboard-empty-p)
    (let ((lines (split-string (get-clipboard-data)
                               #\LFD)))
      (dolist (l lines)
        (insert (format nil "~A~A~%" *quotation-prefix* l))))))

挿入&削除

行頭行末のホワイトスペースとか空行とかを削除

バッファ全体の行頭行末のホワイトスペースとか空行とかを削除する場合は、こんな感じ。

(defun delete-foo ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (削除処理)
    ))

(削除処理)の部分は、こんな感じ。replace-regexp 関数で置換えを行なう。

行末ホワイトスペースを削除する場合。

(replace-regexp "[ \t]*$" "" t)

行頭ホワイトスペースを削除する場合。

(replace-regexp "^[ \t]*" "" t)

行頭行末ホワイトスペースを削除する場合。

(replace-regexp "^[ \t]*\\(.*?\\)[ \t]*$" "\\1" t)

空行を削除する場合。

(replace-regexp "^\n" "" t)

空行を削除(スペースやタブだけの行も含む)する場合。

(replace-regexp "^[ \t]*\n" "" t)

置換は、replace-buffer 関数でもできるみたい。「空行を削除」の場合だとこんな感じ。

(replace-buffer "^\n"  "" :regexp  t)

私は、セレクションに対して処理をすることが多いので、 こんな風にしてみた。


セレクション各行の先頭に指定した文字を挿入

結構お気に入りなもの。

(defun insert-str-bol-selection ()
  (interactive "*")
  (ed::map-selection #'(lambda (start end)
                         (let ((*quotation-prefix*
                                (read-string "挿入文字: ")))
                           (quote-region start end)))))

日付や時刻を挿入

日付を挿入を挿入する。

(defun insert-date()
  (interactive)
  (insert (format-date-string "%Y/%m/%d")))
(global-set-key '(#\C-x #\t #\d) 'insert-my-date-string)

フォーマットを変更すると、いろいろできる。

日付と時刻を挿入する場合。

"%Y/%m/%d %H:%M:%S %Z"

日付と曜日を挿入する場合。

"%Y/%m/%d(%v)"

詳しくは、lisp/timestmp.l 参照。


セレクションの各行頭に指定文字を挿入またはトグル

セレクションがあれば、選択範囲の行頭に文字列を挿入、なければ、文字列をトグルする。

コメント文字列挿入またはトグル用に、あっちのモードやこっちのモードで使っている。 [xyzzy:06776](松田 里都さん)と、 bat-mode.l(OHKUBO Hiroshi さん)を参考に。

key --- コメント指定文字
key-regexp --- 行頭のコメント指定文字を表す正規表現(トグル時の削除用)

(encomment-selection-or-comment-toggle-line ";") とかしてつかっている。

(defun encomment-selection-or-comment-toggle-line (key &optional key-regexp)
  (if (pre-selection-p)
      (let ((from (selection-mark))
            (to (selection-point)))
        (if (> from to)
            (rotatef from to))
        (save-excursion
          (save-restriction
            (narrow-to-region from to)
            (goto-char from)
            (insert key)
            (while (forward-line 1)
              (insert key)))))
    (save-excursion
      (let (bol eol keyreg)
        (goto-eol)
        (setq eol (point))
        (goto-bol)
        (setq bol (point))
        (if key-regexp
            (setq keyreg key-regexp)
          (setq keyreg (format nil "^[ \t]*\\~A+" key)))
        (if (string-match keyreg
                          (buffer-substring bol eol))
            (delete-region (+ bol (match-beginning 0)) (+ bol (match-end 0)))
          (insert key))))))

セレクションの指定行頭文字を削除

コメント文字列削除用に、あっちのモードやこっちのモードで使っている。 [xyzzy:06789](松田 里都さん)を参考に。

key --- コメント指定文字

(defun outcomment-selection (key)
  (or (pre-selection-p)
      (error "selectionがない。"))
  (let ((from (selection-mark))
        (to (selection-point)))
    (if (> from to)
        (rotatef from to))
    (save-excursion
      (save-restriction
        (narrow-to-region from to)
        (goto-char from)
        (replace-buffer (concat "^" key) "" :regexp t)))))

セレクションまたはリージョンをコメントアウト

kia さんcomment.l を使って,セレクションをコメントアウトする。 C-x ; に割り当てている。コメントを外す場合は,C-u C-x ; 。 xyzzy Part8 987 より。autoload 前だとエラーになってしまうので,require を追加したのだけれども, もっと良い方法があるかも。

(defun comment-out-selection-or-region (&optional count)
  (interactive "p")
  (require "comment")
  (let (beg end)
    (if (pre-selection-p)
        (setq beg (selection-point) end (selection-mark))
      (setq beg (point) end (mark)))
    (let ((fn (cond ((eq *prefix-args* 'universal-argument)
                     (setq count (list count))
                     'comment-do-uncomment)
                    ((and (numberp count)
                          (> 0 count))
                     'comment-do-uncomment)
                    (t
                     'comment-do-comment))))
      (funcall fn beg end count))))
(define-key ctl-x-map #\; 'comment-out-selection-or-region)

1 行コメントをトグル

ブロック単位のコメントアウト&アンコメントは, kia さんcomment.l を使うようになったのだけれども, モード毎に壱行単位のコメントアウト&アンコメントも手軽にしたかったのでつくってみた。 インデントは,そのまま残しているつもり。 OHKUBO さんbat-mode の,bat-comment-toggle-line を参考にさせていただきました。

*one-line-comment-alist* の設定は,各モードの設定より後に記述する必要があるのだと思います。

(defvar *one-line-comment-alist*
  '(
    (awk-mode   . ("#"))
    (css-mode   . ("/* " " */"))
    (html+-mode . ("<!-- " " -->"))
    (lisp-mode  . (";"))
    (lisp-interaction-mode . (";"))
    (perl-mode  . ("#"))
    (php-mode   . ("//"))
    (sql-mode   . ("--"))
    ))

(defun toggle-one-line-comment ()
  (interactive)
  (let ((li (cdr (assoc buffer-mode *one-line-comment-alist*)))
        bol eol str keyreg)
    (when li
      (save-excursion
        (goto-eol)
        (setq eol (point))
        (back-to-indentation)
        (setq bol (point))
        (setq str (buffer-substring bol eol))
        (if (= (length li) 1)
            (let ((key (car li)))
              (setq keyreg (format nil "^~A+[ \t]*" (regexp-quote key)))
              (if (string-match keyreg str)
                  (delete-region (+ bol (match-beginning 0))
                                 (+ bol (match-end 0)))
                (progn
                  (back-to-indentation) (insert key))))
          (let ((key1 (car li))
                (key2 (cadr li)))
            (setq keyreg (format nil
                                 "^\\(~A\\)+[ \t]*\\(.*\\)[ \t]*\\(~A\\)+$"
                                 (regexp-quote key1)
                                 (regexp-quote key2)))
            (if (string-match keyreg str)
                (progn
                  (setq str (string-replace-match str "\\2"))
                  (delete-region (+ bol (match-beginning 0))
                                 (+ bol (match-end 0)))
                  (insert str))
              (progn
                (back-to-indentation) (insert key1)
                (goto-eol) (insert key2)))))))))

comment.l と 1 行コメントトグルを合わせて使う

結局これに落ち着きそう。 kia さんcomment.l と,toggle-one-line-comment を使って。

(defun comment-out-selection-or-one-line (&optional count)
  (interactive "p")
  (if (pre-selection-p)
      (progn
        (require "comment")
        (let ((fn (cond ((eq *prefix-args* 'universal-argument)
                         (setq count (list count))
                         'comment-do-uncomment)
                        ((and (numberp count)
                              (> 0 count))
                         'comment-do-uncomment)
                        (t
                         'comment-do-comment)))
              beg end)
          (setq beg (selection-point) end (selection-mark))
          (funcall fn beg end count)))
    (toggle-one-line-comment)))
(global-set-key #\C-\; 'comment-out-selection-or-one-line)

いろいろ

一発でインデント

バッファ全体をインデントする場合。

(defun indent-whole-buffer ()
  (interactive)
  (save-excursion
    (indent-region (point-min) (point-max))))

セレクションをインデントする場合。セレクションがなければ、バッファ全体をインデントする。

(defun indent-selection ()
  (interactive)
  (if (get-selection-type)
      (indent-region (selection-mark) (selection-point))
    (save-excursion
      (and (yes-or-no-p "バッファ全体を一発インデントしますよ。")
           (indent-region (point-min) (point-max))))))

リージョンをインデントする場合は、M-x indent-region でおけ。


セレクションを行結合

セレクションの行頭行末のホワイトスペースを削除して、改行を除く。 置換えは一回の処理でできるのかもしれないが、私にはできなかった。

(defun join-line ()
  (interactive)
  (when (get-selection-type)
    (selection-start-end (start end)
      (narrow-to-region start end)
      (goto-char (point-min))
      (replace-buffer "^[ \t]*\\(.*?\\)[ \t]*" "\\1" :regexp  t)
      (goto-char (point-min))
      (replace-buffer "^\\(.*?\\)\n" "\\1" :regexp  t)
      (widen))))

セレクション対応の fill-paragraph

セレクションがあればセレクション内を、なければ普通に fill-paragraph 。

(defun fill-selection ()
  (interactive)
  (if (get-selection-type)
      (selection-start-end (start end)
        (fill-region start end))
    (fill-paragraph)))
(global-set-key #\M-q 'fill-selection)

TAB で indent と同時に補完

モノグサなひとが TAB キーだけでできるそうです。 OHKUBO Hiroshi さんのぺーじより。(ごちそうさまです。)

(defun lisp-indent-line-and-complete-symbol ()
  (interactive)
  (lisp-indent-line)
  (if (looking-at "\\_>")
      (lisp-complete-symbol)))
(define-key ed::*lisp-mode-map*
            #\TAB  'lisp-indent-line-and-complete-symbol)
(define-key ed::*lisp-interaction-mode-map*
            #\TAB  'lisp-indent-line-and-complete-symbol)

リージョンの文字列を逆順に並べ替え

xyzzy Part8 368 より。

(defun revseq-region (from to)
  (interactive "*r")
  (let (insseq)
    (save-excursion
      (setq insseq (reverse (buffer-substring from to)))
      (delete-region from to)
      (goto-char from)
      (insert insseq)
      )))

セレクションの文字列を逆順に並べ替え

大久保さんちの *scratch* より。

(defun reverse-selection ()
  (interactive "*")
  (when (member (get-selection-type) '(1 2))
    (selection-start-end (from to)
      (insert (prog1
                  (reverse (buffer-substring from to))
                (delete-region from to))))))

HTML 関連

HTML 文字参照挿入

メニューの作成方法は、たわしとさんの siteinit.l を参考にさせて頂きました。

(defun insert-character-references ()
  (interactive)
  (message " 1:<  2:>  3:&  4:\"")
  (let ((b_ime (get-ime-mode)))
    (toggle-ime nil)
    (case (read-char)
      ((#\1 #\<) (insert "&lt;"))
      ((#\2 #\>) (insert "&gt;"))
      ((#\3 #\&) (insert "&amp;"))
      ((#\4 #\") (insert "&quot;"))
      )
    (toggle-ime b_ime))
  (clear-message)(stop-selection))

html+-mode で一発インデント

html+-mode で indent-region すると、データのない行はインデントされない。 ので、html+-indent-line を1行ずつ実行するようにした。 M-i に割り当てている。

(in-package "editor")

(defun html+-indent-region (from to)
  (interactive "*r")
  (narrow-to-region from to)
  (goto-char (point-min))
  (html+-indent-line)
  (while (forward-line 1)
    (html+-indent-line))
  (widen))

(add-hook '*html+-mode-hook*
          #'(lambda ()(interactive)
              (define-key *html+-mode-map* #\M-i 'html+-indent-region)))

(in-package "user")

セレクションに対しては、こんな感じでしている。 (html+-mode では、M-h M-i とかしないので、私はこちらだけでいいのかも。)

(defun html+-indent-selection ()
  (interactive)
  (if (get-selection-type)
      (selection-start-end (start end)
        (narrow-to-region start end)
        (my-html+-indent)
        (widen))
    (save-excursion
      (and (yes-or-no-p "バッファ全体を一発インデントしますよ。")
           (my-html+-indent)))))

改行を<BR>にして貼り付け

xyzzyでタグ打ってる人の数 → 347 より。キーバインドは一応 C-S-Insert (お好みで)。

(defun paste-clipboard-with-br ()
  (interactive)
  (when (get-clipboard-data)
    (insert (substitute-string (get-clipboard-data) "\n" "<br>\n"))))
(global-set-key #\C-\S-\Insert 'paste-clipboard-with-br)

タブ区切りデータをテーブルに変換

テーブルをつくるのが面倒なときに使っている。セレクションのタブ区切りデータを変換する。 各行の列数とかはチェックしてないので、毎行タブ数 + 1 の列ができる。

ちゃんとした csv (or tsv) ファイルの変換とか、正しい人とかは、 csv-mode を使いましょう。

(defun tab2table-selection ()
  (interactive "*")
  (when (get-selection-type)
    (selection-start-end (start end)
      (narrow-to-region start end)
      (goto-char (point-min))
      (while (not (eobp))
        (insert "<tr><td>")
        (goto-eol)(insert "</td></tr>")
        (unless (forward-line 1)
          (return)))
      (goto-char (point-min))
      (replace-regexp "\t" "</td><td>" t)
      (widen))))

クリップボードの中身が http:// で始まっていたら、リンクをつけてペースト

xyzzyでタグ打ってる人の数 → 366, 367, 369 より。

(defun insert-url-with-link ()
  (interactive "*")
  (let ((cb (get-clipboard-data)))
    (cond
     ((and (stringp cb)
           (string-match "^\\(ht\\|f\\)tp://.+" cb))
      (insert (format nil "<a href=\"~A\">~A</a>" cb cb)))
     (t (message "URLではないようです")))))

ミニバッファからコメントを挿入

ミニバッファから入力した文字列を、 <!-- --> で囲んで挿入する。 xyzzyでタグ打ってる人の数 → 371 より。

(defun html-insert-comment (&optional (comment ""))
  (interactive "*sComment: ")
  (insert "<!-- " comment " -->"))

リージョンをコメントアウト

リージョンの文字列を <!-- --> で囲む。 xyzzyでタグ打ってる人の数 → 371 より。

(defun html-region-to-comment ()
  (interactive "*")
  (let ((begin (mark))
        (end (point)))
    (unless (eq end (max begin end))
      (let ((tmp begin))
        (setq begin end
              end tmp)))
    (save-excursion
      (goto-char end)
      (insert " -->")
      (goto-char begin)
      (insert "<!-- "))))

リージョンを指定したタグで囲む

xyzzyでタグ打ってる人の数 → 374, 375 より。

(defun html-quote-region-by-tag (&optional (quotetag ""))
  (interactive "*sTag: ")
  (let ((begin (mark))
        (end (point)))
    (when (> begin end)
      (let ((tmp begin))
        (setq begin end
              end tmp)))
    (save-excursion
      (goto-char end)
      (insert "</" quotetag ">")
      (goto-char begin)
      (insert "<" quotetag ">"))))

buf2html-region で作成したソースをクリップボードへコピー

この機能は、本体で実装していただけました。

リージョンのデータを buf2html に渡して、結果をクリップボードにコピーする。 私は、どうしてもこうして使いたい。(-_-)

※ 純正オプションを頂きましたが、一応恥ずかしいコードの一例として残しときます。 (^_^)

(defun my-buf2html-region (from to)
  (interactive "*r")
  (buf2html-region from to)
  (selection-whole-buffer)
  (copy-selection-to-clipboard)
  (close-selected-buffer))

純正オプション をつくっていただけたので、追加。 こちらの方が lisp らしい(?)感じがする。 確かに "*" は、いらないよなあ。
最後の改行はいつも手動で消してたので、1- させていただきました。

■ buf2html-region で作成したソースをキルリングへコピー

(defun buf2html-copy-region-as-kill (from to)
  (interactive "r")
  (save-window-excursion
    (buf2html-region from to)
    (copy-region-as-kill (point-min) (1- (point-max)))
    (close-selected-buffer)))

■ buf2html-region で作成したソースをクリップボードへコピー

(defun buf2html-copy-region-to-clipboard (from to)
  (interactive "r")
  (save-window-excursion
    (buf2html-region from to)
    (copy-region-to-clipboard (point-min) (1- (point-max)))
    (close-selected-buffer)))