unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Execute a string as a command
@ 2015-11-06  3:23 Tim Johnson
  2015-11-06  3:53 ` Emanuel Berg
  2015-11-06  4:40 ` Random832
  0 siblings, 2 replies; 16+ messages in thread
From: Tim Johnson @ 2015-11-06  3:23 UTC (permalink / raw)
  To: Emacs

Example : A string has the value of :
"toggle-truncate-lines"

(setq string-wants-to-be-a-command "toggle-truncate-lines")

How may I convert 'string-wants-to-be-a-command to a command:
I.E. => (toggle-truncate-lines) to be used programmatically?

thanks
-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
       [not found] <mailman.1811.1446780244.7904.help-gnu-emacs@gnu.org>
@ 2015-11-06  3:36 ` Barry Margolin
  2015-11-06  3:59   ` Tim Johnson
  2015-11-06  3:59   ` Emanuel Berg
  0 siblings, 2 replies; 16+ messages in thread
From: Barry Margolin @ 2015-11-06  3:36 UTC (permalink / raw)
  To: help-gnu-emacs

In article <mailman.1811.1446780244.7904.help-gnu-emacs@gnu.org>,
 Tim Johnson <tim@akwebsoft.com> wrote:

> Example : A string has the value of :
> "toggle-truncate-lines"
> 
> (setq string-wants-to-be-a-command "toggle-truncate-lines")
> 
> How may I convert 'string-wants-to-be-a-command to a command:
> I.E. => (toggle-truncate-lines) to be used programmatically?
> 
> thanks

(call-interactively (intern string-wants-to-be-a-command))

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  3:23 Execute a string as a command Tim Johnson
@ 2015-11-06  3:53 ` Emanuel Berg
  2015-11-06  4:06   ` Tim Johnson
  2015-11-06  4:40 ` Random832
  1 sibling, 1 reply; 16+ messages in thread
From: Emanuel Berg @ 2015-11-06  3:53 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson <tim@akwebsoft.com> writes:

> Example : A string has the value of :
> "toggle-truncate-lines"
>
> (setq string-wants-to-be-a-command
> "toggle-truncate-lines")
>
> How may I convert 'string-wants-to-be-a-command to
> a command: I.E. => (toggle-truncate-lines) to be
> used programmatically?

(Why do you want this? Is there a better way to
do it?)

Do you mean you want to parenthesize the string? - in
what case this is an editing issue, at least for
uncomplicated commands.

Or do you want to store commands in strings and have
a function execute the commands that the string
contain? - if so, take a look at something I wrote
several years ago:

;; This file: http://user.it.uu.se/~embe8573/conf/emacs-init/shell-cli.el

(defun string-to-cmd (str)
  (interactive (list (read-string " $> ")))
  (let*((cmd  (read (car (split-string str " "))))
        (args (cdr (make-arg-list (string-to-list str)))) )
    (dolist (arg (nreverse args))
      (push 13 unread-command-events) ; 13 is RET
      (dolist (n (reverse (string-to-list arg)))
        (push n unread-command-events) ))
    (call-interactively cmd) ))

;; test: (string-to-cmd "goto-char 0")

