0

When I'm writing a php program I often face the following situation:

step 1: '[' pressed:
Result:
[<cursor>

step 2: ']' pressed
Result:
[]<cursor>

step 3: move the cursor between '[]':
Result:
[<cursor>]

My idea was to save 1 keystroke and do step 3 automatically when '[]' sequence was pressed.

Currently I did the following:

;flag to signal us the '[' was pressed
(defvar *kb--bracket-pressed* nil)
;activate flag
(defun bracket-pressed ()
      "[ key pressed"
      (interactive)
      ;activate flag
      (setq *kb--bracket-pressed* t)
      (insert "[")
      )

(defun back-bracket-pressed ()
      "] key pressed"
      (interactive)
      (when *kb--bracket-pressed*
            (insert "]")
            (backward-char 1)
            ;deactivate flag
            (setq *kb--bracket-pressed* nil)
            )
      )

;when php-mode is activated
(local-set-key (kbd "[") 'bracket-pressed)
(local-set-key (kbd "]") 'back-bracket-pressed)

The problem is: I don't know how to reset the flag to nil, when any other key except "]" was pressed after "[".

  • 3
    Consider using smartparens (get it from MELPA) -- that way you can save two keystrokes (in some cases, anyway). – Constantine Feb 12 '16 at 23:49
  • On a more serious note: I would add a function to that checks if the text before point matches "[]" to post-self-insert-hook. – Constantine Feb 13 '16 at 1:06
  • Auto-pair-mode is your friend. :-) – Malabarba Feb 13 '16 at 2:40
  • @Constantine I solved the problem, but is not sure that my solution is optimal. Can you take a look? – user4035 Feb 22 '16 at 23:37
0

To save the keystrokes I created the following. I found that pretty often I have to type: [''], which requires 4 keystrokes. So, I desided to add the following rules:

step 1. "[" pressed: 
    print "["
    ;output looks like: "[<cursor>"

step 2. "[" pressed for the 2-nd time. 
    output "'']"; 
    move cursor 2 characters to the left 
   ;output looks like: "['<cursor>']"
step 3. "[" pressed for the 3-rd time: 
    delete 1 character backwards
    delete 1 character forward
   ;output looks like: "[]"

Code:

(defvar *kb--bracket-pressed* 0)

;this function is called when any other characted except "[" is pressed 
(defun clean-bracket-pressed ()
      (when (and
                  (not (= *kb--bracket-pressed* 0))
                  (not (string= (this-command-keys) "[")
                        ))
            (setq *kb--bracket-pressed* 0)
            )
      )

;this function is called when "[" is pressed 
(defun bracket-pressed ()
      "[ key pressed"
      (interactive)
      (cond
            ((= 0 *kb--bracket-pressed*)
                  (insert "[")
                  (setq *kb--bracket-pressed* (1+ *kb--bracket-pressed*))
                  )
            ((= 1 *kb--bracket-pressed*)
                  (insert "'']")
                  (backward-char 2)
                  (setq *kb--bracket-pressed* (1+ *kb--bracket-pressed*))
                  )
            ((= 2 *kb--bracket-pressed*)
                  (delete-char -1)
                  (delete-char 1)
                  (setq *kb--bracket-pressed* 0)
                  )
            )
      )

(defun my-php-mode ()
  "My php-mode customisations."
  (local-set-key (kbd "[") 'bracket-pressed)
  (add-hook 'pre-command-hook 'clean-bracket-pressed nil 'make-it-local)
)

(add-hook 'php-mode-hook 'my-php-mode)

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.