4

What should I use in Emacs for developing PHP files with SQL queries?

When indenting the buffer the code should look like this:

<?php
$query = "
    SELECT
        id,
        name
    FROM 
        products
    WHERE 
        id > 12"
?>

In web-mode and php-mode it looks like this:

<?php 
$query = "
SELECT
id,
name
FROM
products
WHERE
id > 12"
?>

If this isn't possible, one alternative would be to have it enable manual indentation (using TAB and ShiftTAB, like in Sublime and other editors) when at multi-line strings in PHP code. How would I do that?

2
  • See also Indenting SQL in another major mode in Emacs. Commented Jun 25, 2014 at 0:56
  • @phils Hmm, it almost works. The indentation is a bit off. It doesn't consider indentation level of the PHP code but it does indent the SQL code. Commented Jul 4, 2014 at 23:32

3 Answers 3

10

Doing this automatically when the buffer is indenting will be very hard, you can try multiple-major modes but that isn't ideal.

One solution will be to write a function that will format the sql underneath your cursor, you can then manually run this command when you are finished writing your query string.

This example requires two packages: expand-region and sql-indent, both are available for download on MELPA.

If you have the packages installed this function will format the SQL at point, this also handles indenting the entire SQL string according to depth of the code around it unlike the solution in the comments.

(defun sql-indent-string ()
  "Indents the string under the cursor as SQL."
  (interactive)
  (save-excursion
    (er/mark-inside-quotes)
    (let* ((text (buffer-substring-no-properties (region-beginning) (region-end)))
           (pos (region-beginning))
           (column (progn (goto-char pos) (current-column)))
           (formatted-text (with-temp-buffer
                             (insert text)
                             (delete-trailing-whitespace)
                             (sql-indent-buffer)
                             (replace-string "\n" (concat "\n" (make-string column (string-to-char " "))) nil (point-min) (point-max))
                             (buffer-string))))
      (delete-region (region-beginning) (region-end))
      (goto-char pos)
      (insert formatted-text))))

The function works by copying the string under your cursor and moving it to a temporary buffer where sql-indent will format it, then going back to the original buffer and replacing the old string with the new one. It is functional but not pretty.

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

(Thanks Jordon Biondo! However, I would like to add calling the function ` sqlup-capitalize-keywords-in-region` from SQLup. When I add sqlup-capitalize-keywords-in-region inside the function, and call it from the sql string, I got an empty result. Any tips?
Can you turn this into a minor mode?
2

The last version (9.0.84) of web-mode (available on github) provides native sql indentation in block strings.

4 Comments

I can't get it to work with the code (second part) I had in the question. Should I be able to be on the third row, press TAB and have it indented?
SELECT should be just after " Moreover are you sure you have the latest version ?
Great! It works on the example but could I make it indent it even if SELECT is on a new line? Also, there seems to be a bug when having SELECT inside JOIN. INSERT queries doesn't indent either. It's a great start but seems to need some more work.
I've added highlighting and compatibility with insert, update, delete. I do not plan to work on indentation on new line. If you have other requests and issues, please open an issue on github
0

Emacs doesn't handle SQL with PHP very well. There's an extension you can get here that supposedly helps with SQL only so I'm not sure if it will behave the way you want it to with PHP code. There are other alternatives to using Emacs though, and I would strongly suggest it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.