0

My goal was to improve the php mode. Very often I have to define an array element. And the possible code is this:

$array['key']
$array[$key]

So, I wanted to create Emacs function, reacting upon clicking '[' key like this:

if '[' was clicked once:
    print '[';
if  '[' was clicked twice:
    #this is for the string key
    print "['']";
    move the cursor between "''";
if  '[' was clicked 3 times:
    #this is for the variable as a key
    remove "''" at the center;
    #so we got [<cursor>]

I created a function:

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

(defun bracket-pressed ()
      "[ key pressed"
      (interactive)
      (cond
            ((= 0 *kb--bracket-pressed*)
                  (insert "[")
                  (setq *kb--bracket-pressed* 1)
                  )
            ((= 1 *kb--bracket-pressed*)
                  (insert "'']")
                  (backward-char 2)
                  (setq *kb--bracket-pressed* 2)
                  )
            ((= 2 *kb--bracket-pressed*)
                  (delete-char 1)
                  (delete-char -1)
                  (setq *kb--bracket-pressed* 0)
                  )
            )
      )

Then I added a function that will set *kb--bracket-pressed* = 0 when any non-bracket key was pressed:

(defun clean-bracket-pressed ()
      (if (stringp (this-command-keys))
            (when (and
                        (not (= *kb--bracket-pressed* 0))
                        (not (string= (this-command-keys) "["))
                        )
                  (setq *kb--bracket-pressed* 0))
            )
            (setq *kb--bracket-pressed* 0)
      )

When opening a php file the following hook is launched:

(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)

For some reason clean-bracket-pressed doesn't work correctly. When I click '[' twice, and then click any other key *kb--bracket-pressed* is still equal to 2. While I am expecting it to become 0.

1

Your parentheses are off in the clean-bracket-pressed function, and the final setq is outside the if. If you reindent using standard Elisp style, this pops right out at you:

(defun clean-bracket-pressed ()
  (if (stringp (this-command-keys))
      (when (and
             (not (= *kb--bracket-pressed* 0))
             (not (string= (this-command-keys) "[")))
        (setq *kb--bracket-pressed* 0)))
  (setq *kb--bracket-pressed* 0))

Your original indentation suggests you want this instead:

(defun clean-bracket-pressed ()
  (if (stringp (this-command-keys))
      (when (and
             (not (= *kb--bracket-pressed* 0))
             (not (string= (this-command-keys) "[")))
        (setq *kb--bracket-pressed* 0))
    (setq *kb--bracket-pressed* 0)))

And indeed, after this change everything works as intended.

  • No, sorry, it's still equal to 2. Can you try to reproduce on your machine? – user4035 Jul 29 '16 at 15:21
  • On my machine, I see *kb--bracket-pressed* as equal to 1 immediately after a bracket and 0 otherwise (when inspecting in post-command-hook). Maybe the code in your question is different in some way from what's running on your machine? – Aaron Harris Jul 29 '16 at 16:01
  • Also, I should clarify that the code in my original answer didn't fix the problem, just showed you the problem. I've edited it to be more explicit. – Aaron Harris Jul 29 '16 at 16:36

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.