views:

181

answers:

7

I am new to emacs, but shocked at what I can really do and how much time it saves (Macros save A LOT of time). But I was wondering it was possible to create step based scripts where it asks the user for input and executes code based on that. For example maybe I want to create a SQL query so it would prompt something like:

>table name?
myTable
>type of query (select, insert, update, delete)
select
>fields to get
name, id
>Result query is "select (name, id) from myTable"

This is just an outline of an idea but I was wonder because something like this would be useful to have. Someone mentioned AWK scripts but I wasn't sure if that was the right tree to bark up or not. I am on Windows but I don't think that matters a whole lot.

I definitely appreciate any info on this, Thanks

A: 

Yes. Read up on emacs lisp.

anon
+2  A: 

You can use read-from-minibuffer, using Emacs Lisp, aka elisp.

Maurits Rijk
This works, but is not pleasant, since you cannot see the output of previous interactions.
Charles Stewart
+2  A: 

eg in awk.

BEGIN{
while (1){
    printf "Enter table name: "
    getline tablename
    printf "Enter type of query: (s)elect, (i)nsert, (u)pdate, (d)elete, (q)uit: "
    getline querytype
    if ( querytype ~ /^q|Q$/) { exit}
    printf "Enter fields to get (field1,..): "
    getline fields
    sql=querytype" ("fields") from " tablename
    print "Result query is " sql
    printf "Do you want to execute query??: (yY)es, (nN)o"
    getline choice
    if ( choice ~ /^y|Y$/) {
    # use sql cmd here
    }
 }
}

save as myscript.awk and on command line

 c:\test> gawk -f myscript.awk
ghostdog74
Wow awesome response. More than I could have hoped for. Thanks A LOT! :-)
John Baker
upon thinking about it this wouldn't seem to allow me to use emacs commands on each available line. But it's good to know this solution is out there.
John Baker
+5  A: 

Hi,

see this little hack on emacswiki: Prompting During Keyboard Macro Execution. Otherwise you can always pause a macro and insert you text execution at the points where you give C-x q during definition, see Executing Macros with Variations. Finally you can define a function and use interactive to get the required parameters, i.e.:

(defun my-build-query (table type field)
  (interactive "sTable name: \nsType of query: \nsFields to get: ")
  (message "%s (%s) from %s" type fields table)
)

You could put this function in your ~/.emacs and execute it with M-x: my-build-query.

Hope this gives you some pointers to get started!

P.S.: Ahh, and one more idea. The probably easier approach for this kind of stuff is to use YASnippet (have a look at the screencast on the page).

danielpoe
yeah I use yasnippet, I wasn't aware that they allowed you to create snippets where it prompts for info, I'm also not sure if it can handle really heavy duty scripting where I'm going to build out lots of stuff, but I will definitely check it out
John Baker
Hi John, yasnippet won't actually prompt for input, but you can <tab> from option to option. I was thinking of something in the line of "select ${1:fields} from ${2:table} $0". But if you want something more complex a "defun" might be better ...
danielpoe
You can also set it up to insert the query straight into the buffer with (insert....) But yeah, arguments to an interactive function are a really nice thing to know about
Brian Postow
+1  A: 

The right thing, I think, is to write a readline-like function that allows prompting and user input within the buffer.

This is one of those things that is easy enough to implement, but hard to do in a really pleasing way. There's probably good reusable elisp code out there to do this, but I don't know of it.

Charles Stewart
+1  A: 

Here's a basic implementation to get you started:

(defun prompt-for-sql-statement (table type fields)
  (interactive
   (list
    (read-from-minibuffer "Table name? ")
    (completing-read "Type of statement? " '("select" "insert" "update" "delete"))
    (let (field fields (index 1))
      (while (not (string= "" (setq field (read-from-minibuffer (format "Field #%d: " index)))))
        (setq fields (cons field fields) index (1+ index)))
      (mapconcat 'identity (nreverse fields) ", "))))
  (insert type " (" fields ") from " table))

When you type M-x prompt-for-sql-statement (or type a key sequence you've bound the command to), you'll get a series of prompts:

Table name? myTable
Type of statement? select
Field #1: foo
Field #2: bar
Field #3: baz
Field #4:

You can do tab-completion on the statement type, and an empty field will terminate the list. Then the function will insert the constructed SQL statement wherever point was when you invoked the command.

The command as written will generate SQL statements that all look like a SELECT ("select ... from table", "insert ... from table", etc). A smarter implementation would know how to produce the correct syntax for each type of SQL statement.

Sean
+1  A: 

another possiblity might be a skeleton or other emacs template (maybe tempo?) possibly combined with abbrevs

jk