smartparens icon indicating copy to clipboard operation
smartparens copied to clipboard

Smart parens behavior inside word

Open walmes opened this issue 10 years ago • 1 comments

Hi @Fuco1,

I'm using smartparens and I would like to set a even more smart behavior. I've tried to set a behavior that is put enclosing pair in a word when the point is inside it. I read the smartparens wiki and searches in the internet and I almost got it. Below is the code (that I spent hours modifying and reevaluating).

When hit the quote mark, for example, o would like this Do What I Mean:

  • If point is before or inside a word, surround the word with the pair.
  • If point is after, close the pair (or complete if the opening is missing, why not?).
  • If the point is surround by white space (newlines, spaces, line beginning, don't touching a word), insert the pair (as usual);
  • If region is active, surround the region with the pair (as usual);

In my tries, I got something partial. I got put pair when before a word, but I lost insert pair when region is active. I also got put pair when inside a word, but the opening stayed at the point, not at word beginning.

Below is the code I'm using. In the comments, the pipe (|) indicates the point when I hit double quotes. The greater/less signs indicates direction of region mark.

This settings, if possible, could be part of the tips and thicks section. Thanks in advance for any help.

;;-------------------------------------------
;; Smart Parenthesis
;; https://github.com/Fuco1/smartparens.

(require 'smartparens)
(smartparens-global-mode 1)

;; To mark the current word.
(defun mark-whole-word (id action context)
  (interactive)
  (when (eq action 'insert)
    (skip-chars-backward "[[:alnum:]]._")
    (set-mark (point))
    (skip-chars-forward "[[:alnum:]]._")
  ))

;; Return t if the point is inside or touching a word.
(defun string-at-point-p (id action context)
  "Test if the point is in a word."
  (if (stringp (thing-at-point 'word)) t nil))

;;-------------------------------------------
;; Do Waht I Mean, example with quotes.
;; this is a |short word  => this is a "short" word
;; this is a sh|ort word  => this is a "short" word
;; >this is a short word> => "this is a short word"
;; <this is a short word< => "this is a short word"
;; this is a "short| word => this is a "short" word
;; this is a short| word  => this is a "short" word (why not?)

;;-------------------------------------------

(sp-with-modes
    '(markdown-mode gfm-mode rst-mode)
  ;; Don't put a pair when after a word.
  (sp-local-pair "\"" nil
                 :unless '(sp-point-after-word-p))
  (sp-local-pair "\"" nil
                 ;; :when '(sp-point-before-word-p)
                 :when '(string-at-point-p)
                 :pre-handlers '(mark-whole-word)
                 :actions '(insert))
 )

;; Using this, I got:
;; this is a |short word  => this is a "short" word
;; this is a sh|ort word  => this is a sh"ort word
;; >this is a short word> => "
;; <this is a short word< => "

;;-------------------------------------------

(sp-with-modes
    '(markdown-mode gfm-mode rst-mode)
  (sp-local-pair "\"" nil
                 :when '(string-at-point-p)
                 :pre-handlers '(mark-whole-word)
                 :actions '(insert)))

;; Using this, I got all the same, except:
;; this is a sh|ort word  => this is a sh"ort" word

walmes avatar Jan 11 '16 19:01 walmes

These are pretty cool ideas, I like it!

We will probably need to implement it on lower level than the hooks, although I'm not exactly sure.

Fuco1 avatar Jan 11 '16 19:01 Fuco1