Disable pairing inside text #8

Open
hendrikweisser opened this Issue Aug 30, 2012 · 3 comments

3 participants

@hendrikweisser

See also http://code.google.com/p/autopair/issues/detail?id=45.

When I'm programming, I often find myself wrapping functions around functions - but starting with the inner parts. So whenever I add another function name and opening bracket in the beginning, autopair immediately puts in the closing bracket, which I have to delete (before adding one in the end).

In this context, skeleton-pair-like functionality would be great: Compare what's behind the cursor to a regular expression (user-adjustable), and suppress/allow pairing of brackets based on the result.

Example:

  1. type a function call:

    • what I type: unique(x
    • what appears on the screen: unique(x)

    -> autopair has added the closing bracket - good!

  2. wrap around another function:

    • what I type: [C-a]length(
    • what appears on the screen: length()unique(x)

    -> autopair has closed the bracket prematurely - bad!

  3. delete the bracket and add it at the end:

    • what I type: [C-d][C-e])
    • what appears on the screen: length(unique(x))

    -> this is the end result that I wanted to have

The difference, between when I want and don't want the closing bracket added, is the context of what's behind the cursor. I can't think of a situation where a closing bracket would be immediately followed by text/numbers. Thus, it would be preferable to not insert one in such cases.

@joaotavora
Owner

For what it's worth , this is what I do for 2.

[C-a] length C-M-SPC C-M-SPC (

or

[C-a] length C-M-SPC C-M-SPC )

depending where I want the cursor to end. In other words, it's more idiomatic in autopair to wrap the selected region. Still I will analyse this request, although it's a little against the grain of autopair to contribute to the unbalancing of the buffer.

@hendrikweisser

Thanks for the hint. I didn't know about [C-M-SPC] before.

@thorrr

Hacked up a bit of elisp that may help you out.

The following code detects whether the cursor is at whitespace or not. If it's on non-whitespace it runs the normal autopair-insert function but immediately deletes the second paired character.

(defun autopair-dont-if-point-non-whitespace (action pair pos-before)
  (if (or (eq 'opening action) (eq 'insert-quote action) (eq 'paired-delimiter action))
      (let ((delete? (save-excursion
         ;;move forward past the paired element
         (goto-char (+ (point) 1))
         (let* ((eol? (eq (point) (line-end-position)))
                (next-whitespace (save-excursion (search-forward " " (point-max) t) (point)))
                (next-char-is-whitespace? (eq next-whitespace (+ (point) 1)))
                (delete? (not (or eol? next-char-is-whitespace?))))
           delete?))))
        (if delete? (delete-char 1) 't))
    't))

Insert the hook with the usual mechanism. Here I'm putting it into python mode:

(add-hook 'python-mode-hook  ;;make python work with triple quotes
           #'(lambda () (setq autopair-handle-action-fns (list #'autopair-default-handle-action
                           #'autopair-dont-if-point-non-whitespace
                           #'autopair-python-triple-quote-action))))

I came up with this because I was constantly "Ctrl-d"-ing if my cursor was directly in front of a word. For example, in python, if I type

python_variable = 
                   ^----cursor here

And then a double quote, I usually want it paired:

python_variable = ""
                   ^----cursor here after typing "

But if I'm going back and editing something that exists I probably don't want the double quote paired:

string_to_split = This is a line of code I'm modifying"
                                    ^---------cursor here:  A new opening double quote

It would probably be good to enhance this snippet with regexp-driven matching logic so that it's smarter about when to delete the paired element but I haven't gotten around to it yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment