Pintasan keyboard mana yang digunakan untuk menavigasi keluar dari string

9

Ketika saya di tengah-tengah string looooong, seperti berikut ini

(setq Emacs-beta "Which keyboard shortcut to use for navigating out of a string")

Bisakah saya melewatkannya, tepat sebelum yang pertama "(setelah Emacs-beta) dengan pintasan?

Dieter.Wilhelm
sumber
Bukan jawaban C-r " C-b.
Nama

Jawaban:

12

Emacs 25 atau lebih baru

Anda ingin C-M-uyang menjalankan perintah backward-up-list.

Bergerak mundur dari satu tingkat tanda kurung. Perintah ini juga akan berfungsi pada ekspresi seperti tanda kurung lainnya yang ditentukan oleh mode bahasa saat ini.

Jika ESCAPE-STRING adalah non-nil (seperti itu secara interaktif), keluarlah dari ikatan juga.

pengasuh
sumber
Anda harus menyebutkan bahwa itu hanya 25.
abo-abo
@ abo-abo Ini bukan: Saya baru mengujinya di 24.5.1. Saya tidak yakin kapan itu ditambahkan, tetapi jika seseorang dapat mengetahuinya, saya akan mengeditnya.
pengasuh
@ abo-abo Ups, maaf, Anda benar.
pengasuh
Saya dengan Emacs-24.5 -Qdalam sebuah string, tapi aku mendapatkan dengan CMu: up-list: Scan error: "Unbalanced parentheses"?
Dieter.Wilhelm
1
@ Dieter.Wilhelm Kanan: seperti yang Anda lihat dari komentar dan edit saya, saya salah. Ini hanya akan bekerja di Emacs 25 atau lebih baru.
pengasuh
3

Ini bisa dilakukan seperti ini:

(defun exit-string-backwards ()
  (interactive)
  (goto-char (nth 8 (syntax-ppss))))

Dalam mode lispy , menekan [akan membawa Anda ke awal daftar yang berisi, keluar dari string apa pun. Setelah Anda berada di awal daftar, Anda dapat menjangkau bagian lain dengan mudah, misalnya, untuk sampai ke akhir Emacs-betapers 2m.

abo-abo
sumber
1

Ini sebenarnya pertanyaan pemrograman Emacs Lisp yang sangat menarik. Kita dapat tetap maju-char atau mundur-char sampai kita menemukan karakter di bawah kursor bukan bagian dari string.

Anda dapat menggunakan wajah font untuk memutuskan apakah karakter di dalam string. Ini adalah trik hebat yang saya pelajari dari flyspell. Secara teori itu tidak sempurna, tetapi di dunia nyata itu bekerja dengan hampir semua mode utama bahasa pemrograman pada Emacs23, Emacs24, Emacs25 .

Ini kode lengkapnya:

(defun font-face-is-similar (f1 f2)
  (let (rlt)
    ;; (message "f1=%s f2=%s" f1 f2)
    ;; in emacs-lisp-mode, the '^' from "^abde" has list of faces:
    ;;   (font-lock-negation-char-face font-lock-string-face)
    (if (listp f1) (setq f1 (nth 1 f1)))
    (if (listp f2) (setq f2 (nth 1 f2)))

    (if (eq f1 f2) (setq rlt t)
      ;; C++ comment has different font face for limit and content
      ;; f1 or f2 could be a function object because of rainbow mode
      (if (and (string-match "-comment-" (format "%s" f1)) (string-match "-comment-" (format "%s" f2)))
          (setq rlt t)))
    rlt))

(defun goto-edge-by-comparing-font-face (&optional step)
"Goto either the begin or end of string/comment/whatever.
If step is -1, go backward."
  (interactive "P")
  (let ((cf (get-text-property (point) 'face))
        (p (point))
        rlt
        found
        end)
    (unless step (setq step 1)) ;default value
    (setq end (if (> step 0) (point-max) (point-min)))
    (while (and (not found) (not (= end p)))
      (if (not (font-face-is-similar (get-text-property p 'face) cf))
          (setq found t)
        (setq p (+ p step))))
    (if found (setq rlt (- p step))
      (setq rlt p))
    ;; (message "rlt=%s found=%s" rlt found)
    (goto-char rlt)))

Pemakaian:

  • (goto-edge-by-comparing-font-face 1)pergi ke tepi kanan, (goto-edge-by-comparing-font-face -1)ke tepi kiri
  • itu tidak tergantung pada mode utama tertentu, Anda dapat menggunakannya di mana saja dalam bahasa apa pun

backward-up-listtidak terlalu dapat diandalkan dari sudut pandang pengguna karena dirancang sebagai perintah generik berdasarkan scan-sexps. Misalnya, untuk kode if (true) { return 'hello world'; }dalam mode js2, itu akan memindahkan fokus ke {karakter daripada karakter kutipan tunggal pertama. Untuk kode printf("hello world")dalam mode c ++ -, itu tidak akan berfungsi. Saya diuji dengan Emacs 24.5

chen bin
sumber
Ini pergi ke tepi kanan, OP telah meminta ke titik sebelum tepi kiri. Bagaimana jika mode-lisp tidak diaktifkan?
Nama
(goto-edge-by-compare-font-face -1) pergi ke tepi kiri, backward-charatau forward-charjika Anda memindahkan kursor keluar dari tepi.
chen bin
Ok, ide bagus, tetapi jika Anda menjalankannya ketika mode teks diaktifkan, poinnya akan menyusul ). Jadi tergantung pada mode, kode Anda memiliki perilaku yang berbeda.
Nama
Ini menggunakan algoritma yang sama dengan flyspell. Jadi ini mendukung semua mode utama dukungan flyspell
chen bin
0

Inilah satu lagi cara (yang cenderung saya gunakan lebih banyak) hanya untuk variasi. Solusinya tidak spesifik untuk string tetapi juga berfungsi untuk kasus penggunaan ini.

  • Instal iy-go-to-char(juga tersedia di Melpa).
  • Bind iy-go-to-char-backwarddan iy-go-to-charbindings pilihan Anda. Demi penjelasan ini, katakanlah Anda terikat iy-go-to-char-backwarduntuk C-c C-,dan iy-go-to-charuntuk C-c C-..
  • Sekarang jika Anda berada di dalam string, Anda akan memanggil iy-go-to-char-backwarddan mengetik ".

    Itu akan terlihat seperti C-c C-, ". Jika Anda telah iy-go-to-char-continue-when-repeatingmengatur ke t(default), menekan "sekali lagi akan membawa Anda ke "kejadian char sebelum itu, dan seterusnya.

  • Jika Anda berada di dalam string, dan jika sekarang Anda ingin pergi ke akhir string, Anda akan memanggil iy-go-to-chardan mengetik ".

    Itu akan terlihat seperti C-c C-. ". Jika Anda telah iy-go-to-char-continue-when-repeatingmenetapkan ke t(default), menekan "sekali lagi akan membawa Anda ke "karakter berikutnya .

Kaushal Modi
sumber