2

I have this Vim command to jump outside any parentheses or quotes or double quotes or bracked, when you're inside a closed region. When I press jj fast, it allows me to jump outside the closed region:

inoremap jj <Esc>/[)}"'\]>]<CR>:nohl<CR>a

Note that the regular expression begins after <Esc>. I was missing this in Emacs.

I decided to give a try with the following:

(key-chord-define evil-insert-state-map "jj" 
  ;; Escape from capsuled string
  '(lambda () 
     (interactive) 
     (forward-char 1)
     (insert " ")))

For example, * is the place of the cursor.

This is an another "example of a string *" within this sentence

Pressing the jj fast allows me to jump outside the string inside the sentence.

2 questions:

1. It's only working if the cursor is on the last character before the quote. And not in middle for example. How to solve it?

2. How get it working for single quotes ('), brackets '}', or parentheses ())?.

Any suggestion would be really appreciated.

  • 1
    You probably want to mention the mode of the buffer, e.g., what kind of text or programming language this is for. Each mode defines what constitute paired delimiters, for example. – Drew May 10 '15 at 22:24
  • if you use smartparens or paredit you can use the commands sp-up-sexp/paredit-forward-up (bound to C-M-n) to do this. It should work in any major mode as long as sp/paredit is active. – nanny May 11 '15 at 13:33
4

Here is a function I use:

(defun my-step-out-forward ()
  "Step forward out of current list or string."
  (interactive)
  (if (nth 3 (syntax-ppss (point)))
      (progn
        (forward-char)
        (while (and (not (eobp)) (nth 3 (syntax-ppss (point))))
          (forward-char)))
    (up-list)))

The syntax-ppss stuff is a bit obtuse, but what it does is get a set of info about your current position in the buffer, the 3rd piece being if you are inside a string. So if you are, it walks forward until it's out of the string. There may be a better way to do this, but for an interactive function I find it's good enough. The up-list is the easier part, it simply jumps outside the nearest enclosing paren, for whatever is defined to be a paren in the current mode.

  • Thanks for your answer! It was the right one, it works fine with quotes, single quotes and brackets/parentheses. Thanks for that, I appreciate it! – – ReneFroger May 11 '15 at 8:18
3
(defun ar-leave-delimited-forward ()
  "Go one char beyond string, paren, bracket etc. "
  (interactive)
  (ar-beginn-of-delimited)
  (forward-sexp))

(defun ar-beginn-of-delimited ()
  "Go to beginn of a string or parentized/braced/bracketed. "
  (let ((pps (parse-partial-sexp (point-min) (point))))
    (cond
     ((nth 3 pps)
      (goto-char (nth 8 pps)))
     ((nth 1 pps)
      (goto-char (nth 1 pps))))))    

Code is developed here:

https://github.com/emacs-berlin/leave-delimited/blob/master/leave-delimited.el

which provides also an ar-leave-delimited-backward

  • Thanks for your answer! I wish I could validate it as the right one but scottfrazer above was earlier with it and his function is also shorter. I upvoted it anyway, it works fine with quotes, single quotes and brackets/parentheses. Thanks for that, I appreciate it! – ReneFroger May 11 '15 at 8:16
  • Neat, I hadn't thought about going to the beginning then jumping of the sexp. – scottfrazer May 11 '15 at 13:56
0

I previously posted this as a comment, but I think this tip is useful enough to warrant an answer.

As we know, in Lisp, code is organized into nested lists, or trees, of s-expressions. To jump "outside a delimiter" is then analogous to moving "up" the list/tree.

If you use smartparens or paredit you can use the commands sp-up-sexp/paredit-forward-up (bound to C-M-n) to move up the tree. It should work in any major mode as long as smartparens or paredit is active.

Consider the following tree of sexps, where the cursor is a pipe:

(define (greet-someone name) 
  (apply string-append `("Hello, |" ,name "!\n")))

Repeatedly pressing C-M-n take you outside the quotes, then outside the quasiquote, then outside the (apply ...) expression, then outside the entire define. Pressing C-M-p (sp/paredit-backward-down) will do the same thing in reverse.

Along with these "up" commands, there are also commands to go in the opposite directions:

C-M-d: down-list/sp-down-sexp/paredit-forward-down C-M-u: up-list/sp-backward-up-sexp/paredit-backward-up

These commands are extremely useful for navigating (especially in Lisp), but I don't see them mentioned a lot, at least relative to their value.

(There are also built-in commands forward-list and backward-list but they don't work in as many cases and the smartparens/paredit ones do.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.