(defun make-arg-list (chars)
  (interactive)
  (if chars
      (let ((WS  39) ; whitespace ( )
            (SQM 32) ;      quote (')
            (c  (car chars))
            (cs (cdr chars)) )
        (if (eq c WS) (make-word cs '() WS)
          (if (eq c SQM) (make-arg-list cs)
            (make-word chars '() SQM)) ))
  '() ))

(defun make-word (chars wd sep)
  (interactive)
  (if chars
      (let ((c  (car chars))
            (cs (cdr chars)))
        (if (eq c sep) (cons wd (make-arg-list cs))
          (make-word cs (append wd (list c)) sep)))
    (list wd) ))

(defun zow (string symbol number)
  "Test: shell-cli.el"
   (interactive "sstring: \nSsymbol: \nnnumber: ")
   (message "got: %S" (list string symbol number)) )

(provide 'shell-cli)

-- 
underground experts united
http://user.it.uu.se/~embe8573




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  3:36 ` Barry Margolin
@ 2015-11-06  3:59   ` Tim Johnson
  2015-11-06  3:59   ` Emanuel Berg
  1 sibling, 0 replies; 16+ messages in thread
From: Tim Johnson @ 2015-11-06  3:59 UTC (permalink / raw)
  To: help-gnu-emacs

* Barry Margolin <barmar@alum.mit.edu> [151105 18:51]:
> In article <mailman.1811.1446780244.7904.help-gnu-emacs@gnu.org>,
>  Tim Johnson <tim@akwebsoft.com> wrote:
> 
> > Example : A string has the value of :
> > "toggle-truncate-lines"
> > 
> > (setq string-wants-to-be-a-command "toggle-truncate-lines")
> > 
> > How may I convert 'string-wants-to-be-a-command to a command:
> > I.E. => (toggle-truncate-lines) to be used programmatically?
> > 
> > thanks
> 
> (call-interactively (intern string-wants-to-be-a-command))
  That's exactly what I was looking for. I knew about 'intern, but
  had tried eval, make-symbol and others to no evail.

  thanks very much.
-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  3:36 ` Barry Margolin
  2015-11-06  3:59   ` Tim Johnson
@ 2015-11-06  3:59   ` Emanuel Berg
  1 sibling, 0 replies; 16+ messages in thread
From: Emanuel Berg @ 2015-11-06  3:59 UTC (permalink / raw)
  To: help-gnu-emacs

Barry Margolin <barmar@alum.mit.edu> writes:

> (call-interactively (intern
> string-wants-to-be-a-command))

Yeah, you can do "goto-char" with that and provide the
position the ordinary way (not in the string as in
"goto-char 0"). If you don't want that you can `push'
the arguments in reversed order to
`unread-command-events' and first of all push 13 for
RET. Very high-skill/knowledge and complicated ways to
do basic stuff, for sure. No one said it is supposed
to be easy!

-- 
underground experts united
http://user.it.uu.se/~embe8573




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  3:53 ` Emanuel Berg
@ 2015-11-06  4:06   ` Tim Johnson
  2015-11-06 21:47     ` Emanuel Berg
  0 siblings, 1 reply; 16+ messages in thread
From: Tim Johnson @ 2015-11-06  4:06 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg <embe8573@student.uu.se> [151105 18:51]:
> Tim Johnson <tim@akwebsoft.com> writes:
> 
> > Example : A string has the value of :
> > "toggle-truncate-lines"
> >
> > (setq string-wants-to-be-a-command
> > "toggle-truncate-lines")
> >
> > How may I convert 'string-wants-to-be-a-command to
> > a command: I.E. => (toggle-truncate-lines) to be
> > used programmatically?
> 
> (Why do you want this? Is there a better way to
> do it?)
 
  Probably. Bearing in mind that I am just beginning to code in
  elisp.

  I'm going to save your code and digest it tomorrow. I have a
  larger need, and that is, a series of popup(or tmm-prompt)-driven
  commands.

  However, I believe it would be better for future searches, if I
  posted any question I might have on that issue in a morely
  suitably titled subject.

  I can't get to that phase for another day or two..
  thanks, Emanuel.

> Do you mean you want to parenthesize the string? - in
> what case this is an editing issue, at least for
> uncomplicated commands.
> 
> Or do you want to store commands in strings and have
> a function execute the commands that the string
> contain? - if so, take a look at something I wrote
> several years ago:
> 
> ;; This file: http://user.it.uu.se/~embe8573/conf/emacs-init/shell-cli.el
> 
> (defun string-to-cmd (str)
>   (interactive (list (read-string " $> ")))
>   (let*((cmd  (read (car (split-string str " "))))
>         (args (cdr (make-arg-list (string-to-list str)))) )
>     (dolist (arg (nreverse args))
>       (push 13 unread-command-events) ; 13 is RET
>       (dolist (n (reverse (string-to-list arg)))
>         (push n unread-command-events) ))
>     (call-interactively cmd) ))
> 
> ;; test: (string-to-cmd "goto-char 0")
> 
> (defun make-arg-list (chars)
>   (interactive)
>   (if chars
>       (let ((WS  39) ; whitespace ( )
>             (SQM 32) ;      quote (')
>             (c  (car chars))
>             (cs (cdr chars)) )
>         (if (eq c WS) (make-word cs '() WS)
>           (if (eq c SQM) (make-arg-list cs)
>             (make-word chars '() SQM)) ))
>   '() ))
> 
> (defun make-word (chars wd sep)
>   (interactive)
>   (if chars
>       (let ((c  (car chars))
>             (cs (cdr chars)))
>         (if (eq c sep) (cons wd (make-arg-list cs))
>           (make-word cs (append wd (list c)) sep)))
>     (list wd) ))
> 
> (defun zow (string symbol number)
>   "Test: shell-cli.el"
>    (interactive "sstring: \nSsymbol: \nnnumber: ")
>    (message "got: %S" (list string symbol number)) )
> 
> (provide 'shell-cli)
> 
> -- 
> underground experts united
> http://user.it.uu.se/~embe8573
> 
> 

-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  3:23 Execute a string as a command Tim Johnson
  2015-11-06  3:53 ` Emanuel Berg
@ 2015-11-06  4:40 ` Random832
  2015-11-06  5:52   ` Tim Johnson
       [not found]   ` <mailman.1818.1446789151.7904.help-gnu-emacs@gnu.org>
  1 sibling, 2 replies; 16+ messages in thread
From: Random832 @ 2015-11-06  4:40 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson <tim@akwebsoft.com> writes:

> Example : A string has the value of :
> "toggle-truncate-lines"
>
> (setq string-wants-to-be-a-command "toggle-truncate-lines")
>
> How may I convert 'string-wants-to-be-a-command to a command:
> I.E. => (toggle-truncate-lines) to be used programmatically?
>
> thanks

If you want it to literally be interpreted as a symbol name and
damn the consequences if it's anything else, you can use intern
to get the symbol:

(intern "toggle-truncate-lines")
(intern string-wants-to-be-a-command)
(intern (symbol-value 'string-wants-to-be-a-command))

If it can be a lambda rather than just a symbol, then use
read-from-string instead:

(car (read-from-string "toggle-truncate-lines"))
(car (read-from-string "(lambda () (interactive))"))

But why are you storing a string instead of the command object
(symbol/function/lambda) anyway?

And then you can call it with funcall or call-interactively.

funcall requires you to specify the arguments, so only commands
that don't require an argument will work. To read the arguments
from the keyboard instead, use call-interactively.




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  4:40 ` Random832
@ 2015-11-06  5:52   ` Tim Johnson
       [not found]   ` <mailman.1818.1446789151.7904.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 16+ messages in thread
From: Tim Johnson @ 2015-11-06  5:52 UTC (permalink / raw)
  To: help-gnu-emacs

* Random832 <random832@fastmail.com> [151105 19:52]:
> Tim Johnson <tim@akwebsoft.com> writes:
> 
> > Example : A string has the value of :
> > "toggle-truncate-lines"
> >
> > (setq string-wants-to-be-a-command "toggle-truncate-lines")
> >
> > How may I convert 'string-wants-to-be-a-command to a command:
> > I.E. => (toggle-truncate-lines) to be used programmatically?
> >
> > thanks
<...> 
> But why are you storing a string instead of the command object
> (symbol/function/lambda) anyway?
 
   Because I'm a total noob when I comes to using menu objects as
   per tmm-prompt (my preference) and x-popup-menu, and I have had
   problems finding instructions for my needs as illustrated below.

> And then you can call it with funcall or call-interactively.
> 
> funcall requires you to specify the arguments, so only commands
> that don't require an argument will work. To read the arguments
> from the keyboard instead, use call-interactively.

Here is an example of what could be a working function 'interning'
a string :
(defun tj-toggle-funcs ()
  "Toggle functions"
  (interactive)
  (let ((menu
	 '("" ("" ("Transient Mark Mode" . "transient-mark-mode"))
	       ("Truncate Lines" . "toggle-truncate-lines")
	       ("Show Tabs" .  "toggle-tabs-font-lock"))))
	(choice ))
    (setq choice (tmm-prompt menu))
    (if choice
	(call-interactively (intern choice)))))

My preference *would* be that a command object be read from the
'menu structure, but wasn't able to make it work.	
So my next step is to figure out how to place a command object as a
value instead of a string... and then evaluate it properly.

thanks, late here, my response would be in 9-10 hours..

-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
       [not found]   ` <mailman.1818.1446789151.7904.help-gnu-emacs@gnu.org>
@ 2015-11-06  9:43     ` Joost Kremers
  2015-11-06 16:17       ` Tim Johnson
  0 siblings, 1 reply; 16+ messages in thread
From: Joost Kremers @ 2015-11-06  9:43 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson wrote:
> Here is an example of what could be a working function 'interning'
> a string :
> (defun tj-toggle-funcs ()
>   "Toggle functions"
>   (interactive)
>   (let ((menu
> 	 '("" ("" ("Transient Mark Mode" . "transient-mark-mode"))
> 	       ("Truncate Lines" . "toggle-truncate-lines")
> 	       ("Show Tabs" .  "toggle-tabs-font-lock"))))
> 	(choice ))
>     (setq choice (tmm-prompt menu))
>     (if choice
> 	(call-interactively (intern choice)))))
>
> My preference *would* be that a command object be read from the
> 'menu structure, but wasn't able to make it work.	
> So my next step is to figure out how to place a command object as a
> value instead of a string... and then evaluate it properly.

Check out the Elisp manual on pop-up menus, which use the function
x-popup-menu, which takes the same kind of menu structure as tmm-prompt.

C-h i Elisp RET Pop-up menus RET

An alternative to what you're trying to do would be to use the hydra
package:

https://github.com/abo-abo/hydra

Here is my toggle hydra, for example:

```
(defhydra jk-hydra-toggle (:color blue)
  "Change"
  ("d" toggle-debug-on-error "Debug")
  ("w" writeroom-mode "Writeroom")
  ("i" ispell-change-dictionary "Change Ispell Dictionary")
  ("f" toggle-fill-unfill "Fill")
  ("F" follow-mode "Follow mode")
  ("t" orgtbl-mode "OrgTbl mode")
  ("y" typo-mode "Typo mode")
  ("q" nil "Cancel"))
(bind-key "s-r" #'jk-hydra-toggle/body)
```

Yeah, ok, so `ispell-change-dictionary` is not a toggle... But you get the
idea. ;-)

HTH


-- 
Joost Kremers                                   joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  9:43     ` Joost Kremers
@ 2015-11-06 16:17       ` Tim Johnson
  2015-11-06 16:49         ` Tim Johnson
  0 siblings, 1 reply; 16+ messages in thread
From: Tim Johnson @ 2015-11-06 16:17 UTC (permalink / raw)
  To: help-gnu-emacs

* Joost Kremers <joost.m.kremers@gmail.com> [151106 00:57]:
> Tim Johnson wrote:
> > Here is an example of what could be a working function 'interning'
> > a string :
> > (defun tj-toggle-funcs ()
> >   "Toggle functions"
> >   (interactive)
> >   (let ((menu
> > 	 '("" ("" ("Transient Mark Mode" . "transient-mark-mode"))
> > 	       ("Truncate Lines" . "toggle-truncate-lines")
> > 	       ("Show Tabs" .  "toggle-tabs-font-lock"))))
> > 	(choice ))
> >     (setq choice (tmm-prompt menu))
> >     (if choice
> > 	(call-interactively (intern choice)))))
> >
> > My preference *would* be that a command object be read from the
> > 'menu structure, but wasn't able to make it work.	
> > So my next step is to figure out how to place a command object as a
> > value instead of a string... and then evaluate it properly.
  Thanks for the reply :

> Check out the Elisp manual on pop-up menus, which use the function
> x-popup-menu, which takes the same kind of menu structure as tmm-prompt.
 
   1)I'm a bit "mouse averse" - I.E. I prefer tmm-prompt for
   numerous reasons.

   2)The Elisp manual (as far as I have found it) does not give any
   working examples which have edified me.

   What has eluded me so far is how to use commands as values in the
   alist - this is why I introduced the topic of evaluating a string
   as a command.

> C-h i Elisp RET Pop-up menus RET
> 
> An alternative to what you're trying to do would be to use the hydra
> package:
> 
> https://github.com/abo-abo/hydra
> 
> Here is my toggle hydra, for example:
> 
> ```
> (defhydra jk-hydra-toggle (:color blue)
>   "Change"
>   ("d" toggle-debug-on-error "Debug")
>   ("w" writeroom-mode "Writeroom")
>   ("i" ispell-change-dictionary "Change Ispell Dictionary")
>   ("f" toggle-fill-unfill "Fill")
>   ("F" follow-mode "Follow mode")
>   ("t" orgtbl-mode "OrgTbl mode")
>   ("y" typo-mode "Typo mode")
>   ("q" nil "Cancel"))
> (bind-key "s-r" #'jk-hydra-toggle/body)
> ```
  The formatting of this structure above makes total sense, but can
  it be used for tmm-prompt.

> Yeah, ok, so `ispell-change-dictionary` is not a toggle... But you get the
> idea. ;-)
> 
> HTH

  Thanks very much.
-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06 16:17       ` Tim Johnson
@ 2015-11-06 16:49         ` Tim Johnson
  0 siblings, 0 replies; 16+ messages in thread
From: Tim Johnson @ 2015-11-06 16:49 UTC (permalink / raw)
  To: help-gnu-emacs

* Tim Johnson <tim@akwebsoft.com> [151106 07:30]:
> * Joost Kremers <joost.m.kremers@gmail.com> [151106 00:57]:
> > Tim Johnson wrote:
> > > Here is an example of what could be a working function 'interning'
> > > a string :
> > > (defun tj-toggle-funcs ()
> > >   "Toggle functions"
> > >   (interactive)
> > >   (let ((menu
> > > 	 '("" ("" ("Transient Mark Mode" . "transient-mark-mode"))
> > > 	       ("Truncate Lines" . "toggle-truncate-lines")
> > > 	       ("Show Tabs" .  "toggle-tabs-font-lock"))))
> > > 	(choice ))
> > >     (setq choice (tmm-prompt menu))
> > >     (if choice
> > > 	(call-interactively (intern choice)))))
> > >
> > > My preference *would* be that a command object be read from the
> > > 'menu structure, but wasn't able to make it work.	
> > > So my next step is to figure out how to place a command object as a
> > > value instead of a string... and then evaluate it properly.
>   Thanks for the reply :
> 
> > Check out the Elisp manual on pop-up menus, which use the function
> > x-popup-menu, which takes the same kind of menu structure as tmm-prompt.
>  
>    1)I'm a bit "mouse averse" - I.E. I prefer tmm-prompt for
>    numerous reasons.
> 
>    2)The Elisp manual (as far as I have found it) does not give any
>    working examples which have edified me.
> 
>    What has eluded me so far is how to use commands as values in the
>    alist - this is why I introduced the topic of evaluating a string
>    as a command.
> 
> > C-h i Elisp RET Pop-up menus RET
> > 
> > An alternative to what you're trying to do would be to use the hydra
> > package:
> > 
> > https://github.com/abo-abo/hydra
> > 
> > Here is my toggle hydra, for example:
> > 
> > ```
> > (defhydra jk-hydra-toggle (:color blue)
> >   "Change"
> >   ("d" toggle-debug-on-error "Debug")
> >   ("w" writeroom-mode "Writeroom")
> >   ("i" ispell-change-dictionary "Change Ispell Dictionary")
> >   ("f" toggle-fill-unfill "Fill")
> >   ("F" follow-mode "Follow mode")
> >   ("t" orgtbl-mode "OrgTbl mode")
> >   ("y" typo-mode "Typo mode")
> >   ("q" nil "Cancel"))
> > (bind-key "s-r" #'jk-hydra-toggle/body)
> > ```
>   The formatting of this structure above makes total sense, but can
>   it be used for tmm-prompt.
> 
> > Yeah, ok, so `ispell-change-dictionary` is not a toggle... But you get the
> > idea. ;-)
  Oh! I've read further on hydra. Doesn't even need tmm-prompt. It
  looks pretty awesome. I will try it.

  BTW: After a night's sleep and some coffee, I think I have a
  working tmm-prompt solution with command objects:
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun tj-toggle-funcs ()
  "Toggle functions"
  (interactive)
  (let ((menu
	 '("" ("" ("1)Transient Mark Mode" . (transient-mark-mode))
	       ("2)Truncate Lines" . (toggle-truncate-lines))
	       ("3)Show Tabs" .  (toggle-tabs-font-lock))
	       ("4)Cursor Color" . (tj-cursor-color)))))
	(choice))
    (setq choice (tmm-prompt menu))
    (if choice
	(eval choice))))
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cheers
-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06  4:06   ` Tim Johnson
@ 2015-11-06 21:47     ` Emanuel Berg
  2015-11-07  1:32       ` Tim Johnson
       [not found]       ` <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 16+ messages in thread
From: Emanuel Berg @ 2015-11-06 21:47 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson <tim@akwebsoft.com> writes:

> I can't get to that phase for another day or two..
> thanks, Emanuel.

No, there are much better things for you to do than to
digest that code. For example, ask yourself why you
want to execute strings as commands, and if there is
a better way still.

That code of mine is more like a demo to show of
skills and attract ohs and ahs. It is not really
helpful (tho sometimes I use it so it *does* work).

-- 
underground experts united
http://user.it.uu.se/~embe8573




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-06 21:47     ` Emanuel Berg
@ 2015-11-07  1:32       ` Tim Johnson
  2015-11-07  3:57         ` Emanuel Berg
       [not found]       ` <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 16+ messages in thread
From: Tim Johnson @ 2015-11-07  1:32 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg <embe8573@student.uu.se> [151106 12:47]:
> Tim Johnson <tim@akwebsoft.com> writes:
> 
> > I can't get to that phase for another day or two..
> > thanks, Emanuel.
> 
> No, there are much better things for you to do than to
> digest that code. For example, ask yourself why you
> want to execute strings as commands, and if there is
> a better way still.
> 
> That code of mine is more like a demo to show of
> skills and attract ohs and ahs. It is not really
> helpful (tho sometimes I use it so it *does* work).

  By this time, you've probably read from the continuation of this
  thread that I had problems with setting up the menu structure so
  that command objects could be read from it. Thus I used a string
  representation to see if that could be evaluated. 

  I have since found the right combination of menu syntax and 'eval
  syntax to make the command objects readable.

  So, I've learned two bits of emacsen knowledge 
  1) How to evaluate a string
  2) How to evaluate a command object
  *and* I've been
  introduced to hydra, which might prove to be what I was really
  looking for.

  Thanks, as always, for your replies. They are always enlightening.

-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-07  1:32       ` Tim Johnson
@ 2015-11-07  3:57         ` Emanuel Berg
  0 siblings, 0 replies; 16+ messages in thread
From: Emanuel Berg @ 2015-11-07  3:57 UTC (permalink / raw)
  To: help-gnu-emacs

Tim Johnson <tim@akwebsoft.com> writes:

> By this time, you've probably read from the
> continuation of this thread that I had problems with
> setting up the menu structure so that command
> objects could be read from it. Thus I used a string
> representation to see if that could be evaluated.

I don't use menus so I can't say but my gut feeling
tells me that to keep commands as strings to be
evaluated isn't a good idea.

It is disencouraged in shell scripting as well (e.g.,
bash, zsh). And isn't the famous SQL injection attack
based on somewhat the same data/code intermingling?

One problem is the string needs to be parsed somehow
into code. You may say this happens all the time when
programming. However when programming, even tho you
aren't compiling your code, after each evaluation of
a function, that function is simply invoked. At that
stage the function is at least formally correct in the
sense that evaluation was possible. But, in your menu
case, evaluation must be done each time. Otherwise it
is just a string. This is not only inefficient, it is
also insecure as there is no telling if that string
holds anything that can sensibly be put together into
a function.

The argument problem has been mentioned. In general,
commands that are not strings but commands hold much
more power. Much more stuff can be done with them, and
around them: e.g., advices, lambdas, keybindings, and
probably a lot more.

> I have since found the right combination of menu
> syntax and 'eval syntax to make the command
> objects readable.

In old Lisp books (e.g., [1]), `eval' is one of the
first things they mention and they put it as
a cornerpiece of Lisp. Since then this has changed and
eval should only be used with what is explicitly
commands, i.e. stuff that is beyond doubt prepared
for execution. In your case, you have used it correct.
Another example might be:

    (eval (car command-history) )

Here, both the name and the docstring "List of recent
commands..." support the use of `eval'. (Other people
can tell you more about why you shouldn't use
eval otherwise.)

> Thanks ... for your replies. They are
> always enlightening.

Well, "always" may be stretching it just a bit :)

% [1]
@book{artificial-intelligence-and-the-design,
  title      = {Artificial Intelligence and the Design of Expert Systems},
  author     = {George Luger; William Stubblefield},
  publisher  = {Benjamin-Cummings},
  year       = 1989,
  ISBN       = 0805301399
}

--
underground experts united
http://user.it.uu.se/~embe8573




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
       [not found]       ` <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>
@ 2015-11-07 18:32         ` Barry Margolin
  2015-11-07 19:36           ` Tim Johnson
  0 siblings, 1 reply; 16+ messages in thread
From: Barry Margolin @ 2015-11-07 18:32 UTC (permalink / raw)
  To: help-gnu-emacs

In article <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>,
 Tim Johnson <tim@akwebsoft.com> wrote:

> * Emanuel Berg <embe8573@student.uu.se> [151106 12:47]:
> > Tim Johnson <tim@akwebsoft.com> writes:
> > 
> > > I can't get to that phase for another day or two..
> > > thanks, Emanuel.
> > 
> > No, there are much better things for you to do than to
> > digest that code. For example, ask yourself why you
> > want to execute strings as commands, and if there is
> > a better way still.
> > 
> > That code of mine is more like a demo to show of
> > skills and attract ohs and ahs. It is not really
> > helpful (tho sometimes I use it so it *does* work).
> 
>   By this time, you've probably read from the continuation of this
>   thread that I had problems with setting up the menu structure so
>   that command objects could be read from it. Thus I used a string
>   representation to see if that could be evaluated. 

The usual way to implement things like this is with an association list.
The key is the string that's displayed in the menu, and the value is a 
symbol that names a function or a lambda expression.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Execute a string as a command
  2015-11-07 18:32         ` Barry Margolin
@ 2015-11-07 19:36           ` Tim Johnson
  0 siblings, 0 replies; 16+ messages in thread
From: Tim Johnson @ 2015-11-07 19:36 UTC (permalink / raw)
  To: help-gnu-emacs

* Barry Margolin <barmar@alum.mit.edu> [151107 09:44]:
> In article <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>,
>  Tim Johnson <tim@akwebsoft.com> wrote:
> 
> > * Emanuel Berg <embe8573@student.uu.se> [151106 12:47]:
> > > Tim Johnson <tim@akwebsoft.com> writes:
> > > 
> > > > I can't get to that phase for another day or two..
> > > > thanks, Emanuel.
> > > 
> > > No, there are much better things for you to do than to
> > > digest that code. For example, ask yourself why you
> > > want to execute strings as commands, and if there is
> > > a better way still.
> > > 
> > > That code of mine is more like a demo to show of
> > > skills and attract ohs and ahs. It is not really
> > > helpful (tho sometimes I use it so it *does* work).
> > 
> >   By this time, you've probably read from the continuation of this
> >   thread that I had problems with setting up the menu structure so
> >   that command objects could be read from it. Thus I used a string
> >   representation to see if that could be evaluated. 
> 
> The usual way to implement things like this is with an association list.
> The key is the string that's displayed in the menu, and the value is a 
> symbol that names a function or a lambda expression.

  Absolutely. This is what I was finally able to make work:
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (defun tj-toggle-funcs ()
  "Toggle functions"
  (interactive)
  (let ((menu
	 '("" ("" ("1)Transient Mark Mode" . (transient-mark-mode))
	       ("2)Truncate Lines" . (toggle-truncate-lines))
	       ("3)Show Tabs" .  (toggle-show-tabs-show-ws)))
	(choice))
    (setq choice (tmm-prompt menu))
    (if choice
	  (eval choice))))
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Any creative or instructive comments are more than welcome.

-- 
Tim 
http://www.akwebsoft.com, http://www.tj49.com



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-11-07 19:36 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-06  3:23 Execute a string as a command Tim Johnson
2015-11-06  3:53 ` Emanuel Berg
2015-11-06  4:06   ` Tim Johnson
2015-11-06 21:47     ` Emanuel Berg
2015-11-07  1:32       ` Tim Johnson
2015-11-07  3:57         ` Emanuel Berg
     [not found]       ` <mailman.1860.1446859974.7904.help-gnu-emacs@gnu.org>
2015-11-07 18:32         ` Barry Margolin
2015-11-07 19:36           ` Tim Johnson
2015-11-06  4:40 ` Random832
2015-11-06  5:52   ` Tim Johnson
     [not found]   ` <mailman.1818.1446789151.7904.help-gnu-emacs@gnu.org>
2015-11-06  9:43     ` Joost Kremers
2015-11-06 16:17       ` Tim Johnson
2015-11-06 16:49         ` Tim Johnson
     [not found] <mailman.1811.1446780244.7904.help-gnu-emacs@gnu.org>
2015-11-06  3:36 ` Barry Margolin
2015-11-06  3:59   ` Tim Johnson
2015-11-06  3:59   ` Emanuel Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).